Menu
Coddy logo textTech

eラーニングプラットフォーム

CoddyのGOジャーニー「オブジェクト指向プログラミング」セクションの一部。レッスン 105/107。

challenge icon

チャレンジ

簡単

コース、学生を管理し、学習の進捗を追跡する E-Learning Platform を構築しましょう!struct、interface、composition、polymorphism を組み合わせて、学生がコースに登録し、lesson を完了できる一貫したシステムを作成します。

コードを5つのファイルに分けて整理します。

  • lesson.go: 個々の学習単位を表す Lesson struct を定義します。各 lesson には IDTitleDuration(分単位)があります。Lesson へのポインターを返す NewLesson constructor を含めます。
  • course.go: IDTitleInstructor、および *Lesson ポインターのスライスを含む Course struct を作成します。NewCourse constructor と AddLesson method を含めます。また、コース内のすべての lesson の duration の合計を返す TotalDuration() int method も実装します。
  • student.go: IDNameEmail field を持つ Student struct を定義します。NewStudent constructor を含めます。
  • enrollment.go: ここで進捗追跡の仕組みを実装します。学生をコースに関連付け、どの lesson を完了したかを追跡する Enrollment struct を作成します。次の要素を持たせます。
    • Student へのポインター
    • Course へのポインター
    • CompletedLessons map(lesson ID から boolean への対応)

    パーセンテージ(0.0 から 100.0)を返す Progress() float64 method を持つ Progressable interface を定義します。

    Enrollment に次の method を実装します。

    • NewEnrollment(student *Student, course *Course) *Enrollment: 空の completed lessons map を初期化する constructor
    • CompleteLesson(lessonID string) string: lesson を完了としてマークします。コースに lesson が存在しない場合は lesson not found、すでに完了している場合は already completed、成功時は completed を返します
    • Progress() float64: 完了した lesson の割合(完了数/合計数 * 100)を返します。コースに lesson がない場合は 0.0 を返します
  • main.go: プラットフォームを構築し、enrollment の操作を処理します。

    コースの ID、title、instructor を読み取ります。次に lesson の数と、各 lesson の ID、title、duration を読み取ります。学生の ID、name、email を読み取ります。学生とコースを関連付ける enrollment を作成します。

    続いて操作の数を読み取ります。各操作は complete [lessonID] または progress のいずれかです。complete 操作では結果メッセージを出力します。progress 操作では、進捗を小数点以下1桁でフォーマットし、その後にパーセント記号を付けて出力します。

次の入力が提供されます。

  • Course ID、Title、Instructor(3行)
  • lesson の数、その後に各 lesson の ID、Title、Duration(各3行)
  • Student ID、Name、Email(3行)
  • 操作の数、その後に各操作(各1行)

たとえば、次の入力が与えられた場合:

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 struct が composition を使用して学生とコースを関連付け、一方で Progressable interface によって任意の型が完了状況を報告できることに注目してください。この設計は拡張が容易です。同じ interface を使用して、個々の lesson や学習パス全体に進捗追跡機能を追加することもできます。

自分で試してみよう

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("") // 実際の結果に置き換える
		}
	}
}

オブジェクト指向プログラミングのすべてのレッスン

自分で練習してみよう: Goオンラインコンパイラ