diff --git a/koans.tm b/koans.tm index 95247e2..d4e1fac 100644 --- a/koans.tm +++ b/koans.tm @@ -71,7 +71,7 @@ func ask_continue(): func clear_screen(): say("$\x1b[2J$\x1b[H", newline=no) -func summarize_tests(highlight=none:Path): +func summarize_tests(results:[TestResult], highlight=none:Path): $Colorful" @(yellow,b,u:Lessons) @@ -80,7 +80,7 @@ func summarize_tests(highlight=none:Path): passing := 0 failing := 0 for i,lesson in LESSONS: - result := lesson:get_result() + result := results[i] if result:is_success(): passing += 1 $Colorful" @@ -104,12 +104,23 @@ func summarize_tests(highlight=none:Path): ":print() +func short_summarize_tests(results:[TestResult]): + say("Progress: ", newline=no) + for result in results: + if result:is_success(): + $Colorful"@(green,bold:#)":print(newline=no) + else: + $Colorful"@(red,dim:#)":print(newline=no) + + say(\n) + func choose_option(options:{Text,Text} -> Text): repeat: for k,v in options: $Colorful" @(b:($k)) $v ":print() + say("") choice := (ask("Choose an option: ") or goodbye()):lower():to(1) if options:has(choice): return choice @@ -194,7 +205,7 @@ func main(clean=no -> Abort): ask_continue() repeat: clear_screen() - summarize_tests() + summarize_tests(test_results) choice := ask("Choose a test or (q)uit: ") or stop repeat if choice == "q" or choice == "Q": stop repeat @@ -216,6 +227,7 @@ func main(clean=no -> Abort): repeat: lesson := LESSONS[n] show_lesson(lesson, test_results[n]) + short_summarize_tests(test_results) options := &{ "e"="Edit file and try again", diff --git a/lesson-templates/lesson-08-tables.tm b/lesson-templates/lesson-08-tables.tm index 730c96c..4c3a783 100644 --- a/lesson-templates/lesson-08-tables.tm +++ b/lesson-templates/lesson-08-tables.tm @@ -27,7 +27,7 @@ func main(): total += score >> total - = 9999 + = ??? # Table keys and values can be accessed as an array: >> scores.keys diff --git a/lesson-templates/lesson-09-text.tm b/lesson-templates/lesson-09-text.tm index dd76b6b..b6588b5 100644 --- a/lesson-templates/lesson-09-text.tm +++ b/lesson-templates/lesson-09-text.tm @@ -22,7 +22,7 @@ func main(): line three " - # Methods calls use `:` + # Method calls use `:` >> multiline:lines() = [???] diff --git a/lesson-templates/lesson-10-structs.tm b/lesson-templates/lesson-10-structs.tm index a40376e..0872d63 100644 --- a/lesson-templates/lesson-10-structs.tm +++ b/lesson-templates/lesson-10-structs.tm @@ -9,7 +9,7 @@ struct Point(x:Int, y:Int): # There is no implicit `self` argument, only the # arguments you explicitly define. - func absolute(p:Point -> Point): + func abs(p:Point -> Point): return Point(p.x:abs(), p.y:abs()) # Constants can be declared inside of a struct's namespace: @@ -22,7 +22,7 @@ struct Point(x:Int, y:Int): func main(): # You can create a struct instance like this: - p := Point(x=3, y=4) + p := Point(x=3, y=-4) >> p = Point(x=???, y=???) @@ -35,8 +35,12 @@ func main(): >> p.y = ??? - >> p.sum() + >> p:abs() = ??? >> Point.squared_int(5) = ??? + + >> Int.abs(-2) + + >> -2:abs() diff --git a/lesson-templates/lesson-11-enums.tm b/lesson-templates/lesson-11-enums.tm index 3622933..a211ce2 100644 --- a/lesson-templates/lesson-11-enums.tm +++ b/lesson-templates/lesson-11-enums.tm @@ -6,7 +6,7 @@ enum Shape(Circle(radius: Num), Rectangle(width: Num, height: Num), Point): # Use `when` to pattern match an enum: func area(shape: Shape -> Num): when shape is Circle(radius): - return Num.PI * radius * radius + return Num.PI * radius^2 is Rectangle(width, height): return width * height is Point: @@ -15,23 +15,23 @@ enum Shape(Circle(radius: Num), Rectangle(width: Num, height: Num), Point): func main(): # You can create instances of an enum: - s1 := Shape.Point + point := Shape.Point # Single member enums display without the field names: - s2 := Circle(radius=10) - >> s1 + circle := Shape.Circle(radius=10) + >> circle = Circle(10) # Multi-member enums explicitly list their field names: - s3 := Shape.Rectangle(width=4, height=5) - >> s3 + rect := Shape.Rectangle(width=4, height=5) + >> rect = Rectangle(width=4, height=5) - >> s1:area() + >> point:area() = ??? - >> s2:area() + >> rect:area() = ??? - >> "My shape is $s3" + >> "My shape is $circle" = ??? diff --git a/lesson-templates/lesson-13-paths.tm b/lesson-templates/lesson-13-paths.tm index 6ac0144..3ced10f 100644 --- a/lesson-templates/lesson-13-paths.tm +++ b/lesson-templates/lesson-13-paths.tm @@ -5,43 +5,40 @@ func main(): # Tomo includes a built-in literal type for file paths # A path is inside parentheses and begins with `/`, `~`, `.` or `..` - file := (/tmp/test-file.txt) - >> file + path := (/tmp/test-file.txt) + >> path = /tmp/test-file.txt - file:write("first line") - >> file:read() + path:write("first line") + >> path:read() = "???" - file:append(" + path:append(" second line ") - >> file:exists() + >> path:exists() = yes - >> file:lines() - = [???] - # You can iterate over a file by lines: - >> upper_lines := [line:upper() for line in file:by_line()] + >> upper_lines := [line:upper() for line in path:by_line()!] = [???] - >> file:parent() + >> path:parent() = /??? - >> file:extension() + >> path:extension() = "???" - >> file:parent():child("other-file.txt") + >> path:parent():child("other-file.txt") = /??? >> dir := (/tmp/test-*.txt):glob() = [???] - file:remove() + path:remove() - >> file:exists() + >> path:exists() = ???