פלטפורמת למידה מקוונת
חלק מהיחידה תכנות מונחה עצמים במסלול ה-GO של Coddy. שיעור 105 מתוך 107.
אתגר
קלבואו נבנה פלטפורמת למידה מקוונת שמנהלת קורסים ותלמידים ועוקבת אחר התקדמות הלמידה! תשלבו מבנים, ממשקים, הרכבה ופולימורפיזם כדי ליצור מערכת אחידה שבה תלמידים יכולים להירשם לקורסים ולהשלים שיעורים.
תארגנו את הקוד שלכם בחמישה קבצים:
lesson.go: הגדירו מבנהLessonשמייצג יחידות למידה בודדות. לכל שיעור ישID,Titleו-Duration(בדקות). כללו בנאיNewLessonשמחזיר מצביע ל-Lesson.course.go: צרו מבנהCourseשמכילID,Title,Instructorופרוסה של מצביעים מסוג*Lesson. כללו בנאיNewCourseומתודהAddLesson. כמו כן, ממשו מתודהTotalDuration() intשמחזירה את סכום משכי כל השיעורים בקורס.student.go: הגדירו מבנהStudentעם השדותID,Nameו-Email. כללו בנאיNewStudent.enrollment.go: כאן מתרחש הקסם של מעקב ההתקדמות. צרו מבנהEnrollmentשמקשר תלמיד לקורס ועוקב אחר השיעורים שהתלמיד השלים. צריכים להיות בו:- מצביע ל-
Student - מצביע ל-
Course - מפה
CompletedLessons(מזהה שיעור לערך בוליאני)
הגדירו ממשק
Progressableעם מתודהProgress() float64שמחזירה אחוז (מ-0.0 עד 100.0).ממשו את המתודות האלה ב-Enrollment:
NewEnrollment(student *Student, course *Course) *Enrollment: בנאי שמאתחל מפה ריקה של שיעורים שהושלמוCompleteLesson(lessonID string) string: מסמנת שיעור כהושלם. מחזירהlesson not foundאם השיעור לא קיים בקורס,already completedאם הוא כבר הושלם, אוcompletedבמקרה של הצלחהProgress() float64: מחזירה את אחוז השיעורים שהושלמו (שהושלמו/סה״כ * 100), או 0.0 אם אין בקורס שיעורים
- מצביע ל-
main.go: בנו את הפלטפורמה ועבדו את פעולות ההרשמה.קראו את מזהה הקורס, את הכותרת שלו ואת שם המדריך. לאחר מכן קראו את מספר השיעורים ואת המזהה, הכותרת והמשך של כל שיעור. קראו את מזהה התלמיד, את שמו ואת כתובת הדוא״ל שלו. צרו הרשמה שמקשרת את התלמיד לקורס.
לאחר מכן קראו את מספר הפעולות. כל פעולה היא
complete [lessonID]אוprogress. עבור פעולות השלמה, הדפיסו את הודעת התוצאה. עבור פעולות התקדמות, הדפיסו את ההתקדמות בפורמט של ספרה אחת אחרי הנקודה העשרונית, ואחריה סימן אחוז.
הקלטים הבאים יסופקו:
- מזהה הקורס, הכותרת ושם המדריך (3 שורות)
- מספר השיעורים, ולאחר מכן המזהה, הכותרת והמשך של כל שיעור (3 שורות לכל שיעור)
- מזהה התלמיד, השם וכתובת הדוא״ל (3 שורות)
- מספר הפעולות, ולאחר מכן כל פעולה (שורה אחת לכל פעולה)
לדוגמה, בהינתן:
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 L002הפלט שלכם צריך להיות:
0.0%
completed
33.3%
already completed
completedובהינתן:
C100
Python Basics
Bob Teacher
2
L100
Intro
20
L101
Loops
40
S100
Charlie
charlie@edu.com
4
complete L999
complete L100
complete L101
progressהפלט שלכם צריך להיות:
lesson not found
completed
completed
100.0%שימו לב כיצד המבנה Enrollment משתמש בהרכבה כדי לקשר בין תלמידים לקורסים, בעוד שהממשק Progressable מאפשר לכל סוג לדווח על מצב ההשלמה שלו. כך קל להרחיב את המערכת. אפשר להוסיף מעקב אחר התקדמות של שיעורים בודדים או של מסלולי למידה שלמים באמצעות אותו ממשק!
נסו בעצמכם
package main
import (
"bufio"
"fmt"
"os"
"strconv"
"strings"
)
func main() {
scanner := bufio.NewScanner(os.Stdin)
// פונקציית עזר לקריאת שורה
readLine := func() string {
scanner.Scan()
return strings.TrimSpace(scanner.Text())
}
// קריאת פרטי הקורס
courseID := readLine()
courseTitle := readLine()
courseInstructor := readLine()
// TODO: ליצור את הקורס באמצעות NewCourse
_ = courseID
_ = courseTitle
_ = courseInstructor
// קריאת מספר השיעורים
numLessons, _ := strconv.Atoi(readLine())
// TODO: לקרוא כל שיעור ולהוסיף אותו לקורס
for i := 0; i < numLessons; i++ {
lessonID := readLine()
lessonTitle := readLine()
lessonDuration, _ := strconv.Atoi(readLine())
// TODO: ליצור שיעור ולהוסיף אותו לקורס
_ = lessonID
_ = lessonTitle
_ = lessonDuration
}
// קריאת פרטי הסטודנט
studentID := readLine()
studentName := readLine()
studentEmail := readLine()
// TODO: ליצור את הסטודנט באמצעות NewStudent
_ = studentID
_ = studentName
_ = studentEmail
// TODO: ליצור רישום המקשר את הסטודנט לקורס
// קריאת מספר הפעולות
numOps, _ := strconv.Atoi(readLine())
// עיבוד כל פעולה
for i := 0; i < numOps; i++ {
operation := readLine()
if operation == "progress" {
// TODO: לקרוא ל-Progress() ולהדפיס בפורמט "%.1f%%"
fmt.Println("0.0%") // החליפו בהתקדמות בפועל
} else if strings.HasPrefix(operation, "complete ") {
lessonID := strings.TrimPrefix(operation, "complete ")
// TODO: קראו ל-CompleteLesson והדפיסו את התוצאה
_ = lessonID
fmt.Println("") // החליפו בתוצאה בפועל
}
}
}
כל השיעורים ביחידה תכנות מונחה עצמים
1יסודות OOP ב-Go
קבצים חיצונייםסביבת העבודה והמודולים של Goחבילות וייבואשמות מיוצאים לעומת שמות לא מיוצאיםמבוא ל-OOP ב-GoStructs כמחלקותהגדרת מתודות עבור Structsמקבלי Pointer לעומת Valueאתחול Structפונקציות Constructorחזרה – מחשבון פשוט4ממשקים
מבוא לממשקיםמימוש משתמעממשק כחוזהממשק ריק (any)אימות טיפוסמתג טיפוסיםהרכבת ממשקיםממשקי Stringer ו-Errorסיכום – מחשבון צורות7כימוס
שדות מיוצאים לעומת שדות לא מיוצאיםכימוס ברמת החבילהמתודות Getter ו-Setterהסתרת מידע ב-Goסיכום – רשומות תלמידים10Generics (Go 1.18 ומעלה)
מבוא ל־Genericsפרמטרים של טיפוסיםאילוצי טיפוסיםמבנים גנרייםפתרון עוקף למתודות גנריותסיכום – אוסף גנרי2העמקה בסוגים וב-Structs
סוגים בסיסיים ומורכביםהגדרות של סוגים מותאמים אישיתתגיות StructStructs אנונימייםStructs מקונניםערכי אפס וברירות מחדלסיכום – ספר אנשי קשר5קומפוזיציה במקום ירושה
למה ב-Go אין ירושהיסודות הטמעת Structקידום מתודותהטמעת כמה Structsהטמעה לעומת אגרגציההסתרת מתודות מוטמעותסיכום – היררכיית עובדים8טיפול בשגיאות ו-OOP
ממשק errorסוגי שגיאות מותאמים אישיתעטיפת שגיאות (fmt.Errorf)שגיאות Sentinelerrors.Is() ו-errors.As()Panic, Defer ו-Recoverסיכום – מנתח קבצים11ספרייה סטנדרטית ותכנות מונחה עצמים
io.Reader ו-io.Writersort.Interfaceהממשק fmt.Stringerencoding/json עם מבניםהממשק http.Handlerסיכום – מודלים של REST API3מצביעים וזיכרון
יסודות המצביעים ב-Goמצביעים למבניםהעברה לפי ערך לעומת לפי הפניההפונקציה new()איסוף אשפה ב-Goסיכום - בונה רשימה מקושרת6פולימורפיזם ב-Go
פולימורפיזם באמצעות ממשקיםטיפוס ברווז ב-Goכללי התאמה לממשקאוספים פולימורפייםהזרקת תלויותסיכום - מעבד תשלומים9מקביליות ו-OOP
יסודות GoroutinesChannels ותקשורתChannel עם חוצץ לעומת ללא חוצץפקודת Selectsync.Mutex ו-sync.RWMutexsync.WaitGroupתכנון Struct בטוח לשימוש במקבילסיכום - מאגר עובדים12מושגים מתקדמים בתכנות מונחה עצמים
דפוס האפשרויות הפונקציונליותדפוס Builder ב-Goשרשור מתודותכינויי טיפוסים לעומת הגדרותיסודות Reflectionסקירה כללית של יצירת קודתרגלו בעצמכם: קומפיילר Go אונליין