Plataforma de E-Learning
Parte de la sección Programación Orientada a Objetos del Journey de GO de Coddy. Lección 105 de 107.
Desafío
Fácil¡Construyamos una plataforma de aprendizaje electrónico que administre cursos y estudiantes, y realice un seguimiento del progreso de aprendizaje! Combinarás structs, interfaces, composición y polimorfismo para crear un sistema cohesivo donde los estudiantes puedan inscribirse en cursos y completar lecciones.
Organizarás tu código en cinco archivos:
lesson.go: Define un structLessonque represente unidades de aprendizaje individuales. Cada lección tiene unID, unTitley unaDuration(en minutos). Incluye un constructorNewLessonque devuelva un puntero a un Lesson.course.go: Crea un structCourseque contenga unID, unTitle, unInstructory un slice de punteros*Lesson. Incluye un constructorNewCoursey un métodoAddLesson. Implementa también un métodoTotalDuration() intque devuelva la suma de las duraciones de todas las lecciones del curso.student.go: Define un structStudentcon los camposID,NameyEmail. Incluye un constructorNewStudent.enrollment.go: Aquí ocurre la magia del seguimiento del progreso. Crea un structEnrollmentque vincule a un estudiante con un curso y registre qué lecciones ha completado. Debe tener:- Un puntero a
Student - Un puntero a
Course - Un mapa
CompletedLessons(del ID de la lección a un booleano)
Define una interfaz
Progressablecon un métodoProgress() float64que devuelva un porcentaje (de 0.0 a 100.0).Implementa estos métodos en Enrollment:
NewEnrollment(student *Student, course *Course) *Enrollment: constructor que inicializa un mapa vacío de lecciones completadasCompleteLesson(lessonID string) string: marca una lección como completada. Devuelvelesson not foundsi la lección no existe en el curso,already completedsi ya se completó, ocompletedsi tiene éxitoProgress() float64: devuelve el porcentaje de lecciones completadas (completadas/total * 100), o 0.0 si el curso no tiene lecciones
- Un puntero a
main.go: Construye tu plataforma y procesa las operaciones de inscripción.Lee el ID, el título y el instructor de un curso. Después, lee el número de lecciones y el ID, el título y la duración de cada lección. Lee el ID, el nombre y el correo electrónico de un estudiante. Crea una inscripción que vincule al estudiante con el curso.
Después, lee el número de operaciones. Cada operación es
complete [lessonID]oprogress. Para las operaciones de completar, imprime el mensaje del resultado. Para las operaciones de progreso, imprime el progreso con un decimal, seguido de un signo de porcentaje.
Se proporcionarán las siguientes entradas:
- ID, título e instructor del curso (3 líneas)
- Número de lecciones y, después, el ID, el título y la duración de cada lección (3 líneas cada una)
- ID, nombre y correo electrónico del estudiante (3 líneas)
- Número de operaciones y, después, cada operación (1 línea cada una)
Por ejemplo, dada la siguiente entrada:
C001
Go Fundamentals
Jane Smith
3
L001
Variables
30
L002
Functions
45
L003
Structs
60
S001
Alice
alice@learn.com
5
progress
complete L001
progress
complete L001
complete L002Tu salida debería ser:
0.0%
completed
33.3%
already completed
completedY dada la siguiente entrada:
C100
Python Basics
Bob Teacher
2
L100
Intro
20
L101
Loops
40
S100
Charlie
charlie@edu.com
4
complete L999
complete L100
complete L101
progressTu salida debería ser:
lesson not found
completed
completed
100.0%Observa cómo el struct Enrollment utiliza la composición para vincular estudiantes y cursos, mientras que la interfaz Progressable permite que cualquier tipo informe su estado de finalización. Este diseño facilita la ampliación. ¡Podrías añadir el seguimiento del progreso a lecciones individuales o a rutas de aprendizaje completas utilizando la misma interfaz!
Pruébalo tú mismo
package main
import (
"bufio"
"fmt"
"os"
"strconv"
"strings"
)
func main() {
scanner := bufio.NewScanner(os.Stdin)
// Función auxiliar para leer una línea
readLine := func() string {
scanner.Scan()
return strings.TrimSpace(scanner.Text())
}
// Leer información del curso
courseID := readLine()
courseTitle := readLine()
courseInstructor := readLine()
// TODO: Crear el curso usando NewCourse
_ = courseID
_ = courseTitle
_ = courseInstructor
// Leer el número de lecciones
numLessons, _ := strconv.Atoi(readLine())
// TODO: Leer cada lección y añadirla al curso
for i := 0; i < numLessons; i++ {
lessonID := readLine()
lessonTitle := readLine()
lessonDuration, _ := strconv.Atoi(readLine())
// TODO: Crear la lección y añadirla al curso
_ = lessonID
_ = lessonTitle
_ = lessonDuration
}
// Leer información del estudiante
studentID := readLine()
studentName := readLine()
studentEmail := readLine()
// TODO: Crear el estudiante usando NewStudent
_ = studentID
_ = studentName
_ = studentEmail
// TODO: Crear la inscripción vinculando el estudiante al curso
// Leer el número de operaciones
numOps, _ := strconv.Atoi(readLine())
// Procesar cada operación
for i := 0; i < numOps; i++ {
operation := readLine()
if operation == "progress" {
// TODO: Llamar a Progress() e imprimir con el formato "%.1f%%"
fmt.Println("0.0%") // Reemplazar con el progreso real
} else if strings.HasPrefix(operation, "complete ") {
lessonID := strings.TrimPrefix(operation, "complete ")
// TODO: Llama a CompleteLesson e imprime el resultado
_ = lessonID
fmt.Println("") // Reemplazar con el resultado real
}
}
}
Todas las lecciones de Programación Orientada a Objetos
1Fundamentos de POO en Go
Archivos externosEspacio de trabajo y módulos de GoPaquetes e importacionesNombres exportados vs. no exportadosIntroducción a la POO en GoStructs como clasesDefinición de métodos en structsReceptores de puntero vs. de valorInicialización de structsFunciones constructorasResumen - Calculadora simple4Interfaces
Introducción a las interfacesImplementación implícitaLa interfaz como contratoInterfaz vacía (any)Type AssertionType SwitchComposición de interfacesInterfaces Stringer y ErrorResumen: Calculadora de figuras7Encapsulamiento
Campos exportados vs. no exportadosEncapsulamiento a nivel de paqueteMétodos Getter y SetterOcultamiento de información en GoResumen - Registros de estudiantes10Genéricos (Go 1.18+)
Introducción a los GenéricosParámetros de tipoRestricciones de tipoStructs genéricosSolución alternativa para métodos genéricosResumen - Colección genérica13Patrones de diseño - Parte 1
Introducción a los patrones de diseñoPatrón SingletonPatrón FactoryPatrón Abstract FactoryPatrón ObserverPatrón Strategy2Inmersión profunda en Tipos y Structs
Tipos básicos y compuestosDefiniciones de tipos personalizadosEtiquetas de StructsStructs anónimosStructs anidadosValores cero y por defectoRepaso - Libreta de contactos5Composición sobre herencia
Por qué Go no tiene herenciaConceptos básicos de incrustación de structsPromoción de métodosIncrustación de múltiples structsIncrustación vs AgregaciónShadowing de métodos incrustadosResumen - Jerarquía de empleados8Manejo de Errores y OOP
La interfaz errorTipos de errores personalizadosEnvoltura de errores (fmt.Errorf)Errores centinelaerrors.Is() y errors.As()Panic, Defer y RecoverResumen - Analizador de archivos3Punteros y Memoria
Fundamentos de punteros en GoPunteros a StructsPaso por valor vs referenciaLa función new()Garbage Collection en GoResumen - Constructor de Linked List6Polimorfismo en Go
Polimorfismo mediante interfacesDuck Typing en GoReglas de satisfacción de interfacesColecciones polimórficasInyección de dependenciasResumen - Procesador de pagos9Concurrencia y POO
Fundamentos de GoroutinesChannels y comunicaciónChannels con buffer vs. sin bufferSentencia Selectsync.Mutex y sync.RWMutexsync.WaitGroupDiseño de estructuras Thread-SafeResumen - Worker PoolPractica por tu cuenta: Compilador de Go online