Plateforme d’apprentissage en ligne
Fait partie de la section Programmation Orientée Objet du Journey GO de Coddy. Leçon 105 sur 107.
Défi
FacileConstruisons une plateforme d’apprentissage en ligne qui gère les cours et les étudiants, et qui suit la progression de l’apprentissage ! Tu combineras les structs, les interfaces, la composition et le polymorphisme pour créer un système cohérent dans lequel les étudiants peuvent s’inscrire à des cours et terminer des leçons.
Tu organiseras ton code sur cinq fichiers :
lesson.go: définis une structLessonreprésentant des unités d’apprentissage individuelles. Chaque leçon possède unID, unTitleet uneDuration(en minutes). Inclus un constructeurNewLessonqui renvoie un pointeur vers une Lesson.course.go: crée une structCoursequi contient unID, unTitle, unInstructoret une slice de pointeurs*Lesson. Inclus un constructeurNewCourseet une méthodeAddLesson. Implémente également une méthodeTotalDuration() intqui renvoie la somme des durées de toutes les leçons du cours.student.go: définis une structStudentavec les champsID,NameetEmail. Inclus un constructeurNewStudent.enrollment.go: c’est ici que la magie du suivi de la progression opère. Crée une structEnrollmentqui relie un étudiant à un cours et suit les leçons qu’il a terminées. Elle doit contenir :- Un pointeur vers le
Student - Un pointeur vers le
Course - Une map
CompletedLessons(ID de leçon vers booléen)
Définis une interface
Progressableavec une méthodeProgress() float64qui renvoie un pourcentage (de 0.0 à 100.0).Implémente ces méthodes sur Enrollment :
NewEnrollment(student *Student, course *Course) *Enrollment: constructeur qui initialise une map vide des leçons terminéesCompleteLesson(lessonID string) string: marque une leçon comme terminée. Renvoielesson not foundsi la leçon n’existe pas dans le cours,already completedsi elle est déjà terminée, oucompleteden cas de succèsProgress() float64: renvoie le pourcentage de leçons terminées (terminées/total * 100), ou 0.0 si le cours ne contient aucune leçon
- Un pointeur vers le
main.go: construis ta plateforme et traite les opérations d’inscription.Lis l’ID, le titre et l’instructeur d’un cours. Lis ensuite le nombre de leçons, puis l’ID, le titre et la durée de chaque leçon. Lis l’ID, le nom et l’adresse e-mail d’un étudiant. Crée une inscription reliant l’étudiant au cours.
Lis ensuite le nombre d’opérations. Chaque opération est soit
complete [lessonID], soitprogress. Pour les opérations de complétion, affiche le message de résultat. Pour les opérations de progression, affiche la progression formatée avec une décimale, suivie d’un signe de pourcentage.
Les entrées suivantes seront fournies :
- ID du cours, titre, instructeur (3 lignes)
- Nombre de leçons, puis l’ID, le titre et la durée de chaque leçon (3 lignes chacune)
- ID de l’étudiant, nom, adresse e-mail (3 lignes)
- Nombre d’opérations, puis chaque opération (1 ligne chacune)
Par exemple, étant donné :
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 L002Ta sortie doit être :
0.0%
completed
33.3%
already completed
completedEt étant donné :
C100
Python Basics
Bob Teacher
2
L100
Intro
20
L101
Loops
40
S100
Charlie
charlie@edu.com
4
complete L999
complete L100
complete L101
progressTa sortie doit être :
lesson not found
completed
completed
100.0%Remarque comment la struct Enrollment utilise la composition pour relier les étudiants et les cours, tandis que l’interface Progressable permet à n’importe quel type de signaler son état d’avancement. Cette conception est facile à étendre. Tu pourrais ajouter le suivi de la progression à des leçons individuelles ou à des parcours d’apprentissage entiers en utilisant la même interface !
Essayez vous-même
package main
import (
"bufio"
"fmt"
"os"
"strconv"
"strings"
)
func main() {
scanner := bufio.NewScanner(os.Stdin)
// Fonction auxiliaire pour lire une ligne
readLine := func() string {
scanner.Scan()
return strings.TrimSpace(scanner.Text())
}
// Lire les informations du cours
courseID := readLine()
courseTitle := readLine()
courseInstructor := readLine()
// TODO: Créer le cours en utilisant NewCourse
_ = courseID
_ = courseTitle
_ = courseInstructor
// Lire le nombre de leçons
numLessons, _ := strconv.Atoi(readLine())
// TODO: Lire chaque leçon et l'ajouter au cours
for i := 0; i < numLessons; i++ {
lessonID := readLine()
lessonTitle := readLine()
lessonDuration, _ := strconv.Atoi(readLine())
// TODO: Créer la leçon et l'ajouter au cours
_ = lessonID
_ = lessonTitle
_ = lessonDuration
}
// Lire les informations de l'étudiant
studentID := readLine()
studentName := readLine()
studentEmail := readLine()
// TODO: Créer l'étudiant en utilisant NewStudent
_ = studentID
_ = studentName
_ = studentEmail
// TODO: Créer l'inscription liant l'étudiant au cours
// Lire le nombre d'opérations
numOps, _ := strconv.Atoi(readLine())
// Traiter chaque opération
for i := 0; i < numOps; i++ {
operation := readLine()
if operation == "progress" {
// TODO: Appeler Progress() et afficher avec le format "%.1f%%"
fmt.Println("0.0%") // Remplacer par la progression réelle
} else if strings.HasPrefix(operation, "complete ") {
lessonID := strings.TrimPrefix(operation, "complete ")
// TODO: Appeler CompleteLesson et afficher le résultat
_ = lessonID
fmt.Println("") // Remplacer par le résultat réel
}
}
}
Toutes les leçons de Programmation Orientée Objet
1Fondamentaux de la POO en Go
Fichiers externesEspace de travail et modules GoPackages et importsNoms exportés et non exportésIntroduction à la POO en GoStructs comme classesDéfinir des méthodes sur des structsRécepteurs pointeurs ou par valeurInitialisation des structsFonctions constructeursRécapitulatif - Calculatrice simple4Interfaces
Introduction aux interfacesImplémentation impliciteL’interface comme contratInterface vide (any)Assertion de typeCommutation de typeComposition d’interfacesInterfaces Stringer et ErrorRécapitulatif - Calculateur de formes7Encapsulation
Champs exportés vs non exportésEncapsulation au niveau du packageMéthodes Getter et SetterDissimulation de l’information en GoRécapitulatif – Fiches d’étudiants10Génériques (Go 1.18+)
Introduction aux génériquesParamètres de typeContraintes de typeStructures génériquesSolution de contournement pour les méthodes génériquesRécapitulatif - Collection générique2Plongée approfondie dans les types et les structs
Types de base et compositesDéfinitions de types personnalisésTags de structStructs anonymesStructs imbriquésValeurs zéro et valeurs par défautRécapitulatif - Carnet de contacts5La composition plutôt que l’héritage
Pourquoi Go n’a pas d’héritageBases de l’inclusion de structsPromotion des méthodesInclure plusieurs structsInclusion ou agrégationMasquage des méthodes inclusesRécapitulatif : hiérarchie des employés8Gestion des erreurs et POO
L’interface errorTypes d’erreurs personnalisésEnrobage des erreurs (fmt.Errorf)Erreurs sentinelleserrors.Is() et errors.As()Panic, Defer et RecoverRécapitulatif - Analyseur de fichiers11Bibliothèque standard et POO
io.Reader et io.Writersort.InterfaceInterface fmt.Stringerencoding/json avec des structsInterface http.HandlerRécapitulatif - Modèles d’API REST14Modèles de conception – Partie 2
Modèle CommandeModèle AdaptateurModèle DécorateurModèle Méthode modèleModèle ÉtatModèle CompositeMiddleware comme décorateur3Pointeurs et mémoire
Notions de base des pointeurs en GoPointeurs vers des structuresPassage par valeur ou par référenceLa fonction new()Garbage collection en GoRécapitulatif - Constructeur de listes chaînées6Polymorphisme en Go
Polymorphisme via les interfacesDuck typing en GoRègles de satisfaction des interfacesCollections polymorphesInjection de dépendancesRécapitulatif – Processeur de paiements9Concurrence et POO
Bases des GoroutinesCanaux et communicationCanaux tamponnés ou non tamponnésInstruction selectsync.Mutex et sync.RWMutexsync.WaitGroupConception de structures thread-safeRécapitulatif - Pool de workersEntraînez-vous par vous-même : Compilateur Go en ligne