Mostrar Mensajes

Esta sección te permite ver todos los posts escritos por este usuario. Ten en cuenta que sólo puedes ver los posts escritos en zonas a las que tienes acceso en este momento.


Mensajes - Kabuto

Páginas: 1 ... 5 6 7 8 9 [10] 11 12 13 14 15 ... 50
181
¿En qué te falla?
A mi si me cuenta bien hombres y mujeres. Solo faltaría añadir más funciones para completar lo que pide el enunciado.

Citar
Consola de depuraci6n de Microsoft Visual Studio

Escriba el Nombre 5:luis

Escriba la Edad de 5:32

Escriba el Sexo 5:hombre

Escriba el Sueldo de 5:4400

El registro de personas que se introdujeron es:

Pedro 23 hombre 4500
sara 25 mujer 4700
david 30 hombre 4300
laura 28 mujer 4500
luis 32 hombre 4400

Cantidad hombres: 3
Cantidad mujeres: 2

Por cierto, ya que estamos con C++, para las cadenas mejor usar "string" en lugar de arrays de caracteres.
Así luego es más fácil hacer comparaciones, sin tener que usar strcmp()

Código: [Seleccionar]
#include <iostream>
#include <string>
using namespace std;
struct persona {
    string nombre;
    int edad;
    string sexo;
    int sueldo;

};

//Declaración de procedimientos/funciones
void contarPorSexo(persona *personas);

int main() {
    persona amigo[5];
    for (int i = 0; i < 5; i++) {
        cout << "Escriba el Nombre " << i + 1 << ":";
        cin >> amigo[i].nombre;
        cout << "\nEscriba la Edad de " << i + 1 << ":";
        cin >> amigo[i].edad;
        cout << "\nEscriba el Sexo " << i + 1 << ":";
        cin >> amigo[i].sexo;
        cout << "\nEscriba el Sueldo de " << i + 1 << ":";
        cin >> amigo[i].sueldo;

        cout << endl;
    }
    cout << "El registro de personas que se introdujeron es: \n\n";
    for (int i = 0; i < 5; i++) {
        cout << "\t" << amigo[i].nombre;
        cout << "\t" << amigo[i].edad;
        cout << "\t" << amigo[i].sexo;
        cout << "\t" << amigo[i].sueldo << "\n\n";
    }
    //Pasamos el array a los procedimientos/funciones para que hagan sus tareas
    contarPorSexo(amigo);

    return 0;
}

//Definición de procedimientos/funciones
void contarPorSexo(persona *personas) {
    int hombres = 0, mujeres = 0;

    for (int i = 0; i < 5; i++) {
        if (personas[i].sexo == "mujer")
            mujeres++;
        else
            hombres++;
    }

    cout << "Cantidad hombres: " << hombres << endl;
    cout << "Cantidad mujeres: " << mujeres << endl;
}

182
De todo un poco... / Re: Interés Compuesto
« en: 19 de Junio 2022, 18:18 »
La s de Scanner debe ir en mayúscula, ya que es el nombre de una clase

Citar
import java.util.Scanner;

183
De todo un poco... / Re: Interés Compuesto
« en: 19 de Junio 2022, 11:38 »
Ahí ocurren dos cosas.

Una, que lo estás poniendo en el editor de Python. Tienes que cambiarlo a Java.
Arriba a la derecha, hay un desplegable para elegir lenguaje




Dos, que no se por qué...., te ha traducido el texto del código al español  :o
Te ha puesto "clase pública Principal", cuando el código original es "public class Main"

No se por qué te ha hecho una traducción al español, quizás ha sido tu navegador que ha pensado que estabas copiando un texto en inglés y te ha hecho una traducción automática.

184
Aprender a programar desde cero / Re: Editor de codigo fuente
« en: 19 de Junio 2022, 11:06 »
Lo que comentas de los puntos de colores, seguramente será por el sistema operativo Mac OS de Apple.
Todas sus aplicaciones se muestran con esos marcos y botones.

Hay formas de cambiar el aspecto de Windows 10 para que se vea similar a Mac.
Por ejemplo:
https://www.youtube.com/watch?v=T1u-HL55Fnk

Pero no es sencillo y conlleva ciertos riesgos.
Investiga un poco más sobre como personalizar los temas de Windows. Quizás exista alguna aplicación, aunque sea de pago, que lo haga de forma fácil y segura.

185
De todo un poco... / Re: Interés Compuesto
« en: 19 de Junio 2022, 10:57 »
Que raro, a mi me funciona.
No se porque te sale lo de "SinTitulo3", debería salir como "Main.java".

Pero bueno, entra la página de inicio, elige Java en el selector de lenguaje de la parte de arriba y copia el código de aquí abajo.

Código: [Seleccionar]
import java.util.Scanner;

public class Main {

public static void main(String[] args) {
Scanner teclado = new Scanner(System.in);

System.out.print("Indique valor: ");
int valor = teclado.nextInt();
System.out.print("Indique veces quiere doblar: ");
int vecesDoblar = teclado.nextInt();

System.out.println("\nResultado: " + doblar(valor, vecesDoblar));

teclado.close();

}

public static long doblar(int valor, int veces) {

long valorDoblado = valor;

for (int i = 0; i < veces; i++)
valorDoblado = valorDoblado * 2;

return valorDoblado;
}

}

186
Pero tienes que modular el código, es decir, escribir procedimientos y funciones que reciban el array de struct persona y realicen una tarea específica con él.

Por ejemplo, aquí estaríamos usando un procedimiento para el conteo de hombres y mujeres.
Puede que hay alguna incorrección, C++ no es lo mío...

Código: [Seleccionar]
#include <iostream>
using namespace std;
struct persona {
    char nombre[15];
    int edad;
    char sexo[15];
    int sueldo;

};

//Declaración de procedimientos/funciones
void contarPorSexo(persona *personas);

int main() {
    persona amigo[5];
    for (int i = 0; i < 5; i++) {
        cout << "Escriba el Nombre " << i + 1 << ":";
        cin >> amigo[i].nombre;
        cout << "\nEscriba la Edad de " << i + 1 << ":";
        cin >> amigo[i].edad;
        cout << "\nEscriba el Sexo " << i + 1 << ":";
        cin >> amigo[i].sexo;
        cout << "\nEscriba el Sueldo de " << i + 1 << ":";
        cin >> amigo[i].sueldo;

        cout << endl;
    }
    cout << "El registro de personas que se introdujeron es: \n\n";
    for (int i = 0; i < 5; i++) {
        cout << "\t" << amigo[i].nombre;
        cout << "\t" << amigo[i].edad;
        cout << "\t" << amigo[i].sexo;
        cout << "\t" << amigo[i].sueldo << "\n\n";
    }
    //Pasamos el array a los procedimientos/funciones para que hagan sus tareas
    contarPorSexo(amigo);

    return 0;
}

//Definición de procedimientos/funciones
void contarPorSexo(persona *personas) {
    int hombres = 0, mujeres = 0;

    for (int i = 0; i < 5; i++) {
        if (strcmp(personas[i].sexo,"hombre") > 0)
            mujeres++;
        else
            hombres++;
    }

    cout << "Cantidad hombres: " << hombres << endl;
    cout << "Cantidad mujeres: " << mujeres << endl;
}

187
De todo un poco... / Re: Interés Compuesto
« en: 19 de Junio 2022, 00:11 »
Bueno, ese título se presta a confusión  ;)

En cualquier caso, el código en realidad es muy similar. Un bucle donde lo que hacemos es multiplicar por 2 un valor, tantas veces como queramos.

Y como antes, el tipo de dato puede limitar resultados. Porque aunque no lo parezca, doblar 31 veces incluso un valor de 1, nos puede dar una cifra enorme.

Puedes probar el código aquí

Código: [Seleccionar]
import java.util.Scanner;

public class Main {

public static void main(String[] args) {
Scanner teclado = new Scanner(System.in);

System.out.print("Indique valor: ");
int valor = teclado.nextInt();
System.out.print("Indique veces quiere doblar: ");
int vecesDoblar = teclado.nextInt();

System.out.println("\nResultado: " + doblar(valor, vecesDoblar));

teclado.close();

}

public static long doblar(int valor, int veces) {

long valorDoblado = valor;

for (int i = 0; i < veces; i++)
valorDoblado = valorDoblado * 2;

return valorDoblado;
}

}

188
Ya veo.
Claro, tú no guardas objetos Usuarios ya instanciados, lo que guardas son valores de atributos en una BBDD.

Bueno, lo que puedes hacer es, en lugar de guardar un Usuario como te dije, guarda solo el nombre en un String.

Y al método de getPartida() en lugar de pasarle un Usuario, le pasas ese nombre para que haga una query a la BBDD y así recuperar los datos para crear el objeto Usuario dentro de ese método.

Si crees que hay riesgo de que hayan varios usuarios con exactamente el mismo nombre, puedes guardar también el password.

Creo que tus usuarios tienen un ID, en ese caso, puedes intentar obtener el ID del usuario que se ha logueado y que ese sea el dato que guardes para identificar el "usuario activo"

189
De todo un poco... / Re: Interés Compuesto
« en: 17 de Junio 2022, 11:08 »
¿Hablamos de "doblar" o de "potenciar"?

Doblar sería multiplicar x2 varias veces un valor.

Potenciar es multiplicar un valor por sí mismo, varias veces.

Lo que vimos en la fórmula del interés compuesto, era una potencia
Citar
((1.0 + tasa/100)^31)

Es decir, ese valor no se dobla 31 veces. Si no que se multiplica por sí mismo, 31 veces
valor * valor * valor * valor  * valor * valor  ........ así 31 veces

En una potencia, tenemos una base (valor inicial) y un exponente (las x veces que la base  se multiplica por ella misma.

Así que para hacerlo con un bucle, lo que haremos dentro del bucle será multiplicar la base por sí misma tantas veces como diga el exponente.

Esto sería un ejemplo completo escrito en Java.
El proceso de potenciar se hace en una función escrita separada del programa principal, el cuál lo único que hace es pedir base y exponente para luego mostrar el resultado.
Código: [Seleccionar]
import java.util.Scanner;

public class Potencia {

public static void main(String[] args) {
Scanner teclado = new Scanner(System.in);

System.out.print("Indique valor: ");
int valor = teclado.nextInt();
System.out.print("Indique exponente: ");
int exponente = teclado.nextInt();

System.out.println("\nResultado de la potencia: " + potenciar(valor, exponente));

teclado.close();

}

/*
* Función que recibe una base y un exponente
* y realiza la potencia mediante un bucle.
*/
public static int potenciar(int base, int exp) {

int valorPotenciado = base;

for (int i = 1; i < exp; i++)
valorPotenciado = valorPotenciado * base;

return valorPotenciado;
}

}

Ese código puedes probarlo online en esta URL

Está escrito en Java, pero el proceso sería el mismo para cualquier lenguaje.
Lo único que hay que tener en cuenta son las limitaciones de los tipos de datos.

Ese ejemplo lo he escrito para trabajar con enteros (int), lo cuál sirve para potencias pequeñas.
Citar
Indique valor: 4
Indique exponente: 5

Resultado de la potencia: 1024
Pero una potencia de exponente grande, como puede ser 31, puede dar resultados enormes que sobrepasan las capacidades del tipo de dato int, así que nos dará resultados que no son válidos, incluso incongruentes:
Citar
Indique valor: 4
Indique exponente: 31

Resultado de la potencia: 0

Así que habría que escoger otros tipos de datos con capacidades más amplias.

Para tipos de datos primitivos, tenemos el double, pero incluso este puede no ser suficiente.
Nos dará resultados válidos y correctos, pero usando notación científica para las cifras muy grandes, y puede que no sea esto lo que queramos:
Citar
Indique valor: 4
Indique exponente: 31

Resultado de la potencia: 4.6116860184273879E18

Si queremos seguir trabajando con valores enteros, en Java tenemos la clase BigInteger, que al ser una clase y no un tipo primitivo, hay que modificar la sintaxis del código para operar con él.
Citar
import java.math.BigInteger;
import java.util.Scanner;

public class Potencia {

   public static void main(String[] args) {
      Scanner teclado = new Scanner(System.in);
      
      System.out.print("Indique valor: ");
      BigInteger valor = new BigInteger(teclado.nextLine());
      System.out.print("Indique exponente: ");
      int exponente = teclado.nextInt();
      
      System.out.println("\nResultado de la potencia: " + potenciar(valor, exponente));
      
      teclado.close();

   }
   
   /*
    * Función que recibe una base y un exponente
    * y realiza la potencia mediante un bucle.
    */
   public static BigInteger potenciar(BigInteger base, int exp) {
      
      BigInteger valorPotenciado = base;
      
      for (int i = 1; i < exp; i++)
         valorPotenciado = valorPotenciado.multiply(base);
      
      return valorPotenciado;
   }

}

Ahora sí podemos hacer potencias grandes:
Citar
Indique valor: 4
Indique exponente: 31

Resultado de la potencia: 4611686018427387904

Si quisiéramos, lo mismo, pero trabajando con números reales (más apropiado para cálculos financieros) en lugar de enteros, tenemos la clase BigDecimal


Pero bueno, esto ya es en lo que respecta a Java. Cada lenguaje tendrá sus tipos de datos, sus clases y sus limitaciones propias.

Al margen de esto, la lógica a aplicar para hacer una potencia mediante un bucle, es la misma para cualquier lenguaje:
Citar
   public static int potenciar(int base, int exp) {
      
      int valorPotenciado = base;
      
      for (int i = 1; i < exp; i++)
         valorPotenciado = valorPotenciado * base;
      
      return valorPotenciado;
   }

190
Eso ya depende de como tengas estructurado el resto del código.
En algún lugar deberías poder declarar un atributo Usuario para dejar ahí almacenado al usuario que se ha logueado en cada momento.

La idea es que cuando hayamos validado los datos del login, dejemos una copia de ese objeto Usuario en un atributo de ámbito global (un atributo de clase) para poder pasárselo a otros métodos, de esa clase principal o de otras, y que trabajen con él.

Dejo aquí una idea genérica de la lógica a seguir, escrita en una mezcla de pseudocódigo/pseudoJava xDD

Citar
Clase Main {
   //Lista atributos de clase
   public ... blablaba
   public ... blablaba
   public ... blablaba
   public ... blablaba
   public Usuario userActivo; //Aquí guardamos copia del usuario logueado

   //Método para hacer login
   public void loguearUsuario() {
        //Pedir id
        //Pedir contraseña
        //Buscar usuario con esa id y contraseña

        Usuario buscar = buscarUsuario(id, contraseña);
        si (buscar == null)
                "No existe ese usuario, pruebe otros datos"
        si no
                userActivo = buscar;//Usuario valido para login, lo guardamos como activo
    }

    //Método main principal del programa
    public void main(String[] args) {

        //Inicialización de atributos, clases y lo que corresponda
        //Comenzamos con proceso de login
        loguearUsuario();
        //Si conseguimos un usuario "activo", podemos recuperar su historial partidas
        List<Partida>historial =  getPartida(userActivo);
    }
}


Insisto en que según la estructura de tu programa, esto mismo se podrá hacer de distintas formas, pero la idea genérica es esta.

Algo similar a eso hice en este mensaje

191
De todo un poco... / Re: Interés Compuesto
« en: 11 de Junio 2022, 10:03 »
El "por qué" de la fórmula ya tendría que explicárnoslo alguien con conocimientos de matemáticas financieras.

Supongo que la diferencia entre interés simple y compuesto radica en eso.
El simple se calcula con multiplicaciones y el compuesto aplicando potencias.

Pero vamos, las mates nunca han sido lo mío... :-[

192
Hay algo que no entiendo.
A ese  método, le pasas como argumento un objeto Usuario u

Citar
public List<Partida> getPartida(Usuario u)

Pero luego, en cada iteración del bucle, ese objeto los estás machacando por un nuevo Usuario

Citar
while (rs.next()) {
    Partida p = new Partida(0, null, 0, 0);
    u = new Usuario(0, null);

Si lo que quieres son solo las partidas de ese usuario que has recibido por argumentos, no deberías machacarlo.

En cada iteración del bucle, deberías preguntar si los datos que has recibido de la query actual corresponde a ese usuario o no, por ejemplo preguntando si coincide el id de usuario.
Si no corresponde, no haces nada y dejas que el bucle se repita para obtener una nueva query

Y si corresponde, pues entonces ahora sí creas una nueva Partida con esta query y la agregas al historial


Creo que esta es la lógica que has de seguir para conseguir lo que quieres, es decir, seleccionar solo las partidas del usuario que has recibido como argumento.
Y claro, para ello, lo primero es NO machacar a ese usuario xD

193
De todo un poco... / Re: Interés Compuesto
« en: 10 de Junio 2022, 21:17 »
No soy matemático, y aún menos financiero.
Pero creo que puedo explicar lo que hace esa línea de código donde se ejecuta la fórmula.

La fórmula lo que hace es por un lado calcular la tasa de interés, que es un tanto por ciento

(1.0 + tasa/100)

Esta tasa, es la que hay duplicar 31 veces, así que para ello, hacemos una potencia, es decir, la elevamos a 31
(1.0 + tasa/100)^31

Eso va a dar un resultado, y ahora dicho resultado, lo multiplicamos por el capital inicial
((1.0 + tasa/100)^31) * capitalInicial


Todo eso nos da la suma del dinero que habíamos puesto, más el interés compuesto que ha generado.
Es decir, el monto total que tendríamos una vez transcurridos los 31 días.
MONTO = ((1.0 + tasa/100)^31) * capitalInicial

Pero si queremos conocer solamente el interés compuesto que esto ha generado, no el monto de dinero que tenemos, pues ahora simplemente le restaríamos el capital inicial.

INTERES_COMPUESTO = MONTO - capitalInicial


No se si así explicado y con colorines, es más fácil de entender.

194
De todo un poco... / Re: me podrían ayudar con este problema?
« en: 08 de Junio 2022, 18:54 »
Por favor, no dupliquemos la misma duda una y otra vez.
No va a servir para tener ayuda más rápido.
Publicándolo una vez, se va a ver igual que publicándolo tres veces.

Seguimos aquí

195
Hola.
El ejercicio es prácticamente el mismo, solo hay que modificarlo un poco para adaptarlo a lo que se pide.

En lugar de una clase Venta, ahora trabajaremos con una clase Multa.
La lógica es similar a la que usamos para las ventas, al generar un objeto Multa, sus atributos se van a autorellenar usando valores random al azar.
Como de nuevo para la fecha solo se va a trabajar con el año, lo he simplificado y ya no genero una fecha completa, solo un valor para el año entre 2015 y 2020.
Si se quiere generar una fecha completa, es simplemente copiar el código que usé para la clase Venta.

Clase Multa:
Código: [Seleccionar]
import java.util.Random;

public class Multa {

private String ciudad;
private String tipo;
private int fecha; //Solo año, sin dia ni mes
private int valor;

public Multa() {
Random azar = new Random();
ciudad = ciudadRandom(azar);
tipo = tipoRandom(azar);
fecha = azar.nextInt(6) + 2015;//Genera años entre 2015 y 2020
valor = azar.nextInt(2000) + 1;//Genera valores entre 1 y 2000
}

private String ciudadRandom(Random rnd) {
final String[] ciudades = {"Manta","Portoviejo","Chone","Montecristi","Jipijapa"};
return ciudades[rnd.nextInt(ciudades.length)];
}

private String tipoRandom(Random rnd) {
final String[] tipos = {"A", "B", "C", "D"};
return tipos[rnd.nextInt(tipos.length)];
}

public String toTXT() {
return String.format("%s,%s,%d,%d", ciudad, tipo, fecha, valor);
}

}

Ahora hay que modificar las clases para los threads.
Hilo1 ahora cuenta las multas de unos determinados años y tipo, para luego calcular un porcentaje sobre el total de multas.
Código: [Seleccionar]
import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;

import javax.swing.JOptionPane;
import javax.swing.JProgressBar;
import javax.swing.JTextArea;

/**
 * Porcentaje de año 2015 tipo A, año 2017 tipo C, año 2019 tipo D
 */
public class Hilo1 extends Thread{

private JProgressBar progreso;
private JTextArea texto;

public void setProgreso(JProgressBar progreso) {
this.progreso = progreso;
}

public void setTexto(JTextArea texto) {
this.texto = texto;
}

@Override
public void run() {
progreso.setValue(0);
texto.setText("      Porcentajes de años > 2015 tipo A, 2017 tipo C, 2019 tipo D\n"
+ "      ----------------------------------------------------------------------------\n\n");
//Contadores de años
int cont2015 = 0, cont2017 = 0, cont2019 = 0;
int total = 0;

File archivo = new File("DatosMultas.txt");

try {
long inicio = System.currentTimeMillis();
BufferedReader lector = new BufferedReader(new FileReader(archivo));
String linea = lector.readLine();
while (linea != null) {
//Actualizamo la barra de progreso
progreso.setValue(progreso.getValue() + 1);

total++; //Contamos esta multa para luego calcular porcentaje sobre el total

//Separamos los datos de la línea leída
String[] datos = linea.split(",");
//Capturamos el año
int year = Integer.parseInt(datos[2]);
//Consultamos el tipo y contamos años, si corresponde.
switch(datos[1]) {
case "A":
if (year == 2015)
cont2015++;
break;
case "C":
if (year == 2017)
cont2017++;
break;
case "D":
if (year == 2019)
cont2019++;
}
//Pasamos a la siguiente línea
linea = lector.readLine();
}
lector.close();
long fin = System.currentTimeMillis();
//Resultados
float porc2015 = cont2015 * 100 / total;
float porc2017 = cont2017 * 100 / total;
float porc2019 = cont2019 * 100 / total;
texto.append("Total multas: " + total);
texto.append(String.format("\nAño 2015 tipo A: %.2f%%", porc2015));
texto.append(String.format("\nAño 2017 tipo C: %.2f%%", porc2017));
texto.append(String.format("\nAño 2019 tipo D: %.2f%%", porc2019));
texto.append("\n\nTiempo: " + (fin - inicio) + " ms");
} catch (FileNotFoundException e) {
JOptionPane.showMessageDialog(null, "No hay archivo de datos.", "Calculos de Hilo1",
JOptionPane.ERROR_MESSAGE);
} catch (IOException e) {
JOptionPane.showMessageDialog(null, "Error accediendo a:\n" + archivo.getAbsolutePath(),
"Calculos de Hilo1", JOptionPane.ERROR_MESSAGE);
}
}

}

Hilo2 buscará el valor menor de multa de tipo A, para unas ciudades determinadas:
Código: [Seleccionar]
import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;

import javax.swing.JOptionPane;
import javax.swing.JProgressBar;
import javax.swing.JTextArea;

/**
 * El menor valor de MANTA, PORTOVIEJO, CHONE de tipo A
 */
public class Hilo2 extends Thread{

private JProgressBar progreso;
private JTextArea texto;

public void setProgreso(JProgressBar progreso) {
this.progreso = progreso;
}

public void setTexto(JTextArea texto) {
this.texto = texto;
}

@Override
public void run() {
progreso.setValue(0);
texto.setText("      El menor valor de MANTA, PORTOVIEJO, CHONE de tipo A\n"
+ "      ----------------------------------------------------------------------------------\n\n");
//Variables donde ir guardando los valores menores
int menorManta = Integer.MAX_VALUE, menorPorto = Integer.MAX_VALUE, menorChone = Integer.MAX_VALUE;

File archivo = new File("DatosMultas.txt");

try {
long inicio = System.currentTimeMillis();
BufferedReader lector = new BufferedReader(new FileReader(archivo));
String linea = lector.readLine();
while (linea != null) {
progreso.setValue(progreso.getValue() + 1);
String[] datos = linea.split(",");
//Consultamos ciudad y guardamos valores sin son tipo A y menor que valor guardado actualmente
switch(datos[0]) {
case "Manta":
if (datos[1].equals("A")) {
int valor = Integer.parseInt(datos[3]);
if (valor < menorManta)
menorManta = valor;
}
break;
case "Portoviejo":
if (datos[1].equals("A")) {
int valor = Integer.parseInt(datos[3]);
if (valor < menorPorto)
menorPorto = valor;
}
break;
case "Chone":
if (datos[1].equals("A")) {
int valor = Integer.parseInt(datos[3]);
if (valor < menorChone)
menorChone = valor;
}
}
linea = lector.readLine();
}
lector.close();
long fin = System.currentTimeMillis();
//Resultados
texto.append("Menor valor de Manta: " + menorManta);
texto.append("\nMenor valor de Portoviejo: " + menorPorto);
texto.append("\nMenor valor de Chone: " + menorChone);
texto.append("\n\nTiempo: " + (fin - inicio) + " ms");
} catch (FileNotFoundException e) {
JOptionPane.showMessageDialog(null, "No hay archivo de datos.", "Calculos de Hilo2",
JOptionPane.ERROR_MESSAGE);
} catch (IOException e) {
JOptionPane.showMessageDialog(null, "Error accediendo a:\n" + archivo.getAbsolutePath(),
"Calculos de Hilo2", JOptionPane.ERROR_MESSAGE);
}
}

}

Pasamos a las clases que componen la interfaz. El PanelCrear ahora va a crear 2 millones de multas y las volcará en un archivo de texto.
Código: [Seleccionar]
public class PanelCrear extends JPanel{

private JButton btCrear;

public PanelCrear() {
btCrear = new JButton("Crear nuevo fichero de datos");
btCrear.addActionListener(new AccionCrear());
add(btCrear);
setBorder(BorderFactory.createCompoundBorder(
BorderFactory.createEmptyBorder(25, 25, 25, 25),
BorderFactory.createLoweredSoftBevelBorder()));
}

private class AccionCrear implements ActionListener {
@Override
public void actionPerformed(ActionEvent e) {
JOptionPane.showMessageDialog(null, "A continuación se creará un archivo con 2 millones de líneas."
+ "\nEsto puede tardar unos segundos según las capacidades de tu PC.\nTen paciencia...",
"Crear Archivo", JOptionPane.WARNING_MESSAGE);
File archivo = new File("DatosMultas.txt");
try {
BufferedWriter escritor = new BufferedWriter(new FileWriter(archivo, false));
//Creamos 2 millones de registros
for (int i = 1; i <= 2000000; i++) {
Multa nueva = new Multa(); //Generamos nueva MULTA
escritor.write(nueva.toTXT()); //Creamos una línea de texto con los datos de la MULTA
escritor.newLine();
}
escritor.close();
JOptionPane.showMessageDialog(null, "Nuevos datos creados en:\n" + archivo.getAbsolutePath(),
"Crear Archivo", JOptionPane.INFORMATION_MESSAGE);
} catch (IOException e1) {
JOptionPane.showMessageDialog(null, "No se pudo crear archivo:\n" + archivo.getAbsolutePath(),
"Crear Archivo", JOptionPane.ERROR_MESSAGE);
}

}
}

}

En la clase PanelHilo, no hay que cambiar absolutamente nada. Es lo bueno de modular el código y conseguir abstraer unas clases de otras. Aunque las clases thread cambien, este panel conseguirá ponerlos en marcha sin que eso importe.
Código: [Seleccionar]
public class PanelHilo extends JPanel{

private JProgressBar barraProgreso;
private JTextArea areaTexto;
int tipoHilo; //Se le indica al panel si ha de usar un Hilo1 o un Hilo2

public PanelHilo(int hilo) {
barraProgreso = new JProgressBar(0,2000000);
barraProgreso.setStringPainted(true);
areaTexto = new JTextArea(10, 33);
areaTexto.setEditable(false);
tipoHilo = hilo;

setLayout(new BorderLayout());
JPanel pnBarra = new JPanel();
pnBarra.add(barraProgreso);
pnBarra.setBorder(BorderFactory.createCompoundBorder(
BorderFactory.createEmptyBorder(15,15,15,15),
BorderFactory.createRaisedSoftBevelBorder()));

JPanel pnArea = new JPanel();
pnArea.add(areaTexto);
setBorder(BorderFactory.createCompoundBorder(
BorderFactory.createTitledBorder("Hilo " + tipoHilo),
BorderFactory.createEtchedBorder(EtchedBorder.RAISED)));

add(pnBarra, BorderLayout.NORTH);
add(pnArea, BorderLayout.CENTER);
}

public void calcular() {
//Instanciamos un Hilo1 o un Hilo2 según el atributo tipoHilo
if (tipoHilo == 1) {
Hilo1 hiloCalculos = new Hilo1();
hiloCalculos.setProgreso(barraProgreso);
hiloCalculos.setTexto(areaTexto);
hiloCalculos.start();
}
else {
Hilo2 hiloCalculos = new Hilo2();
hiloCalculos.setProgreso(barraProgreso);
hiloCalculos.setTexto(areaTexto);
hiloCalculos.start();
}
}

}

Por último, la clase principal Formulario.
Aquí tampoco hay que hacer apenas ningún cambio, solo asegurarnos de que le estamos dando correctamente el nombre del archivo de texto con el que ha de trabajar.
Yo como le he cambiado el nombre a este archivo, pues sí tengo que reflejarlo en el código de esta clase:
Código: [Seleccionar]
public class Formulario extends JFrame{

private PanelHilo pnHilo1;
private PanelHilo pnHilo2;
private JButton btIniciar;

public Formulario() {
pnHilo1 = new PanelHilo(1); //Especificamos que "tipo" de hilo ha de usar
pnHilo2 = new PanelHilo(2);

JPanel pnHilos = new JPanel();
pnHilos.add(pnHilo1);
pnHilos.add(pnHilo2);

btIniciar = new JButton("Iniciar Calculos");
btIniciar.addActionListener(new AccionIniciar());
JPanel pnIniciar = new JPanel();
pnIniciar.add(btIniciar);

setLayout(new BorderLayout());
add(new PanelCrear(), BorderLayout.NORTH);
add(pnHilos, BorderLayout.CENTER);
add(pnIniciar, BorderLayout.SOUTH);

setTitle("Calculos con Hilos");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
pack();
setLocationRelativeTo(null);
setVisible(true);
}

public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
new Formulario();
}
});
}

private class AccionIniciar implements ActionListener {
@Override
public void actionPerformed(ActionEvent e) {
File archivo = new File("DatosMultas.txt");
if (archivo.exists()) {
pnHilo1.calcular();
pnHilo2.calcular();
}
else
JOptionPane.showMessageDialog(null, "No existe ningun archivo de datos.",
"Iniciar Calculos", JOptionPane.WARNING_MESSAGE);
}
}
}


Y ya podemos ejecutar el programa.
Sin embargo, en este ejercicio los resultados son un poco decepcionantes, porque la inmensa mayoría de las veces, siempre son los mismos:


Esto es porque la muestra de datos es muy grande (2 millones) así que aunque los datos se generan al azar, al ser tan grande los datos generados tienen oportunidades de sobra para quedar muy igualados.
Así que todas las ciudades van a tener multas de valor 1  y los porcentajes de tipo y año apenas hay diferencias.
Si hacemos una prueba con una muestra menor, por ejemplo 200 multas, o 2000... entonces se obtienen resultados menos igualados. (y más interesantes)

Por favor, no dudes en preguntar lo que no entiendas.

Un saludo.

196
Comunidad / Re: El nuevo xD
« en: 07 de Junio 2022, 17:26 »
Bienvenido.

En la web tienes distintos cursos con los que empezar a programar.

Y aquí en el foro puedes consultar dudas o bien compartir lo que vayas aprendiendo.

Un saludo.

197
Bien, me alegro que se haya resuelto el problema.

Y claro que mejoraras, nadie nace sabiendo. La programación es como todo, al principio cuesta y se cometen errores. Pero cada error es una oportunidad de aprender.

Un saludo.

198
¿Y has comprobado que recibes bien los datos de la BBDD?
Al final de ese método pro ejemplo, puedes probar a poner un bucle y mostrar en pantalla con System.out.println() el contenido de ese ArrayList de partidas, a ver si realmente has conseguido objetos Partida o no.

Si los has conseguido, entonces el fallo estará en la parte donde los intentas mostrar en la tableview

199
¡Oh! :o

Pues es verdad que falta parte del código, parece que en su momento no lo publiqué correctamente.

AccionIniciar es una clase interna anidada dentro de la clase Formulario.
Es una clase que implementa la interfaz ActionListener y así crear una "acción" para el botón que inicia los cálculos.

Pongo aquí la clase Formulario, marcando en negrita la parte de código que faltaba:

Citar
public class Formulario extends JFrame{
   
   private PanelHilo pnHilo1;
   private PanelHilo pnHilo2;
   private JButton btIniciar;
   
   public Formulario() {
      pnHilo1 = new PanelHilo(1); //Especificamos que "tipo" de hilo ha de usar
      pnHilo2 = new PanelHilo(2);
      
      JPanel pnHilos = new JPanel();
      pnHilos.add(pnHilo1);
      pnHilos.add(pnHilo2);
      
      btIniciar = new JButton("Iniciar Calculos");
      btIniciar.addActionListener(new AccionIniciar());
      JPanel pnIniciar = new JPanel();
      pnIniciar.add(btIniciar);
      
      setLayout(new BorderLayout());
      add(new PanelCrear(), BorderLayout.NORTH);
      add(pnHilos, BorderLayout.CENTER);
      add(pnIniciar, BorderLayout.SOUTH);
      
      setTitle("Calculos con Hilos");
      setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      pack();
      setLocationRelativeTo(null);
      setVisible(true);
   }

   public static void main(String[] args) {
      SwingUtilities.invokeLater(new Runnable() {
         @Override
         public void run() {
            new Formulario();   
         }
      });
   }
   
   private class AccionIniciar implements ActionListener {
      @Override
      public void actionPerformed(ActionEvent e) {
         File archivo = new File("DatosVentas.txt");
         if (archivo.exists()) {
            pnHilo1.calcular();
            pnHilo2.calcular();
         }
         else
            JOptionPane.showMessageDialog(null, "No existe ningun archivo de datos.",
                  "Iniciar Calculos", JOptionPane.WARNING_MESSAGE);
      }   
   }

}

200
Yo de momento intento esquivar Windows 11  ;D
Pero vamos, no es un mal S.O. y NetBeans debería funcionar.

¿Qué error te da? A ver si puedes mostrarnos el texto del error, o una captura de pantalla.

Páginas: 1 ... 5 6 7 8 9 [10] 11 12 13 14 15 ... 50

Sobre la educación, sólo puedo decir que es el tema más importante en el que nosotros, como pueblo, debemos involucrarnos.

Abraham Lincoln (1808-1865) Presidente estadounidense.

aprenderaprogramar.com: Desde 2006 comprometidos con la didáctica y divulgación de la programación

Preguntas y respuestas

¿Cómo establecer o cambiar la imagen asociada (avatar) de usuario?
  1. Inicia sesión con tu nombre de usuario y contraseña.
  2. Pulsa en perfil --> perfil del foro
  3. Elige la imagen personalizada que quieras usar. Puedes escogerla de una galería de imágenes o subirla desde tu ordenador.
  4. En la parte final de la página pulsa el botón "cambiar perfil".