En este post vamos a resolver un ejercicio de programación en Java. No voy a poner un examen o cuestionario de Java; no. Vamos a resolver un ejercicio para implementar un cuestionario que recibe infinitas preguntas con infinitas respuestas en donde una de éstas es la correcta.
Luego, se le hace cada pregunta al usuario, se registra su respuesta y se van contando los aciertos así como los errores. Al final se muestra el porcentaje de errores y aciertos de acuerdo al total de preguntas.
Resolveré este ejercicio propuesto en Java con programación orientada a objetos de la manera más elegante que pueda. Por cierto, el ejercicio dice así:
Tener un banco de preguntas, mínimo 12 con las 12 respuestas. Se pedirá que el usuario responda todas las preguntas. Una vez finalizado, se mostrará los resultados diciendo si la respuesta del usuario era correcta o no. También se mostrará el porcentaje de preguntas acertadas con decimales.
De hecho esto se parece a algo que ya había hecho tiempo atrás.
Vamos a crear un programa que permite crear un cuestionario, agregarle varias preguntas (infinitas) con infinitas respuestas, indicando en las respuestas si la misma es correcta.
De este modo podemos crear varios exámenes con distinto número de preguntas y respuestas, permitiendo también crear infinitos cuestionarios.
Comencemos desde abajo. Una respuesta va dentro de una pregunta, y se debe indicar si la misma es correcta o no. Entonces tenemos la clase en Java:
class Respuesta {
String respuesta;
boolean esCorrecta;
public Respuesta(String respuesta, boolean esCorrecta) {
this.respuesta = respuesta;
this.esCorrecta = esCorrecta;
}
}
Solo tenemos la respuesta que es una cadena y un booleano indicando si la respuesta es correcta. Esto es porque al crear una pregunta vamos a agregarle varias respuestas pero solo una de ellas es la correcta.
Ahora pasemos a la pregunta. Una pregunta tiene varias respuestas, además de la pregunta en sí. La pregunta debe ser capaz de imprimirse a sí misma, recibir la respuesta del usuario e indicar si el usuario ha respondido correctamente.
Para ello tenemos el siguiente código:
class Pregunta {
private final String pregunta;
private final List<Respuesta> respuestas;
// Nota: si crees que agregarás más respuestas, amplía las letras
private static final String letras = "abcdefghijklmnñopqrstuvwxyz";
public Pregunta(String pregunta, List<Respuesta> respuestas) {
this.pregunta = pregunta;
this.respuestas = respuestas;
}
public Pregunta(String pregunta) {
this.pregunta = pregunta;
this.respuestas = new ArrayList<>();
}
public void agregarRespuesta(Respuesta r) {
this.respuestas.add(r);
}
public boolean respuestaCorrecta(char respuesta) {
int indice = letras.indexOf(respuesta);
if (indice == -1) {
return false;
}
return this.respuestas.get(indice).esCorrecta;
}
public boolean preguntar(int numero) {
System.out.println(numero + ". " + this.pregunta);
int indice = 0;
for (Respuesta r : this.respuestas) {
System.out.printf("%c) %s\n", letras.charAt(indice), r.respuesta);
indice++;
}
System.out.println("Elige: ");
Scanner sc = new Scanner(System.in);
char respuesta = sc.nextLine().charAt(0);
return this.respuestaCorrecta(respuesta);
}
}
Aquí las cosas empiezan a tomar forma. Vamos paso por paso. Como puedes ver, las respuestas son un ArrayList
para que podamos tener una lista de tamaño variable.
Después tenemos métodos para agregar una respuesta, o también se puede indicar la lista de respuestas al construir el objeto; estamos sobrecargando el constructor.
También tenemos una función que nos dice si la respuesta es correcta, eligiendo el índice de la letra que ha elegido el usuario. Y finalmente tenemos el método preguntar que imprime la pregunta, imprime todas las posibles respuestas y lee lo que el usuario elija.
Es importante explicar la línea 39. En este caso estoy convirtiendo una cadena a char; ya que solo me interesa le primer carácter de toda la cadena (pues es la letra que el usuario introdujo).
El método de la línea 30 hace la pregunta y regresa un booleano indicando si la respuesta fue correcta. Este método lo usamos después dentro del cuestionario.
Finalmente, un cuestionario se compone de varias preguntas, infinitas preguntas si lo queremos ver así, pero también lleva un conteo interno de los aciertos y errores.
Para el total de preguntas basta con medir la longitud de la lista, en este caso podemos obtenerlo con el método size
del ArrayList
.
class Cuestionario {
private final List<Pregunta> preguntas;
private int aciertos;
private int errores;// ¿Alguien sabe el antónimo de acierto en este contexto? yo no
public Cuestionario() {
this.preguntas = new ArrayList<>();
}
public void agregarPregunta(Pregunta p) {
this.preguntas.add(p);
}
public void preguntar() {
int numero = 1;
for (Pregunta p : this.preguntas) {
boolean acierta = p.preguntar(numero);
numero++;
if (acierta) {
System.out.println("Correcto");
this.aciertos++;
} else {
System.out.println("Incorrecto");
this.errores++;
}
}
}
public void imprimirResultados() {
int total = this.preguntas.size();
double porcentajeAciertos = (100 * (double) this.aciertos) / total;
double porcentajeErrores = (100 * (double) this.errores) / total;
System.out.printf("Total de preguntas: %d\nAciertos: %d (%.2f %%)\nErrores: %d (%.2f %%)", total, this.aciertos, porcentajeAciertos, this.errores, porcentajeErrores);
}
}
La magia sucede en la línea 15; en este caso recorre todo el ArrayList e invoca a la función preguntar de cada pregunta… bellezas de la programación orientada a objetos.
También verifica si la respuesta es correcta, en ese caso aumenta los aciertos, y si no, aumenta los errores. Ya al final vemos a los resultados que básicamente calculan los porcentajes e imprimen los resultados.
El lector disculpará el uso de printf
pero prefiero usar esa función que concatenar y convertir los valores.
Ya vimos las 3 clases que nos permitirán hacer este simulador de cuestionario con preguntas, respuestas y estadísticas en Java. Veamos cómo usarlo, su uso es expresivo y elegante.
Por cierto, las respuestas correctas son solo de prueba, no quiero decir que yo esté en lo correcto.
public class Main {
public static void main(String[] args) {
Cuestionario c = new Cuestionario();
c.agregarPregunta(new Pregunta("Lenguaje de programación más fácil de aprender", List.of(
new Respuesta("Java", false),
new Respuesta("Go", false),
new Respuesta("Python", true),
new Respuesta("JavaScript", false)
)));
c.agregarPregunta(new Pregunta("1 + 1", List.of(
new Respuesta("3", false),
new Respuesta("2", true),
new Respuesta("4", false)
)));
c.agregarPregunta(new Pregunta("¿NetBeans es un lenguaje de programación?", List.of(
new Respuesta("Sí", false),
new Respuesta("No", true)
)));
c.agregarPregunta(new Pregunta("Lenguajes de programación (¡Miren! alguien dijo el chiste de que HTML no es un lenguaje de programación, ríanse) que sirven para programar en la web del lado del cliente", List.of(
new Respuesta("HTML, CSS y JavaScript", true),
new Respuesta("PHP, Python y JavaScript", false),
new Respuesta("C y C++", false),
new Respuesta("Perl y Kotlin", false),
new Respuesta("Go, JavaScript y TypeScript", false)
)));
c.preguntar();
c.imprimirResultados();
}
}
Como puedes ver se debe crear una instancia de Cuestionario
, y a partir de ahí invocar las veces que sea necesario a agregarPregunta
. En este caso para hacerlo simple y no crear un ArrayList
cada vez que creo una pregunta, estoy usando a List.of
.
El código de Java completo queda así:
/*
____ _____ _ _ _
| _ \ | __ \ (_) | | |
| |_) |_ _ | |__) |_ _ _ __ _____| |__ _ _| |_ ___
| _ <| | | | | ___/ _` | '__|_ / | '_ \| | | | __/ _ \
| |_) | |_| | | | | (_| | | / /| | |_) | |_| | || __/
|____/ \__, | |_| \__,_|_| /___|_|_.__/ \__, |\__\___|
__/ | __/ |
|___/ |___/
____________________________________
/ Si necesitas ayuda, contáctame en \
\ https://parzibyte.me /
------------------------------------
\ ^__^
\ (oo)\_______
(__)\ )\/\
||----w |
|| ||
Creado por Parzibyte (https://parzibyte.me).
------------------------------------------------------------------------------------------------
Si el código es útil para ti, puedes agradecerme siguiéndome: https://parzibyte.me/blog/sigueme/
Y compartiendo mi blog con tus amigos
También tengo canal de YouTube: https://www.youtube.com/channel/UCroP4BTWjfM0CkGB6AFUoBg?sub_confirmation=1
------------------------------------------------------------------------------------------------
*/
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
class Respuesta {
String respuesta;
boolean esCorrecta;
public Respuesta(String respuesta, boolean esCorrecta) {
this.respuesta = respuesta;
this.esCorrecta = esCorrecta;
}
}
class Pregunta {
private final String pregunta;
private final List<Respuesta> respuestas;
// Nota: si crees que agregarás más respuestas, amplía las letras
private static final String letras = "abcdefghijklmnñopqrstuvwxyz";
public Pregunta(String pregunta, List<Respuesta> respuestas) {
this.pregunta = pregunta;
this.respuestas = respuestas;
}
public Pregunta(String pregunta) {
this.pregunta = pregunta;
this.respuestas = new ArrayList<>();
}
public void agregarRespuesta(Respuesta r) {
this.respuestas.add(r);
}
public boolean respuestaCorrecta(char respuesta) {
int indice = letras.indexOf(respuesta);
if (indice == -1) {
return false;
}
return this.respuestas.get(indice).esCorrecta;
}
public boolean preguntar(int numero) {
System.out.println(numero + ". " + this.pregunta);
int indice = 0;
for (Respuesta r : this.respuestas) {
System.out.printf("%c) %s\n", letras.charAt(indice), r.respuesta);
indice++;
}
System.out.println("Elige: ");
Scanner sc = new Scanner(System.in);
char respuesta = sc.nextLine().charAt(0);
return this.respuestaCorrecta(respuesta);
}
}
class Cuestionario {
private final List<Pregunta> preguntas;
private int aciertos;
private int errores;// ¿Alguien sabe el antónimo de acierto en este contexto? yo no
public Cuestionario() {
this.preguntas = new ArrayList<>();
}
public void agregarPregunta(Pregunta p) {
this.preguntas.add(p);
}
public void preguntar() {
int numero = 1;
for (Pregunta p : this.preguntas) {
boolean acierta = p.preguntar(numero);
numero++;
if (acierta) {
System.out.println("Correcto");
this.aciertos++;
} else {
System.out.println("Incorrecto");
this.errores++;
}
}
}
public void imprimirResultados() {
int total = this.preguntas.size();
double porcentajeAciertos = (100 * (double) this.aciertos) / total;
double porcentajeErrores = (100 * (double) this.errores) / total;
System.out.printf("Total de preguntas: %d\nAciertos: %d (%.2f %%)\nErrores: %d (%.2f %%)", total, this.aciertos, porcentajeAciertos, this.errores, porcentajeErrores);
}
}
public class Main {
public static void main(String[] args) {
Cuestionario c = new Cuestionario();
c.agregarPregunta(new Pregunta("Lenguaje de programación más fácil de aprender", List.of(
new Respuesta("Java", false),
new Respuesta("Go", false),
new Respuesta("Python", true),
new Respuesta("JavaScript", false)
)));
c.agregarPregunta(new Pregunta("1 + 1", List.of(
new Respuesta("3", false),
new Respuesta("2", true),
new Respuesta("4", false)
)));
c.agregarPregunta(new Pregunta("¿NetBeans es un lenguaje de programación?", List.of(
new Respuesta("Sí", false),
new Respuesta("No", true)
)));
c.agregarPregunta(new Pregunta("Lenguajes de programación (¡Miren! alguien dijo el chiste de que HTML no es un lenguaje de programación, ríanse) que sirven para programar en la web del lado del cliente", List.of(
new Respuesta("HTML, CSS y JavaScript", true),
new Respuesta("PHP, Python y JavaScript", false),
new Respuesta("C y C++", false),
new Respuesta("Perl y Kotlin", false),
new Respuesta("Go, JavaScript y TypeScript", false)
)));
c.preguntar();
c.imprimirResultados();
}
}
Puedes descargar el código y, como siempre, eres libre de modificarlo, compartirlo, mejorarlo, etcétera. Además, este programa también puede ser importado a NetBeans, IntelliJ IDEA, etcétera.
El ejemplo de ejecución lo dejé al inicio del post en la imagen. Finalmente te dejo más posts sobre Java en el blog de Parzibyte.
Hoy te voy a presentar un creador de credenciales que acabo de programar y que…
Ya te enseñé cómo convertir una aplicación web de Vue 3 en una PWA. Al…
En este artículo voy a documentar la arquitectura que yo utilizo al trabajar con WebAssembly…
En un artículo anterior te enseñé a crear un PWA. Al final, cualquier aplicación que…
Al usar Comlink para trabajar con los workers usando JavaScript me han aparecido algunos errores…
En este artículo te voy a enseñar cómo usar un "top level await" esperando a…
Esta web usa cookies.