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 ... 38 39 40 41 42 [43] 44 45 46 47 48 ... 50
841
Aprender a programar desde cero / Re:Ayuda URGENTE
« en: 14 de Septiembre 2018, 01:49 »
Hola.
Quizás sería más interesante que mostraras lo que tienes hecho y donde te has atascado para poder ayudarte.
O bien volver a empezar desde el principio y rehacer el programa juntos..

En fin, vamos paso a paso.
Estas serían las clases básicas conforme a lo que pide el enunciado. No creo que aquí hayas tenido ningún problema.
Clase Paciente
Código: [Seleccionar]
package clinica;

public final class Paciente {

private String id;
private String nombre;
private String apellidos;
private int edad;
private String genero;

public Paciente(String id, String nombre, String apellidos, int edad, String genero) {
this.id = id;
this.nombre = nombre;
this.apellidos = apellidos;
this.edad = edad;
this.genero = genero;
}

public String getId() {
return id;
}

public void setId(String id) {
this.id = id;
}

public String getNombre() {
return nombre;
}

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

public String getApellidos() {
return apellidos;
}

public void setApellidos(String apellidos) {
this.apellidos = apellidos;
}

public int getEdad() {
return edad;
}

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

public String getGenero() {
return genero;
}

public void setGenero(String genero) {
this.genero = genero;
}

/**
* Muestra por consola todos los datos del Paciente
*/
public void mostrar() {
System.out.println("\n\t---------------");
System.out.println("ID Paciente: " + id);
System.out.println("Nombre: " + nombre);
System.out.println("Apellidos: " + apellidos);
System.out.println("Edad: " + edad);
System.out.println("Genero: " + genero);
System.out.println("\t---------------");
}
}

Clase Medico
Código: [Seleccionar]
package clinica;

public final class Medico {

private String id;
private String nombre;
private String apellidos;
private String especialidad;

public Medico(String id, String nombre, String apellidos, String especialidad) {
this.id = id;
this.nombre = nombre;
this.apellidos = apellidos;
this.especialidad = especialidad;
}

public String getId() {
return id;
}

public void setId(String id) {
this.id = id;
}

public String getNombre() {
return nombre;
}

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

public String getApellidos() {
return apellidos;
}

public void setApellidos(String apellidos) {
this.apellidos = apellidos;
}

public String getEspecialidad() {
return especialidad;
}

public void setEspecialidad(String especialidad) {
this.especialidad = especialidad;
}

/**
* Muestra por consola todos los datos del Medico
*/
public void mostrar() {
System.out.println("\n\t---------------");
System.out.println("ID Medico: " + id);
System.out.println("Nombre: " + nombre);
System.out.println("Apellidos: " + apellidos);
System.out.println("Especialidad: " + especialidad);
System.out.println("\t---------------");
}

}

Clase HistorialClinico
Código: [Seleccionar]
package clinica;

public final class HistorialClinico {

private String codigo;
private String fecha;
private String idPaciente;
private String idMedico;
private String observaciones;

public HistorialClinico(String codigo, String fecha, String idPaciente,
String idMedico, String observaciones) {
this.codigo = codigo;
this.fecha = fecha;
this.idPaciente = idPaciente;
this.idMedico = idMedico;
this.observaciones = observaciones;
}

public String getCodigo() {
return codigo;
}

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

public String getFecha() {
return fecha;
}

public void setFecha(String fecha) {
this.fecha = fecha;
}

public String getIdPaciente() {
return idPaciente;
}

public void setIdPaciente(String idPaciente) {
this.idPaciente = idPaciente;
}

public String getIdMedico() {
return idMedico;
}

public void setIdMedico(String idMedico) {
this.idMedico = idMedico;
}

public String getObservaciones() {
return observaciones;
}

public void setObservaciones(String observaciones) {
this.observaciones = observaciones;
}

/**
* Muestra por consola todos los datos del Historial Clinico
*/
public void mostrar() {
System.out.println("\n\t---------------");
System.out.println("Codigo Historial: " + codigo);
System.out.println("Fecha: " + fecha);
System.out.println("ID Pacielnte: " + idPaciente);
System.out.println("ID Medico: " + idMedico);
System.out.println("Observaciones:\n" + observaciones);
System.out.println("\t---------------");
}
}

Fíjate que en cada clase, les he creado un metodo llamado mostrar() que se encargaría de mostrar por pantalla todos los datos de la clase en cuestión.

Bueno, esta es la parte fácil.
La otra parte, en realidad no es nada difícil, pero si tiene el inconveniente de que requiere mucho código.
Hay que escribir un menu principal, un menu para las opciones del Paciente, Medico e Historial, submenus para crear y modificar Pacientes, Medicos e Historiales...

Repito que no es nada dificil, pero tantas líneas de código, si no se organizan correctamente, tendremos un código enooooorme, muy caótico, dificil de comprender y de mantener.. que solo mirarlo ya nos dará dolor de cabeza.

Y es entonces cuando yo te pregunto: ¿Sabes si hay que ceñirse únicamente a esas clases?
¿O podríamos crear otras clases que nos ayuden a facilitar la tarea?


De hecho, sería lo lógico y lo que cualquier programador haría para encarar este ejercicio.
Podríamos hacer tres nuevas clases, las cuáles cada una se encargaría de la gestión de cada una de las anteriores.
Por ejemplo, una clase llamada GestorPacientes, tendría como atributo un ArrayList                                                                                     donde se guardarían los Pacientes.
Y tendría unos métodos para cada una de las acciones necesarias para gestionar esta base de datos.
Un metodo para dar de alta un nuevo Paciente, otro para mostrar listado de pacientes, otro para modificar, otro para borrar...
De este modo, todo el código necesario para gestionar Pacientes, estaría concentrado en su propia clase y separado de todo el código necesario para gestionar Medicos y de todo el código necesario para gestionar Historiales, los cuáles estarían en sus respectivas clases de Gestion.

La clase GestorPacientes podría ser como la que pongo a continuación. Aunque no está completa, solo incluye los metodos para crear nuevo Paciente y para mostrar todo el listado de pacientes.
Faltarían los metodos para modificar y borrar pacientes.

Clase GestorPacientes
Código: [Seleccionar]
package clinica;

import java.util.ArrayList;
import java.util.Scanner;

public final class GestorPacientes {

private ArrayList<Paciente> pacientes;
private Scanner teclado;

public GestorPacientes() {
pacientes = new ArrayList<Paciente>();
teclado = new Scanner(System.in);
}

/**
* Crea y registra un nuevo paciente.
* @return True si se pudo registrar con éxito el nuevo paciente.
* False si no fue posible registrarlo.
*/
public boolean nuevoPaciente() {
System.out.println("\n\tALTA NUEVO PACIENTE");
System.out.print("Introduzca Identificador: ");
String id = teclado.nextLine();
System.out.print("Nombre: ");
String nombre = teclado.nextLine();
System.out.print("Apellidos: ");
String apellidos = teclado.nextLine();
System.out.print("Genero: ");
String genero = teclado.nextLine();
System.out.print("Edad: ");
int edad = teclado.nextInt();
teclado.nextLine();//Tras leer un int, conviene "limpiar" el stream de entrada, para evitar problemas al querer leer luego datos String
Paciente nuevoPaciente = new Paciente(id, nombre, apellidos, edad, genero);
return pacientes.add(nuevoPaciente);//Devuelve TRUE si se insertó correctamente, FALSE si no se pudo insertar
}

/**
* Lista por pantalla los datos de todos los pacientes registrados.
*/
public void mostrarPacientes() {
for (Paciente p: pacientes)
p.mostrar();
}

}

Si crees que es posible enfocar el ejercicio de esta manera, podemos seguir adelante a partir de aquí.
Intenta completar los dos métodos que faltarían para esta clase y tomandola como ejemplo, intenta escribir las clases GestorMedicos y GestorHistoriales

Fíjate que tienen un segundo atributo, un Scanner para pedir datos por pantalla.
Cada clase tendrá su propio Scanner

He usado un Scanner porque es lo habitual para pedir datos por consola. Si estas acostumbrado a pedir datos al usuario usando otras formas como la clase JOptionPane que muestra pequeñas ventanas de dialogo para que el usuario meta datos, podemos modificarlo.


Insisto en que lo ideal e inteligente sería crear estas tres nuevas clases para separa la gestión de las tres entidades principales.
Crear estas tres nuevas clases no supone escribir más código. La cantidad de código será la misma, solo que de este modo está mejor organizado.
Si no usamos estas tres clases para la gestión, todo este código estará escrito en la clase donde pongamos el metodo main(), con lo cuál será una clases muy sobrecargada de código... :-\

Un saludo

842
Al principio es fácil no tener clara la función y mecánica de los constructores.

Como su nombre indica, se encarga de "construir" el objeto, cuya clase estamos definiendo.

Así que pedirá parametros al usuario, si es que los necesita.
Y pasará valores a los atributos, si es que necesita hacerlo.

Subrayo esto porque solemos caer en el error de pensar que los constructores tienen unas estructuras digamos... "obligadas".
Creemos que hay que poner un constructor sin parametros y otro que pida todos los parámetros.
Y en ambos casos lo unico que va a hacer el constructor es inicializar los atributos.

Y no es así, tenemos total flexibilidad para estructurar nuestros constructores y estos pueden hacer lo que queramos.

Podemos hacer tantos constructores como queramos, o no poner ninguno.
Y escribir dentro de ellos todo el código que necesitemos para "construir" nuestro objeto.

Una clase puede tener muchos atributos, pero a lo mejor a la hora de construir el objeto solo necesitamos pedir un único atributo al usuario.
Pues haremos un constructor que pida un único dato.

Hace poco ayudando a otro forero, desarrollamos una clase con varios atributos, pero que solo necesitamos pedir uno por el constructor:

Código: [Seleccionar]
public class Sala {

//Atributos
private String nombrePelicula;
private int asientosLibres = 20;
private int contJubilados = 0;
private int contAdultos = 0;
private int contMenores = 0;
private double recaudacion = 0;

//Constructor
public Sala(String nombre) {
nombrePelicula = nombre;
}


En estos ejemplos de aprendizaje, las clases son sencillas y los cosntructores son también simples. Básicamente pasan el parámetro recibido al atributo correspondiente.

Pero en realidad un constructor puede tener código mucho más complejo. Todo depende de lo que se necesite.


Con el tiempo irás viendo mejor cuál es la función de un constructor y tu mismo te irás dando cuenta de que ciertas clases pueden necesitar varios constructores, que otras solo necesitan pedir determinados parámetros para los atributos, que algunas van a tener que pedir ciertos parámetros que no serán para los atributos si no para otra tareas..

Conforme avanza la complejidad de los ejercicios, también aumenta la variedad y versatilidad de lo que necesitamos que hagan los constructores

843
Comunidad / Re:no se por donde empezar
« en: 13 de Septiembre 2018, 01:19 »
Lo de aprender C antes que Java, es una recomendación tan habitual como obsoleta, por no decir absurda.
No es necesario en absoluto.

NetBeans es un IDE, un entorno de desarrollo. No es un lenguaje de programación, sino el programa donde vas a escribir tus programa en Java.
Estos IDE (hay más como por ejemplo Eclipse, IntelliJ, Microsoft Visual Studio, etc...) suelen tener decenas de opciones y comandos, pero la mayoría no son necesarios ni útiles cuando se está aprendiendo a programar.

No te sientas abrumado por la cantidad de menus que tiene NetBeans, la mayoría no los vas a necesitar.

Lo que ha de preocuparte es aprender la metodología de la programación y el lenguaje Java, que ya te adelanto que es bastante fácil y cómodo de aprender.

Se supone que en el ciclo donde estás ya te van a enseñar lo que necesites saber.
Pero paralelamente, si puedes compaginarlo, esta web ofrece un curso gratuito para aprender Java desde Cero

En este curso se propone empezar a aprender con un IDE muy distinto a los habituales, el BlueJ, que está totalmente enfocado a la enseñanza y tiene muy poco que ver con los IDE pensados para el desarrollo más profesional.
Puedes practicar con ambos IDE sin problemas, BlueJ es tan simplificado que no conlleva ningún esfuerzo aprender a manejarlo.

Otra peculiaridad de este curso gratuito, es que empieza directamente enseñando los conceptos más básicos de la Programación Orientada a Objetos (clases, objetos, constructores...), de ahí que hayan escogido BlueJ como IDE porque es ideal para enseñar estos conceptos.
Sin embargo, la mayoría de cursos y ciclos reglados suelen empezar por la programación más "tradicional" y dejan la Programación Orientada a Objetos (abreviada como POO) para más adelante.

Esto lo menciono porque si te decides a hacer paralelamente este curso, puede que te extrañe que empiece enseñando cosas que quizás no se parezcan en nada a lo que te están explicando en clase.
La POO tarde o temprano te la enseñaran, toda la programación actual está enfocada a la POO.
Así que no tiene nada de malo si paralelamente vas aprendiendo POO por un lado mientras por otro te enseñan programación "tradicional".

Lo importante es que no te vuelvas loco preguntándote porque es tan distinto lo que enseñan unos de lo que explican otros

Además, la POO y la programación tradicional no son opuestas, sino que se complementan. Así que necesitarás ambas.

844
Estás escribiendo código directamente en el cuerpo de la clase Sala.
Esto no es correcto.
Sala es una clase, una entidad, que va a representar algo y que tiene determinadas funcionalidades.
Estas funcionalidades, por ejemplo vender una entrada/boleto de cine, solo ha de ejecutarse cuando se lo pidamos. Por lo tanto, esta parte del código ha de estar escrita en un método, para que solo se ejecute cuando invoquemos a este metodo.

Es decir, esta clase ha de tener unos atributos, un constructor y los métodos que pueda necesitar para cumplir con su cometido

Pensemos en los atributos. ¿Que propiedades tiene una sala? Mejor dicho, ¿que propiedades de una sala son las que nos interesan?
Porque una sala tiene unas dimensiones, tiene cierta cantidad de puertas de emergencia, tiene una moqueta de un determinado color.... pero todo esto no nos interesa.

También tiene una película en proyección. Esto sí nos interesa, queremos un atributo que guarde el nombre de la película que está proyectando. Este atríbuto es el que permite diferenciar una sala de otra. Porque nuestro ejercicio final va a trabajar de hecho con 3 salas distintas al mismo tiempo. Y cada una tendrá sus clientes, sus ventas y su propia recaudación.

Tiene una cantidad determinada de asientos. 20 asientos para ser más exactos.
Esto también nos interesa. Otro atributo más.

Luego además, la sala tiene clientes. Esto también nos interesa contarlos, para poder hacer una estadística de clientes. Hay tres tipos de clientes distintos, así que como atributos usaremos tres contadores distintos, uno para cada tipo de cliente.

Por último, la sala tiene una recaudación que va aumentando con cada entrada/boleto que se vende. Esto también nos interesa contabilizarlo.

Así pues, estos podrían ser los atributos de nuestra clase Sala
Código: [Seleccionar]
private String nombrePelicula;
private int asientosLibres = 20;
private int contJubilados = 0;
private int contAdultos = 0;
private int contMenores = 0;
private double recaudacion = 0;

El contador de asientos lo he llamado asientosLibres y lo he iniciado en 20.
También podríamos haberlo llamado asientosOcupados e iniciarlo con valor 0.
Ambas opciones serían válidas, es cuestión de gustos.

Ya tenemos atributos. Pensemos en un constructor.
No hay mucho que pensar la verdad. El valor de los atributos siempre van a ser los mismos al crear un objeto Sala. Da igual si creamos 500 objetos Sala, todos empezarán con el contador de asientos en 20 y el resto de contadores en 0.
El único atributo que será distinto para cada objeto Sala, sería el nombre de la película que va a proyectar. Ergo, este es el único valor que queremos recibir mediante el constructor.

Código: [Seleccionar]
public Sala(String nombre) {
nombrePelicula = nombre;
}

De este modo, cuando instanciemos objetos Sala desde otra clase con metodo main, le indicaremos a cada una el nombre de la pelicula que proyecta.

Y ahora viene lo "complicado". Los métodos para esta clase.
Se podría empezar poniendo los típicos setters y getters. Pero lo cierto es que en principio no los vamos a necesitar ya que la mayoría de los atributos se van a gestionar dentro de la clase, no van a ser solicitados(get) y mucho menos modificados(set) desde otras clases. Así que podemos ahorrarlos.
Como mucho, un get para el nombre de la película. Así cada objeto Sala podrá indicar que película está proyectando:
Código: [Seleccionar]
public String getNombrePelicula() {
return nombrePelicula;
}

Pasemos a los métodos importantes. Necesitaremos uno que lleve a cabo la gestión de la venta de entradas.
Y otro que nos muestre estadísticas de venta de la sala.

Centrémonos, únicamente en el de la venta.
El código que habías escrito pinta bastante bien. Uno de los errores que te da es cuando preguntas por el valor de la variable metodoPago casi al final.

Esta variable solo la declaras si hay suficientes asientos libres para cubrir la demanda del cliente.
Si no hay asientos,
    no declaro variable metodoPago;
si hay asientos
    sí la declaro;


Esto es correcto.
Pero luego intentas acceder a esta variable desde un punto del programa que da por hecho que la variable está declarada independientemente de si hay asientos o no.
Es decir, "te has salido del alcance de esta variable"

Te marco en verde el "alcance" (scope) de la variable metodoPago.
Y en rojo la parte donde intentas acceder a ella, estando ya fuera de su alcance.

Citar
if (asientosLibres == 0) {
         System.out.println("NO HAY ASIENTOS LIBRES");
      } else {
         System.out.println("Indique tipo cliente: J - Jubilado o adulto mayor (mayor a 55) / A - Adulto / M - Menor (menores de 12)");
         String tipoCliente = cine.nextLine();
         System.out.println("Indique cuantas entradas desea: ");
         int cantidadEntradas = cine.nextInt();
         if (cantidadEntradas > asientosLibres) {
            System.out.println("NO HAY ASIENTOS LIBRES");
         } else {
            System.out.println("Elija metodo de pago: E - Efectivo / T - Tarjeta");
            String metodoPago = cine.nextLine();
            if (tipoCliente.equalsIgnoreCase("J")) {
               precio = 15;
            }
            if (tipoCliente.equalsIgnoreCase("A")) {
               precio = 30;
            }
            if (tipoCliente.equalsIgnoreCase("M")) {
               precio = 10;
            }
         }
         }

      if (metodoPago.equalsIgnoreCase("T")) {
         precio = (int) (precio + precio*0.18);
         System.out.println("VENTA REALIZADA. PRECIO FINAL: " + precio);
      }

      cont ++;
      if (cont <= asientosLibres) {
         cont = asientosLibres;
         System.out.println("QUEDAN " + (int) (asientosLibres - cont) + "asientos.");
      }

La variable metodoPago solo "existe" en la porción marcada en verde, ese es el límite de su alcance.
Esta porción verde, solo se ejecutaría si se cumple una determinada condición (que haya suficientes asientos libres)
Por lo tanto es posible que no se ejecute.
Si no se ejecuta, no se declara la variable metodoPago. Y si no se declara, no puedes preguntar por ella.
Y esto es lo que estás haciendo en la porción marcada en rojo, estás preguntando por una variable que posiblemente NO se ha declarado.
Por eso el compilador Java muestra un warning. Si permitiese ejecutarse el código tal y como está escrito, cuando ocurriese que alguien pide más asientos de los que quedan libres, se produciría un error fatal porque el programa preguntaría por una varaible que no se ha llegado a declarar.

Para corregir esto, tienes dos opciones.
Una, declarar la variable al principio del método, para asegurarte de que va a existir siempre, ante cualquier posibilidad.
Esto aumentaría el alcance de la variable a todo el método completo. Marco en verde todo su alcance, vamos, el método al completo
Citar
      String metodoPago;
      if (asientosLibres == 0) {
         System.out.println("NO HAY ASIENTOS LIBRES");
      } else {
         System.out.println("Indique tipo cliente: J - Jubilado o adulto mayor (mayor a 55) / A - Adulto / M - Menor (menores de 12)");
         String tipoCliente = cine.nextLine();
         System.out.println("Indique cuantas entradas desea: ");
         int cantidadEntradas = cine.nextInt();
         if (cantidadEntradas > asientosLibres) {
            System.out.println("NO HAY ASIENTOS LIBRES");
         } else {
            System.out.println("Elija metodo de pago: E - Efectivo / T - Tarjeta");
            metodoPago = cine.nextLine();
            if (tipoCliente.equalsIgnoreCase("J")) {
               precio = 15;
            }
            if (tipoCliente.equalsIgnoreCase("A")) {
               precio = 30;
            }
            if (tipoCliente.equalsIgnoreCase("M")) {
               precio = 10;
            }
         }
         }
      if (metodoPago.equalsIgnoreCase("T")) {
         precio = (int) (precio + precio*0.18);
         System.out.println("VENTA REALIZADA. PRECIO FINAL: " + precio);
      }
      cont ++;
      if (cont <= asientosLibres) {
         cont = asientosLibres;
         System.out.println("QUEDAN " + (int) (asientosLibres - cont) + "asientos.");
      }
   }

Segunda opcion.
Más correcta a mi entender. Introducir la porción de código que antes habíamos marcado en rojo, dentro de la parte que solo se ejecuta si hay suficientes asientos.
Es más correcta porque lo cierto es que, si no hay suficientes asientes, no haremos ninguna venta. Y si no hacemos ninguna venta, no necesitamos preocuparnos del método de pago, ya que no ha habido ningún pago en realidad.

Citar
if (asientosLibres == 0) {
         System.out.println("NO HAY ASIENTOS LIBRES");
      } else {
         System.out.println("Indique tipo cliente: J - Jubilado o adulto mayor (mayor a 55) / A - Adulto / M - Menor (menores de 12)");
         String tipoCliente = cine.nextLine();
         System.out.println("Indique cuantas entradas desea: ");
         int cantidadEntradas = cine.nextInt();
         if (cantidadEntradas > asientosLibres) {
            System.out.println("NO HAY ASIENTOS LIBRES");
         } else {
            System.out.println("Elija metodo de pago: E - Efectivo / T - Tarjeta");
            String metodoPago = cine.nextLine();
            if (tipoCliente.equalsIgnoreCase("J")) {
               precio = 15;
            }
            if (tipoCliente.equalsIgnoreCase("A")) {
               precio = 30;
            }
            if (tipoCliente.equalsIgnoreCase("M")) {
               precio = 10;
            }
            if (metodoPago.equalsIgnoreCase("T")) {
               precio = (int) (precio + precio*0.18);
               System.out.println("VENTA REALIZADA. PRECIO FINAL: " + precio);
            }

         }

Otra cosa importante que hay corregir. La parte final donde contabilizamos los asientos que quedan libres (o que están ocupados).
Esto que has puesto:
Código: [Seleccionar]
cont++;
if (cont <= asientosLibres) {
cont = asientosLibres;
System.out.println("QUEDAN " + (int) (asientosLibres - cont) + "asientos.");
}

No tiene mucho sentido. Parece que cuentas los asientos de uno en uno. Cada oper acion de venta, un asiento (cont++);
Pero no es así, porque en una operación de venta el usuario puede pedir 5 asientos, 10 asientos, incluso los 20 asientos de toda la sala, para el solito.

No necesitas ninguna varaible cont, porque ya sabemos gracias a la variable cantidadEntradas, cuantos asientos tenemos que restar del atributo asientosLibres.
Y esto, además, solo ha de hacerse en el caso de que se haya completado la venta.
Por lo tanto, también iría en la misma parte de código que hemos modificado antes.

El metodo quedaría así, ahora ya sí, libre de errores de compilación.
Y subrayo lo de compilación, porque el método aún tiene fallos y carencias, las menciono despues.
Citar
   public void venderEntrada() {
      Scanner cine = new Scanner (System.in);
      int precio = 0;
      
      if (asientosLibres == 0) {
         System.out.println("NO HAY ASIENTOS LIBRES");
      } else {
         System.out.println("Indique tipo cliente: J - Jubilado o adulto mayor (mayor a 55) / A - Adulto / M - Menor (menores de 12)");
         String tipoCliente = cine.nextLine();
         System.out.println("Indique cuantas entradas desea: ");
         int cantidadEntradas = cine.nextInt();
         if (cantidadEntradas > asientosLibres) {
            System.out.println("NO HAY ASIENTOS LIBRES");
         } else {
            System.out.println("Elija metodo de pago: E - Efectivo / T - Tarjeta");
            String metodoPago = cine.nextLine();
            if (tipoCliente.equalsIgnoreCase("J")) {
               precio = 15;
            }
            if (tipoCliente.equalsIgnoreCase("A")) {
               precio = 30;
            }
            if (tipoCliente.equalsIgnoreCase("M")) {
               precio = 10;
            }
            if (metodoPago.equalsIgnoreCase("T")) {
               precio = (int) (precio + precio*0.18);
               System.out.println("VENTA REALIZADA. PRECIO FINAL: " + precio);
            }
            asientosLibres = asientosLibres - cantidadEntradas;
            System.out.println("QUEDAN " + asientosLibres + "asientos.");

         }
      }
      cine.close();
   }

Como decía, este método ya compila. Pero hay alguna cosilla por corregir:

- Hay que contar los tipos de cliente. Es decir, una vez finalizada la venta, hay que aumentar el contador asignado a cada tipo de cliente según la cantidad de entradas que acaba de comprar.
Si un jubilado ha comprado entradas --> contJubilados = contJubilados + cantidadEntradas;

- El cálculo de precios no es correcto. Aunque se le pregunta la cantidadEntradas que quiere, luego en el precio siempre se le cobra el valor de una sola entrada.
Hay que multiplicar el precio por la cantidadEntradas que ha pedido el usuario.

-El calculo de suplemento e impuestos no es correcto
 Si paga el usuario con tarjeta, se le carga un 3.5% de suplemento extra.
Y ya luego, se le añade el 18% de impuestos, sea cual sea el método de pago.

- No estamos usando el tipo de dato double para el calculo del precio.
Puesto que estamos trabajando con "tantos por ciento", divisiones y decimales... y además el dinero del mundo real es fraccionable (30$ no es lo mismo que 30.75$ ) lo correcto sería usar el tipo double para calcular el precio y no el int.
Es cierto que el tipo double tiene el inconveniente de que luego en pantalla pueden salirnos número muy feos, con un montón de decimales que no necesitamos.
Y que bueno, esto es un ejercicio de aprendizaje y tampoco es demasiado importante.
El inconveniente este de los decimales en pantalla en realidad es fácil de corregir, usando el metodo format() de la clase String.
Pero yo propongo que esto de momento lo dejemos de lado. Si quieres, seguimos haciendo casting a int como has hecho aquí:
Citar
precio = (int) (precio + precio*0.18);
y ya luego al final, cuando el programa ya esté funcionando, si quieres lo cambiamos para usar el tipo double y vemos como formatear el resultados para que solo nos muestre dos decimales en pantalla.

Dejo aquí la clase al completo tal y como la tenemos ahora. Falta corregir estas cosas que he mencionado. Y luego añadir otro método más que se encargue de mostrar estadísticas.

Código: [Seleccionar]
package boleteria_cine;

import java.util.Scanner;

public class Sala {

//Atributos
private String nombrePelicula;
private int asientosLibres = 20;
private int contJubilados = 0;
private int contAdultos = 0;
private int contMenores = 0;
private double recaudacion = 0;

//Constructor
public Sala(String nombre) {
nombrePelicula = nombre;
}

//Metodos
public String getNombrePelicula() {
return nombrePelicula;
}

public void venderEntrada() {
Scanner cine = new Scanner (System.in);
int precio = 0;

if (asientosLibres == 0) {
System.out.println("NO HAY ASIENTOS LIBRES");
} else {
System.out.println("Indique tipo cliente: J - Jubilado o adulto mayor (mayor a 55) / A - Adulto / M - Menor (menores de 12)");
String tipoCliente = cine.nextLine();
System.out.println("Indique cuantas entradas desea: ");
int cantidadEntradas = cine.nextInt();
if (cantidadEntradas > asientosLibres) {
System.out.println("NO HAY ASIENTOS LIBRES");
} else {
System.out.println("Elija metodo de pago: E - Efectivo / T - Tarjeta");
String metodoPago = cine.nextLine();
if (tipoCliente.equalsIgnoreCase("J")) {
precio = 15;
}
if (tipoCliente.equalsIgnoreCase("A")) {
precio = 30;
}
if (tipoCliente.equalsIgnoreCase("M")) {
precio = 10;
}
if (metodoPago.equalsIgnoreCase("T")) {
precio = (int) (precio + precio*0.18);
System.out.println("VENTA REALIZADA. PRECIO FINAL: " + precio);
}
asientosLibres = asientosLibres - cantidadEntradas;
System.out.println("QUEDAN " + asientosLibres + "asientos.");
}
}
cine.close();
}
}

845
Hola, ¿cómo lo llevas?
Tengo un código ya escrito y funcionando, pero el ejercicio has de hacerlo tú.

Si el conjunto del ejercicio te parece demasiado grande y abrumador, ves afrontándolo en pequeñas partes.
Por ejemplo, olvida el "todo" y piensa sola y unicamente en como podría ser el algoritmo que hace la venta de entradas.
No tienes ni que pensarlo en código Java, puedes hacerlo con un simple pseudocódigo, sin pensar en "convencionalismos". Escríbelo a tu modo, como tu lo entiendas mejor.
Por ejemplo:
Citar
precio = 0
si asientosLibres = 0
    escribir "No hay asientos libres"
sino
    escribir "Indique tipo cliente: J - Jubilado / A - Adulto / M - Menor"
    leer tipoCliente
    escribir "Indique cuantas entradas quiere"
    leer cantidadEntradas
    si cantidadEntradas > asientosLibres
        escribir "No hay suficientes asientos"
    sino
        escribir "Elija metodo de pago: E - Efectivo / T - Tarjeta"
        leer metodoPago;
        si tipoCliente = "J"
            precio = //Calcular precio para jubilados
        si tipoCliente = "A"
            precio = //Calcular precio para adultos
        si tipoCliente = "M"
            precio = //Calcular precio para menores
        finsi
        si metodoPago = "T"
            precio = precio  + 3.5% //Comision por tarjeta
        finsi
        precio = precio + 18% //Impuesto
        escribir "Venta realizada. Precio final: " + precio
finsi

Esto es parte de lo que este algoritmo, que sería un método de la clase Sala, tiene que hacer.
No está completo, por ejemplo tendría que actualizar contadores (que serían atributos de Sala) para saber cuantos asientos libres quedan tras esta venta y contar el tipo de cliente al que se le ha hecho la venta para posteriormente mostrar estadisticas.

Intenta completarlo y de ahí luego intentar saca un código Java.

846
Hola.

Puede haber varias formas de resolverlo.
Puesto que la información con la que nos interesa trabajar es todo relacionado con la sala de cine: titulo de la pelicula que se proyecta en la sala, asientos disponibles, tipo de personas que han comprado entrada....

Parece que la entidad "sala" es el centro clave de este ejercicio, así que podríamos crear una clase llamada Sala.
Esta clase se encargaría por si sola de la gestión de sus asientos. Es decir, ella se encargaría de controlar cuantos asientos quedan disponibles, contar los tipos de persona que han comprado entrada para luego poder mostrar estadisticas, mostrar la estadística cuando se lo pidamos,  y sobre todo gestionar la venta: preguntar cuantas entradas quiere el usuario, para que tipo de usuario, comprobar que hay suficientes asientos, preguntar método de pago...

Así que ves pensando que atributos necesitaría esta clase Sala.
Algunos son muy evidentes, como el título de la película que proyecta o los asientos disponibles, que empezarían con valor 20 e irían disminuyendo según se venden entradas.
Otros no son tan evidentes, pero probablemente nos interesaría tener contadores para cada tipo de cliente (jubilados, adultos y menores) para luego poder mostrar estadisticas

Piensa también que posibles método podríamos necesitar. EL más importante sin duda sería el de hacer la venta, ya que pide toda la informacion, comprueba si es posible realizar la venta con los asientos que hay disponibles, calcula el importe de la venta final y actualiza todos los contadores que podamos necesitar.

Ves pensándolo, yo intentaré hacer una por mi parte y a ver si mañana sobre esta misma hora puedo compartirla por aquí.

Una vez tengamos esta clase Sala. Desde otra clase con un metodo main() podemos crear tres objetos de la clase Sala, uno por cada película y crear el menu para que el usuario elija para cuál Sala quiere comprar entrada.

Si lo piensas, hay otras "entidades" en el ejercicio: Jubilados, Adultos y Menores que podrían ser clases herederas de una clase abstracta llamada Persona, puesto que todos son personas.

Sin embargo, para este ejercicio, no resulta necesario crear clases para estas entidades ya que apenas necesitamos tener información sobre ellos. Básicamente solo queremos contarlos para las estadísticas y aplicarles el precio que les corresponda. Nada más.

Si el ejercicio nos pidiera más información sobre estas Personas, como por ejemplo tener un listado de clientes asociados al cine, saber su nombre, su documenteo de identidad, saber si ha comprado algún bono que por ejmplo le permitiera ver 10 peliculas a precio reducido, saber cuantas entradas de ese bono ha gastado ya, etc...
entonces si sería necesario crear clases para estas entidades.

Pero no es el caso, y con crear una clase para la entidad Sala, es más que suficiente

847
Aprender a programar desde cero / Re:Respuesta CU00640B
« en: 04 de Septiembre 2018, 01:04 »
Hola.

El motivo de que un constructor reciba parámetros, es utilizar dichos parámetros para incializar el objeto.
Así que este constructor:
Código: [Seleccionar]
public ProfesorCU00640B(String nombre, String apellidos, int edad,
            boolean casado, boolean especialista) {
        nombre = "Juan Diego";
        apellidos = "Mosquera Herrera";
        edad = 18;
        casado = true;
        especialista = true;
    }

No tendría sentido.
Lo que tiene sentido es recuperar los valores de esos parámetros y adjudicarselos a los atributos del objeto. Tal que así:

Código: [Seleccionar]
public ProfesorCU00640B(String nombre, String apellidos, int edad,
            boolean casado, boolean especialista) {
        this.nombre = nombre;
        this.apellidos = apellidos;
        this.edad = edad;
        this.casado = casado;
        this.especialista = especialista;
    }

Puesto que los parámetros tienen exactamente el mismo nombre, es necesario usar la palabra reservada this. para que el compilador sepa distinguirlos.
Los que está precedidos de this. corresponden a los atributos del objeto.
Los que no, corresponden a los parámetros del constructor.


Si los parametros tuvieran nombres distintos de los atributos, no sería necesario usar la palabra reservada this. ya que el compilador de Java ahora no tendría problemas para diferenciar los atributos de los parámetros por llamarse diferente.
Mucha gente sigue usando el this. igualmente en estos casos, eso ya depende del gusto de cada uno, pero no sería necesario y el siguiente ejemplo funcionaría perfectamente:

Código: [Seleccionar]
public ProfesorCU00640B(String nom, String ape, int ed,
            boolean cas, boolean espe) {
        nombre = nom;
        apellidos = ape;
        edad = ed;
        casado = cas;
        especialista = espe;
    }

848
Hola.
Lo primero indicar que esta sección es para presentarse y/o hacer sugerencias para el foro, no para plantear dudas. Luego un moderador lo moverá a la sección correspondiente.

Sobre lo que planteas.
Supongo que lo que piden es hacer que, de manera aleatoria, se decida si el X-Wing ha sido destruido o no.
De modo que si ha sido destruido, ya no podrá disparar misiles cuando se lo ordenemos.

Así que  habría que añadirle a la clase un atributo booleano. Podemos llamarlo destruido y se iniciaría con valor "falso".
Citar
   private String nombre;
   private int misiles = 6;
   private int disparos = 0;
   private boolean destruido = false;

Luego habría que añadir un método donde usando el random que proponían, decidiremos si la nave sufre una destruccion o no.
Este método sería privado, porque es una función interna de esta clase. En principio, no queremos que otras clases puedan llamar a este método.
El código que te proponian genera numeros aleatorios entre 0 y 11.
Ahora podemos decidir a nuestro antojo cómo decidir cuando será destruida la nave.
Yo por ejemplo he decidido que si se genera un 0, un 5 o un 11... la nave será destruida.
Pero podríamos decidir otra forma, por ejemplo destruir solo si el número generado es un numero par, o cualquier cosa que se nos ocurra.
Citar
   /**
    * Método interno que decide si el XWing sufre una destrucción o no.
    * En caso de ser destruido, ya no podrá seguir disparando.
    */

   private void decidirDestruccion() {
      Random randomGenerator = new Random();
      int destruir = randomGenerator.nextInt(12);
      //Decidimos que el X-Wing será destruido si obtenemos: 0, 5 ó 11
      if (destruir == 0 || destruir == 5 || destruir == 11)
         destruido = true;
   }

Bien, ahora ya tenemos COMO decidir si la nave se destruye o no.
Ahora hay que establecer el CUANDO vamos a tomar esta decisión.
Puesto que no se indica nada en el enunciado, a mi se me ocurre que podemos hacerlo cada vez que el X-Wing recibe orden de disparar, es decir, cuando se invoque el método disparar_misil().
Este método lo vamos a modificar, lo primero que hará es consultar el atributo destruido, de modo que si tiene valor "verdadero", es decir, la nave está destruida, entonces no disparará e informará con un mensaje.
Si no, es decir, la nave aún está "viva", entonces sí disparará (si es que le quedan misiles). Y tras el disparo (o intento de disparo), será CUANDO decidiremos si va a sufrir una destrucción llamando a nuestro método privado.
Marco en rojo los cambios:
Citar
   public boolean disparar_misil() {
      if (destruido)
      {
         System.out.println("El X-Wing " + nombre + " ha sido destruido y no puede disparar");
         return false;
      }

      else
      {
         if (misiles > 0) {
            System.out.println(this.nombre + "...: L A N Z A N D O   M I S I L  # :" + misiles);
            misiles = misiles - 1;
            //Tras cada accion de ataque, echamos a suertes si el X-Wing  sufre una destrucción.
            decidirDestruccion();

            return true;
         } else {
            System.out.println(this.nombre + "**** WARNING : NO HAY MISILES ****");
            decidirDestruccion();
            return false;
         }
      }
   }

Así que finalmente, esta podría ser la clase XWing finalizada:
Código: [Seleccionar]
import java.util.Random;

public class XWing {

private String nombre;
private int misiles = 6;
private int disparos = 0;
private boolean destruido = false;

public XWing() {

}

public XWing(String nombre) {
this.nombre = nombre;
}

/**
* Método interno que decide si el XWing sufre una destrucción o no.
* En caso de ser destruido, ya no podrá seguir disparando.
*/
private void decidirDestruccion() {
Random randomGenerator = new Random();
int destruir = randomGenerator.nextInt(12);
//Decidimos que el X-Wing será destruido si obtenemos: 0, 5 ó 11
if (destruir == 0 || destruir == 5 || destruir == 11)
destruido = true;
}

/**
* @return boolean
*/
public boolean disparar_misil() {
if (destruido)
{
System.out.println("El X-Wing " + nombre + " ha sido destruido y no puede disparar");
return false;
}
else
{
if (misiles > 0) {
System.out.println(this.nombre + "...: L A N Z A N D O   M I S I L  # :" + misiles);
misiles = misiles - 1;
//Tras cada accion de ataque, echamos a suertes si el X-Wing  sufre una destrucción.
decidirDestruccion();
return true;
} else {
System.out.println(this.nombre + "**** WARNING : NO HAY MISILES ****");
decidirDestruccion();
return false;
}
}
}

/**
* @param rafaga
*/
public void disparar_canon(boolean rafaga) {
if (rafaga) {
for (int i = 0; i < 20; i++) {
System.out.println(this.nombre + " RAFAGA laser shot !!!");
disparos = disparos + 1;
}
} else {
System.out.println(this.nombre + " laser shot !!!");
disparos = disparos + 1;
}

System.out.println(this.nombre + " *** INFO para el piloto : van " + disparos + " disparos ***");
}

public String getNombre() {
return nombre;
}

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

}


Ahora nos piden un main donde poner en práctica esta función.
Yo propongo aquí una clase supersencilla. Básicamente creamos un objeto XWing y ponemos un menú con dos opciones: disparar y terminar programa.
Tras cada accion de disparo, se decidirá si el Xwing es destruido tal y como hemos programado en su clase.
Así que en algún momento indeterminado, pediremos disparar pero ya no será posible porque la nave habrá sido destruida.

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

public class Test {

public static void main(String[] args) {

XWing xW = new XWing("Falcon");
Scanner teclado = new Scanner(System.in);
int opcion = 0;
do {
System.out.println("\n\n1 - Disparar");
System.out.println("9 - Terminar programa");
System.out.println("Elija opcion: ");
opcion = teclado.nextInt();
switch (opcion) {
case 1:
xW.disparar_misil();
break;
case 9:
System.out.println("\n\nFIN DE PROGRAMA");
break;
default:
System.out.println("Opcion invalida");
}
}while(opcion != 9);
teclado.close();

}

}


849
Hola.

El error está en el constructor de la clase Taxi

En la clase TaxiCond estás inicializando un objeto Taxi con un constructor sin parametros:

Citar
  public TaxiCond () {
      vehiculoTaxi = new Taxi(); //Creamos un objeto Taxi con el constructor general de Taxi
      conductorTaxi = new Persona (); //Creamos un objeto Persona con el constructor general de Persona
  }

Pero resulta la clase Taxi solo tiene un constructor definido, y está definido con parametros:

Citar
    public Taxi (String valorCiudad, String valorMatricula, String valorDistrito, int valorTipoMotor) {

        ciudad = "";       
        matricula = "";
        distrito = "";
        tipoMotor = 0;
    }

Que por cierto, este constructor de Taxi no tiene ningún sentido, ya que pide parámetros pero luego dentro del constructor no los está usando. Inicializa los atributos con valores 0 y cadenas vacías, tal y como haríamos en un constructor sin parametros

Par corregir el error, hay que modificar el constructor para que no pida parametros, total no los está usando.

O ya puestos podemos definir dos constructores para Taxi, uno sin parametros y otro con parametros, aunque este último no se va a utilizar, al menos no en este ejercicio..
Obviamente el que pide parametros, luego ha de usarlos convenientemente para la inicialización de los atributos:

Código: [Seleccionar]
    //Constructor SIN parametros
    public Taxi() {
   
    ciudad = "";       
        matricula = "";
        distrito = "";
        tipoMotor = 0;
    }

  //Constructor CON parametros
    public Taxi (String valorCiudad, String valorMatricula, String valorDistrito, int valorTipoMotor) {

        ciudad = valorCiudad;       
        matricula = valorMatricula;
        distrito = valorDistrito;
        tipoMotor = valorTipoMotor;
    }

Con esto ya desaparece el error y puedes compilar bien.

Confirmanos que has entendido bién a que se debe el error, si no te queda claro intentamos explicarlo de otra forma.

No se si en este punto del curso de Java, se ha visto ya por qué un constructor pide parametros y cómo se inicializa un objeto con parametros.

Por si acaso, lo intento explicar de forma muy resumida.

Al inicializar un objeto, podemos elegir si queremos hacerlo pasandole o no parametros.

Si no le pasamos parametros, tendremos un objeto creado pero seguramente sus atributos no tendrán ningún valor asignado. Así que posteriormente tendremos que usar los "setters" para establecer el valor de esos atributos.
Por ejemplo:
Código: [Seleccionar]
Persona persona1 = new Persona();
persona1.setNombre("Kabuto");
persona1.setGenero("Hombre");
persona1.setEdad(38);

Ahora bien, podemos hacer eso mismo en una sola linea, usando un constructor al que le podamos pasar parametros.
Código: [Seleccionar]
Persona persona1 = new Persona("Kabuto", "Hombre", 38);
Por esto es común que las clases tengan al menos dos constructores, uno sin parametros y otro con parametros.
Si ya tenemos los datos de los atributos, por ejemplo porque los estamos leyendo de una base de datos o de un fichero de texto, preferiremos utilizar el constructor con atributos.

Si todavía no tenemos los datos de los atributos, porque tenemos que pedirle al usuario que los introduzca por teclado, seguramente preferiremos utilizar el constructor sin parametros. Luego, tras crear el objeto, pediremos datos por teclado al usuario y los iremos asignando a los atr
iobutos mediante los "setters"

Como ves, elegir uno u otro dependerá de las necesidades de nuestro programa.

850
Aprender a programar desde cero / Re:Respuesta CU00634B
« en: 26 de Agosto 2018, 00:52 »
Hola Ronald,
para este ejercicio no se pedía escribir ningún código. Lo que se pide es comprobar si tú eres capaz de discernir cuál será el resultado de evaluar esas expresiones.
Es decir, tú has de evaluar mentalmente cada expresión y decidir si el resultado es verdadero o falso.

Aún así, tampoco está mal haber escrito ese código, pues te sirve para comprobar si tu analisis mental de cada expresión ha sido correcto o no.

Pero lo importante es que el programador sepa evaluar esas expresiones mentalmente.
Cuando se escriben programas, el programador ha de decidir cuáles son las condiciones a evaluar en cada caso, y por donde seguirá la ejecución del código según el resultado de hacer dichas evaluaciones.
Así que por tanto, el programador ha de ser capaz de entender los operadores lógicos que evaluan estas expresiones para poder sacarles provecho.

Así que intenta hacerlo tú mentalmente y no dudes en preguntar cuando encuentres alguna que no sepas como evaluar.

En realidad, es bastante fácil, pues solo hay que aplicar la lógica (por eso se le llaman operadores lógicos)

Por ejemplo, si c = 3

Y evaluo esta expresión con un AND --> (c == 3 ) && (c ==5)

Estoy diciendo que "c es igual a 3" y que "c es igual a 5".
Estoy diciendo que las dos posibles condiciones, se están cumpliendo.
Obviamente, eso es falso. El valor de c es 3, eso es cierto, pero no es 5. Y ahí estoy diciendo que c es 3 y que también es 5, lo cuál es mentira.

De hecho, esta expresión que hemos evaluado, da igual cuál sea el valor real de c. Esta expresión SIEMPRE será falso.
Porque una variable nunca tendrá dos valores distintos al mismo tiempo (quizás sí en computación quántica pero eso ya lo veremos el siglo que viene je je)
Una variable solo tendrá un posible y único valor. ASí que cualquier expresión que diga que esa variable tiene dos valores distintos al mismo tiempo, siempre será FALSE.

Lógico, ¿no?

En cambio, si ahora evaluamos con un OR en lugar de un AND
Con OR --> (c == 3 ) || (c ==5)

Ahí estoy diciendo que "c es igual a 3" o que "c es igual a 5".
Estoy diciendo que al menos una de esas dos condiciones, se está cumpliendo. La otra condición puede que se cumpla también, o no...

Esta expresión es verdadera, porque es cierto que al menos una de esas condiciones se está cumpliendo, pues hemos dicho que c tiene valor 3, así que esta condición se cumple.

Estos ejemplos son fáciles de entender y en realidad rara vez necesitaremos utilizar condiciones que sean mucho más complejas.
Pero es importante ser capaces de evaluar mentalmente cualquier posible condición, ya que a veces si nos vendrá bien usar condiciones complejas y/o ingeniosas que nos pueden ayudar a simplificar el resto del código.

Un saludo

851
Aprender a programar desde cero / Re:Respuesta CU00632B
« en: 23 de Agosto 2018, 01:00 »
Hola.
Comento lo que bajo mi humilde opinión no es enteramente correcto.

Los metodos getter, en principio, solo deberían devolver el valor que le estamos pidiendo.
Salvo casos muy concretos, no deberían encargarse de imprimir por consola ningún mensaje.

Esto es porque estos métodos han de servir para multiples propósitos, no solo para mostrar información en pantalla.
Me explico.
Pongamos como ejemplo este método:
Código: [Seleccionar]
public int getEdad() {
        System.out.println("Su edad es de");
        return edad;
    }

Supón que en nuestro programa tenemos un listado de 50 médicos, es decir, 50 objetos de la clase Medico.
Y supongamos que queremos calcular la media de edad de estos médicos, por lo que a cada objeto le pediremos que nos de su edad llamando a su método getEdad().
Esta edad no queremos mostrarla en pantalla, solo queremos que nos la devuelva para poder sumar todas las edades del listado de médicos, y luedo dividir por 50 para obtener la media.
Bien, pues con tu método, al pedir la edad a los 50 médicos, resulta que nos saldría en pantalla 50 veces el mensaje:
Citar
Su edad es de
Su edad es de
Su edad es de
Su edad es de
Su edad es de
...
Ni siquiera saldría el valor de las edades, ya que el método no imprime la edad, solo imprime el mensaje "Su edad es de" y el valor lo retorna.
Pero es que para este caso no queremos que imprima la edad, ni el mensaje, ni nada.
Tan solo queremos obtener los valores de cada edad para poder hacer operaciones aritméticas con ellos.

Así que quedaría muy extraño, y esto es porque le estás pidiendo al método getEdad() que haga cosas que no debería hacer.
Debería limitarse sola y únicamente, a devolver la edad:
Código: [Seleccionar]
public int getEdad() {
        return edad;
    }

Y ya luego, en el metodo main(), haremos las concatenaciones necesarias para mostrar el mensaje con la edad:
Código: [Seleccionar]
System.out.println("Su edad es de " + medico.getEdad() + " años");
Lo mismo con el resto de metodos "getter": getNombreMed(), getApellidosMed(), etc...
Deberían ocuparse de retorna el valor del atributo. Ya está, nada más. No es recomendable que además se ocupen de mostrar mensajes por consola ni ninguna otra cosa.

Quizás has incluido estos mensaje debido a este premisa del enunciado del ejercicio:
Citar
En cada método, incluye una instrucción para que se muestre por consola un mensaje informando del cambio.Por ejemplo si cambia la especialidad del médico, debe aparecer un mensaje que diga: “Ha cambiado la especialidad del médico de nombre … . La nueva especialidad es: …”.

Vale, pues de esos mensajes deberían encargarse los "setters", no los "getters".
Los "getters" devuelven valores de los atributos, los "setters" se encargan de establecerlos, es decir, modificarlos.
Por ejemplo, si queremos cambiar la especialidad, invocaremos al método setEspecialidad().
Por lo tanto, será él mismo quien se encargue de lanzar el mensaje informando del cambio.
Código: [Seleccionar]
public void setEspecialidad(String especialidad) {
        this.especialidad = especialidad;
        System.out.println("Ha cambiado la especialidad del médico de nombre " + this.nombre);
        System.out.println("La nueva especialidad es " + this.especialidad");
    }

Por último, sobre como tratar el atributo de "casado".
Este atributo es booleano, es decir, solo tiene dos posibles valores: true o false

Bien, este valor no debemos mostrarlo directamente en pantalla porque no es lo suficientemente informativo para el usuario.
Ni siquiera intentando hacer una aclaración como tú has hecho, no es elegante:
Código: [Seleccionar]
System.out.println(medico.esCasado() + ". Nota si es true (esta casado)\n"
                + "si es false (esta soltero)");

La forma correcta y elegante es comprobar el valor del atributo con el condicional if y preparar los dos posibles mensajes.
Por ejemplo:
Código: [Seleccionar]
if (medico.esCasado() == true)
        System.out.println("Estado civil: Casado");
else
        System.out.println("Estado civil: Soltero");

Implica escribir unas poquitas más de lineas de código, pero la información en pantalla es más elegante y correcta.

853
Exacto.
En el bucle for, la variable num no cambia nunca de valor, es la variable i la que se va modificando en cada iteración y por tanto la que usaremos para el cálculo del factorial.
Dos correciones.
la primera, sin importancia, en esta línea, no es necesario multiplicar la i * 1:
Citar
factorial = factorial + (i*1);

Si lo piensas, multiplicar por 1 nunca sirve para nada.
5 multiplicado por 1, sigue siendo 5.
15 multiplicado por 1, sigue siendo 15.
543 multiplicado por 1, sigue siendo 543.
7236476274627 multiplicado por 1, sigue siendo 7236476274627

En conclusión,
i multiplicado por 1, sigue siendo i

Así que con esto es suficiente:
Citar
factorial = factorial + i;

LA segunda, importante:
Ahora mismo no estás consiguiendo obtener el factorial

Mira, por ejemplo, el factorial de 5, sería:
5 * 4 * 3 * 2 * 1 = 120

Sin embargo, con tu código obtenemos como resultado 15
Porque estás haciendo:
5 + 4 + 3 + 2 + 1 = 15

Revísalo, casi lo tienes, pero no estás haciendo la operacion matemática correcta.
Y enseguida te darás cuenta de que no te va a bastar cambiar la suma por una mutiplicación.
Hay que hacer más modificaciones en el código. La solución tiene la estructura que propones, pero aún faltan un par de detalles.

854
AHora vamos a ver la clase principal llamada Encuesta
Esta clase es la que dibujará el marco principal, por lo tanto hereda de JFrame tal como ya hiciste en tu código.
Este marco irá apilando objetos de nuestra clase Pregunta (recordemos que cada Pregunta es un JPanel), uno encima de otro. Por lo tanto también usaremos un BoxLayout vertical para la organizacion visual.
El ultimo panel que tendrá abajo de todo, no será una Pregunta sino un JPanel con los dos botones de "Enviar" y "Salir"

Para poder gestionar fácilmente las Preguntas que vamos a crear, las debemos agrupar en algún tipo de colección, al menos en un arreglo, pero yo he preferido usar un ArrayList.
Al tenerlas todas agrupadas en una coleccion, luego mediante bucles podemos recorrer las Preguntas una a una para ir añadiendolas al marco principal, o para preguntarles que respuestas tienen marcadas cada una, o para lo que necesitemos...

Así que esta clase tan solo tendrá tres atributos: el ArrayList con los objetos Pregunta y los dos botones JButton.

El constructor lo primero que hace es poner nombre al marco y justo después llama a un método que es el que se encarga de crear las Preguntas. Esto podría haberlo escrito directamente en el constructor, pero para que sea todo más legible, esta parte he preferido escribirla en un método separado.
Este método es muy sencillo, lo que hace es crear preguntas, con el enunciado deseado y los va añadiendo al ArrayList que se llama listaPreguntas
Código: [Seleccionar]
private void inicializarListaPreguntas() {
listaPreguntas.add(new Pregunta("1.¿Ha leído folletos informativos respecto a la Donación de Sangre?"));
listaPreguntas.add(new Pregunta("2.¿Ha donado sangre, plaquetas o plasma en los últimos 3 años?"));
/*
* Debido a la longitud de la pregunta 3, usamos codigo HTML dentro del JLabel para conseguir saltos de
* linea perfectamente centrados todo dentro de una unica etiqueta JLabel.
* Esto es gracias a que muchos componentes Swing soportan un HTML basico
*/
listaPreguntas.add(new Pregunta("<html><body><span align='center'>3.¿En los últimos 12 meses se ha realizado tatuajes, perforaciones,</span<br>"
+ "<span align='center'>acupuntura, transfusiones, cateterismos, endoscopias o ha tenido</span><br>"
+ "<span align='center'>contacto sexual con desconocidos?</span></body></html>"));
listaPreguntas.add(new Pregunta("4.¿Ha recibido algún transplante de órgano en los últimos 6 meses?"));
listaPreguntas.add(new Pregunta("5.¿Ha viajado en los últimos 28 dias a zonas con brotes epidemiológicos?"));
}

Una curiosidad es lo que ocurre con la pregunta numero 3. Su enunciado es mucho más largo que las de las otras preguntas. Si todo ese texto lo dejamos en una sola linea, nos deja una ventana un poco fea. Ya que es muy ancha para poder albergar toda esa linea, pero luego el resto de preguntas quedan un poco ridiculas con tan poco texto para tanta ventana.
Para evitar esto, lo ideal es añadir saltos de linea para partirla en tres lineas en lugar de solo una.
Pero, hay un problema. A un JLabel no puedes ponerle saltos de lineas -->(\n)
Se podría solventar usando tres JLabel en luga de uno, pero hemos diseñado nuestra clase Pregunta para que solo tenga un JLabel y no vamos a diseñar una nueva clase especificamente para esta Pregunta tan especial...
¿Como solucionarlo?
Pues con un truquito que a veces viene de maravilla para estas situaciones. Resulta que dentro del JLabel podemos usar codigo HTML a nivel básico, más que suficiente para crear saltos de linea y hacer que las tres lineas tengan el texto centrado.
Todo ello dentro de un único JLabel.

EL resto de preguntas no presentan problema, instanciamos un objeto Pregunta, le pasamos el enunciado y lo añadimos al ArrayList.

Fíjate que fácil nos pone esto las cosas. Aquí podríamos hacer 10 preguntas, 50, 100, 5000....las que quisieramos... sin tener que declarar cientos de RadioButton y etiquetas JLabel especificas para cada pregunta que quisieramos poner en la encuesta.
Valiéndonos de las ventajas de la Programacion Orientada a Objetos (POO), simplemente hemos necesitado diseñar una sencilla clase llamada Pregunta y ahora podemos replicarla tantas veces como queramos y gestionarlas fácilmente desde un ArrayList.

Una vez inicialiadas las Preguntas, ya cada una con su propio enunciado.
Inicializamos los botones send y salir. Les ponemos un texto, una fuente a nuestro gusto y les añadimos  un ActionListener para indicarles que ha de hacer cada boton.
Código: [Seleccionar]
send = new JButton("Enviar");
send.setFont(new Font("Berlin Sans FB", Font.PLAIN, 14));
send.addActionListener(new AccionEnviar());
salir = new JButton("Salir");
salir.setFont(new Font("Berlin Sans FB", Font.PLAIN, 14));
salir.addActionListener(new AccionSalir());
De nuevo, para no hacer un código de dificil lectura, las acciones de los ActionListener las he declarado como clases separadas. Así el constructor no está saturado de lineas de código.

Estas clases están declaradas dentro de la propia clase Encuesta (es lo que se llama anidar clases) y tienen el siguiente codigo.
La del boton salir es fácil, ocultar el marco y dar orden de eliminarlo con dispose()
Código: [Seleccionar]
class AccionSalir implements ActionListener {

@Override
public void actionPerformed(ActionEvent arg0) {
setVisible(false);
dispose();
}
}

La del boton enviar tampoco es complicada.
Eso sí, se supone que este boton ha de escribir las respuestas en un fichero de texto. Esto de momento no lo he hecho. Primero centrémonos en que nos quede claro como hemos creado y organizado la encuesta, y luego nos ponemos con como queremos escribir la informacion en el archivo texto.

Esta clase lo que hace es recorrer las Preguntas una a una (bendito ArrayList) pregunta que respuesta hay marcada y las va juntando en unico String que luego mostraremos en un ventana pop-up.
Además comprueba si alguna de las Preguntas responde con un null.
Esto significa que el usuario se ha olvidado de marcar alguna respuesta. En este caso, lo que le mostramos al usuario es una advertencia indicandole su olvido.

Para saber que respuesta hay marcada, usamos el método getRespuesta() que habíamos creado en la clase Pregunta

Código: [Seleccionar]
class AccionEnviar implements ActionListener {

@Override
public void actionPerformed(ActionEvent e) {
String respuestas = "";
boolean todasContestadas = true;
for (int i = 0; i < listaPreguntas.size(); i++) {
if (listaPreguntas.get(i).getRespuesta() == null) {
JOptionPane.showMessageDialog(null, "Por Favor, conteste todas las preguntas",
"Preguntas sin respuesta", JOptionPane.WARNING_MESSAGE);
todasContestadas = false;
break;//Dejamos de obtener respuestas.
}
else {
respuestas += (i+1) + " --> " + listaPreguntas.get(i).getRespuesta() + "\n";
}
}

//Mostramos respuestas, si es que las tenemos todas
if (todasContestadas)
JOptionPane.showMessageDialog(null, respuestas, "Respuestas", JOptionPane.INFORMATION_MESSAGE);
}
}

Y bueno, ya tenemos las preguntas inicializadas y también los botones, con sus acciones ya establecidas.
Ahora hay que indicarle al JFrame que layout deseamos:
Código: [Seleccionar]
setLayout(new BoxLayout(getContentPane(), BoxLayout.PAGE_AXIS));Fijate que aquí al constructor del BoxLayout usamos el metodo getContentPane()
En la clase Pregunta nos bastaba con usar la palabra reservada this. Esto es porque Pregunta hereda de JPanel, pero Encuesta hereda de JFrame

Al crear un gestor BoxLayout() hay que pasarle dos parametros, el primero indicarle que contenedor ha de gestionar y segundo la orientacion (vertical u horizontal)
Cuando se trata de una JPanel, estamos tratando explicitamente con un contenedor así que nos basta con referirnos a él con this
Pero cuando tratamos con un JFrame, estamos tratando con un marco, no directamente con su contenedor.. así que tenemos que solicitarle su contenedor con el metodo getContentPane() para que el BoxLayout sepa qué es lo que tiene que gestionar.

Establecido el layout, añadimos las Preguntas que ya están inicializadas. De nuevo gracias al ArrayList, lo hacemos fácilmente con un bucle
Código: [Seleccionar]
for (Pregunta pregun: listaPreguntas)
add(pregun);
Tras las preguntas, creamos un último JPanel para los botones. Para que los botones queden centrados, dejamos el FlowLayout que viene por defecto.
Añadimos lo botones al JPanel, y este JPanel al marco, donde quedará por debajo de las preguntas.
Código: [Seleccionar]
JPanel panelBotones = new JPanel();
panelBotones.add(send);
panelBotones.add(salir);
add(panelBotones);

Y ya por último, al marco JFrame hay que darle unas últimas indicaciones. Los comentarios lo explican

Código: [Seleccionar]
pack();//Automaticamente se organizan todos los componentes dentro del marco
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);//Cerrar al pulsar la pestaña superior de cierre.
setResizable(false);//Evitamos que las dimensiones del marco sean manipulables por el usuario
setLocationRelativeTo(null);//El marco aparecerá justo en el centro de la pantalla
setVisible(true);//Hacemos el marco visible

Y con esto ya tenemos el marco listo.

Solo hace falta ponerlo en marcha. Para ello, a nuestra clase Encuesta le añadimos un metodo main() que se encargue de instanciarla.
Código: [Seleccionar]
public static void main(String[] args) {
new Encuesta();

}

Todo esto nos da un formulario muy simple, pero que funciona perfectamente.



Ahora aquí te pongo el código completo de la clase Encuesta.
Ya solo quedaría hablar de como queremos que los datos se graben en un archivo de texto. Pero antes, asegurate de que todo lo que hemos hecho te ha quedado más o menos claro, así que pregunta todo lo que no entiendas, prueba tu a modificar cosas para ver como se comporta, haz lo que sea necesario para entenderlo.
Un saludo.

Código: [Seleccionar]
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;

import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;

public final class Encuesta extends JFrame{

private ArrayList<Pregunta> listaPreguntas = new ArrayList<Pregunta>();
private JButton send, salir;

public Encuesta(){
super("Encuesta");
//Inicializamos componentes
inicializarListaPreguntas();
send = new JButton("Enviar");
send.setFont(new Font("Berlin Sans FB", Font.PLAIN, 14));
send.addActionListener(new AccionEnviar());
salir = new JButton("Salir");
salir.setFont(new Font("Berlin Sans FB", Font.PLAIN, 14));
salir.addActionListener(new AccionSalir());
/*
* Organizamos layout del marco.
* Usaremos un BoxLayout vertical donde se irán apilando las preguntas
* una encima de otra.
* Al final añadiremos un ultimo Jpanel con los dos JButton
*/
setLayout(new BoxLayout(getContentPane(), BoxLayout.PAGE_AXIS));
//Agregamos la preguntas. Recorremos el ArrayList y añadimos una a una
for (Pregunta pregun: listaPreguntas)
add(pregun);
//Finalmente, un JPanel con los botones. Este Jpanel usará el FLowLayout por defecto
JPanel panelBotones = new JPanel();
panelBotones.add(send);
panelBotones.add(salir);
add(panelBotones);
//Definimos comportamiendo del marco
pack();//Automaticamente se organizan todos los componentes dentro del marco
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);//Cerrar al pulsar la pestaña superior de cierre.
setResizable(false);//Evitamos que las dimensiones del marco sean manipulables por el usuario
setLocationRelativeTo(null);//El marco aparecerá justo en el centro de la pantalla
setVisible(true);//Hacemos el marco visible
}

class AccionSalir implements ActionListener {

@Override
public void actionPerformed(ActionEvent arg0) {
setVisible(false);
dispose();
}
}

class AccionEnviar implements ActionListener {

@Override
public void actionPerformed(ActionEvent e) {
String respuestas = "";
boolean todasContestadas = true;
for (int i = 0; i < listaPreguntas.size(); i++) {
if (listaPreguntas.get(i).getRespuesta() == null) {
JOptionPane.showMessageDialog(null, "Por Favor, conteste todas las preguntas",
"Preguntas sin respuesta", JOptionPane.WARNING_MESSAGE);
todasContestadas = false;
break;//Dejamos de obtener respuestas.
}
else {
respuestas += (i+1) + " --> " + listaPreguntas.get(i).getRespuesta() + "\n";
}
}

//Mostramos respuestas, si es que las tenemos todas
if (todasContestadas)
JOptionPane.showMessageDialog(null, respuestas, "Respuestas", JOptionPane.INFORMATION_MESSAGE);
}
}

/**
* Inicializa el arrayList con los objetos de la clase Pregunta
*/
private void inicializarListaPreguntas() {
listaPreguntas.add(new Pregunta("1.¿Ha leído folletos informativos respecto a la Donación de Sangre?"));
listaPreguntas.add(new Pregunta("2.¿Ha donado sangre, plaquetas o plasma en los últimos 3 años?"));
/*
* Debido a la longitud de la pregunta 3, usamos codigo HTML dentro del JLabel para conseguir saltos de
* linea perfectamente centrados todo dentro de una unica etiqueta JLabel.
* Esto es gracias a que muchos componentes Swing soportan un HTML basico
*/
listaPreguntas.add(new Pregunta("<html><body><span align='center'>3.¿En los últimos 12 meses se ha realizado tatuajes, perforaciones,</span<br>"
+ "<span align='center'>acupuntura, transfusiones, cateterismos, endoscopias o ha tenido</span><br>"
+ "<span align='center'>contacto sexual con desconocidos?</span></body></html>"));
listaPreguntas.add(new Pregunta("4.¿Ha recibido algún transplante de órgano en los últimos 6 meses?"));
listaPreguntas.add(new Pregunta("5.¿Ha viajado en los últimos 28 dias a zonas con brotes epidemiológicos?"));
}

public static void main(String[] args) {
new Encuesta();

}

}


855
Hola de nuevo. Te explico mi propuesta.
Para facilitar la creación de la encuesta, y que sea más fácil leer el código, etc... lo ideal es hacer uso de las ventajas de la Programacion Orientada a Objetos(POO)
Así que he pensado en crear una clase llamada Pregunta con una etiqueta JLabel para el enunciado y dos RadioButon con los valores "Si" y "No".
Esta clase hereda de JPanel, es decir, por cada pregunta que vayamos a crear, obtendremos un panel que podremos ir añadiendo a la clase principal donde crearemos el marco JFrame.
Así, desde el JFrame, podemos crear facilmente objetos de la clase Pregunta, tan solo habrá que pasarles el texto que queremos que tenga el enunciado y listo.
Ya no habrá que crear decenas de radioButton, decenas de JLabel... tan solo instanciar objetos de la clase Pregunta pasandoles un texto para el enunciado

Esta es la clase Pregunta
Código: [Seleccionar]
import java.awt.Font;

import javax.swing.BorderFactory;
import javax.swing.BoxLayout;
import javax.swing.ButtonGroup;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
import javax.swing.border.EtchedBorder;

public final class Pregunta extends JPanel{

private JLabel enunciado;
private JRadioButton radioSi, radioNo;

public Pregunta(String enun) {
//Inicializamos componentes
enunciado = new JLabel(enun);
enunciado.setFont(new Font("Berlin Sans FB", Font.PLAIN, 14));
radioSi = new JRadioButton("Si");
radioNo = new JRadioButton("No");
radioSi.setFont(new Font("Berlin Sans FB", Font.BOLD, 14));
radioNo.setFont(new Font("Berlin Sans FB", Font.BOLD, 14));
//Opcionalmente, podemos añadir un borde a cada Pregunta
setBorder(BorderFactory.createEtchedBorder(EtchedBorder.LOWERED));
/*
* Organizamos el layout.
* Usaremos dos subpaneles colocados en vertical con un BoxLayout para el panel principal.
* Cada subpanel a su vez usarán el FlowLayout que tienen activado por defecto.
* El subpanel de arriba tendrá el enunciado de la pregunta
* El subpanel de abajo tendrá los radioButton.
*/
//SubPanel arriba
JPanel arriba = new JPanel();
arriba.add(enunciado);
//SubPanel abajo
JPanel abajo = new JPanel();
abajo.add(radioSi);
abajo.add(radioNo);
//Panel principal
setLayout(new BoxLayout(this, BoxLayout.PAGE_AXIS));//decimos que "ESTE panel" (nuestra clase hereda de JPanel) organiza los componentes de arriba a abajo
add(arriba);
add(abajo);
}

/**
* Nos indica que respuesta ha sido seleccionada devolviendo una cadena
* con "Si" o con "No".
* Si no hay ninguna seleccionada, devolverá null
* @return String con valores "Si", "No" o null
*/
public String getRespuesta() {
if (radioSi.isSelected())
return "Si";
else if (radioNo.isSelected())
return "No";
else
return null;
}

}

Como ves, el constructor tiene como argumento un String donde recibirá el enunciado para la pregunta.

Los RadioButton son fáciles de usar. Tan solo hay que instanciarlos indicándoles que texto queremos que muestren y luego añadirlos al panel que nos interese.

Para la organización de los componentes en pantalla, en lugar de "nullear" el gestor de layout y pelearnos poniendo valores absolutos con el setBounds(), es más cómodo combinar paneles cada uno con el layout que nos interese.
Yo he preferido diseñarlo de modo que el enunciado este arriba y debajo los dos radioButton uno al lado del otro. Todo lo más centrado posible.
Para conseguir centrarlo, lo que hago es crear dos subpaneles llamados arriba y abajo.
Ambos conservan el gestor layout que traen por defecto, que es un FLowLayout desde el centro, es decir, los componentes que añadamos se irán centrando.
Entonces, a arriba le pongo el JLabel con el enunciado.
Y a abajo le pongo los dos radioButton.

Luego, al panel principal (que es el que hereda nuestra clase Pregunta de JPanel) sí le cambio el gestor de layout por un BoxLayout.
BoxLayout agrupa los componentes como si fueran cajas (box = caja). Los puede agrupar en horizontal o en vertical según le indiquemos.
Yo le indico que lo haga en vertical en esta linea:
Código: [Seleccionar]
setLayout(new BoxLayout(this, BoxLayout.PAGE_AXIS));De este modo, cuando al panel principal yo le añada los subpaneles arriba y abajo, el primero quedará por encima del otro y estos a su vez conservan sus componentes centrados con su propio FlowLayout.

Y con esto ya tenemos explicado la parte visual de la clase Pregunta.
Pero ahora nos falta la parte lógica.
Y esta es muy sencilla. La unica lógica que esperamos de una Pregunta, es que nos pueda decir cuál de las dos posibles respuestas es la que está marcada, o si tal vez no se ha marcado ninguna todavía.
Para esto tan solo necesitamos un metodo tan sencillo como este:
Código: [Seleccionar]
public String getRespuesta() {
if (radioSi.isSelected())
return "Si";
else if (radioNo.isSelected())
return "No";
else
return null;
}
Casi no hay ni que explicarlo.
Si el radiobutton llamado radioSi (muy importante usar nombres descriptivos para nuestras variables, componentes, etc...) está marcado, nos devuelve una cadena String con el texto "Si.
Si el que está marcado es radioNo, nos devuelve "No".
Si no hay ninguna respuesta marcada, nos devolverá el valor null

Esto luego, en la clase principal, nos será muy util para comprobar si el usuario ha marcado respuestas en todas las Preguntas, y saber cuáles son esas respuestas.

Y con esto ya está explicada la clase Pregunta. Pasamos a un post nuevo para explicar la clase principal Encuesta

856
Hola
Intento compilar y encuentro algunos errores.
Pero sobre todo hay cosas muy raras en el evento del boton Send:

Citar
@Override
                    public void actionPerformed(ActionEvent ae) {
                        String us = u.getText(); <--¿Que es u?No esta declarado en ningun sitio
                        String P1 = p1.getText();<-- p1, p2, p3... son JLabel, las etiquetas
                        String P2 = p2.getText();      donde has escrito el enunciado de las preguntas.
                        String P3 = p3.getText();      ¿Para que quieres recuperar los enunciados y pasarlos a objetos String?
                        String P31 = pp.getText();
                        String P32 = ppp.getText();
                        String P4 = p4.getText();
                        String P5 = p5.getText();
                        String P = "Si";
                        String R = "No";
                        if (us.equals(u) ){<--Sea lo que sea u, esta condición no parece tener mucho sentido.Habria que pensar mejor que condicion nos interesa comprobar si se cumple o no
                            JOptionPane.showMessageDialog(null, "Por Favor, conteste todas las preguntas");
                            if (P1.equals("") == y1.isSelected()){
                                P += "Si";
                            }
etc.....

Más cosas:
- los add() que haces, al no indicar nada, los estás añadiendo al JFrame principal, no al JPanel who que has declarado.
Si quieres añadirlo al JPanel, has de poner who.add()

Y finalmente añadir este JPanel al JFrame principal con:
add(who);

A parte hay que hacer visible al JFrame una vez terminado todo y un par de cosas más para que se cierre cuando pulsemos el boton X para Cerrar Ventana.

- Los JCheckBoxMenuItem, son elementos para añadir a las barras de menú superiores de las ventanas. Son los típicos elementos que se despliegan en todas las aplicaciones cuando apretamos en Archivo, Editar, Ayuda...
Esto no te sirve para lo que quieres hacer, habría que usar JRadioButton tal y como indicas en el enunciado, sin embargo, no hay ninguno en tu código.

-Prescindes de usar ningún layout y prefieres establecer tú las posiciones con setBounds().
Esto es válido, pero no muy recomendable ya que al mover o ampliar la ventana de aplicación los elementos pueden acabar desordenándose.
¿Es necesario hacerlo así? Creo que combinando uno o dos layout puede quedar mejor y sin tener que preocuparse de establecer posiciones con setBound()

Ahora me es imposible dedicarle a esto tiempo (Son las 2 de la noche por aquí..)
Si encuentro tiempo en las próximas horas, voy a intentar yo hacer el diseño de este marco para luego poder explicartelo mucho mejor.
Luego con esas explicaciones, ya puedes hacer tú el diseño a tu gusto y necesidades.

Despues de todo eso, tocaremos otro tema, que es cómo han de guardarse los resultados en el archivo de texto.
Porque veo que tienes dos String P y R a los que les vas añadiendo "Si" a uno y "No" al otro según lo que responda el usuario.
Y eso, si lo escribimos en un txt, tendríamos algo así como:
Código: [Seleccionar]
SiSiSi
NoNo

Vale que es un ejercicio de práctica y aprendizaje, pero lo que guardemos en el txt debería tener algo de sentido, que de algún modo supieramos a que pregunta corresponde cada Si y cada No.
Pero eso ya se verá luego. Primero intentaremos ver si conseguimos diseñar un formulario de preguntas y luego le añadiremos funcionalidad.

857
Me pidieron hacer un programa que elija 3 números aleatorios y así hasta que el usuario escriba "Ya no juego", cómo puedo hacerlo?

Primero especifica para que lenguaje de programación te lo piden.
Eclipse no es un lenguaje, es una interfaz de desarrollo para escribir programas.
Muy posiblemente sea para Java, ya que Eclipse y Java suelen ir de la mano... pero en realidad podría ser para otro lenguaje como C++.

Luego, intenta realizar TÚ el programa solicitado y pide ayuda cuando te atasques. No podemos ayudarte si no has escrito una sola línea de código.

En lugar de pensar directamente en el objetivo principal, piensa en objetivos menores para luego ir a por los siguientes.

Empieza por hacer un código que genera un número al azar. Tan solo eso, generar un único número al azar y fin de programa.
Si no sabes como, y suponiendo que sea para Java, aqui puedes aprender sobre la clase Random
Una vez consigas esto, amplia el objetivo. Generar números hasta que el usuario decida parar.

Por último, aclara bien qué es lo que se pide, no me queda claro ¿pedir numeros aleatorios? ¿Elegir entre tres números aleatorios?...

858
FlowLayout.LEFT no implica que se ponga a la izquierda.
Lo que hace es que se pondrá en el centro, y a partir de ahí, "flotará" a la izquierda en el caso de que añadas más objetos a ese panel para dejarles sitio y todo el conjunto de objetos quede lo más centrado posible.
Pero si dejas a ese boton solo, como ya has comprobado, se quedará en el centro.

Además, el FlowLayout.LEFT creo que no se lo puedes especificar al boton. Se lo especificas al Layout del panel, para decirle si quieres que los objetos floten a la izquierda, o a la derecha.
Pero no podrías por ejemplo, indicar distintas direcciones de "flotación" a cada objeto de ese panel.

El tema layouts es toda una pelea para aprenderles a sacar partido.
Muchas veces es necesario combinar layouts hasta encontrar una manera de obtener, o al menos acercarnos, a lo que tenemos en mente.
Hay un layout bastante "poderoso", el GridBagLayout, pero llegar a entenderlo y utilizarlo bien, a veces requiere más tiempo y código del que vale la pena invertir.

En tu caso, si tan solo quieres poner ese boton. Puedes eliminar el layout de ese panel.
panelTop.setLayout(null);
y luego especificar tu la posicion y tamaño de ese boton:
JButton botonLeft = new JButton("LEFT");
panelTop.add(botonLeft);
botonLeft.setBounds (5,5,35,20);//Posicion 5,5 y tamaño 35px de ancho y 20px alto

El problema de esto es que al redimensionar la ventana los componentes no se adaptarán  y además el JPanel tampoco se adaptará bien a todos los componentes, teniendo que establecer tu manualmente tamaño por defecto, tamaño preferido, tamaño maximo....

Suele se mala opción esta de "nullear" el layout.

Otra opción más adecuada para desplazar objetos a las posiciones que deseas, es la de añadir "Componentes Invisibles" para que hagan de relleno y "empujen" tu botón hacia donde quieras colocarlo.

Echa un vistazo a esta parte de la documentación oficial
Está en inglés, pero se entiende bien.

No dudes en hacer pruebas, trastear y cacharrear con esto y también con otros layouts.

Cada uno tiene sus comportamientos, peculiaridades, virtudes y limitaciones. Y la única forma de conocerlas es experimentar con ellos.

Paciencia, yo llevo algún tiempo practicando y aún muchas veces tengo algunas dificultades


Mucha gente usa editores SWING automatizados que se pueden implementar a Eclipse, Netbeans..
Tú colocas objetos en un editor visual y el se encarga de añadir el código necesario para que se quede donde tú le digas.

Personalmente no me gusta usarlos.
Quizás para actividad profesional donde no puedes perder tiempo experimentando puede estar bien.
Pero para los que estamos aprendiendo, creo que es mejor pelearnos nosotros con la documentación y buscando ejemplos o tutoriales en la red.

Además estos editores suelen incluir muchas líneas de código, algunas no siempre necesarias y como programador te encuentas con un archivo de texto descomunal, donde pierdes el control de qué hace cada una de esas lineas, cuál es su propósito, cómo y a cuál componente afecta...
Y a mi me gusta tener absoluto control y conocimiento de cada linea de código. Y escribirlo a mi manera, de forma que se pueda entender e intuir que es cada cosa, incluso si es necesario escribo varios archivos .java por separado para cada uno de los JPanel que componen mi JFrame, evitando así un único archivo .java gigantesco.

859
Vale, a ver. Recuperando un código mio de Java, lo he porteado a C y lo he integrado en tu código.
No estoy muy ducho en C, lo mio es Java. Pero lo he compilado y funciona.

He modificado la constante dimension a valor 10, para que la busqueda sea un poco más larga e interesante.

El resto de código apenas lo he modificado, solo la parte donde hacemos la busqueda.
He cambiado el bucle while, por un do ..while.
Viene a ser lo mismo en realidad, pero para este ejercicio queda mejor en mi opinion.

Tambien añado un booleano para controlar si hemos encontrado el valor a buscar o no.
Es mejor informar de si lo hemos encontrado o no cuando el bucle haya terminado de buscar.
El bucle puede terminar por haberlo encontrado o porque ya no quedan números para seguir comparando. Esta variable booleana nos servirá para saber cuál de las dos posibilidades ha ocurrido.
He puesto una linea que empieza por "Debug Info:" para que informe por pantalla que posicion del vector está consultando en cada momento.
No es necesaria para resolver el problema, pero es interesante ver como se va recalculando el valor de central. Sobre todo si aumentamos aún más la dimension del vector.

En fin, lo realmente interesante y algo difícil, es la parte en como recalculamos los valores de alto, bajo y central según si el numero es mayor o menor.

Código: [Seleccionar]
if (valor < arreglo[central])//Verificamos si el valor introducido por el usuario, es menor al de la variable en central//
{
//Valor es menor, hay que recalcular primero la variable alto y luego central
alto = central - 1;
central = (alto - bajo) / 2 + bajo;
}
else
{
//Valor es mayor, hay que recalcular primero la variable bajo y luego central
bajo = central + 1;
central = (alto - bajo) / 2 + bajo;
}

Las dos líneas que pusiste tú, se acercaban bastante a la solución, pero esta es en realidad un poquito más complicada.
No parece evidente al principio, sobre todo al trabajar con un vector de solo dimension 3, pero el resultado de dividir por 2 la resta de alto - bajo, hay que sumarsela despues a bajo
Supón un vector de dimension 10. REsulta que
bajo = 0
alto  = 9
central = 4 --> (9/2 = 4.5 --> Al pasar a int la posicion es 4 )

El numero no coincide y es mayor, así que tenemos que recalcular la variable bajo y central
bajo = central + 1 -- > 5
alto = 9 (este no cambia)
central = (alto - bajo) / 2 --> (9 - 5) / 2 --> 2
¿Como que un 2 ? Esto no es correcto, debemos preguntar por una posicion mayor que 4 , y 2 es menor ....

Claro, por eso digo que el resultado de este cálculo, hay que sumárselo siempre a bajo.
Atentos:
central = (alto - bajo) / 2  + bajo--> (9 - 5) / 2 + 5 --> 7

Ahora sí!!! Hemos conseguido el 7, que si es mayor que la posicion 4 por la cuál habiamos preguntado anteriormente.

No se si con esta explicación ha quedado claro, si haces tu mismo a lapiz y papel una simulación de estos cálculos cada vez que el bucle se repite buscando el número, quizás lo entiendas mejor.

En fin, te pongo abajo el código completo. Si lo compilas debería funcionar.

Importante, esto que yo he hecho es una búsqueda dicotómica, pero no es recursiva

Si consigues que te quede claro como funciona esta búsqueda, prueba a transformarlo tú en una búsqueda recursiva.

Suponiendo que entendemos lo mismo "por recursiva". Es decir, cuando hablamos "de recursividad", hablamos de una función que se llama a si misma internamente varias veces proporcionandose distintos valores para sus parametros.

Por eso dije al principio que en ese caso, tendrás que escribir una función que se encargue de hacer busquedas dicotómicas y que se llame a si misma hasta encontrar el número a buscar o hasta que no queden numeros por comprobar.

Aqui mi código completo:
Código: [Seleccionar]
#include <stdio.h>
#include <stdlib.h>
#define dimension 10

int main()
{
int indice, j;
int pos_menor, alto, central, bajo;
float arreglo[dimension];
float menor, AUX;
float valor;

/*Leer Vector*/
for (indice = 0; indice<dimension; indice++)
{
printf("arreglo[%i]= ", indice);//Ingresa los valores para el arreglo//
scanf("%f", &arreglo[indice]);
}

//Orden por Selección//
for (indice = 0; indice<dimension; indice++)
{
menor = arreglo[indice];//Asignamos el contenido del arreglo a la variable menor//
pos_menor = indice;//Asignamos el valor del indice del arreglo a la variable pos_menor/
for (j = indice + 1; j<dimension; j++)//Ciclo iterativo para ordenar por selección//
{
if (menor>arreglo[j])// Sentencia if para evaluar que la variable menor sea mayor ha arreglo//
{
menor = arreglo[j];//Se asigna el contenido del arreglo en la posición j, a la variable menor//
pos_menor = j;//Asignamos el contenido o valor de j a la variable pos_menor//
}
}
//Intecambiar//
AUX = arreglo[indice];//Se usa para almacenar el contenido del arreglo, en la posicion indicada por el indice//
arreglo[indice] = arreglo[pos_menor];//Igualamos el contenido de los indices del arreglo con los de arreglo pos_menor//
arreglo[pos_menor] = AUX;//Se asignan a la variable auxiliar los valores anteriores//
}
//Imprimir o mostrar el Vector en orden ascendente//
for (indice = 0; indice<dimension; indice++)
{
printf("arreglo[%i]=%f\n", indice, arreglo[indice]); //Muestra el vector ordenado, en orden ascendente, %i indica numeros enteros//
}
printf("\n Que valor desea buscar? ");//indicamos al usuario que diga cual valor desea buscar//
scanf("%f", &valor);//capturamos el valor anterior anterior en la variable valor//
bajo = 0;//asignamos el valor 0  a la variable bajo//
alto = dimension - 1;//restamos 1 a la variable dimension, el resultado lo asignamos a la variable alto//
central = alto / 2;//sumanos los contenidos de alto y bajo lo dividimos entre 2, el resultado lo asignamos a la variable central//
    //Busqueda Binaria
bool encontrado = false;
do
{
printf("--Debug info: Consultando Posicion --> %i\n", central);
if (valor == arreglo[central])
{
printf("Encontrado!!\n");
encontrado = true;
}
else
{
if (valor < arreglo[central])//Verificamos si el valor introducido por el usuario, es menor al de la variable en central//
{
//Valor es menor, hay que recalcular primero la variable alto y luego central
alto = central - 1;
central = (alto - bajo) / 2 + bajo;
}
else
{
//Valor es mayor, hay que recalcular primero la variable bajo y luego central
bajo = central + 1;
central = (alto - bajo) / 2 + bajo;
}
}
} while ((bajo <= alto) && !encontrado);
//Consultamos si lo hemos encontrado o no
if (encontrado)
printf("El valor se encuentra en la posicion:%i", central);
else
printf("Valor no encontrado");

printf("\n");
system("PAUSE");
return 0;
}


860
Y ¿ha de ser recursiva?
En dicho caso tendrías que escribir una función y supongo que como parámetros tendría que recibir el vector, el número a buscar, y valores para el bajo y el alto. Estos valores "bajo" y "alto" irían cambiando con cada llamada recursiva para ir acotando la búsqueda.

Es decir, supongamos un vector de 10 elementos.
Entonces tendríamos que bajo = 0 y alto = 9

Comparamos el numero a buscar con la posicion intermedia, que sería el indice 5 del vector.

Si el número a buscar es menor que el que tenemos en el índice 5 del vector, ya sabemos que el numero que buscamos no está entre el 5 y el 9.
Entonces volvemos a llamar a la funcion, con bajo = 0 pero ahora alto = 4.

Si el numero fuera mayor, encontes bajo = 6 y alto = 9.

Así hasta encontrar el numero.

He escrito algoritmos (en Java) para busquedas dicotómicas pero nunca recursivas. Simplemente un bucle que se repite actualizando los valores de bajo y alto hasta encontrar el numero o bien hasta que no queden posiciones por consultar.

Quizás deberías intentar hacer esto primero, para que te quede clara la mecánica de la búsqueda dicotómica. Y luego intentar lo mismo pero por recursividad, que por otra parte, no se si es algo adecuado para este tipo de ejercicio. Tal vez sí, no lo sé, nunca lo he intentado.

Páginas: 1 ... 38 39 40 41 42 [43] 44 45 46 47 48 ... 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".