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 ... 11 12 13 14 15 [16] 17 18 19 20 21 ... 50
301
A ver, alguna pequeña mejora.
El menú mejor meterlo dentro del bucle while, así se muestra siempre después de cada acción.
De lo contrario, solo se muestra una vez

Citar
   void estructuraMenu(){
      Scanner leer=new Scanner(System.in);
      gestionPaciente datos=new gestionPaciente();
      gestionHorario info = new gestionHorario(datos);
      int op;
      boolean Salir=false;
      
      while(!Salir){
         System.out.println("\nMenú de acciones");
         System.out.println("1. Registrar nuevo paciente");
         System.out.println("2. Agendar Cita (Ya sea nuevo o no el paciente)");
         System.out.println("3. Mostrar datos del Paciente");
         System.out.println("4. Mostrar datos de la Cita");
         System.out.println("4. Eliminar cita");
         System.out.println("6. Salir");

         try {
            System.out.println("¿Cuál acción desea realizar?");
            op=leer.nextInt();
            switch (op){

Sobre el caso 2.
Yo lo que detecto al indicar 'N' es que el Scanner se salta la lectura de la cita;
Citar
if(op=='N'){
            System.out.println("Introduzca el ID de la cita");
            String cita=leer.nextLine();

Y eso se debe a que anteriormente, se ha hecho una lectura con next()
Citar
public boolean nuevo() {
      char op;
      System.out.println("¿Es nuevo el paciente?(S/N)");   
      do{
         op=leer.next().charAt(0);


next() debería usarse solo en caso concretos (yo de hecho no lo uso prácticamente nunca), porque no hace una lectura "completa" de lo que ha entrado por teclado.
next() devuelve lo "siguiente" que se pueda considerar una palabra o una letra, pero deja en el buffer de entrada cosas como el caracter "retorno de carro", que es un carácter especial que generamos cada vez que pulsamos la tecla enter/intro para introducir un dato.
¿Problema?
Que si luego queremos hacer una lectura con nextLine(), este método si retorna TODO lo que se encuentre en el buffer. Entonces, si al momento de invocarlo se encuentra con que el buffer de entrada ya tiene un carácter de "retorno de carro" disponible, entonces nextLine() piensa que el usuario ya ha terminado de introducir el dato, pero no es cierto.

Por eso, al menos a mi me ocurre, se me salta la lectura del ID de la cita y pasa a la del paciente, sin que yo haya podido teclear nada.

Citar
Vuelva a introducir el dato correcto.
n
Vuelva a introducir el dato correcto.
N
Introduzca el ID de la cita
Inroduce el ID del paciente
2
Esto se soluciona haciendo siempre lecturas con nextLine(), así las lecturas son "completas" y no se dejan restos que luego puedan falsear lecturas posteriores.

A partir de ahí, al introducir id de paciente, nos encontramos con un error de metodología.
Pedimos el ID, pero no hacemos absolutamente nada con ese dato. Lo siguiente que se hace es llamar al método mostrar() del gestor de pacientes, que lo que hace es pedir de nuevo el id mediante un JOptionPane.
Citar
         if(op=='N'){
            System.out.println("Introduzca el ID de la cita");
            String cita=leer.nextLine();
            System.out.println("Inroduce el ID del paciente");
            String id=leer.nextLine();
            pacientes.mostrar();

Por cierto, según el programa que estés usando para ejecutar el código, puede que no veas el JOptionPane porque se queda por detrás del programa. Esto ocurre también con los otros case del switch.

A mí me pasa usando Eclipse, parece que al llegar a ese punto la aplicación no está haciendo nada, pero en realidad ha salido un JOptionPane que para verlo tengo que minimizar Eclipse.

Pero supongo que no necesitamos que nos muestren ningún paciente, si no que nos retornen uno a partir del ID.

Y con el paciente y los otros datos, debemos crear una cita, bueno, lo que tu has llamado como clase Horarios.
Pero veo que en esta clase (donde por cierto los métodos setter están mal), has comentado las líneas relativas al paciente:
Citar
public class Horarios {
   
   private String hora,fecha,cita;
   // private gestionPaciente paciente;
   
   public Horarios(String fecha, String hora, String cita){
      this.hora=hora;
      this.fecha=fecha;
      this.cita=cita;
      //this.paciente=paciente;
   }
   
   String getFecha(){
      return fecha;
   }
   void setfecha(){
      this.fecha=fecha;
   }
   String getHora(){
      return hora;
   }
   void setHora(){
      this.hora=hora;
   }
   String getCita(){
      return cita;
   }
   void setCita(){
      this.cita=cita;
   }
   // gestionPaciente getPac(){
   //  return paciente;
   //}
   //void setPac(){
   //  this.paciente=paciente;
   //
}
   public void mostrar(){
      System.out.println("\n\t---------------");
      System.out.println("HORARIO");
      System.out.println("ID Cita: ");
      System.out.println(cita);
      System.out.println("Fecha: ");
      System.out.println(fecha);
      System.out.println("Hora: "+hora);
      System.out.println("\t---------------");
   }
}

¿Por qué? ¿No se debe incluir al paciente en la cita?
¿Cómo sabemos luego a cuál paciente corresponde cada cita agendada?

Creo que lo correcto es que sí esté incluido, pero no un gestionPaciente, si no un datosPacientes, que es la clase que representa a un paciente en concreto.

Quedaría así la clase Horarios(con setters corregidos)
Citar
public class Horarios {

   private String hora,fecha,cita;
   private datosPacientes paciente;

   public Horarios(String fecha, String hora, String cita, datosPacientes paciente){
      this.hora=hora;
      this.fecha=fecha;
      this.cita=cita;
      this.paciente=paciente;
   }

   public String getFecha(){
      return fecha;
   }
   public void setfecha(String fecha){
      this.fecha=fecha;
   }
   public String getHora(){
      return hora;
   }
   public void setHora(String hora){
      this.hora=hora;
   }
   public String getCita(){
      return cita;
   }
   public void setCita(String cita){
      this.cita=cita;
   }
   public datosPacientes getPac(){
      return paciente;
   }
   public void setPac(datosPacientes paciente){
      this.paciente=paciente;
   }

   public void mostrar(){
      System.out.println("\n\t---------------");
      System.out.println("HORARIO");
      System.out.println("ID Cita: ");
      System.out.println(cita);
      System.out.println("Fecha: ");
      System.out.println(fecha);
      System.out.println("Hora: "+hora);
      System.out.println("Paciente: " + paciente.nom);
      System.out.println("\t---------------");
   }
}

Y ahora, en el case 2 donde agendamos las citas, podemos usar nextLine() para las lecturas de Strings y caracteres char (además nos permite transformar lo tecleado a mayúsculas) y también rediseñar los condicionales IF, con IF ELSE... para quede un poco más elegante.

Cuando se introduzca N para indicar que el paciente ya existe, debemos pedir el ID y que el gestor de pacientes nos retorne el paciente correspondiente.
Y con ese paciente creamos el objeto Horarios.
El método que nos retorna el paciente según el ID, si no encuentra el paciente nos va a retornar null. Esto estaría bien controlarlo, pero para no complicar más el código, yo de momento lo dejaría sin controlar, y en todo caso, cuando ya todo funcione y se tenga más clara la lógica que se está siguiendo, entonces se pueden mejorar estos detalles.

Pero, ¿y cuando se introduce S? Hay que crear un paciente nuevo, pero además necesitamos tenerlo a mano para crear el objeto Horarios.
El paciente se crea DENTRO del método pacientes.nuevo(), pero FUERA de él, que es donde nos encontramos en el momento en que lo llamamos, no nos va a quedar nada para identificar al paciente que se acaba de crear: ni el id, ni el nombre, ni nada...

Es decir, en la línea que marco en rojo, se ha creado un paciente, pero en las siguientes líneas no tenemos nada para encontrar el paciente que se acaba de crear, y lo necesitamos para agendar la cita en el objeto Horarios

Citar
if(op=='S'){
            System.out.println("Introduzca el ID de la cita");
            String cita=leer.next();
            leer.nextLine();
            pacientes.nuevo();
            System.out.println("Introduzca la hora:");
            String hora=leer.nextLine();
            System.out.println("Introduzca la fecha (dd/mm/aa)");
            String fecha=leer.nextLine();
            Horarios nuevo=new Horarios(cita,hora,fecha);
            horas.add(nuevo);

Para solucionarlo y agilizar el código, podemos cambiar el método que crea pacientes.
Ahora mismo es de tipo boolean, devuelve true o false, y la verdad es que no estamos dando uso a ese boolean. No nos aporta nada.

Podemos cambiarlo, y hacer que una vez creado el paciente, además de guardarlo nos lo retorne. Así podemos recogerlo y usarlo para agendar la cita.

En la clase gestionPaciente, cambiamos el método nuevo():
Citar
   public datosPacientes nuevo() {
      System.out.println("\n\t NUEVO PACIENTE");
      System.out.println("Introduzca ID: ");
      String id=leer.next();
      System.out.println("Ingrese el nombre: ");
      String nom=leer.next();
      leer.nextLine();
      System.out.println("Ingrese el domicilio: ");
      String dir=leer.next();
      leer.nextLine();
      System.out.println("Ingrese el número de telefono: ");
      String telPac=leer.next();
      leer.nextLine();
      System.out.println("Ingrese el número celular: ");
      String celPac=leer.next();
      System.out.println("Ingrese el correo electrónico: ");
      String corr_ele=leer.next();
      System.out.println("Ingrese la edad: ");
      int ed=leer.nextInt();
      leer.nextLine();
      datosPacientes nuevoPaciente =new datosPacientes( nom, telPac, celPac,
            corr_ele,  dir,  id,  ed);
      pacientes.add(nuevoPaciente);
      return nuevoPaciente; //Retornamos el paciente recién creado
   }

Así, al crear un paciente nuevo cuando agendamos cita, recibimos el paciente creado para poder dárselo al objeto Horarios

En la clase gestionHorario, aplicamos todos estos cambios al método nuevo():
Citar
public void nuevo() {
      char op;
      System.out.println("¿Es nuevo el paciente?(S/N)");   
      do{
         op=leer.nextLine().toUpperCase().charAt(0);
         
         if(op=='S'){
            System.out.println("Introduzca el ID de la cita");
            String cita=leer.next();
            leer.nextLine();
            datosPacientes paci = pacientes.nuevo();//Se crea un paciente y nos lo retornan
            System.out.println("Introduzca la hora:");
            String hora=leer.nextLine();
            System.out.println("Introduzca la fecha (dd/mm/aa)");
            String fecha=leer.nextLine();
            Horarios nuevo=new Horarios(cita,hora,fecha,paci);
            horas.add(nuevo);
         }
         else if(op=='N'){
            System.out.println("Introduzca el ID de la cita");
            String cita=leer.nextLine();
            System.out.println("Introduzca el ID del paciente");
            String idPaci = leer.nextLine();
            datosPacientes paci = pacientes.getPac(idPaci); //No estamos controlando si retorna null
            System.out.println("Introduzca la hora:");
            String hora=leer.nextLine();
            System.out.println("Introduzca la fecha (dd/mm/aa)");
            String fecha=leer.nextLine();
            Horarios nuevo=new Horarios(cita,hora,fecha,paci);
            horas.add(nuevo);
         }
         else
            System.out.println("Vuelva a introducir el dato correcto.");

      }while((op!='S')&&(op!='N'));
   }

Ahora ya podemos agendar citas, sin embargo, todavía hay un error.
Si pedimos que se muestren las citas agendadas (recuerda que el JOptionPane se queda escondido detrás de tu editor de código), falla al encontrar citas buscando por el id de la cita.

Y es porque al construir los objetos Horarios, no estamos dando los parámetros en el orden correcto.
Para crearlos estamos dando el id de la cita, la hora, la fecha y el paciente:
Código: [Seleccionar]
Horarios nuevo=new Horarios(cita,hora,fecha,paci);
Pero en su clase, el constructor lo hemos definido con un orden distinto.
Primero la fecha, luego la hora, luego el id de la cita y finalmente el paciente
Código: [Seleccionar]
public Horarios(String fecha, String hora, String cita, datosPacientes paciente)
Hay que construir los Horarios dandole los datos en el mismo orden que hemos establecido en el constructor, si no, los valores de los atributos están intercambiados unos con otros y por eso ahora no se encuentran citas por el id de cita.
Hay que corregirlo:
Código: [Seleccionar]
Horarios nuevo=new Horarios(fecha,hora,cita,paci);

Y con esto, ya parece funcionar más o menos todo bien.
Habrá cosas y detalles por pulir, por ejemplo, al eliminar una cita el mensaje que se muestra en pantalla es que se ha eliminado un paciente y no una cita
Citar
   public boolean eliminar(){
      String cita=JOptionPane.showInputDialog(null,"Introduzca identificador de la cita para mostar datos: ",
            "Mostrar datos de la cita",JOptionPane.QUESTION_MESSAGE);
      Horarios citas=null;
      for (int i=0;i<horas.size();i++){
         if(horas.get(i).getCita().equals(cita)){
            citas=horas.remove(i);
         }
      }
      if(citas==null){
         JOptionPane.showMessageDialog(null, "No se encuentra ninguna cita con el ID:\n"+cita,
               "Cita no encontrada", JOptionPane.WARNING_MESSAGE);
         return false;
      }else {
         JOptionPane.showMessageDialog(null, "Se elimino el paciente con ID:\n" + cita,
               "Paciente Eliminado", JOptionPane.INFORMATION_MESSAGE);

         return false;
      }
   }

Pero son detalles para ir puliendo poco a poco.

Sobre todo recuerda que cuando al elegir una opción parezca que el programa no hace nada, seguramente es que ha aparecido un JOptionPane que se ha quedado detrás del editor de código.
Minimiza el editor, o usa las teclas ALT+TAB para rotar entre las ventanas abiertas.

Si no es obligatorio usar los JOptionPane, yo lo quitaría y lo haría todo por la consola de texto.

Un saludo.

302
Gracias por compartir la solución.
Seguro que algún día alguien se encuentra con un problema similar y agradecerá encontrarse con tus mensajes.

Un saludo.

303
No tengo claro que la herencia sea lo más correcto.

Hay que tener claro lo que implica "heredar".
Cuando decimos que la clase Perro hereda de Animal, estamos diciendo que un perro es un animal.
Y es cierto.

Si decimos que la clase Empleado hereda de Persona, estamos diciendo que un empleado es una persona.
Y es cierto.

Si decimos que la clase GestionCitas hereda de GestionPaciente, estamos diciendo que un gestor de citas es un gestor de pacientes.
Pero no creo que eso sea cierto.
Son cosas distintas, puede existir una relación entre ellas, pero no de herencia.

Lo que se desea es que al gestionar una cita con gestionCitas, tengamos rápido acceso a los pacientes creados en gestionPaciente.
Vale, pero porque hagamos una herencia, no vamos a tener acceso a esos pacientes que pertenecen a otro objeto.

En el programa, hay un objeto gestionPaciente que tendrá unos pacientes creados.
Pero cuando tu creas un objeto gestionCitas, aunque le des herencia a gestionPaciente, en realidad estarás creando un nuevo gestor de Pacientes, que no tiene los pacientes que se hayan creado en el otro objeto gestor de pacientes.
Al hacer herencia, gestionCitas ahora tendrá su propio ArrayList de pacientes, e insisto en que será totalmente ajeno al "otro" ArrayList del otro gestor de pacientes.

Entonces, yo personalmente no haría una herencia.
Si quiero que el gestor de citas tenga una relación directa con el gestor de pacientes, lo que haría sería colocarle un atributo gestionPacientes y pasarle por el constructor una referencia al objeto gestionPacientes que habremos construido en el programa principal.
No sería una relación de herencia, sino una relación "de inclusión".

Citar
public class gestionCitas {
    private gestionPacientes pacientes;
    private ArrayList<claseCita>citas;
    private Scanner leer;
        public gestionCitas(gestionPacientes paci){ //Constructor recibe referencia
            pacientes  = paci; //El gestor de pacientes, queda aquí referenciado
            citas=new ArrayList<claseCita>();
            leer=new Scanner(System.in);
            gestionPaciente pac=new gestionPaciente();
        }

Esto implica que en el programa principal, creare los dos objetos gestores, y uno recibirá al otro por su constructor, para que así queden relacionados.

Citar
public final class TestClinica {
   
   static gestionPacientes gestorPaci = new gestionPacientes();
   static gestionCitas gestorCitas = new gestionCitas(gestorPaci); //Citas recibe referencia de pacientes

   public static void main(String[] args) {
      

   }

De esta manera, hay un único gestor de pacientes, pero tiene dos referencias apuntando a él, la del programa principal y el atributo que hemos puesto en el gestor de citas.
De esta forma, el gestor de citas tiene acceso directo a los pacientes.
Y no es necesaria hacer ninguna herencia.

Ahora bien, dicho esto, si el enunciado exige hacerlo por herencia, pues se puede hacer.
Pero para que funcione bien, el programa principal solamente ha de tener un objeto de gestor de citas. Nada más.

Citar
public final class TestClinica {
   
   static gestionCitas gestorCitas = new gestionCitas();

   public static void main(String[] args) {
      

   }

Pero entonces, ¿Dónde están los pacientes?¿Quién los gestiona?

Bueno, si hacemos herencia, estamos diciendo que un gestor de citas, es un gestor de pacientes.....
Por lo tanto, el gestor de citas será quien se encargue de todo, de gestionar las citas, y también los pacientes.
Al hacer herencia, recibe un ArrayList donde insertar objetos de la clase Paciente, y recibe también todos los métodos necesarios para gestionarlos.

Solo habría que prestar atención a dos cosas.
Una, asegurarnos con la instrucción super() de que al construir un gestor de citas, se construye el gestor de pacientes.
No es obligatorio poner super(), pero siempre es mejor ponerlo, aunque solo sea para recalcar que existe una relación de herencia.

Citar
public class gestionCitas extends gestionPaciente {
    private ArrayList<claseCita>citas;
    private Scanner leer;
        public gestionCitas(){
            super(); //Nos aseguramos de que primero se construye la clase madre, o sea,  el gestor de pacientes
            citas=new ArrayList<claseCita>();
            leer=new Scanner(System.in);
        }

Y lo segundo, es irnos a la clase gestionPacientes y cambiar la visibilidad de su ArrayList, de private a protected.
Citar
public final class gestionPaciente {
    protected ArrayList<datosPacientes>pacientes;
    private Scanner leer;
        public gestionPaciente(){
            pacientes=new ArrayList<datosPacientes>();
            leer=new Scanner(System.in);
        }
De esta manera, sigue siendo privado para que clases ajenas no puedan meterle mano, pero si es visible para sus clases hijas, en este caso gestionCitas, quien sí necesita acceso al ArrayList de pacientes.

Ahora la clase gestionCitas, debería poder nombrar directamente al ArrayList de pacientes, como si fuera suyo (de hecho, sí lo es).
Si no ponemos protected, creo que las llamadas al ArrayList que marco en azul a continuación, no habrían funcionado.
Citar
public class gestionCitas extends gestionPaciente {
    private ArrayList<claseCita>citas;
    private Scanner leer;
        public gestionCitas(){
            super();
            citas=new ArrayList<claseCita>();
            leer=new Scanner(System.in);
        }   
        public boolean nuevaCita(){
                System.out.println("\n\t NUEVO CITA");
                String id=JOptionPane.showInputDialog(null,"Introduzca identificador del paciente para mostrar datos: ",
                    "Mostrar datos del paciente",JOptionPane.QUESTION_MESSAGE);
                datosPacientes paciente=null;
                        for (int i=0;i<pacientes.size();i++){
                            if(pacientes.get(i).getID().equals(id)){
                                 paciente=pacientes.get(i);
                                 paciente.mostrarDatos();
                        }


Y de esta manera, el gestor de citas , será también el gestor de pacientes, dos en uno.
Así que si queremos crear un paciente, el gestor de citas será quien se encargue porque dispone de los métodos necesarios.

Citar
public final class TestClinica {
   
   static gestionCitas gestorCitas = new gestionCitas();

   public static void main(String[] args) {
      
      gestorCitas().nuevoPaciente();//El gestor de citas puede crear pacientes, porque es un gestor de pacientes
   }


Espero que se haya entendido la explicación, puede ser un poco liosa la filosofía de la programación orientada a objetos.

Lo que se pide se puede resolver con una relación de herencia, pero si nos ponemos un poco filosóficos, no sería la forma correcta.

Si quiero modelar un coche con su motor y tal.
Y digo:
Código: [Seleccionar]
public Coche extends Motor {

    public Coche() {
        super();
    }

}
Sí, he conseguido que el coche tenga acceso a un motor, pero lo que estoy diciendo es que un Coche es un Motor..., y eso es una burrada.

Un Coche, tiene un Motor, lo correcto sería una relación de inclusión: Coche incluye a Motor (pero no son lo mismo)

Código: [Seleccionar]
public Coche {

    Motor motor;

    public Coche() {
        motor = new Motor();
    }
}

A efectos prácticos puede parecer lo mismo una relación que la otra...., pero no, no son lo mismo... y de hecho en según que escenarios elegir la relación equivocada puede traer complicaciones no deseadas.

Pero bueno, si el enunciado manda herencia, pues herencia...  ::)

304
Para la opcion1, hay que pedir dimensiones de la matriz, filas y columnas. Con estos datos construimos matriz y pasamos a pedir valores mediante bucles anidados.
Para aligerar, no estoy poniendo posibles controles de errores, como que no nos pasen enteros para las filas y columnas, o cadenas vacías para los valores...
Eso es algo que se puede añadir después si fuera necesario.
Código: [Seleccionar]
private static void opcion1() {
//Preguntamos dimensiones de la matriz
int filas = Integer.parseInt(JOptionPane.showInputDialog("¿Cuántas filas tendrá la matriz?"));
int columnas = Integer.parseInt(JOptionPane.showInputDialog("¿Cuántas columnas tendrá la matriz?"));
//Creamos nueva matriz
matriz = new String[filas][columnas];
//Pedimos valores
for (int f = 0; f < filas; f++)
for (int c = 0; c < columnas; c++)
matriz[f][c] = JOptionPane.showInputDialog("Deme un valor...");

JOptionPane.showMessageDialog(null, "Nueva matriz creada",
"Crear matriz", JOptionPane.INFORMATION_MESSAGE);
}

Opcion 2.
Para mostrar la matriz en un JOptionPane, tenemos que construir un String con todos los valores, separados con espacio en blanco y con saltos de línea tras terminar cada fila.
Para ello podemos usar un objeto StringBuilder, con bucles anidados recorremos la matriz y en cada iteración añadimos un valor al StringBuilder.
Luego al final, ya tan solo hay que mostrarlo en un JOptionPane
Código: [Seleccionar]
private static void opcion2() {
//Construiremos un String con los datos de la matriz
StringBuilder datos = new StringBuilder("MATRIZ\n");
for (int f = 0; f < matriz.length; f++) {
for (int c = 0; c < matriz[f].length; c++)
datos.append(matriz[f][c] + " ");

datos.append("\n");//Cada fila acaba con un salto de línea
}
//String construido, lo mostramos
JOptionPane.showMessageDialog(null, datos, "Datos Matriz", JOptionPane.INFORMATION_MESSAGE);
}

Opcion 3.
Prácticamente igual que la opción 2, solo hay que invertir el orden en el que recorremos las filas para invertir la matriz.
Código: [Seleccionar]
private static void opcion3() {

StringBuilder datos = new StringBuilder("MATRIZ\n");
//Para invertir, las filas comienzan desde la última a la primera
for (int f = matriz.length -1 ; f >= 0; f--) {
for (int c = 0; c < matriz[f].length; c++)
datos.append(matriz[f][c] + " ");

datos.append("\n");
}
JOptionPane.showMessageDialog(null, datos, "Matriz invertida", JOptionPane.INFORMATION_MESSAGE);
}

Y ya está, eso es todo. Cualquier cosa que no se entienda, solo hay que preguntar.

Abajo pongo el código final definitivo.
Código: [Seleccionar]
import javax.swing.JOptionPane;

public class MenuMatriz {
//Matriz sobre la que vamos a trabajar
private static String[][] matriz;
//Textp con las opciones del menú
private static final String TEXTO_MENU = "1. Llenar Matriz\n2. Consultar datos de la matriz.\n"
+ "3. Invertir el orden de la matriz\n4. Salir.";

public static void main(String[] args) {

String opcion = "";
boolean salir = false;

while (!salir) {
//Mostramos menú
opcion = JOptionPane.showInputDialog(null, TEXTO_MENU, "Elija opción",
JOptionPane.QUESTION_MESSAGE);
//Si usuario elige botón CANCELAR, equivaldrá a elegir la opción de "Terminar programa"
if (opcion == null)
opcion = "4";
//Comprobamos opcion escogida
switch(opcion) {
case "1":
opcion1();
break;
case "2":
opcion2();
break;
case "3":
opcion3();
break;
case "4":
salir = opcion4();
break;
default:
JOptionPane.showMessageDialog(null, "Opción equivocada",
"Elija opción", JOptionPane.WARNING_MESSAGE);
}

}
//Mensaje final
JOptionPane.showMessageDialog(null, "FIN DE PROGRAMA",
"Terminar programa", JOptionPane.INFORMATION_MESSAGE);

}

private static void opcion1() {
//Preguntamos dimensiones de la matriz
int filas = Integer.parseInt(JOptionPane.showInputDialog("¿Cuántas filas tendrá la matriz?"));
int columnas = Integer.parseInt(JOptionPane.showInputDialog("¿Cuántas columnas tendrá la matriz?"));
//Creamos nueva matriz
matriz = new String[filas][columnas];
//Pedimos valores
for (int f = 0; f < filas; f++)
for (int c = 0; c < columnas; c++)
matriz[f][c] = JOptionPane.showInputDialog("Deme un valor...");

JOptionPane.showMessageDialog(null, "Nueva matriz creada",
"Crear matriz", JOptionPane.INFORMATION_MESSAGE);
}

private static void opcion2() {
//Construiremos un String con los datos de la matriz
StringBuilder datos = new StringBuilder("MATRIZ\n");
for (int f = 0; f < matriz.length; f++) {
for (int c = 0; c < matriz[f].length; c++)
datos.append(matriz[f][c] + " ");

datos.append("\n");//Cada fila acaba con un salto de línea
}
//String construido, lo mostramos
JOptionPane.showMessageDialog(null, datos, "Datos Matriz", JOptionPane.INFORMATION_MESSAGE);
}

private static void opcion3() {

StringBuilder datos = new StringBuilder("MATRIZ\n");
//Para invertir, las filas comienzan desde la última a la primera
for (int f = matriz.length -1 ; f >= 0; f--) {
for (int c = 0; c < matriz[f].length; c++)
datos.append(matriz[f][c] + " ");

datos.append("\n");
}
JOptionPane.showMessageDialog(null, datos, "Matriz invertida", JOptionPane.INFORMATION_MESSAGE);
}

private static boolean opcion4() {
int pregunta = JOptionPane.showConfirmDialog(null, "¿Seguro que quiere salir?",
"Terminar programa", JOptionPane.YES_NO_OPTION);
if (pregunta == JOptionPane.YES_OPTION)
return true;
else
return false;
}

}

305
Vamos a desarrollarlo poco a poco.

Mostraremos un menú para que el usuario introduzca la opción.
Esta opción la analizaremos con un switch y llamaremos a distintos métodos según lo que haya escogido.
Cada opción tendrá su propio método.

Para que los métodos tengan acceso a la matriz sobre la que trabajaremos, esta la declararemos como atributo de la clase, para que así tenga un "ámbito global" y sea visible desde cualquier parte del programa.

El menú se mostrará dentro de un bucle while que se repetirá mientras un boolean tenga valor false. Cuando el usuario confirme que SÍ quiere salir, el boolean pasará a valor true y se terminará el programa.

Pongo el programa principal y el método para la opción 4, la de salir si el usuario lo confirma.

Comprueba el código y asegúrate de que lo entiendes, pregunta lo que necesites.
Faltarían los métodos para las opciones 1, 2 y 3.
Luego miraré de desarrollarlo, aunque si primero te atreves tú a intentar hacerlos, mejor.

Código: [Seleccionar]
import javax.swing.JOptionPane;

public class MenuMatriz {
//Matriz sobre la que vamos a trabajar
private static String[][] matriz;
//Texto con las opciones del menú
private static final String TEXTO_MENU = "1. Llenar Matriz\n2. Consultar datos de la matriz.\n"
+ "3. Invertir el orden de la matriz\n4. Salir.";

public static void main(String[] args) {

String opcion = "";
boolean salir = false;

while (!salir) {
//Mostramos menú
opcion = JOptionPane.showInputDialog(null, TEXTO_MENU, "Elija opción",
JOptionPane.QUESTION_MESSAGE);
//Si usuario elige botón CANCELAR, equivaldrá a elegir la opción de "Terminar programa"
if (opcion == null)
opcion = "4";
//Comprobamos opcion escogida
switch(opcion) {
case "1":
//opcion1();
break;
case "2":
//opcion2();
break;
case "3":
//opcion3();
break;
case "4":
salir = opcion4();
break;
default:
JOptionPane.showMessageDialog(null, "Opción equivocada",
"Elija opción", JOptionPane.WARNING_MESSAGE);
}

}
//Mensaje final
JOptionPane.showMessageDialog(null, "FIN DE PROGRAMA",
"Terminar programa", JOptionPane.INFORMATION_MESSAGE);

}

private static boolean opcion4() {
int pregunta = JOptionPane.showConfirmDialog(null, "¿Seguro que quiere salir?",
"Terminar programa", JOptionPane.YES_NO_OPTION);
if (pregunta == JOptionPane.YES_OPTION)
return true;
else
return false;
}

}

306
Cada tema tiene un identificador, por ejemplo: CU00511F

Puedes probar a usar el buscador del foro por esos identificadores.

Sin embargo, los ejercicios propuestos en los cursos normalmente se pueden resolver aplicando lo enseñado en ese mismo tema.
Así que te invito a que intentes resolverlos tú, y si te atascas, si no te funciona,... entonces pregunta por aquí e intentamos ayudarte a resolverlo.

Se aprende mucho más fracasando al intentar resolver el ejercicio, que mirando la solución ya terminada.

Un saludo.

307
Estimado, en la parte que dice var nivel a, var nivel b y var nivel c, me marca un error, no se a que se deba eso

Código: [Seleccionar]
var nivelA = new ArrayList<Deportista>();
var nivelB = new ArrayList<Deportista>();
var nivelC = new ArrayList<Deportista>();

Sustitúyelo por:
Código: [Seleccionar]
ArrayList<Deportista> nivelA = new ArrayList<Deportista>();
ArrayList<Deportista> nivelB = new ArrayList<Deportista>();
ArrayList<Deportista> nivelC = new ArrayList<Deportista>();


Sobre hacerlo con arrays, lo siento, tenía un par de días libres pero ya se acabaron.
No dispongo de tanto tiempo.

De todos modos, consulta con compañeros o algún profesor si realmente hay que resolverlo sin usar clases.
Porque incluso usando un ArrayList para cada tipo de dato, ya supondría un kilombo de código importante.
Y si tuviera que ser con arrays "primitivos", aún peor...  :o

308
Solo necesitas un objeto random e invocar a su método nextInt().
A este método le indicas el tamaño del array, ya sea con atributo .length o directamente el valor 20
Entonces, te devolverá un entero al azar entre 0 y 19 (20 no lo incluye), que son las posiciones disponibles en el arreglo.

Pues ya solo queda mostrar, recoger o lo que sea que necesites, con el elemento que se encuentra en esa posición.

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

public class DoubleAzar {

public static void main(String[] args) {

double[] valores = {10.5, 4.3, 6.0, -4.6, 8.4, 2.2, 1.9, 9.0, 6.3, 45.9,
55.8, 3.23, 1.11, 90.90, 80.3, 65.34, 43.9, 9.0, 12,0, 23,5};

Random azar = new Random();

int posicion = azar.nextInt(valores.length);

System.out.println("Posicion: " + posicion);
System.out.println("Valor: " + valores[posicion]);

}

}

309
Adjunto zip en este mensaje. Abajo de todo, verás enlace para descargarlo

psd: Aun no hemos visto programacion orientada a objetos
¿Seguro?
Porque entonces prácticamente nada de lo que hemos hecho serviría, ya que está enfocado a POO.

Pero vamos, cuando un enunciado comienza así:
Citar
Se sabe que de cada deportista se tiene el código, nombre, edad, nivel y sexo.
Tiene toda la pinta de ser POO y que estén pidiendo crear una clase Deportistas con todos esos atributos.

De lo contrario, la forma "no POO" de poder gestionar todos esos datos es usando 5 arrays, uno para los códigos, otro para los nombres, otro para las edades...
Sin poder usar una clase que gestione esos datos y podamos otorgarle métodos para que haga sus propias tareas..., el código entonces resultaría enorme y muy engorroso.

Citar
cuando hablas de override, de sort. A que te refieres, o sea, como puedo entender eso? y la utima parte donde haces la prueba, como entiendo mejor eso? porque la parte donde dices deportista.add Qué es.
Si realmente nos has visto nada de POO, ni clases, ni métodos, ni herencias... pues puede que no sirva para nada explicar estas cosas.

Override, significa "sobreescribir". En Java se usa la etiqueta @Override para indicar que el método que se va codificar a continuación, en realidad está sobreescribiendo a otro método que ya existe y que se recibe por herencia.

Una clase puede ser heredera de otra. Por ejemplo, imagina la clase Animal y que tiene un método llamado caminar()

Ahora imagina las clases Perro, Gallina y Serpiente.
Todos son animales, así que podemos hacer que sean herederas de la clase Animal, y entonces automáticamente esas tres clases van a disponer del método caminar().

Sin embargo, cada uno camina de forma diferente: el perro usa 4 patas, la gallina solo 2 y la serpiente en realidad usa su cuerpo para desplazarse.

Sí, todos caminan, pero cada uno a su manera, así que para cada uno querremos "sobreescribir"(Override) el método caminar() que han heredado, para adaptarlo a cada uno.

Eso es lo que hicimos al implementar la interfaz Comparable. Una interface es muy similar a una clase (ya te lo explicarán). Entonces, al implementarsela a la clase Deportista, automáticamente heredó el método compareTo()
Pero ese método heredado no le va a servir a un Deportista, hay que sobreescribirlo para que se adapte a los atributos de un Deportista.



sort() es un método que dispone la clase ArrayList. Esta clase puede almacenar una lista de elementos que se los vamos añadiendo con el método add() o quitando con remove().
Los elementos se colocan en la lista según se van añadiendo, pero podemos hacer que se ordenen invocando al método sort().

Este método espera recibir un objeto de la clase Comparable que será quien le diga como ha de ordenar los elementos de su lista: si por nombre, por edad, por estatura, por fecha nacimiento, etc..

Si en lugar de eso le pasamos un valor null, entonces el método sort() comprobará si los elementos de su lista, ya disponen de un método que le indique cómo hay que ordenarlos.
En nuestro ejercicio, el ArrayList contiene objetos de la clase Deportista, la cuál ya tiene implementada la interfaz Comparable y el método compareTo() sobreescrito para indicar como se han de ordenar (por el tiempo de vuelta promedio).
Así que al llamar a sort(), podemos pasarle valor null, porque los Deportistas ya le dirán al ArrayList como se han de ordenar.




En la última parte, lo que hago es añadir por código unos cuantos deportistas para que al iniciar la aplicación, ya tengamos algunos registrados.
Al cerrar aplicación, esos registros se pierden. Si no añadimos algunos por código, entonces cada vez que iniciemos la aplicación, vamos a tener que añadir a mano con la 1ª opción del menú nuevos deportistas.

Es un engorro, y se pierde mucho tiempo, si cada vez que queremos probar las distintas opciones del menú, primero tenemos que registrar unos cuantos deportistas, y además unas cuentas vueltas para cada deportista.
Por eso mejor añadir algunos por código.

Eso es lo que hace este método, construir Deportistas, añadirlos al ArrayList, y luego a algunos les añado Vueltas.
A otros no, para que consten como deportistas que no han competido
Código: [Seleccionar]
private static void deportistasPruebas() {
deportistas.add(new Deportista("DEP001", "Lucas", 4, "C", "Hombre"));
deportistas.add(new Deportista("DEP002", "Sara", 5, "B", "Mujer"));
deportistas.add(new Deportista("DEP003", "Ramon", 6, "C", "Hombre"));
deportistas.add(new Deportista("DEP004", "Laura", 4, "A", "Mujer"));
deportistas.add(new Deportista("DEP005", "Pedro", 10, "A", "Hombre"));
deportistas.add(new Deportista("DEP006", "Soledad", 12, "B", "Mujer"));
deportistas.add(new Deportista("DEP007", "Roberto", 4, "C", "Hombre"));
deportistas.add(new Deportista("DEP008", "Cristina", 11, "A", "Mujer"));
deportistas.get(0).setVueltas(new Vuelta[] {new Vuelta(1,10), new Vuelta(0,55), new Vuelta(1,5)});
deportistas.get(1).setVueltas(new Vuelta[] {new Vuelta(1,5), new Vuelta(0,50), new Vuelta(1,3)});
deportistas.get(3).setVueltas(new Vuelta[] {new Vuelta(1,9), new Vuelta(0,53), new Vuelta(1,13)});
deportistas.get(5).setVueltas(new Vuelta[] {new Vuelta(1,8), new Vuelta(0,57), new Vuelta(1,1)});
deportistas.get(6).setVueltas(new Vuelta[] {new Vuelta(1,7), new Vuelta(0,56), new Vuelta(1,5)});
deportistas.get(7).setVueltas(new Vuelta[] {new Vuelta(1,8), new Vuelta(0,51), new Vuelta(1,11)});
}



Si aún no has visto nada de POO, por mucho que explique estas cosas concretas puede que no se entiendan bien.

En la web hay un curso de Java, puedes empezar desde este capítulo e ir viendo lo que son objetos, clases y demás.

310
Aprender a programar desde cero / Re: Dudas ejercicio POO Java
« en: 07 de Noviembre 2021, 20:30 »
-¿Qué diferencia hay en utilizar "System.out.println(objFecha1);" y "System.out.println(objFecha1.toString());"? Me sale lo mismo a la hora de mostrarlo. Me gustaría saber la diferencia.

Ninguna en este caso.
El método println() siempre espera recibir un String. Si recibe algo distinto, intenta convertirlo por su cuenta a String, y para ello automáticamente invoca el método toString() del objeto que ha recibido, así que no es necesario que lo invoquemos nosotros

311
El compromiso es contigo mismo, no conmigo. ;)

Pongo ahora el código completo. Revísalo y no dudes en preguntar el por qué de esto, el significado de aquello,... lo que sea.

Puede que haya usado cosas que aún no te han explicado, como la interfaz Comparable que he usado para resolver lo de ordenar deportistas según sus tiempos promedios.
Eso puede resolverse sin usar esa interfaz, aunque sería un poco más engorroso.

Pero si crees que hay algo que no se espera que puedas/sepas usarlo, dilo y buscamos otra alternativa.

Clase Vuelta
Código: [Seleccionar]
public class Vuelta {

private int minutos;
private int segundos;

public Vuelta() {
minutos = 0;
segundos = 0;
}

public Vuelta(int minutos, int segundos) {
this.minutos = minutos;
this.segundos = segundos;
}

public int getMinutos() {
return minutos;
}

public void setMinutos(int minutos) {
this.minutos = minutos;
}

public int getSegundos() {
return segundos;
}

public void setSegundos(int segundos) {
this.segundos = segundos;
}

/*
* Para comparar tiempos de distintas vueltas,
* puede ser más cómodo convertir el tiempo
* en segundos totales.
*/
public int totalSegundos() {
return (minutos * 60) + segundos;
}

@Override
public String toString() {
return String.format("[%02d:%02d]", minutos, segundos);
}

}

Clase Deportista, que está relacionada con Vuelta. Porque un Deportista compite dando tres Vueltas.
Código: [Seleccionar]
public class Deportista implements Comparable<Deportista>{

private String codigo;
private String nombre;
private int edad;
private String nivel;
private String sexo;
//Las vueltas que realiza el deportista
private Vuelta[] vueltas;

public Deportista(String codigo, String nombre, int edad, String nivel, String sexo) {
this.codigo = codigo;
this.nombre = nombre;
this.edad = edad;
this.nivel = nivel;
this.sexo = sexo;
//Un competidor realiza 3 vueltas
vueltas = new Vuelta[3];
for (int i = 0; i < 3; i++)
vueltas[i] = new Vuelta();//Inicialmente las vueltas tienen los tiempos en 0
}

public String getCodigo() {
return codigo;
}

public void setCodigo(String codigo) {
this.codigo = codigo;
}

public String getNombre() {
return nombre;
}

public void setNombre(String nombre) {
this.nombre = nombre;
}

public int getEdad() {
return edad;
}

public void setEdad(int edad) {
this.edad = edad;
}

public String getNivel() {
return nivel;
}

public void setNivel(String nivel) {
this.nivel = nivel;
}

public String getSexo() {
return sexo;
}

public void setSexo(String sexo) {
this.sexo = sexo;
}

/*
* Los tiempos de vueltas llegarán ya coleccionadas
*  en un array que machará el actual.
*/
public void setVueltas(Vuelta[] vueltas) {
this.vueltas = vueltas;
}

/*
* El tiempo promedio se retorna calculado
* en segundos
*/
public int tiempoPromedio() {
int segundosTotales = 0;
for (Vuelta v: vueltas)
segundosTotales += v.totalSegundos();

return segundosTotales / 3;
}

/*
* Para saber si un Deportista ha competido podemos comprobar
* si su tiempo promedio es distinto de 0
*/
public boolean haCompetido() {
return tiempoPromedio() != 0;
}

/*
* Para mostrar en pantalla el tiempo promedio
* bien formateado, hay que convertir a minutos y segundos
* para poder construir un objeto Vuelta
*/
public String mostrarPromedio() {
if (haCompetido()) {
int promedio = tiempoPromedio();
int minutos = promedio / 60;
int segundos = promedio % 60;
//El objeto Vuelta ya sabe como mostrarse en pantalla formateado
return new Vuelta(minutos, segundos).toString();
}
else
return "No ha competido.";
}

public void mostrarResultados() {
if (haCompetido()) {
System.out.println("--Tiempos de vueltas--");
System.out.println("1era Vuelta: " + vueltas[0]);
System.out.println("2da Vuelta: " + vueltas[1]);
System.out.println("3era Vuelta: " + vueltas[2]);
}
else
System.out.println("No ha competido.");
}

@Override
public boolean equals(Object obj) {
if (obj instanceof Deportista) {
//Dos deportistas son equivalentes si tienen el mismo codigo
Deportista otroDepor = (Deportista) obj;
return otroDepor.codigo.equals(codigo);
}
else
return false;
}

@Override
public int compareTo(Deportista otroDpt) {
//Esta comparacion ordena deportistas de menor a mayor promedio
return Integer.compare(tiempoPromedio(), otroDpt.tiempoPromedio());
}
}

Y la clase principal, con un menú y un procedimiento para cada uno de los puntos del menú.
Además hay un procedimiento que se ejecuta al arrancar el programa y lo que hace es registrar automáticamente algunos deportistas. Así el programa ya comienza con algunos registros para poder probar todas las opciones directamente, sin tener que hacer nuevos registros cada vez que iniciamos la aplicación.
Código: [Seleccionar]
import java.util.ArrayList;
import java.util.Scanner;

public class MenuCompeticion {

private static ArrayList<Deportista> deportistas;
private static Scanner teclado;

public static void main(String[] args) {

deportistas = new ArrayList<Deportista>();
teclado = new Scanner(System.in);
int opcion = 0;
deportistasPruebas(); //Automáticamente añade algunos deportistas para probar el código

do {
mostrarMenu();
opcion = Integer.parseInt(teclado.nextLine());

switch(opcion) {
case 0:
System.out.println("\nFIN DE PROGRAMA");
break;
case 1:
registrarDeportista();
break;
case 2:
eliminarDeportista();
break;
case 3:
modificarDeportista();
break;
case 4:
registrarVueltas();
break;
case 5:
mostrarPromedios();
break;
case 6:
rankingPorNivel();
break;
case 7:
porcentajeDeportistasSobreNivel();
break;
case 8:
mostrarResultadosDeportista();
break;
case 9:
listaNoHanCompetido();
break;
case 10:
participantesPorEdad();
break;
default:
System.out.println("\nOpcion equivocada");
}

}while (opcion != 0);

}

private static void mostrarMenu() {
System.out.println("\n\t\tMENU COMPETICION");
System.out.println("\t\t---- -----------\n");
System.out.println("[1] -- Registrar Deportista");
System.out.println("[2] -- Eliminar Deportista");
System.out.println("[3] -- Modificar Deportista");
System.out.println("[4] -- Registrar resultados de la competencia");
System.out.println("[5] -- Mostrar tiempos promedios de vueltas");
System.out.println("[6] -- Mostrar posiciones ranking por nivel");
System.out.println("[7] -- Mostrar porcentajes jugadores con promedios superior a su nivel");
System.out.println("[8] -- Mostrar resultados de un deportista");
System.out.println("[9] -- Listar deportistas sin competir");
System.out.println("[10] -- Participantes por rango de edad");
System.out.println("\n[0] -- TERMINAR PROGRAMA");
}
//Opcion 1 del menú
private static void registrarDeportista() {
System.out.println("\n\t--NUEVO DEPORTISTA--");
System.out.print("Codigo: ");
String codigo = teclado.nextLine();
System.out.print("Nombre: ");
String nombre = teclado.nextLine();
System.out.print("Edad: ");
int edad = Integer.parseInt(teclado.nextLine());
System.out.print("Nivel(A/B/C): ");
String nivel = teclado.nextLine().toUpperCase();
System.out.print("Sexo: ");
String sexo = teclado.nextLine();

Deportista nuevo = new Deportista(codigo, nombre, edad, nivel, sexo);
if (deportistas.contains(nuevo))
System.out.println("\nYa existe deportista con codigo: " + codigo);
else {
deportistas.add(nuevo);
System.out.println("\nDeportista registrado");
}
}
//Opcion 2 del menú
private static void eliminarDeportista() {
System.out.println("\n\t--ELIMINAR DEPORTISTA--");
System.out.print("Codigo: ");
String codigo = teclado.nextLine();

Deportista buscado = null;
for (int i = 0; i < deportistas.size(); i++)
if (deportistas.get(i).getCodigo().equals(codigo))
buscado = deportistas.get(i);

if (buscado == null)
System.out.println("\nNo existe deportista con el codigo: " + codigo);
else {
deportistas.remove(buscado);
System.out.println("\nDeportista eliminado");
}
}
//Opcion 3 del menú
private static void modificarDeportista() {
System.out.println("\n\t--MODIFICAR DEPORTISTA--");
System.out.print("Codigo: ");
String codigo = teclado.nextLine();

Deportista buscado = null;
for (int i = 0; i < deportistas.size(); i++)
if (deportistas.get(i).getCodigo().equals(codigo))
buscado = deportistas.get(i);

if (buscado == null)
System.out.println("\nNo existe deportista con el codigo: " + codigo);
else {
//Atributo código no se debe modificar
System.out.println("\nNombre actual: " + buscado.getNombre());
System.out.print("Nuevo nombre: ");
buscado.setNombre(teclado.nextLine());
System.out.println("\nEdad actual: " + buscado.getEdad());
System.out.print("Nueva edad: ");
buscado.setEdad(Integer.parseInt(teclado.nextLine()));
System.out.println("\nNivel actual: " + buscado.getNivel());
System.out.print("Nuevo nivel: ");
buscado.setNivel(teclado.nextLine());
System.out.println("\nSexo actual: " + buscado.getSexo());
System.out.print("Nuevo sexo: ");
buscado.setSexo(teclado.nextLine());

System.out.println("\nDeportista modificado");
}
}
//Opcion 4 del menú
private static void registrarVueltas() {

if (deportistas.isEmpty())
System.out.println("No hay deportistas registrados."
+ "\nNo se pueden registar tiempos de vueltas.");
else {
Vuelta[] vueltas = new Vuelta[3];
System.out.println("\n\tREGISTRAR COMPETENCIA");
System.out.println("Introduzca los tiempos de tres vueltas");
for (int i = 0; i < 3; i++) {
System.out.println("Vuelta #" + (i+1));
System.out.print("Minutos: ");
int minutos = Integer.parseInt(teclado.nextLine());
System.out.print("Segundos: ");
int segundos = Integer.parseInt(teclado.nextLine());
vueltas[i] = new Vuelta(minutos, segundos);
}

//Ahora preguntamos a que Deportista se las asignamos
System.out.print("\nIndique el codigo del Deportista: ");
String codigo = teclado.nextLine();

Deportista buscado = null;
for (int i = 0; i < deportistas.size(); i++)
if (deportistas.get(i).getCodigo().equals(codigo))
buscado = deportistas.get(i);

if (buscado == null)
System.out.println("\nNo existe deportista con el codigo: " + codigo);
else {
buscado.setVueltas(vueltas);
System.out.println("\nTiempos de vueltas se han asignado al deportista.");
}
}
}
//Opcion 5 del menú
private static void mostrarPromedios() {
System.out.println("\n\tTIEMPOS PROMEDIOS");
System.out.println("\t------- ---------\n");
if (deportistas.isEmpty())
System.out.println("No hay deportistas registrados todavía");
else {
for (Deportista dpt: deportistas) {
System.out.println("\n\t---------------------------");
System.out.println("Codigo: " + dpt.getCodigo());
System.out.println("Nombre: " + dpt.getNombre());
System.out.println("Tiempo promedio: " + dpt.mostrarPromedio());
System.out.println("\t---------------------------");
}
}
}
//Opcion 6 del menú
private static void rankingPorNivel() {
System.out.println("\n\t\tRANKING POR NIVEL");
System.out.println("\t\t------- --- -----\n");
if (deportistas.isEmpty())
System.out.println("No hay deportistas registrados todavía");
else {
var nivelA = new ArrayList<Deportista>();
var nivelB = new ArrayList<Deportista>();
var nivelC = new ArrayList<Deportista>();
//Separamos por niveles
for (Deportista dpt: deportistas) {
if (dpt.haCompetido()) {
switch(dpt.getNivel()) {
case "A":
nivelA.add(dpt);
break;
case "B":
nivelB.add(dpt);
break;
case "C":
nivelC.add(dpt);
}
}
}
//Pedimos a los ArrayList que se ordenen.
nivelA.sort(null); //Al indicar null, se ordenan según el compareTo() de los Deportistas
nivelB.sort(null);
nivelC.sort(null);
//Mostramos rankings en pantalla
System.out.println("\n\t---Nivel A---");
for (int i = 0; i < nivelA.size(); i++) {
System.out.println("\n#" + (i+1));
System.out.println("Nombre: " + nivelA.get(i).getNombre());
System.out.println("Promedio: " + nivelA.get(i).mostrarPromedio());
}
System.out.println("\n\t---Nivel B---");
for (int i = 0; i < nivelB.size(); i++) {
System.out.println("\n#" + (i+1));
System.out.println("Nombre: " + nivelB.get(i).getNombre());
System.out.println("Promedio: " + nivelB.get(i).mostrarPromedio());
}
System.out.println("\n\t---Nivel C---");
for (int i = 0; i < nivelC.size(); i++) {
System.out.println("\n#" + (i+1));
System.out.println("Nombre: " + nivelC.get(i).getNombre());
System.out.println("Promedio: " + nivelC.get(i).mostrarPromedio());
}
}
}
//Opcion 7 del menú
private static void porcentajeDeportistasSobreNivel() {
System.out.println("\n\tPORCENTAJE DEPORTISTAS SUPERAN TIEMPOS PROMEDIOS");
System.out.println("\t---------- ----------- ------- ------- ---------\n");
if (deportistas.isEmpty())
System.out.println("No hay deportistas registrados todavía");
else {
//Suma de promedios y recuento de jugadores, según nivel
int sumaA = 0, contadorA = 0;
int sumaB = 0, contadorB = 0;
int sumaC = 0, contadorC = 0;
for (Deportista dpt: deportistas) {
switch(dpt.getNivel()) {
case "A":
sumaA += dpt.tiempoPromedio();
contadorA++;
break;
case "B":
sumaB += dpt.tiempoPromedio();
contadorB++;
break;
case "C":
sumaC += dpt.tiempoPromedio();
contadorC++;
}
}
//Calculamos promedio de cada nivel
int promedioA = sumaA / contadorA;
int promedioB = sumaB / contadorB;
int promedioC = sumaC / contadorC;
//Tenemos el promedio de cada nivel
//volvemos a recorrer deportistas para contar quien está por encima de su promedio
int superanA = 0, superanB = 0, superanC = 0;
for (Deportista dpt: deportistas) {
switch(dpt.getNivel()) {
case "A":
if (dpt.tiempoPromedio() > promedioA)
superanA++;
break;
case "B":
if (dpt.tiempoPromedio() > promedioB)
superanB++;
break;
case "C":
if (dpt.tiempoPromedio() > promedioC)
superanC++;
}
}
//Tenemos todos los datos
System.out.println("--Nivel A--");
System.out.println("Deportistas por encima del promedio: "
+ (superanA * 100 / contadorA) + "%");
System.out.println("\n--Nivel B--");
System.out.println("Deportistas por encima del promedio: "
+ (superanB * 100 / contadorB) + "%");
System.out.println("\n--Nivel C--");
System.out.println("Deportistas por encima del promedio: "
+ (superanC * 100 / contadorC) + "%");
int totalSuperan = superanA + superanB + superanC;
System.out.println("\nTotal deportistas por encima del promedio: "
+ (totalSuperan * 100 / deportistas.size()) + "%");
}
}
//Opcion 8 del menú
private static void mostrarResultadosDeportista() {
System.out.println("\n\t\tRESULTADOS DEPORTISTAS");
System.out.println("\t\t---------- -----------\n");
if (deportistas.isEmpty())
System.out.println("No hay deportistas registrados todavía");
else {
System.out.print("Codigo: ");
String codigo = teclado.nextLine();

Deportista buscado = null;
for (int i = 0; i < deportistas.size(); i++)
if (deportistas.get(i).getCodigo().equals(codigo))
buscado = deportistas.get(i);

if (buscado == null)
System.out.println("\nNo existe deportista con el codigo: " + codigo);
else {
System.out.println("\nNombre: " + buscado.getNombre());
buscado.mostrarResultados();
}
}
}
//Opcion 9 del menú
private static void listaNoHanCompetido() {
System.out.println("\n\t\tLISTA DEPORTISTAS SIN COMPETIR");
System.out.println("\t\t----- ----------- --- --------\n");
if (deportistas.isEmpty())
System.out.println("No hay deportistas registrados todavía");
else {
for (Deportista dpt: deportistas)
if (!dpt.haCompetido()) {
System.out.println("Codigo: " + dpt.getCodigo());
System.out.println("Nombre: " + dpt.getNombre());
System.out.println();
}
}
}
//Opcion 10 del menú
private static void participantesPorEdad() {
System.out.println("\n\t\tPARTICIPANTES POR EDADES");
System.out.println("\t\t------------- --- ------\n");
if (deportistas.isEmpty())
System.out.println("No hay deportistas registrados todavía");
else {
int menor5 = 0, menor10 = 0, mayor10 =0;
for (Deportista dpt: deportistas)
if (dpt.haCompetido()) {
int edad = dpt.getEdad();
if (edad < 5)
menor5++;
else if (edad < 10)
menor10++;
else
mayor10++;
}
//Resultados
System.out.println("Menores de 5 años: " + menor5);
System.out.println("Entre 5 y 9 años: " + menor10);
System.out.println("DE 10 años o mayor: " + mayor10);
}
}
//Deportistas para probar el código y no tener que hacer registros en cada prueba
private static void deportistasPruebas() {
deportistas.add(new Deportista("DEP001", "Lucas", 4, "C", "Hombre"));
deportistas.add(new Deportista("DEP002", "Sara", 5, "B", "Mujer"));
deportistas.add(new Deportista("DEP003", "Ramon", 6, "C", "Hombre"));
deportistas.add(new Deportista("DEP004", "Laura", 4, "A", "Mujer"));
deportistas.add(new Deportista("DEP005", "Pedro", 10, "A", "Hombre"));
deportistas.add(new Deportista("DEP006", "Soledad", 12, "B", "Mujer"));
deportistas.add(new Deportista("DEP007", "Roberto", 4, "C", "Hombre"));
deportistas.add(new Deportista("DEP008", "Cristina", 11, "A", "Mujer"));
deportistas.get(0).setVueltas(new Vuelta[] {new Vuelta(1,10), new Vuelta(0,55), new Vuelta(1,5)});
deportistas.get(1).setVueltas(new Vuelta[] {new Vuelta(1,5), new Vuelta(0,50), new Vuelta(1,3)});
deportistas.get(3).setVueltas(new Vuelta[] {new Vuelta(1,9), new Vuelta(0,53), new Vuelta(1,13)});
deportistas.get(5).setVueltas(new Vuelta[] {new Vuelta(1,8), new Vuelta(0,57), new Vuelta(1,1)});
deportistas.get(6).setVueltas(new Vuelta[] {new Vuelta(1,7), new Vuelta(0,56), new Vuelta(1,5)});
deportistas.get(7).setVueltas(new Vuelta[] {new Vuelta(1,8), new Vuelta(0,51), new Vuelta(1,11)});
}
}

Cuando creas que más o menos lo has entendido, intenta volver a hacerlo por tu cuenta.
No pienses en resolver los 10 puntos de golpe, ya has visto que yo he ido uno a uno, modificando la clase Deportista para adaptarla a lo que iba pidiendo cada uno de los puntos del enunciado.
Piensa en resolver únicamente el primero. Y luego el segundo, luego el tercero,.. etc.

Un saludo.

312
get() te proporciona el objeto., ya solo tendrías que llamar al método mostrarDatos() de la clase datosPaciente. Por cierto, este método no necesita recibir ningún String id entre paréntesis, porque lo que hace es mostrar el valor de los atributos de ese objeto en concreto.
Ni necesita, ni puede.., localizar otro objeto por el id, solo tiene acceso al datosPaciente desde el que se le invoca

Citar
        public void mostrarDatos(String id){//No necesita recibir nada por paréntesis
            System.out.println("\n\t---------------");
            System.out.println("ID Paciente: "+id);
            System.out.println("Nombre: "+nom);
            System.out.println("Edad: "+ed+" años");
            System.out.println("Domicilio: "+dir);
            System.out.println("Telefóno: "+telPac);
            System.out.println("Celular : "+celPac);
            System.out.println("Correo electrónico: "+corr_ele);
            System.out.println("\t---------------");
        }

Citar
        public boolean mostrarPaciente(){
            String id=JOptionPane.showInputDialog(null,"Introduzca identificador del paciente para mostrar datos: ",
                    "Mostrar datos del paciente",JOptionPane.QUESTION_MESSAGE);
            datosPacientes paciente=null;
            for (int i=0;i<pacientes.size();i++){
                if(pacientes.get(i).getID().equals(id)){
                    paciente=pacientes.get(i);
                    paciente.mostrarDatos();//Mostramos datos en pantalla
                }
            }
            if(paciente==null){
                JOptionPane.showMessageDialog(null, "No se encuentra Paciente con el ID:\n"+id,
                        "Paciente no encontrado", JOptionPane.WARNING_MESSAGE);
                return false;
            }
        }


Con esto creo que funcionaría.
Ya nos contarás.

Un saludo.

313
Aprender a programar desde cero / Re: Dudas ejercicio POO Java
« en: 06 de Noviembre 2021, 21:10 »
Algunas cosas a mencionar.
Los atributos, salvo que tengamos algún motivo especial, por regla general se declaran como private

Código: [Seleccionar]
    private enumMes mes;
    private int dia;
    private int anio;
   

Los constructores, salvo que haya un motivo especial, los declararemos como public

Código: [Seleccionar]
    public Fecha(enumMes mes){
        dia = 0;
        anio = 0;
        mes = mes;
    }
   
    public Fecha(int dia, enumMes mes, int anio){
        dia = dia;
        mes = mes;
        anio = anio;
    }

Eso dos constructores, tienen un problema serio.
No estás usando la palabra reservada this
Si no la usamos, el compilador no sabe distinguir cuando nos referimos al atributo de la clase o al objeto que recibe el constructor, cuando estos tienen el mismo nombre.
Por ejemplo, en este constructor, la linea que señalo en rojo:
Citar
    public Fecha(enumMes mes){
        dia = 0;
        anio = 0;
        mes = mes;
    }
Tu ahí pretendes asignarle al atributo llamado mes, la referencia recibida por paréntesis, que también se llama mes.
Pero Java no sabe que tú quieres referirte al atributo y lo que hace es asignar a la referencia mes, a sí misma... lo cuál es absurdo.

O les das nombres distintos, para que Java sepa a quien te refieres
Citar
    public Fecha(enumMes otroMes){
        dia = 0;
        anio = 0;
        mes = otroMes;
    }

O si no, usa la palabra reservada this para indicar cuándo te refieres al atributo

Citar
    public Fecha(enumMes mes){
        dia = 0;
        anio = 0;
        this.mes = mes;//A "este mes", le asignamos el "otro mes"
    }

El otro constructor, requiere la misma corrección, porque ahora mismo no está asignando nada a los atributos
Citar
    public Fecha(int dia, enumMes mes, int anio){
        this.dia = dia;
        this.mes = mes;
        this.anio = anio;
    }

El método isSummer() está mal, por varios motivos.

Primero, porque da igual lo que se compute, solo hay un return que siempre retorna false

Citar
    public boolean isSummer(){
        String mes = null;
       if ( mes == "Junio" || mes == "Julio" || mes == "Agosto" || mes == "Septimebre" ) {
          boolean isSummer = true;
       }
       else {
          boolean isSummer = false;
       }
        return false;
    }

En cuanto a lo computa, nunca va a funcionar, porque no se está trabajando con el atributo mes de esta clase Fecha.
Se está trabajando con un String que tiene valor null

Citar
    public boolean isSummer(){
        String mes = null;
       if ( mes == "Junio" || mes == "Julio" || mes == "Agosto" || mes == "Septimebre" ) {
          boolean isSummer = true;
       }
       else {
          boolean isSummer = false;
       }
        return false;
    }

Hay que hacer comparaciones con el atributo mes de esta clase, que además NO ES UN STRING.
Es un enumerado de tipo enumMes.
Así que hay comparar los enumerados y garantizar que hay un return true y un return false

Código: [Seleccionar]
    public boolean isSummer(){
        if (mes == enumMes.JUNIO || mes == enumMes.JULIO || mes == enumMes.AGOSTO || mes == enumMes.SEPTIEMBRE)
        return true;
        else
        return false;
    }   


Sobre el método toString, solo comentar dos mejoras.
Una, es ponerle al principio la etiqueta @Override
No es obligatorio, pero sí muy recomendable ponerla siempre que vamos a sobreescribir un método.
El método toString(), es un método que TODAS las clases Java heredan de la clase Object

Al escribirle un código, estamos sobreescribiendo ese método heredado. Y es muy recomendable señalarlo con la etiqueta Override, para que tanto Java, como otro programador que vaya a leer tu código, inmediatamente sepa que ese método está siendo sobreescrito

La otra mejora es añadir espacios en blanco a las palabras " de ", para que no salga todo junto

Código: [Seleccionar]
    @Override
    public String toString(){
     
        return dia + " de "+ mes +" de "+ anio;
    }


Bueno, ya tendríamos las clase Fecha corregida.
La pongo completa, tal y como la tengo yo ahora:
Código: [Seleccionar]
public class Fecha {

    public enum enumMes {
        ENERO, FEBRERO, MARZO, ABRIL, MAYO, JUNIO, JULIO, AGOSTO, SEPTIEMBRE, OCTUBRE, NOVIEMBRE, DICIEMBRE
    }
   
    private enumMes mes;
    private int dia;
    private int anio;
   
    public Fecha(enumMes mes){
        dia = 0;
        anio = 0;
        this.mes = mes;
    }
   
    public Fecha(int dia, enumMes mes, int anio){
        this.dia = dia;
        this.mes = mes;
        this.anio = anio;
    }
   
    public int getDia(){
        return dia;
    }
    public void setDia(int dia){
        this.dia = dia;
    }
   
    public enumMes getMes(){
        return mes;
    }
    public void setMes(enumMes mes){
        this.mes = mes;
    }
   
   
    public int getAnio(){
        return anio;
    }
    public void setAnio(int anio){
        this.anio = anio;
    }
   
    public boolean isSummer(){
        if (mes == enumMes.JUNIO || mes == enumMes.JULIO || mes == enumMes.AGOSTO || mes == enumMes.SEPTIEMBRE)
        return true;
        else
        return false;
    }   
   
    @Override
    public String toString(){
     
        return dia + " de "+ mes +" de "+ anio;
    }
}

Vamos a tu main, donde también hay algunos fallos.

El primero es que el objeto Fecha lo inicializas con un constructor que no recibe nada.
El enunciado del ejercicio dice que hay dos constructores, uno recibe el mes y otro recibe todos los datos.
No debería haber ningún constructor que no reciba nada.

Luego, el dia y el año los inicializas en unas variables separadas que no tienen ninguna relación con ese objeto Fecha.

Por cierto, para poder indicarle uno de los meses declarados en enumMes, como este enumerodo está dentro de la clase Fecha, hay que poner primero su nombre.
Fíjate cómo le paso un mes al primer constructor.

Código: [Seleccionar]
public class Principal {

public static void main(String[] args) {

System.out.println("Primera fecha");
//Primer constructor, recibe solo el mes
Fecha objFecha1 = new Fecha(Fecha.enumMes.AGOSTO);
//Configuramos dia y año
objFecha1.setDia(10);
objFecha1.setAnio(2000);
//Mostramos fecha, para esto hemos sobreescrito el método toString() de Fecha
System.out.println(objFecha1);
//Indicamos si es verano o no, usamos operador ternario
System.out.println(objFecha1.isSummer()?"Es verano":"No es verano");

System.out.println("\nSegunda fecha");
//Segundo constructor, recibe todos los datos
Fecha objFecha2 = new Fecha(20, Fecha.enumMes.OCTUBRE, 2021);
//Mostramos solo el año
System.out.println("Año: " + objFecha2.getAnio());
//Fecha completa
System.out.println(objFecha2);
//Comprobamos si es verano
System.out.println(objFecha2.isSummer()?"Es verano":"No es verano");
}

}

Al ejecutar, vemos en pantalla como se muestran las fechas y como se comprueba si son fechas de verano o no:
Citar
Primera fecha
10 de AGOSTO de 2000
Es verano

Segunda fecha
Año: 2021
20 de OCTUBRE de 2021
No es verano



Y ya estaría.
Revisa el código y comprueba que entiendes cada línea.
Cualquier cosa que no te haya quedado clara, solo tienes que preguntar.

Un saludo.  ;)




314
Punto 7
Citar
7.   Determinar el porcentaje de deportistas que emplearon un tiempo mayor al promedio de su nivel.
Parecido al anterior, habrá que distinguir entre deportistas según su nivel.
Calcular el promedio de cada nivel y ver cuántos están por encima y expresarlo en un porcentaje.

La función para realizar esto es un poco larga, no por su dificultad, si no porque hay que hacer varios recuentos y habrá que recorrer el ArrayList de deportistas dos veces
Código: [Seleccionar]
private static void porcentajeDeportistasSobreNivel() {
System.out.println("\n\tPORCENTAJE DEPORTISTAS SUPERAN TIEMPOS PROMEDIOS");
System.out.println("\t---------- ----------- ------- ------- ---------\n");
if (deportistas.isEmpty())
System.out.println("No hay deportistas registrados todavía");
else {
//Suma de promedios y recuento de jugadores, según nivel
int sumaA = 0, contadorA = 0;
int sumaB = 0, contadorB = 0;
int sumaC = 0, contadorC = 0;
for (Deportista dpt: deportistas) {
switch(dpt.getNivel()) {
case "A":
sumaA += dpt.tiempoPromedio();
contadorA++;
break;
case "B":
sumaB += dpt.tiempoPromedio();
contadorB++;
break;
case "C":
sumaC += dpt.tiempoPromedio();
contadorC++;
}
}
//Calculamos promedio de cada nivel
int promedioA = sumaA / contadorA;
int promedioB = sumaB / contadorB;
int promedioC = sumaC / contadorC;
//Tenemos el promedio de cada nivel
//volvemos a recorrer deportistas para contar quien está por encima de su promedio
int superanA = 0, superanB = 0, superanC = 0;
for (Deportista dpt: deportistas) {
switch(dpt.getNivel()) {
case "A":
if (dpt.tiempoPromedio() > promedioA)
superanA++;
break;
case "B":
if (dpt.tiempoPromedio() > promedioB)
superanB++;
break;
case "C":
if (dpt.tiempoPromedio() > promedioC)
superanC++;
}
}
//Tenemos todos los datos
System.out.println("--Nivel A--");
System.out.println("Deportistas por encima del promedio: "
+ (superanA * 100 / contadorA) + "%");
System.out.println("\n--Nivel B--");
System.out.println("Deportistas por encima del promedio: "
+ (superanB * 100 / contadorB) + "%");
System.out.println("\n--Nivel C--");
System.out.println("Deportistas por encima del promedio: "
+ (superanC * 100 / contadorC) + "%");
int totalSuperan = superanA + superanB + superanC;
System.out.println("\nTotal deportistas por encima del promedio: "
+ (totalSuperan * 100 / deportistas.size()) + "%");
}
}
Aunque no lo pide, he hecho que se desglosen los porcentajes por cada nivel, además de mostrar el total, que es lo que se pedía.
Como de todos modos era necesario obtener todos eso datos, ya que los tenemos los usaremos para mostrar más info en pantalla.

Citar
   PORCENTAJE DEPORTISTAS SUPERAN TIEMPOS PROMEDIOS
   ---------- ----------- ------- ------- ---------

--Nivel A--
Deportistas por encima del promedio: 66%

--Nivel B--
Deportistas por encima del promedio: 50%

--Nivel C--
Deportistas por encima del promedio: 66%

Total deportistas por encima del promedio: 62%



Bien restan por hacer los puntos 8 , 9 y 10.
Intenta realizarlos tú (el 9 prácticamente está hecho porque ya tenemos un método para saber quien ha competido y quien no) siguiendo la misma dinámica.

Si te atascas, equivocas o lo que sea. Comparte por aquí lo que hayas conseguido y lo corregimos.

315
Veamos el siguiente punto:
Citar
6.   Asignarle puesto a cada competidor por nivel. Para cada uno de los niveles de los deportistas, se le debe asignar un puesto de acuerdo al promedio de tiempo empleado en completar las tres vueltas, de menor a mayor tiempo.

Parece complejo, pero no lo es tanto.
Los competidores tienen un "nivel", así que se nos pide agrupar deportistas por sus niveles y ordenarlos de menor a mayor tiempo promedio.
No se nos ha dicho exactamente que es ese "nivel", si una categoría o que...

No importa, yo en mi código puse que hay tres niveles: A , B y C.
Así que para hacer lo que nos piden, agruparemos en distintas colecciones a los deportistas que sean A, en otra los B y en otras los C.
Y los ordenaremos según su tiempo promedio.

El proceso de ordenación, podríamos hacerlo más simple y eficiente si le enseñamos a la clase Deportista cómo ha de compararse con ella misma, es decir, que un objeto Deportista pueda recibir otro objeto y determinar quien es "menor o mayor", en función de sus tiempos promedios.

Para esto, podemos modificar la clase Deportista y al principio de todo, en su declaración, pedirle que implemente la interface Comparable

Citar
public class Deportista implements Comparable<Deportista>{

Esto nos "obliga" a incluirle ahora un método llamado compareTo() donde tenemos que escribir el código necesario para decidir cómo se han de comparar dos objetos Deportista.
Puesto que lo queremos comparar son sus tiempos promedios, que ya tenemos un método que nos lo calcula y nos lo retorna como segundos guardados en un int/Integer, pues simplemente tenemos que retornar el resultado de comparar esos Integer.
Código: [Seleccionar]
@Override
public int compareTo(Deportista otroDpt) {
//Esta comparación ordena deportistas de menor a mayor promedio
return Integer.compare(tiempoPromedio(), otroDpt.tiempoPromedio());
}

Y ahora volvemos a la clase principal para añadir una nueva función.
Lo que haremos será crear tres ArrayList, uno para cada nivel. Agruparemos en ellos los Deportistas correspondientes (solo los que hayan competido) y le pediremos al ArrayList que se ordene.
El ArrayList lo que hará será ordenar según lo que hemos establecido en el método compareTo(), así que automáticamente tendremos los deportistas separados por niveles y ordenados de menor a mayor promedio.
Solo faltará mostrarlos en pantalla:
Código: [Seleccionar]
private static void rankingPorNivel() {
System.out.println("\n\t\tRANKING POR NIVEL");
System.out.println("\t\t------- --- -----");
if (deportistas.isEmpty())
System.out.println("No hay deportistas registrados todavía");
else {
var nivelA = new ArrayList<Deportista>();
var nivelB = new ArrayList<Deportista>();
var nivelC = new ArrayList<Deportista>();
//Separamos por niveles
for (Deportista dpt: deportistas) {
if (dpt.haCompetido()) {
switch(dpt.getNivel()) {
case "A":
nivelA.add(dpt);
break;
case "B":
nivelB.add(dpt);
break;
case "C":
nivelC.add(dpt);
}
}
}
//Pedimos a los ArrayList que se ordenen.
nivelA.sort(null); //Al indicar null, se ordenan según el compareTo() de los Deportistas
nivelB.sort(null);
nivelC.sort(null);
//Mostramos rankings en pantalla
System.out.println("\n\t---Nivel A---");
for (int i = 0; i < nivelA.size(); i++) {
System.out.println("\n#" + (i+1));
System.out.println("Nombre: " + nivelA.get(i).getNombre());
System.out.println("Promedio: " + nivelA.get(i).mostrarPromedio());
}
System.out.println("\n\t---Nivel B---");
for (int i = 0; i < nivelB.size(); i++) {
System.out.println("\n#" + (i+1));
System.out.println("Nombre: " + nivelB.get(i).getNombre());
System.out.println("Promedio: " + nivelB.get(i).mostrarPromedio());
}
System.out.println("\n\t---Nivel C---");
for (int i = 0; i < nivelC.size(); i++) {
System.out.println("\n#" + (i+1));
System.out.println("Nombre: " + nivelC.get(i).getNombre());
System.out.println("Promedio: " + nivelC.get(i).mostrarPromedio());
}
}
}

Actualizamos el menú y el switch, y al probarlo, veremos que se clasifican y ordenan correctamente. Y no ha sido tan difícil la verdad.
Usando bien la interfaz Comparable, nos ahorramos tener que ordenar con "métodos burbujas" y algoritmos de ese estilo.

Citar
      RANKING POR NIVEL
      ------- --- -----

   ---Nivel A---

#1
Nombre: Cristina
Promedio: [01:03]

#2
Nombre: Laura
Promedio: [01:05]

   ---Nivel B---

#1
Nombre: Sara
Promedio: [00:59]

#2
Nombre: Soledad
Promedio: [01:02]

   ---Nivel C---

#1
Nombre: Roberto
Promedio: [01:02]

#2
Nombre: Lucas
Promedio: [01:03]

316
La siguiente opción del menú habla de registrar las tres vueltas de la competencia en la que participan cada uno de los deportistas.
No se nos indica de que manera debemos registrar y relacionar las vueltas con los deportistas, así que lo decidimos nosotros.

Hay múltiples formas: una matriz paralela al ArrayList de deportistas, agregar nuevos atributos a los deportistas,...

Tampoco nos dicen cómo hemos de recoger los tiempos de las vueltas: ¿en minutos, en segundos, en minutos y segundos....?

Creo que por equilibrio entre sencillez y lógica, podemos pedir al usuario minutos y segundos por separado.
De hecho, podemos crear una clase llamada Vuelta con esos dos atributos, minutos y segundos.
Luego se nos va a pedir comparar los tiempos de unas vueltas con otras, en este caso si puede resultarnos más cómodo tratar el tiempo total en solo segundos para que sea más fácil comparar. Así que podemos darle a esta clase Vuelta un método que haga este cálculo.

También podemos sobreescribirle el método toString() para que así una Vuelta sepa darnos un String que representa sus tiempos con un formato adecuado

Código: [Seleccionar]
public class Vuelta {

private int minutos;
private int segundos;

public Vuelta() {
minutos = 0;
segundos = 0;
}

public Vuelta(int minutos, int segundos) {
this.minutos = minutos;
this.segundos = segundos;
}

public int getMinutos() {
return minutos;
}

public void setMinutos(int minutos) {
this.minutos = minutos;
}

public int getSegundos() {
return segundos;
}

public void setSegundos(int segundos) {
this.segundos = segundos;
}

/*
* Para comparar tiempos de distintas vueltas,
* puede ser más cómodo convertir el tiempo
* en segundos totales.
*/
public int totalSegundos() {
return (minutos * 60) + segundos;
}

@Override
public String toString() {
return String.format("[%02d:%02d]", minutos, segundos);
}

}

Vale, ahora ya tenemos una clase donde recoger tiempos de vueltas. ¿Cómo las relacionamos con los deportistas?

Cada deportista realizará tres vueltas, y solo tres, así que por ahora (quizás luego cambie de opinión) creo que lo más cómodo es modificar la clase Deportista para que tenga un nuevo atributo, que será un array de tres objetos Vuelta.

En su constructor inicializaremos el array con tres Vueltas con tiempo 0, aunque solo será por no dejar el array con valores null en ningún momento.
Luego los valores de las vueltas, se los haremos llegar (por comodidad) por un setter que machacará el array anterior. Así que en realidad no sería necesario inicializarlo al crear un Deportista, pero no me gusta dejar atributos con valores null si no hay un motivo lógico.

La clase Deportista queda así cambiada:
Citar
public class Deportista {
   
   private String codigo;
   private String nombre;
   private int edad;
   private String nivel;
   private String sexo;
   //Las vueltas que realiza el deportista
   private Vuelta[] vueltas;
   
   public Deportista(String codigo, String nombre, int edad, String nivel, String sexo) {
      this.codigo = codigo;
      this.nombre = nombre;
      this.edad = edad;
      this.nivel = nivel;
      this.sexo = sexo;
      //Un competidor realiza 3 vueltas
      vueltas = new Vuelta[3];
      for (int i = 0; i < 3; i++)
         vueltas = new Vuelta();
//Inicialmente las vueltas tienen los tiempos en 0
   }

   public String getCodigo() {
      return codigo;
   }

   public void setCodigo(String codigo) {
      this.codigo = codigo;
   }

   public String getNombre() {
      return nombre;
   }

   public void setNombre(String nombre) {
      this.nombre = nombre;
   }

   public int getEdad() {
      return edad;
   }

   public void setEdad(int edad) {
      this.edad = edad;
   }

   public String getNivel() {
      return nivel;
   }

   public void setNivel(String nivel) {
      this.nivel = nivel;
   }

   public String getSexo() {
      return sexo;
   }

   public void setSexo(String sexo) {
      this.sexo = sexo;
   }
   
   /*
    * Los tiempos de vueltas llegarán ya coleccionadas
    *  en un array que machará el actual.
    */

   public void setVueltas(Vuelta[] vueltas) {
      this.vueltas = vueltas;
   }

   
   @Override
   public boolean equals(Object obj) {
      if (obj instanceof Deportista) {
         //Dos deportistas son equivalentes si tienen el mismo codigo
         Deportista otroDepor = (Deportista) obj;
         return otroDepor.codigo.equals(codigo);
      }
      else
         return false;
   }
}

Con esto, ya podemos hacer el punto 4 del menú.
Para ello a la clase principal le añadimos una nueva función que, tras comprobar si hay deportistas registrados, pida los tiempos de tres vueltas y luego pida el código del deportista al que quiere asignarle esos tiempos.

Código: [Seleccionar]
private static void registrarVueltas() {

if (deportistas.isEmpty())
System.out.println("No hay deportistas registrados."
+ "\nNo se pueden registar tiempos de vueltas.");
else {
Vuelta[] vueltas = new Vuelta[3];
System.out.println("\n\tREGISTRAR COMPETENCIA");
System.out.println("Introduzca los tiempos de tres vueltas");
for (int i = 0; i < 3; i++) {
System.out.println("Vuelta #" + (i+1));
System.out.print("Minutos: ");
int minutos = Integer.parseInt(teclado.nextLine());
System.out.print("Segundos: ");
int segundos = Integer.parseInt(teclado.nextLine());
vueltas[i] = new Vuelta(minutos, segundos);
}

//Ahora preguntamos a que Deportista se las asignamos
System.out.print("\nIndique el codigo del Deportista: ");
String codigo = teclado.nextLine();

Deportista buscado = null;
for (int i = 0; i < deportistas.size(); i++)
if (deportistas.get(i).getCodigo().equals(codigo))
buscado = deportistas.get(i);

if (buscado == null)
System.out.println("\nNo existe deportista con el codigo: " + codigo);
else {
buscado.setVueltas(vueltas);
System.out.println("\nTiempos de vueltas se han asignado al deportista.");
}
}
}

Añadimos nueva opción al menú y por supuesto al switch del main() para poder llevarla a cabo:

Citar
      do {
         mostrarMenu();
         opcion = Integer.parseInt(teclado.nextLine());
         
         switch(opcion) {
         case 0:
            System.out.println("\nFIN DE PROGRAMA");
            break;
         case 1:
            registrarDeportista();
            break;
         case 2:
            eliminarDeportista();
            break;
         case 3:
            modificarDeportista();
            break;
         case 4:
            registrarVueltas();
            break;

         default:
            System.out.println("\nOpcion equivocada");
         }
         
      }while (opcion != 0);


Si continuamos con la siguiente opción del menú, la 5, nos pide obtener el tiempo promedio de cada deportista en realizar las tres vueltas.
Para esto, primero le vamos a enseñar a la clase Deportista a retornar el tiempo promedio.
Para esto nos será útil el poder convertir los tiempos a segundos, calcular el promedio, y dicho promedio reconvertirlo a minutos y segundos para poder presentarlo en pantalla debidamente formateado.

Así que a la clase Deportista le añadimos los siguientes métodos:
Uno se encargará de calcular el promedio, en segundos. Hay más opciones del menú que dependen de este cálculo, así que va bien tener un método específico para esta tarea y que otros métodos puedan recurrir a él.

Código: [Seleccionar]
/*
* El tiempo promedio se retorna calculado
* en segundos
*/
public int tiempoPromedio() {
int segundosTotales = 0;
for (Vuelta v: vueltas)
segundosTotales += v.totalSegundos();

return segundosTotales / 3;
}


Otro método será el que se encargue de retornar un String para mostrar en pantalla el tiempo promedio.
Para esto, se ha de transformar el promedio en minutos y segundos. Con estos dos elemenos, podemos construir un objeto Vuelta e invocar a su método toString(), al que anteriormente ya le enseñamos a como ha de formatear un tiempo de vuelta para mostrarlo en pantalla.

Pero, ¡¡atención!!...
Pueden haber deportistas que aún no hayan competido, es decir, que no tengan tiempos de vueltas registrados.
En ese caso, convendría mostrar un mensaje en pantalla y no un tiempo.
Hay que distinguir entre los que han competido y los que no, para tratarlos de distinta manera.

Una forma de saberlo, es aprovechar el método calcularPromedio(). Si retorna un valor de 0, que es el tiempo de las vueltas al inicializarse, es que no se le han registrado nuevas Vueltas todavía y por tanto no ha competido el deportista en cuestión.

Podemos hacer otro método boolean que basándose en el promedio, retorne verdadero o falso para indicar si ha competido o no este deportista.
Código: [Seleccionar]
/*
* Para saber si un Deportista ha competido podemos comprobar
* si su tiempo promedio es distinto de 0
*/
public boolean haCompetido() {
return tiempoPromedio() != 0;
}

Y ahora sí, podemos hacer el método que mostrará el tiempo promedio en pantalla si el deportista ha competido, y si no, mostrará un mensaje

Código: [Seleccionar]
/*
* Para mostrar en pantalla el tiempo promedio
* bien formateado, hay que convertir a minutos y segundos
* para poder construir un objeto Vuelta
*/
public String mostrarPromedio() {
if (haCompetido()) {
int promedio = tiempoPromedio();
int minutos = promedio / 60;
int segundos = promedio % 60;
//El objeto Vuelta ya sabe como mostrarse en pantalla formateado
return new Vuelta(minutos, segundos).toString();
}
else
return "No ha competido.";
}

Con esto, ya podemos volver a la clase principal y añadir nueva función que se encargue de recorrer los deportistas registrados y mostrar sus tiempos promedios:
Código: [Seleccionar]
private static void mostrarPromedios() {
System.out.println("\n\tTIEMPOS PROMEDIOS");
System.out.println("\t------- ---------");
if (deportistas.isEmpty())
System.out.println("No hay deportistas registrados todavía");
else {
for (Deportista dpt: deportistas) {
System.out.println("\n\t---------------------------");
System.out.println("Codigo: " + dpt.getCodigo());
System.out.println("Nombre: " + dpt.getNombre());
System.out.println("Tiempo promedio: " + dpt.mostrarPromedio());
System.out.println("\t---------------------------");
}
}
}

Tras esto, actualizamos el menú y el switch para disponer de esta nueva opción.
Y si la ejecutamos, veremos en pantalla que se muestran los tiempos promedios de aquellos que han competido y los que no, se muestra un mensaje.
Citar
   TIEMPOS PROMEDIOS
   ------- ---------

   ---------------------------
Codigo: DEP001
Nombre: Lucas
Tiempo promedio: [01:03]
   ---------------------------

   ---------------------------
Codigo: DEP002
Nombre: Sara
Tiempo promedio: [00:59]
   ---------------------------

   ---------------------------
Codigo: DEP003
Nombre: Ramon
Tiempo promedio: No ha competido.
   ---------------------------

   ---------------------------
Codigo: DEP004
Nombre: Laura
Tiempo promedio: [01:05]
   ---------------------------

Continuaremos en un próximo mensaje.

317
Insisto, primero hay que escribir una clase Deportista, con sus atributos y métodos.
Al menos sus getter y setter, pero ya que nos dicen que uno de sus atributos es un código, se supone que es un código identificador único, es decir, no pueden haber dos Deportistas con el mismo código.

Para poder tener cierto control sobre este aspecto, podemos sobreescribir el método equals() de manera que dos Deportistas se consideren iguales si tienen el mismo código.

Código: [Seleccionar]
public class Deportista {

private String codigo;
private String nombre;
private int edad;
private String nivel;
private String sexo;

public Deportista(String codigo, String nombre, int edad, String nivel, String sexo) {
this.codigo = codigo;
this.nombre = nombre;
this.edad = edad;
this.nivel = nivel;
this.sexo = sexo;
}

public String getCodigo() {
return codigo;
}

public void setCodigo(String codigo) {
this.codigo = codigo;
}

public String getNombre() {
return nombre;
}

public void setNombre(String nombre) {
this.nombre = nombre;
}

public int getEdad() {
return edad;
}

public void setEdad(int edad) {
this.edad = edad;
}

public String getNivel() {
return nivel;
}

public void setNivel(String nivel) {
this.nivel = nivel;
}

public String getSexo() {
return sexo;
}

public void setSexo(String sexo) {
this.sexo = sexo;
}

@Override
public boolean equals(Object obj) {
if (obj instanceof Deportista) {
//Dos deportistas son equivalentes si tienen el mismo codigo
Deportista otroDepor = (Deportista) obj;
return otroDepor.codigo.equals(codigo);
}
else
return false;
}
}

De momento esta será la clase Deportista, luego según se vaya desarrollando el programa puede que la modifiquemos.

Pero por ahora, ya podríamos realizar las tres primeras opciones del menú: registrar deportista, eliminarlos y modificarlos.

Para eso, en otra clase, que será la clase principal con el main(), podemos declarar un ArrayList donde registrar los Deportistas.
Mostraremos un menú de opciones, y para cada opción, escribiremos una función que se encargue de llevarla a cabo.

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

public class MenuCompeticion {

private static ArrayList<Deportista> deportistas;
private static Scanner teclado;

public static void main(String[] args) {

deportistas = new ArrayList<Deportista>();
teclado = new Scanner(System.in);
int opcion = 0;

do {
mostrarMenu();
opcion = Integer.parseInt(teclado.nextLine());

switch(opcion) {
case 0:
System.out.println("\nFIN DE PROGRAMA");
break;
case 1:
registrarDeportista();
break;
case 2:
eliminarDeportista();
break;
case 3:
modificarDeportista();
break;
default:
System.out.println("\nOpcion equivocada");
}

}while (opcion != 0);

}

private static void mostrarMenu() {
System.out.println("\n\t\tMENU COMPETICION");
System.out.println("\t\t---- -----------\n");
System.out.println("[1] -- Registrar Deportista");
System.out.println("[2] -- Eliminar Deportista");
System.out.println("[3] -- Modificar Deportista");
System.out.println("\n[0] -- TERMINAR PROGRAMA");
}

private static void registrarDeportista() {
System.out.println("\n\t--NUEVO DEPORTISTA--");
System.out.print("Codigo: ");
String codigo = teclado.nextLine();
System.out.print("Nombre: ");
String nombre = teclado.nextLine();
System.out.print("Edad: ");
int edad = Integer.parseInt(teclado.nextLine());
System.out.print("Nivel(A/B/C): ");
String nivel = teclado.nextLine().toUpperCase();
System.out.print("Sexo: ");
String sexo = teclado.nextLine();

Deportista nuevo = new Deportista(codigo, nombre, edad, nivel, sexo);
if (deportistas.contains(nuevo))
System.out.println("\nYa existe deportista con codigo: " + codigo);
else {
deportistas.add(nuevo);
System.out.println("\nDeportista registrado");
}
}

private static void eliminarDeportista() {
System.out.println("\n\t--ELIMINAR DEPORTISTA--");
System.out.print("Codigo: ");
String codigo = teclado.nextLine();

Deportista buscado = null;
for (int i = 0; i < deportistas.size(); i++)
if (deportistas.get(i).getCodigo().equals(codigo))
buscado = deportistas.get(i);

if (buscado == null)
System.out.println("\nNo existe deportista con el codigo: " + codigo);
else {
deportistas.remove(buscado);
System.out.println("\nDeportista eliminado");
}
}

private static void modificarDeportista() {
System.out.println("\n\t--MODIFICAR DEPORTISTA--");
System.out.print("Codigo: ");
String codigo = teclado.nextLine();

Deportista buscado = null;
for (int i = 0; i < deportistas.size(); i++)
if (deportistas.get(i).getCodigo().equals(codigo))
buscado = deportistas.get(i);

if (buscado == null)
System.out.println("\nNo existe deportista con el codigo: " + codigo);
else {
//Codigo no se puede modificar
System.out.println("\nNombre actual: " + buscado.getNombre());
System.out.print("Nuevo nombre: ");
buscado.setNombre(teclado.nextLine());
System.out.println("\nEdad actual: " + buscado.getEdad());
System.out.print("Nueva edad: ");
buscado.setEdad(Integer.parseInt(teclado.nextLine()));
System.out.println("\nNivel actual: " + buscado.getNivel());
System.out.print("Nuevo nivel: ");
buscado.setNivel(teclado.nextLine());
System.out.println("\nSexo actual: " + buscado.getSexo());
System.out.print("Nuevo sexo: ");
buscado.setSexo(teclado.nextLine());

System.out.println("\nDeportista modificado");
}
}

}

Bien, ya tenemos lo básico. Antes de seguir, revisa este código, asegúrate de que lo entiendes y ya tu mismo decides si quieres escribir el tuyo propio siguiendo esta lógica o utilizar este.
Sobre todo lo importante es que quede clara la necesidad de modelar una clase y de cómo su gestión se llevará a cabo desde otra clase distinta.

Luego continúo en otro mensaje.

318
Hola.
Puedes crear un nuevo método basándote en borrarPaciente() de la clase GestorPacientes

Fíjate que en ese método pedimos un ID para saber que paciente queremos borrar:
Citar
   public boolean borrarPaciente() {
      String id = JOptionPane.showInputDialog(null, "Introduzca Identificador del paciente a borrar:",
            "Borrar Paciente", JOptionPane.QUESTION_MESSAGE);
      
      Paciente paciente = null;
      for (int i = 0; i < pacientes.size(); i++){
         if (pacientes.get(i).getId().equals(id))
            paciente = pacientes.remove(i);
//Al eliminar el objeto, el ArrayList nos lo devuelve y lo recogemos en "paciente"
      }
      
      if (paciente == null) {
         JOptionPane.showMessageDialog(null, "No se encuentra Paciente con el ID:\n" + id,
               "Paciente no encontrado", JOptionPane.WARNING_MESSAGE);
         return false;
      }
      else {
         JOptionPane.showMessageDialog(null, "Se elimino el paciente con ID:\n" + id,
               "Paciente Eliminado", JOptionPane.INFORMATION_MESSAGE);
         return false;
      }
   }

Pues se puede modificar para que, en lugar de eliminar al paciente, lo que haga sea mostrar en pantalla sus datos.
O bien retornar el objeto Paciente encontrado para recibirlo en el programa principal y mostrarlos desde ahí.

Siempre controlando si se encuentra o no el Paciente solicitado.

Inténtalo, y si te atascas, comparte tu código y miramos de resolverlo.

Un saludo.

319
¿En JavaScript o en Java?
Aunque se parezcan en el nombre, son lenguajes totalmente distintos, para entornos completamente diferentes.

En cualquier caso, comienza tú el código, ves haciendo poco a poco y cuando te atasques te ayudamos.

Comienza por escribir la clase Deportista, el enunciado ya te indica cuáles son los atributos básicos:
Citar
cada deportista se tiene el código, nombre, edad, nivel y sexo.

320
Aprender a programar desde cero / Re: Lenguaje en c
« en: 24 de Octubre 2021, 00:28 »
Bueno, a ver...

La verdad es que el lenguaje C no es lo mío, lo conozco muy por encima...

Aquí he escrito un código que, usando dos funciones para generar distintos tipos de aleatorios, se crean, rellenan y muestran ambos vectores.
No se si es el código más adecuado, ya digo que estoy poco familiarizado con C, pero parece funcionar.

Sería maravilloso que alguien con mejores capacidades nos diera su opinión.

Faltarían los puntos 4) y 5). Inténtalos, a ver hasta donde puedes llegar.

Código: [Seleccionar]
#include <stdio.h>
#include <stdlib.h>
#include <time.h>

int generaImpar5_15(); //Función que genera un impar entre 5 y 15
int generaImpar20_40(); //Función que genera un impar entre 20 y 40, y que no acaba en 5

int main()
{
    srand(time(NULL));
    //Creamos vectores
    int longitud = generaImpar5_15();
    int vector1[longitud], vector2[longitud];
    //Rellenamos
    for (int i  = 0; i < longitud; i++) {
        vector1[i] = generaImpar20_40();
        vector2[i] = generaImpar20_40();
    }
    //Los mostramos
    printf("Vector 1:\n");
    for (int i  = 0; i < longitud; i++) {
        printf("%d ", vector1[i]);
    }
   
    printf("\nVector 2:\n");
    for (int i  = 0; i < longitud; i++) {
        printf("%d ", vector2[i]);
    }
   
    return 0;
}

int generaImpar5_15() {
   
    int impar;
    do {
        impar = 5 + (rand() % 11);
    } while (impar % 2 == 0); //Si es par, se repite el bucle
   
    return impar;
}

int generaImpar20_40() {
   
    int imparNo5;
    do {
        imparNo5 = 20 + (rand() % 21);
    } while(imparNo5 % 2 == 0 || imparNo5 % 5 == 0);//Si es par, o impar múltiplo de 5, se repite el bucle
   
    return imparNo5;
}

Páginas: 1 ... 11 12 13 14 15 [16] 17 18 19 20 21 ... 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".