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
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;
}

}

182
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;
}

183
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;
}

}

184
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"

185
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;
   }

186
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

187
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... :-[

188
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

189
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.

190
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í

191
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.

192
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.

193
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.

194
¿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

195
¡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);
      }   
   }

}

196
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.

197
Supongo que no lo has ejecutado para comprobar funcionamiento, ya que hay errores de sintaxis, como la coma después de alumno:
Citar
System.out.println("El promedio final del alumno: "+alumno, +apellido" con la edad de: "+edad+" años es de: "+promedio);

Y otro fallos, como que esa variable "alumno" no se usa, ya que el nombre se recoge en una variable llamada "nombre". Pero todas esas variables: nombre, apellido y edad... no se ha declarado su tipo, solo se han declarado las de tipo double.

Pero lo peor es que no se ha usado ni el método ni la función, que es el objetivo principal de este ejercicio.

Dejo un código similar pero con correcciones.
Fíjate que el cálculo del promedio es el mismo que habías hecho, pero esta vez se hace mediante una función

Y los datos finales, además de indicar si esta aprobado o reprobado, se hace mediante un procedimiento

La principal diferencia entre uno y otro, es que una función SIEMPRE retorna un valor, en este caso un double con el promedio calculado.
En cambio un procedimiento, no retorna nada. Realiza unas tareas, pero finaliza sin retornar ningún resultado, por eso se declara como void, es decir, un retorno "vacío".

Código: [Seleccionar]
public class Promedio3notas {

public static void main (String[] args){
Scanner teclado=new Scanner(System.in);
double calificacion1,calificacion2,calificacion3,promedio;
//Petición de datos
System.out.println("Nombre del alumno: ");
String nombre=teclado.nextLine();
System.out.println("Apellido del alumno: ");
String apellido=teclado.nextLine();
System.out.println("Edad del alumno: ");
String edad=teclado.nextLine();
System.out.println("Calificacion de la evaluacion 1: ");
calificacion1=teclado.nextDouble();
System.out.println("Calificacion de la evaluacion 2: ");
calificacion2=teclado.nextDouble();
System.out.println("Calificacion de la evaluacion 3: ");
calificacion3=teclado.nextDouble();
teclado.close();
//Cálculo del promedio
promedio=calcularPromedio(calificacion1, calificacion2, calificacion3);
//Resultado en pantalla
mostrarDatos(nombre, apellido, edad, promedio);
}

//Funcion que calcula el promedio
public static double calcularPromedio(double calif1, double calif2, double calif3) {
return (calif1+calif2+calif3)/3;
}

//Procedimiento que muestra datos y evalua si ha aprobado
public static void mostrarDatos(String nombre, String apellido, String edad, double promedio) {
System.out.println("\n\t-- DATOS DEL ALUMNO --");
System.out.println("Nombre: " + nombre + " " + apellido);
System.out.println("Edad: " + edad);
System.out.println("Nota Promedio: " + promedio);
System.out.print("Estado: ");

if (promedio < 5)
System.out.println("Reprobado");
else
System.out.println("Aprobado");
}
}

198
Hola.

Comienza tú un código y te ayudamos a completarlo cuando te atasques.
Empieza cumpliendo objetivos "menores", en lugar de intentar resolver "todo" de una sola vez.

Por ejemplo, comienza por hacer un programa donde simplemente se pidan estos datos:
Citar
1. Nombre
2. Apellido
3. Edad
4. Calificación 1
5. Calificación 2
6. Calificación 3

De momento no computes nada, simplemente pedir esos datos por teclado y fin.

Cuando lo tengas, piensa ahora en como hacer la función que calcule el promedio.
Dicha función ha de recibir como argumentos las tres calificaciones y ha de retornar el promedio.
La firma de dicha función podría ser esta:
Código: [Seleccionar]
public static double calculaPromedio(double calif1, double calif2, double calif3) {

}

Intenta desarrollar el código para hacer el cálculo de ese promedio.

Y ya luego, tocaría pensar en el procedimiento que reciba los datos del alumno y el promedio que haya calculado la función. Este procedimiento mostrará esos datos en pantalla y dirá si está aprobado o reprobado.

Código: [Seleccionar]
public static void mostrarDatos(String nombre, String apellido, int edad, double promedio) {

}

Cumpliendo estos tres objetivos menores más sencillos, habremos cumplido el total de la tarea.

Inténtalo, llega hasta donde puedas, comparte por aquí tu código y te ayudamos a completar/corregir.


Un saludo.

199
El código lo escribí con Eclipse, pero eso no importa, sirve para NetBeans, IntelliJ y cualquier programa editor de código.

Si con "estructurar la carpeta" te refieres a cuáles podrían ser los packages para crear para el proyecto, pues eso va a gusto de cada uno.
Yo lo hice todo dentro de un único package, ya que es un proyecto pequeño, pero sí es buena costumbre separar las clases en distintos packages según su naturaleza.

Se podría crear un package llamado "vista", o "interfaz", o "gui"(de graphical user interface) que agrupe las clases que modelan los paneles y el marco del programa principal.
Es decir, las que crean lo que se ve en pantalla (la vista).
Estas serían las clases: PanelCrear, PanelHilo y Formulario.

En otro package se podrían poner las clases que modelan lo que "no se ve", lo que vienen a ser representación de datos y/o de procesos y que comúmente se llama el "modelo"
Estas serían las clases: Venta, Hilo1 e Hilo2.


Por otra parte, no se si al trabajar con NetBeans, te van a pedir que la interfaz de usuario la construyas usando el "GUI Builder".
Ahí poco o nada puedo ayudarte. Nunca lo uso, no se usarlo, siempre construyo las interfaces Swing tecleando código, no usando formularios de "click y arrastrar" para que autogenere el código.

200
Comunidad / Re: Me presento!!
« en: 27 de Mayo 2022, 17:38 »
Bienvenido Pablo.
Disfruta del contenido que ofrece la página y no dudes en preguntar aquí en el foro cualquier duda que tengas.

Un saludo.

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".