Bucles anidados para crear evaluaciones masivas en C#

Clase 31 de 32Fundamentos de C# con NET Core 2.1

Resumen

Crear evaluaciones automáticas por curso, asignatura y alumno es más simple de lo que parece si dominas bucles anidados, nombres únicos y números aleatorios. Aquí verás cómo generar cinco evaluaciones por alumno, nombrarlas de forma clara y calcular notas decimales entre 0 y 5 con Random, paso a paso y sin complicaciones.

¿Cómo recorrer cursos, asignaturas y alumnos para crear evaluaciones?

Para cumplir el objetivo, se recorre la estructura académica con bucles anidados y se generan cinco evaluaciones por alumno en cada asignatura. La clave es pensar primero en el conjunto completo de objetos que se deben crear y luego iterar siguiendo ese orden lógico.

  • Por cada curso en la escuela.
  • Por cada asignatura del curso.
  • Por cada alumno del curso.
  • Crear cinco evaluaciones por alumno.

Ejemplo en C# usando foreach y for:

foreach (var curso in escuela.Cursos) { foreach (var asignatura in curso.Asignaturas) { foreach (var alumno in curso.Alumnos) { // Semilla por alumno para el generador aleatorio var rnd = new Random(System.Environment.TickCount); for (int i = 0; i < 5; i++) { // Se completará con nombre y nota más abajo } } } }

Puntos clave:

  • Cinco evaluaciones por alumno. Requisito explícito del reto.
  • Orden de iteración: curso → asignatura → alumno → cinco evaluaciones.
  • Inicializar Random por alumno. Controla la semilla y facilita la variación de notas.

¿Cómo asignar nombres únicos y legibles a las evaluaciones?

El nombre debe ser único y comprensible. En lugar de iniciar desde 0, se usa un índice humano-amigable desde 1. Se concatena el nombre de la asignatura con un postfijo "Ev" y el consecutivo.

  • Evita repeticiones de nombre.
  • Mejora la legibilidad para usuarios no programadores.
  • Mantiene un patrón consistente.

Ejemplo:

var nombreEv = $"{asignatura.Nombre} Ev{(i + 1)}"; // p.ej., "Matemáticas Ev1"

Buenas prácticas:

  • Coherencia de formato. Siempre "Asignatura EvN".
  • Sin ceros iniciales. Empieza en 1 para el usuario final.

¿Cómo generar notas decimales de 0 a 5 con Random?

Usar rnd.Next(0, 5) sería un error: genera enteros, no decimales. La solución es rnd.NextDouble(), que produce un decimal en [0, 1). Luego se escala y se hace casting al tipo requerido.

  • *Next* devuelve enteros en un rango. No sirve para decimales.
  • *NextDouble* devuelve decimales entre 0 y 1.
  • Multiplicar por 5 ajusta el rango a [0, 5].
  • Casting a float si la nota es flotante en el modelo.

Código recomendado:

// Genera una nota decimal entre 0 y 5 double nota0a5 = rnd.NextDouble() * 5; // double por precisión float nota = (float)nota0a5; // casting a float si la propiedad es flotante

¿Cómo inicializar la semilla por alumno con System.Environment.TickCount?

Para mostrar control sobre la aleatoriedad, se puede variar la semilla por alumno con System.Environment.TickCount. Así se crea una nueva instancia de Random por alumno, asignatura y curso.

var rnd = new Random(System.Environment.TickCount);

Ventajas:

  • Semilla controlada. Permite reproducibilidad si se necesita.
  • Variación suficiente. Cambia entre alumnos y recorridos.

¿Cómo validar con el depurador y foreach en Visual Studio?

El flujo se verifica con un punto de interrupción en el foreach y revisando el objeto de evaluación en el inspector de variables.

  • Colocar el breakpoint en el bucle que crea las evaluaciones.
  • Inspeccionar nombreEv y nota en cada iteración.
  • Verificar secuencia: Ev1, Ev2, Ev3, Ev4, Ev5.
  • Confirmar rangos: notas entre 0 y 5 con decimales.

Ejemplo de creación integrada:

for (int i = 0; i < 5; i++) { var nombreEv = $"{asignatura.Nombre} Ev{(i + 1)}"; float nota = (float)(rnd.NextDouble() * 5); var ev = new Evaluacion { Asignatura = asignatura, Alumno = alumno, Nombre = nombreEv, Nota = nota }; // Agregar a la colección correspondiente (p. ej., alumno.Evaluaciones.Add(ev)); }

Comparte tus aproximaciones, incluso si son distintas o menos eficientes. Lo valioso es que todos aprendamos juntos. ¿Qué parte te resultó más desafiante y cómo la resolviste?