Practica Tema 1 (Gestión de calificaciones de estudiantes) - jcpichardo/Progra-II GitHub Wiki
El sistema debe permitir:
- Ingresar datos de estudiantes (nombre y calificaciones).
- Validar que las calificaciones estén en el rango correcto (0-10).
- Limitar el número máximo de estudiantes y materias.
- Mostrar un reporte con el promedio de cada estudiante y su estado (aprobado/reprobado).
- Proporcionar un menú interactivo para navegar entre opciones.
- Garantizar que las entradas del usuario sean seguras y manejadas correctamente.
- Muestra un menú interactivo
- Permite agregar estudiantes con sus calificaciones
- Valida las entradas del usuario
- Calcula promedios automáticamente
- Muestra reportes con formato
- Gestiona errores de entrada
-
Comentarios: o Comentarios XML en métodos o Comentarios explicativos en secciones clave
-
Constantes: o MAX_ESTUDIANTES, MAX_MATERIAS, APROBADO
-
Tipos de datos: o Primitivos: int, double, bool, string o Complejos: List, Array, struct
-
Variables: o Uso correcto de ámbitos (locales y de clase) o Nomenclatura descriptiva
-
Operadores: o Aritméticos: +, -, *, / o Comparación: >, <, ==, >= o Lógicos: &&, || o Asignación: =, +=
-
Sentencias: o Declaraciones de variables o Asignaciones o Llamadas a métodos
-
Matrices: o Arreglo unidimensional para calificaciones o Lista genérica para estudiantes
-
Procedimientos: o MostrarMenu() o AgregarEstudiante()
-
Funciones: o LeerCadena(), LeerEntero(), LeerDouble() o LeerCalificacion()
-
Estructuras de control: o if-else o switch o do-while o for o foreach
Abrimos Visual Studio y creamos una aplicación en consola.
Borramos cualquier codigo creado y creamos nuestra clase con su namespace.
namespace PracticaIntegradora
{
class Program
{
}
}
Comenzamos con la declaración de constantes y vamos insertando comentarios en el codigo.
// 1. COMENTARIOS
// 2. CONSTANTES
private const int MAX_ESTUDIANTES = 5;
private const int MAX_MATERIAS = 4;
private const double APROBADO = 7.0;
Necesitamos donde guardar a los estudiantes, para ello nos funciona una colección de registros llamada estructura..
// 10. ESTRUCTURA (Registro para datos estudiantiles)
struct Estudiante
{
// 3. TIPOS DE DATOS (string, int, double, bool, List, Array)
public string Nombre;
public double[] Calificaciones;
}
Creamos nuestra función de inicio
static void Main(string[] args)
{
}
¿Por que el Main no tiene public o private? ¿Por que es estatico?
Ejemplo para ejecutar el proyecto si Main NO fuera estático
class Program
{
void Main(string[] args)
{
Console.WriteLine("Hola Mundo");
}
static void Ejecutar()
{
Program p = new Program(); // Crear instancia
p.Main(new string[] {}); // Llamar al método
}
}
Creamos el menú solicitado
static void MostrarMenu()
{
Console.WriteLine("\n\nSistema de Calificaciones");
Console.WriteLine("1. Agregar estudiante");
Console.WriteLine("2. Mostrar reporte");
Console.WriteLine("3. Salir");
}
Llamamos este método desde la función principal
//9. Funciones y metodos
static void Main(string[] args)
{
MostrarMenu();
}
Corremos la aplicación
Ahora creamos una función para la lectura del dato de entrada.
static int LeerEntero(string mensaje)
{
int resultado;
//Mostramos mensaje de selección
Console.Write(mensaje);
//Leemos el dato
int.TryParse(Console.ReadLine(), out resultado);
return resultado;
}
Antes de llamar a la función hagamos uso de los comentarios formato XML, esto nos sirve para tener bien documentados cada uno de nuestros métodos y funciones.
Arriba del comienzo de la función tecleen tres diagonales ///
Aparecerá una estructura similar a esta donde se abrirá un patrón para la documentación del método.
/// <summary>
/// Funcion que devuelve el entero introducido por el usuario
/// </summary>
/// <param name="mensaje">Mensaje que indicara la instrucción al usuario</param>
/// <returns>Retorna un entero que será la selección del usuario</returns>
Llamamos la función desde el método principal, después de mostrar el menú
static void Main(string[] args)
{
// 4. VARIABLES
int opcion;
MostrarMenu();
opcion = LeerEntero("\nSeleccione una opción:");
}
Creamos una estructura de control para las diferentes opciones del menu
// 10. ESTRUCTURAS DE CONTROL (switch)
switch (opcion)
{
case 1:
// 8. PROCEDIMIENTO
Console.WriteLine("Aqui agregaremos al estudiante");
break;
case 2:
Console.WriteLine("Aqui mostraremos calificaciones");
break;
case 3:
Console.WriteLine("Saliendo del sistema...");
break;
default:
Console.WriteLine("Opción no válida");
break;
}
Nos damos cuenta que sea cual sea la acción sobre el menu, el sistema termina, aunque no presione la opción 3.
¿Qué hacemos para que no suceda esto?





¿Que estructura de control podemos usar?
¿Les suena, estructura de control iterativa?
¿Les da una idea un bucle?
¿Como se usa esto, tienen un ejemplo?
static void Main(string[] args)
{
// 4. VARIABLES
int opcion;
do
{
MostrarMenu();
opcion = LeerEntero("\nSeleccione una opción:");
// 10. ESTRUCTURAS DE CONTROL (switch)
switch (opcion)
{
case 1:
// 8. PROCEDIMIENTO
Console.WriteLine("Aqui agregaremos al estudiante");
break;
case 2:
Console.WriteLine("Aqui mostraremos calificaciones");
break;
case 3:
Console.WriteLine("Saliendo del sistema...");
break;
default:
Console.WriteLine("Opción no válida");
break;
}
} while (opcion != 3);
}
Vamos a debuguear para ver que pasa si introducimos letras, asi que pongamos un punto de interrupción en el Switch y en el método LeerEntero.
Ahora sigamos con los requerimientos.
Se solicita dar de alta estudiantes con sus respectivas calificaciones.
Creamos el metodo AgregarEstudiante
static void AgregarEstudiante(ref List<Estudiante> lista)
{
//Validando el que numero maximo de estudiantes
if (lista.Count >= MAX_ESTUDIANTES)
{
Console.WriteLine("¡Límite de estudiantes alcanzado!");
return;
}
//Si no revaso el limite, crear nuevo estudiante
Estudiante nuevo = new Estudiante();
}
Para crear al estudiante necesitamos leer el nombre y sus calificaciones.
Vamos a crearlas
Creando la función LeerCadena
/// <summary>
/// Funcion para leer una cadena
/// </summary>
/// <param name="mensaje">Texti para indicar la instracción al usuario</param>
/// <returns>Returna una cadena, en caso de valor nulo, retorna una cadena vacia</returns>
static string LeerCadena(string mensaje)
{
string? respuesta ="";
Console.Write(mensaje);
//respuesta = respuesta is null ? "" : respuesta; Esta sintaxis la ocuparemos en otro ejemplo
respuesta = Console.ReadLine() ?? "";
return respuesta;
}
Validación de null El operador ?? (null-coalescing operator) es el que maneja la validación de nulos aquí. Si Console.ReadLine() devuelve un null, el operador ?? lo reemplaza por "", evitando que respuesta sea null. Seria lo mismo que tener esto:
respuesta = Console.ReadLine();
if (respuesta == null)
{
respuesta = "";
}
Creando la funcion LeerCalificacion
// 9. FUNCIÓN con retorno
static double LeerCalificacion(string mensaje)
{
double calificacion;
do
{
calificacion = LeerDouble(mensaje);
if (calificacion < 0 || calificacion > 100)
{
Console.WriteLine("La calificación debe ser entre 0 y 100");
}
} while (calificacion < 0 || calificacion > 100);
return calificacion;
}
Creamos la funcion LeerDouble
static double LeerDouble(string mensaje)
{
double resultado;
do
{
Console.Write(mensaje);
} while (!double.TryParse(Console.ReadLine(), out resultado));
return resultado;
}
Regresamos al método inicial AgregarEstudiante para llamar a la funcion LeerCadena y LeerCalificacion
static void AgregarEstudiante(ref List<Estudiante> lista)
{
//Validando el que numero maximo de estudiantes
if (lista.Count >= MAX_ESTUDIANTES)
{
Console.WriteLine("¡Límite de estudiantes alcanzado!");
return;
}
//Si no revaso el limite, crear nuevo estudiante
Estudiante nuevo = new Estudiante();
nuevo.Nombre = LeerCadena("Nombre del estudiante: ");
//Validar que el nombre no sea un vacio
if (nuevo.Nombre== "")
return;
// 7. MATRIZ para calificaciones
nuevo.Calificaciones = new double[MAX_MATERIAS];
for (int i = 0; i < MAX_MATERIAS; i++)
{
nuevo.Calificaciones[i] = LeerCalificacion($"Calificación {i + 1}: ");
}
lista.Add(nuevo);
Console.WriteLine("!Estudiante agregado correctamente!");
}
Ahora regresamos al metodo **Main ** para llamar a la funcion AgregarEstudiante
Pero antes.

¿Que necesitamos para guardar los estudiantes?
¿Que creamos al inicio de la práctica?




RECORDEMOS
Por lo pronto no tenemos conexión a una base de datos, por lo cual creamos una estructura llamada **Estudiante **que nos guardara la colección de estudiantes con sus calificaciones.
La estructura no es suficiente, ya que esa estructura solo guarda 1 estudiante con un conjunto de calificaciones.
También requerimos una lista del tipo de la estructura de Estudiantes para poder almacenar muchos estudiantes.
Modificar el metodo Main para llamar el guardado del estudiante
List<Estudiante> estudiantes = new List<Estudiante>();
case 1:
// 8. PROCEDIMIENTO
AgregarEstudiante(ref estudiantes);
break;

¿En este punto se entiende por qué la lista estudiantes se pasa como parámetro en una variable por referencia?
Hagamos ahora la funcion de MostrarReporte
Pregunta

¿Por que en este caso no pasamos como variable por referencia la lista de estudiantes?
static void MostrarReporte(List<Estudiante> estudiantes)
{
if (estudiantes.Count == 0)
{
Console.WriteLine("No hay estudiantes registrados");
return;
}
Console.WriteLine("\nReporte de Calificaciones");
Console.WriteLine("=========================");
// 10. ESTRUCTURAS DE CONTROL (foreach, if-else)
foreach (var estudiante in estudiantes)
{
double promedio = estudiante.Calificaciones.Average();
bool aprobado = promedio >= APROBADO;
Console.WriteLine($"\nEstudiante: {estudiante.Nombre}");
Console.WriteLine($"Promedio: {promedio:N2}");
Console.WriteLine($"Estado: {(aprobado ? "APROBADO" : "REPROBADO")}");
}
}
Nota:
Operador ternario (? :): Si respuesta es null, asigna "" (cadena vacía). Si respuesta no es null, deja el mismo valor de respuesta.
Finalmente, hacemos el llamado en el método Main
case 2:
MostrarReporte(estudiantes);
break;
-
Instala .NET SDK: Asegúrate de tener el .NET SDK instalado en tu sistema. Puedes descargarlo desde aquí.
-
Crea un nuevo proyecto de consola: Usa el comando dotnet new para crear un nuevo proyecto de consola. dotnet new console -o my-console-app cd my-console-app
-
Abre el proyecto en Visual Studio Code: code .
-
Escribe el código: El archivo Program.cs se crea automáticamente.