No tienes acceso a esta clase

¡Continúa aprendiendo! Únete y comienza a potenciar tu carrera

Reto final

34/35
Recursos

El último reto del curso colocará a prueba todos los conocimientos que has aprendido a lo largo del curso y te permitirá afianzar todos los conocimientos.

Debes crear distintos métodos para mostrar por consola cada uno de los reportes, debe mantener una vista agradable y es más importante una buena experiencia del usuario al leer la información que la cantidad mostrada.

Aportes 18

Preguntas 1

Ordenar por:

¿Quieres ver más aportes, preguntas y respuestas de la comunidad?

Esta podría ser una idea del menu:

i	nt opcion;
                Console.WriteLine("1-Listar alumnos");
                Console.WriteLine("2-Listar asignaturas");
                Console.WriteLine("3-Listar notas");
                Console.WriteLine("4-Listar promedio");
                Console.WriteLine("Ingrese una opción");
                
                 opcion = Convert.ToInt32(Console.ReadLine());
                switch(opcion){
                    case 1:
                    Console.WriteLine("Lista de alumnos");
                    //LLamar metodo 
                    break;
                    case 2:
                    Console.WriteLine("Lista de asignaturas");
                    //LLamar metodo 
                    break;
                    case 3:
                    Console.WriteLine("Lista de notas");
                    //LLamar metodo 
                    break;
                    case 4:
                    Console.WriteLine("Lista de promedios");
                    //LLamar metodo 
                    break;
                    default:
                    Console.WriteLine("Ingrese una opción correcta");
                    break;
                }

Un adelanto de la solución del Reto:

un método para crear el menú:

/// <summary>
/// Console Application menu.
/// </summary>
private static void CrearMenu()
{
    Clear();
    WriteLine("=====================================================================");
    WriteLine($"Hola {userRunningApplication}, ¿Que reporte deseas visualizar?");
    WriteLine();
    WriteLine("=====================================================================");
    WriteLine("1. Lista de Evaluaciones");
    WriteLine("2. Lista de Asignaturas.");
    WriteLine("3. Lista de Evaluaciones por Asignatura.");
    WriteLine("4. Lista de nota promedio por Asignatura.");
    WriteLine("5. Lista top promedio por Asignatura por Materia.");
    WriteLine("6. Lista top promedio por todas las Asignaturas.");
    WriteLine("=====================================================================");
    WriteLine();
    Write("====> Ingrese el número de la opción aquí => ");
}        	

Un método para Ejecutar los métodos que imprimen los Reportes:

/// <summary>
/// Ejecutar Tarea (opción) del menú.
/// </summary>
/// <param name="parameters"></param>
/// <param name="diccionarioEscuela"></param>
/// <returns></returns>
private static bool EjecucionTarea(string[] parameters, Dictionary<LlaveDiccionario, IEnumerable<ObjetoEscuelaBase>> diccionarioEscuela)
{
    Menu opcion = (Menu)int.Parse(parameters[0]);
    bool response = false;

    Reporteador reporteador = new Reporteador(diccionarioEscuela);

    switch (opcion)
    {
        case Menu.ListaEvaluaciones:
            Printer.WritTitle("Lista de Evaluaciones");

            var listaEvaluaciones = reporteador.GetListaEvaluaciones();

            ImprimirObjetoEscuelaBase(listaEvaluaciones);

            break;

        case Menu.ListaAsignaturas:
            Printer.WritTitle("Lista de Asignaturas");

            var listaAsignaturas = reporteador.GetListaAsignaturas();

            foreach (string item in listaAsignaturas)
            {
                WriteLine($"Nombre Asignatura: {item}");
            }

            break;

        case Menu.ListaEvaluacionesPorAsignatura:
            Printer.WritTitle("Lista de Evaluaciones por Asignatura");

            var listaEvaluacionesPorAsignatura = reporteador.GetEvaluacionesPorAsignatura();

            //TODO: Imprimir diccionario listaEvaluacionesPorAsignatura

            break;

        case Menu.ListaPromedioPorAsignatura:
            Printer.WritTitle("Lista de nota promedio por Asignatura");

            var listaPromedioPorAsignatura = reporteador.GetPromedioAlumnoPorAsignatura();

            //TODO: Imprimir diccionario listaPromedioPorAsignatura

            break;

        case Menu.ListaTopPromedioPorAsignaturaPorMateria:
            Printer.WritTitle("Lista top promedio por Asignatura por Materia");

            var listaTopPromedioPorAsignatura = reporteador.GetTopPromedioAlumnoPorAsignatura(5, "Castellano");

            //TODO: Imprimir diccionario listaTopPromedioPorAsignatura

            break;

        case Menu.ListaTopPromedioPorAsignaturas:
            Printer.WritTitle("Lista top promedio por todas las Asignaturas");

            var listaTopPromedioPorAsignaturas = reporteador.GetTopPromedioAlumnoPorAsignatura(5);

            //TODO: Imprimir diccionario listaTopPromedioPorAsignaturas

            break;

        default:
            Printer.WritTitle("Opción no válida");
            break;
    }

    return response;
}

Y se invocan en el método Main de la clase Program:

...
CrearMenu();

string[] parametros = ReadLine().Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
bool resultadoEjecucionTarea = false;

if (int.TryParse(parametros[0], out int option))
{
    resultadoEjecucionTarea = EjecucionTarea(parametros, diccionarioEscuela);
}
...

Cachen mis hermanos, cualquier cosa que arreglar diganme.
Sino segui bien el reto diganmelo por mas que pasen años voy tratar de responder

Todo esto dentro de mi static void main.


            Reporter reporter = new Reporter(engine.GetObjectDictionary());

            var evalList = reporter.GetEvaluationList();
            var ctList = reporter.GetCourseTopicList();
            var averageGrade = reporter.GetAverageGrade();
            var topStudents = reporter.GetTopStudents(10);
            

		ReportGenerator(engine);


      


//Genera la estructura basica del reporte, con una interfaz de consola, y con un manejador de errores.
            void ReportGenerator(SchoolEngine engine)
            {

                Printer.DrawTitle("Reports");
                Console.WriteLine("Please, enter the number of option you want to see\n1 - Evaluations\n2 - Courses Topics\n3 - Average grades by course topic\n4 - Top 10 students by course topic");
                string input = Console.ReadLine();
                int optionSelected;
                try
                {

                    if (String.IsNullOrEmpty(input))
                    {
                        throw new ArgumentException("The option value cannot be empty");
                    }
                    else if (String.IsNullOrWhiteSpace(input))
                    {
                        throw new ArgumentException("The option value cannot be a whitespace");
                    }






                }
                catch (Exception)
                {

                    throw new Exception("The option entered must be a number ");
                }
                optionSelected = Convert.ToInt32(input);
                ViewReport(optionSelected);

            }

//ViewReport toma el int que habia guardado y lo pasa por el switch que mostrara el reporte
            void ViewReport(int optionSelected)
            {
                switch (optionSelected)
                {
                    case 1:
                        Printer.DrawLine();
                        foreach (var ev in evalList)
                        {
                            Console.WriteLine(ev.ToString());
                        }
                        break;

                    case 2:
                        Printer.DrawLine();
                        foreach (var ct in ctList)
                        {
                            Console.WriteLine(ct.ToString());
                        }
                        break;

                    case 3:
                        Printer.DrawLine();
                        foreach (var keyValuePair in averageGrade)
                        {

                            foreach (var ev in keyValuePair.Value)
                            {
                                Console.WriteLine($"Topic: {keyValuePair.Key} | Student: {ev.studentName} | Average grade: {ev.average}");
                            }

                        }
                        break;

                    case 4:
                        Printer.DrawLine();
                        foreach (var keyValuePair in topStudents)
                        {
                            foreach (var ts in keyValuePair.Value)
                            {
                                Console.WriteLine($"Topic: {keyValuePair.Key} | Student: {ts.studentName} | Grade: {ts.average}");
                            }
                        }

                        break;

                    default:
                        Printer.DrawLine();
                        Console.WriteLine("Out of range");
                        throw new ArgumentOutOfRangeException();


                }
            }

        }

Reporteador.cs

using System.Data;
using System;
using System.Linq;
using System.Collections.Generic;
using CoreEscuela.Entidades;
using CoreEscuela.Util;
using static System.Console;

namespace CoreEscuela.App
{
    public class Reporteador
    {
        Dictionary<LlaveDiccionario, IEnumerable<ObjetoEscuelaBase>> _diccionario;
        public Reporteador(Dictionary<LlaveDiccionario, IEnumerable<ObjetoEscuelaBase>> dicObjEsc)
        {
            if (dicObjEsc == null)
            {
                throw new ArgumentNullException(nameof(dicObjEsc));
            }
            _diccionario = dicObjEsc;
        }

        public IEnumerable<Evaluación> GetListaEvaluaciones()
        {
            // var lista = _diccionario.GetValueOrDefault(LlaveDiccionario.Escuela);
            // IEnumerable<Escuela> rta;
            if (_diccionario.TryGetValue(
                LlaveDiccionario.Evaluación,
                out IEnumerable<ObjetoEscuelaBase> lista
            ))
            {
                return lista.Cast<Evaluación>();
            }
            {
                return new List<Evaluación>();
            }
        }

        public IEnumerable<string> GetListaAsignaturas()
        {
            return GetListaAsignaturas(out var dumy);
        }
        public IEnumerable<string> GetListaAsignaturas(out IEnumerable<Evaluación> listaEvaluaciones)
        {
            listaEvaluaciones = GetListaEvaluaciones();

            return (from Evaluación ev in listaEvaluaciones
                    select ev.Asignatura.Nombre).Distinct();
        }

        public Dictionary<string, IEnumerable<Evaluación>> GetDiccionarioEvaluacionesPorAsignatura()
        {
            var diccionarioRta = new Dictionary<string, IEnumerable<Evaluación>>();

            var listaAsignaturas = GetListaAsignaturas(out var listaEvaluaciones);

            foreach (var asig in listaAsignaturas)
            {
                var evalAsig = from eval in listaEvaluaciones
                               where eval.Asignatura.Nombre == asig
                               select eval;
                diccionarioRta.Add(asig, evalAsig);
            }
            return diccionarioRta;
        }

        public Dictionary<string, IEnumerable<AlumnoPromedio>> GetPromedioAlumnosXAsignatura()
        {
            var rta = new Dictionary<string, IEnumerable<AlumnoPromedio>>();
            var diccionarioEvXAsig = GetDiccionarioEvaluacionesPorAsignatura();
            foreach (var asigConEval in diccionarioEvXAsig)
            {
                var promsAlumnos = from eval in asigConEval.Value
                           group eval by new{
                               eval.Alumno.UniqueId,
                               eval.Alumno.Nombre
                           }
                           into grupoEvalAlumno
                           select new AlumnoPromedio
                           {
                               alumnoId = grupoEvalAlumno.Key.UniqueId,
                               alumnoNombre = grupoEvalAlumno.Key.Nombre,
                               promedio = grupoEvalAlumno.Average(evaluacion => evaluacion.Nota)
                           };                
                rta.Add(asigConEval.Key, promsAlumnos);
            }

            return rta;
        }

        /* Reto 2.
        Realizar un reporteador que tome el top 5, top 10 o top X de los mejores estudiantes por asignatura. */

        public Dictionary<string, IEnumerable<AlumnoPromedio>> GetTopEstudiantesXAsignatura (int cantidad)
        {
            var rta = new Dictionary<string, IEnumerable<AlumnoPromedio>>();
            var listaPromedioXAsignatura = GetPromedioAlumnosXAsignatura();
            foreach (var listaPromedio in listaPromedioXAsignatura)
            {
                var lista = listaPromedio.Value.OrderByDescending(eva => eva.promedio).Take(cantidad);
                rta.Add(listaPromedio.Key, lista);
            }

            return rta;
        }
        public void ImprimirEvaluaciones()
        {
            var eval = GetListaEvaluaciones();
            Printer.WriteTitle("Lista de Evaluaciones por alumno.");
            foreach (var lista in eval)
            {
                WriteLine($"Nombre de la evaluación: {lista.Nombre}{System.Environment.NewLine}Asignatura: {lista.Asignatura.Nombre} {System.Environment.NewLine}Nombre del estudiante: {lista.Alumno.Nombre} Nota: {lista.Nota}{System.Environment.NewLine}=====");
            }
        }
        public void ImprimirAsignaturas()
        {
            var asig = GetListaAsignaturas();
            Printer.WriteTitle("Lista de Asignaturas.");
            foreach (var lista in asig)
            {
                WriteLine($"Nombre de la asignatura: {lista}");
            }
        }

        public void ImprimirEvaluacionesXAsignatura()
        {
            var evXAsig = GetDiccionarioEvaluacionesPorAsignatura();
            Printer.WriteTitle("Lista de Evaluaciones por Asignatura.");
            foreach (var lista in evXAsig)
            {
                Printer.WriteTitle($"Asignatura: {lista.Key}");
                foreach (var eval in lista.Value)
                {
                    WriteLine($"Nombre de la evaluación: {eval.Nombre}{System.Environment.NewLine}Nombre del estudiante: {eval.Alumno.Nombre}{System.Environment.NewLine}Nota: {eval.Nota}");
                }
            }
        }
        public void ImprimirPromedioAlumnosXAsignatura()
        {
            var proms = GetPromedioAlumnosXAsignatura();
            Printer.WriteTitle("Promedio de Alumnos por Asignatura");
            foreach (var lista in proms)
            {
                Printer.WriteTitle($"Asignatura: {lista.Key}");
                foreach (var prom in lista.Value)
                {
                    WriteLine($"Nombre del estudiante: {prom.alumnoNombre} Promedio: {prom.promedio}");
                }
            }
        }
        public void ImprimirTopPromediosXAsignatura(int cantidad)
        {
            var top = GetTopEstudiantesXAsignatura(cantidad);
            Printer.WriteTitle($"Top {cantidad} estudiantes por asignatura.");
            foreach (var lista in top)
            {
                Printer.WriteTitle($"Asignatura: {lista.Key}");
                foreach (var est in lista.Value)
                {
                    WriteLine($"Nombre del estudiante: {est.alumnoNombre} - Promedio {est.promedio}");
                }
            }
        }
    }
}

Program.cs

using System;
using System.Collections.Generic;
using CoreEscuela.Entidades;
using CoreEscuela.Util;
using CoreEscuela.App;
using static System.Console;
using System.Linq;

namespace CoreEscuela
{
    class Program
    {
        static void Main(string[] args)
        {
            var engine = new EscuelaEngine();
            engine.Inicializar();
            Printer.WriteTitle("BIENVENIDOS A LA ESCUELA");
            
            var reporteador = new Reporteador(engine.GetDiccionarioObjetos());
            var evList = reporteador.GetListaEvaluaciones();
            var listaAsig = reporteador.GetListaAsignaturas();
            var listaEvalXAsig = reporteador.GetDiccionarioEvaluacionesPorAsignatura();
            var listaPromXAsig = reporteador.GetPromedioAlumnosXAsignatura();
            var topEstudiantes = reporteador.GetTopEstudiantesXAsignatura(5);
            
            
            /* Reto final.
            El último reto del curso colocará a prueba todos los conocimientos que has aprendido a lo largo del curso y te permitirá afianzar todos los conocimientos.
            Debes crear distintos métodos para mostrar por consola cada uno de los reportes, debe mantener una vista agradable y es más importante una buena experiencia del usuario al leer la información que la cantidad mostrada. */
            
            int selección = 1;
            string _selección;
            string _selector;
            int selector = 0;
            while (selección == 1)
            {
                Printer.WriteTitle("Seleccione el reporte a imprimir.");
                WriteLine("(1) Nombre de la escuela.");
                WriteLine("(2) Lista de cursos.");
                WriteLine("(3) Reporte de evaluaciones.");
                WriteLine("(4) Reporte de asignaturas.");
                WriteLine("(5) Reporte de evaluaciones por asignatura.");
                WriteLine("(6) Reporte del promedio de alumnos por asignatura.");
                WriteLine("(7) Reporte Top X de estudiantes por asignatura.");
                WriteLine("Presione 0 para salir.");
                Printer.PresioneENTER();
                _selector = ReadLine();
                selector = int.Parse(_selector);

                switch (selector)
                {
                    case 0:
                        WriteLine("Saliendo...");
                        selección = 0;
                        break;
                    case 1:
                        WriteLine(engine.Escuela);
                        break;
                    case 2:
                        ImpimirCursosEscuela(engine.Escuela);
                        break;
                    case 3:
                        reporteador.ImprimirEvaluaciones();
                        break;
                    case 4:
                        reporteador.ImprimirAsignaturas();
                        break;
                    case 5:
                        reporteador.ImprimirEvaluacionesXAsignatura();
                        break;
                    case 6:
                        reporteador.ImprimirPromedioAlumnosXAsignatura();
                        break;
                    case 7:
                        int cantidad;
                        string _cantidad;
                        WriteLine("Digite la cantidad Top de estudiantes.");
                        _cantidad = ReadLine();
                        cantidad = int.Parse(_cantidad);
                        reporteador.ImprimirTopPromediosXAsignatura(cantidad);
                        break;
                    default:
                        WriteLine("Selección errónea.");
                        WriteLine("Saliendo...");
                        break;
                }
                WriteLine("Presione 0 para salir, presione 1 para otro reporte.");
                _selección = ReadLine();
                selección = int.Parse(_selección);
            }
        }

 
        private static void ImpimirCursosEscuela(Escuela escuela)
        {

            Printer.WriteTitle("Cursos de la Escuela");


            if (escuela?.Cursos != null)
            {
                foreach (var curso in escuela.Cursos)
                {
                    WriteLine($"Nombre del curso: {curso.Nombre  }, Id:  {curso.UniqueId}");
                }
            }
        }
    }
}

Hola, les dejo algunas de las capturas de lo que hice para el reto.

Les dejo capturas y el repositorio en GitHub.

https://github.com/FernandoAjset/Control-Escuela

Program

        static void Main(string[] args)
        {
            AppDomain.CurrentDomain.ProcessExit += EventAction;
            AppDomain.CurrentDomain.ProcessExit += (o, s) => Printer.Beep(100, 1000, 1);
            AppDomain.CurrentDomain.ProcessExit -= EventAction;
            var engine = new EscuelaEngine();

            Printer.WriteTitle("BIENVENIDOS A LA ESCUELA");

            var reporteador = new Reporteador(engine.GetDictionaryObject());
            var evalList = reporteador.GetEvaluationList();
            var listaAsig = reporteador.GetAsignaturaList();
            var listaEvaluaciones = reporteador.GetDictionaryEvaluaXAsig();
            var listAverageByAsignature = reporteador.GetPromeStudentByAsignature();

            var listAverageTop = reporteador.GetAverageTopByMatter();
            string[] reporteMenu = engine.GetReportMenu();
            var keep = "Y";
            do
            {
                var menuOption = Printer.PrintMenu(reporteMenu, "Menú Core Escuela");
                keep = reporteador.PrintReport(menuOption);
                Console.Clear();
            }
            while (keep.ToUpper() == "Y");

        }

Reporteador.cs

 public string PrintReport(int reportedSelected)
        {
            Printer.DrawLine();
            switch (reportedSelected)
            {
                case 1:
                    foreach (var item in this.GetEvaluationList())
                    {
                        Console.WriteLine($"Alumno: {item.Alumno.Nombre} | {item.Nombre} Nota: {item.Nota}");
                    }

                    break;
                case 2:
                    foreach (var item in this.GetAsignaturaList())
                    {
                        Console.WriteLine($"Nombre: {item}");
                    }

                    break;
                case 3:
                    foreach (var asignatura in this.GetDictionaryEvaluaXAsig())
                    {
                        Printer.WriteTitle(asignatura.Key);
                        foreach (var evaluacion in asignatura.Value)
                        {
                            Console.WriteLine($"Alumno: {evaluacion.Alumno.Nombre} | {evaluacion.Nombre} Nota: {evaluacion.Nota}");
                        }
                        Printer.DrawLine();
                    }

                    break;
                case 4:
                    foreach (var asignatura in this.GetPromeStudentByAsignature())
                    {
                        Printer.WriteTitle($"Promedios {asignatura.Key}");
                        foreach (var average in asignatura.Value.Cast<AlumnoPromedio>())
                        {
                            Console.WriteLine($"Alumno: {average.AlumnoNombre} | Promedio: {average.Promedio}");
                        }
                    }

                    break;
                case 5:
                    Printer.WriteTitle("Top de mejores promedios");
                    Console.WriteLine("Por favor ingrese el maximo de mejores promedios que quieres que se liste");
                    var top = Console.ReadLine();
                    if (!string.IsNullOrEmpty(top))
                    {
                        var topList = this.GetAverageTopByMatter(int.Parse(top));
                        foreach (var matterAvg in topList)
                        {
                            Printer.WriteTitle($"Promedios {matterAvg.Key}");
                            foreach (var average in matterAvg.Value.Cast<AlumnoPromedio>())
                            {
                                Console.WriteLine($"Alumno: {average.AlumnoNombre} | Promedio: {average.Promedio}");
                            }
                        }
                    }
                    else
                    {
                        Console.WriteLine("Error Parametro top vacio, debe ser ingresado, pulse cualquier tecla para continuar");
                        Console.ReadKey();
                        Console.Clear();

                    }

                    break;
                case 6:
                    Environment.Exit(0);
                    break;
            }
            Printer.DrawLine(50);
            Console.WriteLine("¿Desea Continuar? Pulse [Y] si desea continuar o cualquier tecla si no lo desea. ");
            var response = Console.ReadLine();
            return response.ToString();
        }

EscuelaEngine.cs

        private void CargarMenuDeReportes()
        {
            ReportList = new string[]{
                "Lista de Evaluaciones",
                "Lista de Asignaturas",
                "Lista de Evaluaciones por Asignatura",
                "Lista de Promedios por Asignatura",
                "Top de Mejores promedio por Asignatura",
                "Salir"

            };
        }

        public string[] GetReportMenu(){
            return this.ReportList;
        }

Resultado ejemplo:

Posible manera de realizar tu menu, espero les agrade a mas de 1 😄.

class Program
{
static void Main(string[] args)
{
//AppDomain.CurrentDomain.ProcessExit += AccionDelEvento;
//AppDomain.CurrentDomain.ProcessExit += (o,s) => Printer.Beep(100,1000,1);

        var engine = new EscuelaEngine();
        engine.Inicializar();
        bool flag = true;
        string stringOpcion;
        int opcion = 0;

        do{
            Printer.WriteTitle("Bienvenido a " + engine.Escuela.Nombre);
            Printer.Menu();

            WriteLine("Ingrese una opcion >> ");
            stringOpcion = ReadLine();

            try{
                if (string.IsNullOrEmpty(stringOpcion) && int.TryParse(stringOpcion, out int dummy)){
                    opcion = 0;
                }else{
                    opcion = int.Parse(stringOpcion);
                }

            }catch (FormatException fe){
                Printer.WriteTitle(fe.Message);
                WriteLine(nameof(stringOpcion) + ", no se puede convertir a entero \n");
            }

            switch (opcion)
            {
                case 1:

                break;

                case 2:

                break;

                case 3:

                break;

                case 4:

                break;

                case 5:

                break;

                case 6:
                flag = false;
                break;
                
                default:
                    WriteLine("Por favor, ingrese una opcion valida \n\n");
                break;
            }
        }while(flag);

Genial, buen curso…



reto
ahi logre hacer con las logica que tenea jajaja ya que es mi primer lenguaje que ando prendiendo pero espero practicar mucho mas y tener otras formas entendibles

public void reportData()
    {
        Print.writeTitle("Capturaremos todos los reportes");
        WriteLine("1. Lista de evaluaciones \n");
        WriteLine("2. Lista de asignaturas \n");
        WriteLine("3. Lista de evaluaciones por cada aignatura \n");
        WriteLine("4. Lista de promedios de cada estudiante \n");
        WriteLine("5. Lista de los mejores estudiantes por cada asignatura \n");
        WriteLine("================================================================================\n");
        
        string stringNum;
        float num;
        Print.writeTitle("Selecciona cual quieres ver");
        Print.pressENTER();
        stringNum = ReadLine();
        num = float.Parse(stringNum);
        
        

        switch (num)
        {
            case 1:
              var listEva = GetListEvaluation();
              string StringCantEva;
              int cantEva;
              Print.writeTitle("Bienvenido a la lista de evaluaciones");
              WriteLine("Coloque con un numero entero de la cantidad de evaluaciones que quiere ver");
              Print.pressENTER();
              StringCantEva = ReadLine();
              cantEva = int.Parse(StringCantEva);

              for (int i = 1; i <= cantEva; i++)
              { 
                WriteLine($"Evaluacion #{i}"); 
              }
            break;

            case 2:
             Print.writeTitle("Bienvenido a la lista de asignaturas");
             var listaAsi = GetListSubject();
              foreach (var asi in listaAsi)
              {
                  WriteLine($"Asignatura de : {asi}");
              }
            break;

            case 3:
             Print.writeTitle("Bienvenido a la lista de Evaluaciones por Asignatura");
             var listaEvaXAsi = GetEvaXSubjects();
              foreach (var evaXAsi in listaEvaXAsi)
              {
                  WriteLine($"{evaXAsi.Key}: Evaluacion de {evaXAsi.Key}");
              }
            break;

            case 4:
             Print.writeTitle("Bienvenido a la lista de promedio de cada estudiante");
             var listaProm = GetPromeTheStudent();
              foreach (var listProm in listaProm)
              {
                  foreach (var data in listProm.Value)
                  {
                      WriteLine($"{data.studentName} tiene un promedio de |{data.promedio}|\n");
                  }
                
              }
            break;

            case 5:
            Print.writeTitle("Bienvenido a la lista de los mejores promedios por asignatura");
             var listaBetter = GetMejorTopNoteXAsig(5);
              foreach (var betterProm in listaBetter)
              {
                  foreach (var data in betterProm.Value)
                  {
                      WriteLine($"{betterProm.Key}: |{data.studentName}| tiene un promedio de |{data.promedio}|\n");
                  }
              }
              
            break;
            
            default:
              WriteLine("ERROR acabas de ingresar un dato invalido vuelva a intentar");
            break;
            
        }



Me estuve liando un buen rato porque yo lo he hecho pasando de parametros opcionales el reportador y la engine y rebuscando varias cosas opte por crear una clase estática con los fields

Opte por ella ya que sino tenia que estar pasando esos 2 objetos por todas las funciones ya que no deje nada en el main, y quedo perfecto.

Al final quedó un menu en donde el usiario puede elegir entre mostrar cosas de la escuela, registrarse, volver al menu anterior o al principal, cerrar el programa etc etc
![](

el menu sera con opciones numéricas pero tambien pueden ser cadenas.

try
{
    AppDomain.CurrentDomain.ProcessExit += AccionDelEvento;
    var engine = new EscuelaEngine();
    engine.Inicializar();
    var reportes = new Reporteador(engine.GetDiccionarioObjetos());
    Printer.WriteTitle("Reportes");
    WriteLine("1 => Imprimir Cursos");
    WriteLine("2 => Imprimir Alumnos");
    WriteLine("3 => Imprimir Asignaturas");
    WriteLine("4 => Imprimir Promedio Alumnos por Asignatura");
    WriteLine("5 => Imprimir Top Promedios por Asignatura");
    Printer.WriteTitle("Seleccione una opcion");
    string opcionString = ReadLine();
    if (int.TryParse(opcionString, out int opcion))
    {
        switch (opcion)
        {
            case 1:
                reportes.ImprimirCursos();
                break;
            case 2:
                reportes.ImprimirAlumnos();
                break;
            case 3:
                reportes.ImprimirAsignaturas();
                break;
            case 4:
                reportes.ImprimirPromedioAlumnoPorAsignaturas();
                break;
            case 5:
                Printer.WriteTitle("Ingrese la cantidad que desea obtener.");
                string cantidadString = ReadLine();
                if (int.TryParse(cantidadString, out int cantidad))
                {
                    reportes.ImprimirTopPromedioPorAsignaturas(cantidad);
                }else
                {
                    throw new FormatException("Ingrese una cantidad valida.");
                }
                break;
            default:
                throw new ArgumentOutOfRangeException(nameof(opcion), "El numero debe estar entre 1 y 6.");
        }
    }
    else
    {
        throw new FormatException("Ingrese una opcion valida.");
    }
}
catch (FormatException formatException)
{
    Printer.WriteTitle(formatException.Message);
}
catch (ArgumentOutOfRangeException argOutRange)
{
    Printer.WriteTitle(argOutRange.Message);
}
catch (Exception ex)
{
    Printer.WriteTitle(ex.Message);
}
finally
{
    Printer.WriteTitle("Finalmente.");
}
<using System;
using System.Collections.Generic;
using CoreEscuela.Entidades;
using CoreEscuela.Util;
using CoreEscuela.App;
using static System.Console;
using System.Linq;

namespace CoreEscuela
{
    class Program
    {
        static void Main(string[] args)
        {
            var engine = new EscuelaEngine();
            engine.Inicializar();
            Printer.WriteTitle("BIENVENIDOS A LA ESCUELA");
            
            var reporteador = new Reporteador(engine.GetDiccionarioObjetos());
            var evList = reporteador.GetListaEvaluaciones();
            var listaAsig = reporteador.GetListaAsignaturas();
            var listaEvalXAsig = reporteador.GetDiccionarioEvaluacionesPorAsignatura();
            var listaPromXAsig = reporteador.GetPromedioAlumnosXAsignatura();
            var topEstudiantes = reporteador.GetTopEstudiantesXAsignatura(5);
            
            
            /* Reto del menu. */
      
            ConsoleKeyInfo opcion;
          
            do
            {
                Console.Clear();
                Printer.WriteTitle("BIENVENIDO AL PROGRAMA ESCUELA");
                WriteLine(engine.Escuela);
                WriteLine("1 - Lista de cursos.");
                WriteLine("2 - Reporte de evaluaciones.");
                WriteLine("3 - Reporte de asignaturas.");
                WriteLine("4 - Reporte de evaluaciones por asignatura.");
                WriteLine("5 - Reporte del promedio de alumnos por asignatura.");
                WriteLine("6 - Reporte Top X de estudiantes por asignatura.");
                WriteLine("Presione ENTER o ESC para salir");
            
            
                opcion = Console.ReadKey();
                Console.Clear();                
                switch (opcion.Key)
                {
                    case ConsoleKey.D1:
                        ImpimirCursosEscuela(engine.Escuela);
                        presioneCualquierTecla();
                        break;
                    case ConsoleKey.D2:
                        reporteador.ImprimirEvaluaciones();
                        presioneCualquierTecla();
                        break;
                    case ConsoleKey.D3:
                        reporteador.ImprimirAsignaturas();
                        presioneCualquierTecla();
                        break;
                    case ConsoleKey.D4:
                        reporteador.ImprimirEvaluacionesPorAsignatura();
                        presioneCualquierTecla();
                        break;
                    case ConsoleKey.D5:
                        reporteador.ImprimirPromedioAlumnosPorAsignatura();
                        presioneCualquierTecla();
                        break;
                    case ConsoleKey.D6:
                        int top;
                        string cadenaTop;

                        Write("\nDigite la cantidad de estudiantes, luego ENTER: ");
                        cadenaTop = ReadLine();
                        top = int.Parse(cadenaTop);
                        reporteador.ImprimirTopPromediosPorAsignatura(top);
                        presioneCualquierTecla();
                        break;
                    default:
                        Console.Clear();
                        Printer.WriteTitle("Hasta la vista");
                        break;
                }                
            }while (opcion.Key != ConsoleKey.Escape && opcion.Key != ConsoleKey.Enter);
        }

        private static void presioneCualquierTecla()
        {
            System.Console.WriteLine("\n------ Presione cualquier tecla -------");
            System.Console.WriteLine("         para regresar al Menu");
            Console.ReadKey();
        }

        private static void ImpimirCursosEscuela(Escuela escuela)
        {

            Printer.WriteTitle("Cursos de la Escuela");


            if (escuela?.Cursos != null)
            {
                foreach (var curso in escuela.Cursos)
                {
                    WriteLine($"Nombre {curso.Nombre  }, Id  {curso.UniqueId}");
                }
            }
        }
    }
}>

Este es el proyecto que desarrolle y espero pueda ayudarles en algo.
Proyecto

Es mi gitHub para que puedan clonar el proyecto.

https://github.com/ajullier/ESCUELA_PLATZI

Dejo el link de mi proyecto con el reto final.
Eliminé el uso de los diccionarios. No lo vi tan necesario. Realicé reportes con filtros por curso indicando el ID o número por combo.
Seguro se puede mejorar bastante del lado de la experiencia del usuario y claridad de código. Pero hubiera sido interminable.