Skip to content

Commit d95276a

Browse files
authored
Sync: re-write grade-school (#1050)
* Sync: re-write grade-school * Add prerequisites * Change type to any
1 parent 1c394a0 commit d95276a

File tree

6 files changed

+215
-86
lines changed

6 files changed

+215
-86
lines changed

config.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1303,6 +1303,8 @@
13031303
"name": "Grade School",
13041304
"uuid": "4e6d3ddf-b696-40dc-ba02-ed998e595be7",
13051305
"prerequisites": [
1306+
"atoms",
1307+
"tuples",
13061308
"lists",
13071309
"maps",
13081310
"enum"

exercises/practice/grade-school/.meta/config.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
"devonestes",
1313
"drueck",
1414
"elasticdog",
15+
"jiegillet",
1516
"jinyeow",
1617
"kytrinyx",
1718
"lpil",
Lines changed: 38 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,48 @@
11
defmodule School do
2-
def add(db, name, grade) do
3-
if name in List.flatten(Map.values(db)) do
4-
db
2+
@moduledoc """
3+
Simulate students in a school.
4+
5+
Each student is in a grade.
6+
"""
7+
8+
@type school :: map
9+
10+
@doc """
11+
Create a new, empty school.
12+
"""
13+
@spec new() :: school
14+
def new(), do: %{}
15+
16+
@doc """
17+
Add a student to a particular grade in school.
18+
"""
19+
@spec add(school, String.t(), integer) :: {:ok | :error, school}
20+
def add(school, name, grade) do
21+
if name in List.flatten(Map.values(school)) do
22+
{:error, school}
523
else
6-
Map.update(db, grade, [name], &[name | &1])
24+
{:ok, Map.update(school, grade, [name], &[name | &1])}
725
end
826
end
927

10-
def grade(db, grade) do
11-
Map.get(db, grade, [])
28+
@doc """
29+
Return the names of the students in a particular grade, sorted alphabetically.
30+
"""
31+
@spec grade(school, integer) :: [String.t()]
32+
def grade(school, grade) do
33+
Map.get(school, grade, [])
34+
|> Enum.sort()
1235
end
1336

14-
def sort(db) do
15-
db
16-
|> Enum.map(fn {k, v} -> {k, Enum.sort(v)} end)
37+
@doc """
38+
Return the names of all the students in the school sorted by grade and name.
39+
"""
40+
@spec roster(school) :: [String.t()]
41+
def roster(school) do
42+
school
43+
|> Enum.map(fn {grade, students} -> {grade, Enum.sort(students)} end)
1744
|> Enum.sort()
45+
|> Enum.map(fn {_grade, students} -> students end)
46+
|> Enum.concat()
1847
end
1948
end

exercises/practice/grade-school/.meta/tests.toml

Lines changed: 54 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -9,35 +9,78 @@
99
# As user-added comments (using the # character) will be removed when this file
1010
# is regenerated, comments can be added via a `comment` key.
1111

12+
[a3f0fb58-f240-4723-8ddc-e644666b85cc]
13+
description = "Roster is empty when no student is added"
14+
15+
[9337267f-7793-4b90-9b4a-8e3978408824]
16+
description = "Add a student"
17+
1218
[6d0a30e4-1b4e-472e-8e20-c41702125667]
13-
description = "Adding a student adds them to the sorted roster"
19+
description = "Student is added to the roster"
20+
21+
[73c3ca75-0c16-40d7-82f5-ed8fe17a8e4a]
22+
description = "Adding multiple students in the same grade in the roster"
23+
24+
[233be705-dd58-4968-889d-fb3c7954c9cc]
25+
description = "Multiple students in the same grade are added to the roster"
26+
27+
[87c871c1-6bde-4413-9c44-73d59a259d83]
28+
description = "Cannot add student to same grade in the roster more than once"
1429

1530
[c125dab7-2a53-492f-a99a-56ad511940d8]
1631
description = "A student can't be in two different grades"
1732
include = false
1833

1934
[a0c7b9b8-0e89-47f8-8b4a-c50f885e79d1]
2035
description = "A student can only be added to the same grade in the roster once"
36+
include = false
2137
reimplements = "c125dab7-2a53-492f-a99a-56ad511940d8"
2238

23-
[233be705-dd58-4968-889d-fb3c7954c9cc]
24-
description = "Adding more students adds them to the sorted roster"
39+
[d7982c4f-1602-49f6-a651-620f2614243a]
40+
description = "Student not added to same grade in the roster more than once"
41+
reimplements = "a0c7b9b8-0e89-47f8-8b4a-c50f885e79d1"
42+
43+
[e70d5d8f-43a9-41fd-94a4-1ea0fa338056]
44+
description = "Adding students in multiple grades"
2545

2646
[75a51579-d1d7-407c-a2f8-2166e984e8ab]
27-
description = "Adding students to different grades adds them to the same sorted roster"
47+
description = "Students in multiple grades are added to the roster"
48+
49+
[7df542f1-57ce-433c-b249-ff77028ec479]
50+
description = "Cannot add same student to multiple grades in the roster"
2851

2952
[6a03b61e-1211-4783-a3cc-fc7f773fba3f]
3053
description = "A student cannot be added to more than one grade in the sorted roster"
54+
include = false
3155
reimplements = "c125dab7-2a53-492f-a99a-56ad511940d8"
3256

33-
[a3f0fb58-f240-4723-8ddc-e644666b85cc]
34-
description = "Roster returns an empty list if there are no students enrolled"
57+
[c7ec1c5e-9ab7-4d3b-be5c-29f2f7a237c5]
58+
description = "Student not added to multiple grades in the roster"
59+
reimplements = "6a03b61e-1211-4783-a3cc-fc7f773fba3f"
3560

36-
[180a8ff9-5b94-43fc-9db1-d46b4a8c93b6]
37-
description = "Student names with grades are displayed in the same sorted roster"
61+
[d9af4f19-1ba1-48e7-94d0-dabda4e5aba6]
62+
description = "Students are sorted by grades in the roster"
3863

39-
[1bfbcef1-e4a3-49e8-8d22-f6f9f386187e]
40-
description = "Grade returns the students in that grade in alphabetical order"
64+
[d9fb5bea-f5aa-4524-9d61-c158d8906807]
65+
description = "Students are sorted by name in the roster"
66+
67+
[180a8ff9-5b94-43fc-9db1-d46b4a8c93b6]
68+
description = "Students are sorted by grades and then by name in the roster"
4169

4270
[5e67aa3c-a3c6-4407-a183-d8fe59cd1630]
43-
description = "Grade returns an empty list if there are no students in that grade"
71+
description = "Grade is empty if no students in the roster"
72+
73+
[1e0cf06b-26e0-4526-af2d-a2e2df6a51d6]
74+
description = "Grade is empty if no students in that grade"
75+
76+
[2bfc697c-adf2-4b65-8d0f-c46e085f796e]
77+
description = "Student not added to same grade more than once"
78+
79+
[66c8e141-68ab-4a04-a15a-c28bc07fe6b9]
80+
description = "Student not added to multiple grades"
81+
82+
[c9c1fc2f-42e0-4d2c-b361-99271f03eda7]
83+
description = "Student not added to other grade for multiple grades"
84+
85+
[1bfbcef1-e4a3-49e8-8d22-f6f9f386187e]
86+
description = "Students are sorted by name in a grade"

exercises/practice/grade-school/lib/school.ex

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,24 +5,33 @@ defmodule School do
55
Each student is in a grade.
66
"""
77

8+
@type school :: any()
9+
10+
@doc """
11+
Create a new, empty school.
12+
"""
13+
@spec new() :: school
14+
def new() do
15+
end
16+
817
@doc """
918
Add a student to a particular grade in school.
1019
"""
11-
@spec add(map, String.t(), integer) :: map
12-
def add(db, name, grade) do
20+
@spec add(school, String.t(), integer) :: {:ok | :error, school}
21+
def add(school, name, grade) do
1322
end
1423

1524
@doc """
16-
Return the names of the students in a particular grade.
25+
Return the names of the students in a particular grade, sorted alphabetically.
1726
"""
18-
@spec grade(map, integer) :: [String.t()]
19-
def grade(db, grade) do
27+
@spec grade(school, integer) :: [String.t()]
28+
def grade(school, grade) do
2029
end
2130

2231
@doc """
23-
Sorts the school by grade and name.
32+
Return the names of all the students in the school sorted by grade and name.
2433
"""
25-
@spec sort(map) :: [{integer, [String.t()]}]
26-
def sort(db) do
34+
@spec roster(school) :: [String.t()]
35+
def roster(school) do
2736
end
2837
end
Lines changed: 103 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -1,88 +1,133 @@
11
defmodule SchoolTest do
22
use ExUnit.Case
33

4-
@db %{}
4+
def make_school_with_students(students) do
5+
{results, school} =
6+
Enum.reduce(students, {[], School.new()}, fn {student, grade}, {results, school} ->
7+
{result, school} = School.add(school, student, grade)
8+
{[result | results], school}
9+
end)
10+
11+
{Enum.reverse(results), school}
12+
end
513

6-
test "add student" do
7-
actual = School.add(@db, "Aimee", 2)
8-
assert actual == %{2 => ["Aimee"]}
14+
# @tag :pending
15+
test "Roster is empty when no student is added" do
16+
assert School.roster(School.new()) == []
917
end
1018

11-
test "a student can only be added to the same grade once" do
12-
actual =
13-
@db
14-
|> School.add("Aimee", 2)
15-
|> School.add("Aimee", 2)
19+
@tag :pending
20+
test "Add a student" do
21+
{result, school} = School.add(School.new(), "Aimee", 2)
1622

17-
assert actual == %{2 => ["Aimee"]}
23+
assert result == :ok
24+
assert School.roster(school) == ["Aimee"]
1825
end
1926

20-
test "a student cannot be added to more than one grade" do
21-
actual =
22-
@db
23-
|> School.add("Aimee", 2)
24-
|> School.add("Aimee", 1)
27+
@tag :pending
28+
test "Adding multiple students in the same grade in the roster" do
29+
students = [{"Blair", 2}, {"James", 2}, {"Paul", 2}]
30+
{results, school} = make_school_with_students(students)
2531

26-
assert actual == %{2 => ["Aimee"]}
32+
assert results == [:ok, :ok, :ok]
33+
assert School.roster(school) == ["Blair", "James", "Paul"]
2734
end
2835

2936
@tag :pending
30-
test "add more students in same class" do
31-
actual =
32-
@db
33-
|> School.add("James", 2)
34-
|> School.add("Blair", 2)
35-
|> School.add("Paul", 2)
36-
37-
assert Enum.sort(actual[2]) == ["Blair", "James", "Paul"]
37+
test "Cannot add student to same grade in the roster more than once" do
38+
students = [{"Blair", 2}, {"James", 2}, {"James", 2}, {"Paul", 2}]
39+
{results, school} = make_school_with_students(students)
40+
41+
assert results == [:ok, :ok, :error, :ok]
42+
assert School.roster(school) == ["Blair", "James", "Paul"]
3843
end
3944

4045
@tag :pending
41-
test "add students to different grades" do
42-
actual =
43-
@db
44-
|> School.add("Chelsea", 3)
45-
|> School.add("Logan", 7)
46+
test "Adding students in multiple grades" do
47+
students = [{"Chelsea", 3}, {"Logan", 7}]
48+
{results, school} = make_school_with_students(students)
4649

47-
assert actual == %{3 => ["Chelsea"], 7 => ["Logan"]}
50+
assert results == [:ok, :ok]
51+
assert School.roster(school) == ["Chelsea", "Logan"]
4852
end
4953

5054
@tag :pending
51-
test "get students in a grade" do
52-
actual =
53-
@db
54-
|> School.add("Bradley", 5)
55-
|> School.add("Franklin", 5)
56-
|> School.add("Jeff", 1)
57-
|> School.grade(5)
58-
59-
assert Enum.sort(actual) == ["Bradley", "Franklin"]
55+
test "Cannot add same student to multiple grades in the roster" do
56+
students = [{"Blair", 2}, {"James", 2}, {"James", 3}, {"Paul", 3}]
57+
{results, school} = make_school_with_students(students)
58+
59+
assert results == [:ok, :ok, :error, :ok]
60+
assert School.roster(school) == ["Blair", "James", "Paul"]
6061
end
6162

6263
@tag :pending
63-
test "get students in a non existent grade" do
64-
assert [] == School.grade(@db, 1)
64+
test "Students are sorted by grades in the roster" do
65+
students = [{"Jim", 3}, {"Peter", 2}, {"Anna", 1}]
66+
{_results, school} = make_school_with_students(students)
67+
68+
assert School.roster(school) == ["Anna", "Peter", "Jim"]
6569
end
6670

6771
@tag :pending
68-
test "sort school by grade and by student name" do
69-
actual =
70-
@db
71-
|> School.add("Peter", 2)
72-
|> School.add("Anna", 1)
73-
|> School.add("Barb", 1)
74-
|> School.add("Zoe", 2)
75-
|> School.add("Alex", 2)
76-
|> School.add("Jim", 3)
77-
|> School.add("Charlie", 1)
78-
|> School.sort()
79-
80-
expected = [
81-
{1, ["Anna", "Barb", "Charlie"]},
82-
{2, ["Alex", "Peter", "Zoe"]},
83-
{3, ["Jim"]}
72+
test "Students are sorted by name in the roster" do
73+
students = [{"Peter", 2}, {"Zoe", 2}, {"Alex", 2}]
74+
{_results, school} = make_school_with_students(students)
75+
76+
assert School.roster(school) == ["Alex", "Peter", "Zoe"]
77+
end
78+
79+
@tag :pending
80+
test "Students are sorted by grades and then by name in the roster" do
81+
students = [
82+
{"Peter", 2},
83+
{"Anna", 1},
84+
{"Barb", 1},
85+
{"Zoe", 2},
86+
{"Alex", 2},
87+
{"Jim", 3},
88+
{"Charlie", 1}
8489
]
8590

86-
assert expected == actual
91+
{_results, school} = make_school_with_students(students)
92+
93+
assert School.roster(school) == ["Anna", "Barb", "Charlie", "Alex", "Peter", "Zoe", "Jim"]
94+
end
95+
96+
@tag :pending
97+
test "Grade is empty if no students in the roster" do
98+
assert School.grade(School.new(), 1) == []
99+
end
100+
101+
@tag :pending
102+
test "Grade is empty if no students in that grade" do
103+
students = [{"Peter", 2}, {"Zoe", 2}, {"Alex", 2}, {"Jim", 3}]
104+
{_results, school} = make_school_with_students(students)
105+
106+
assert School.grade(school, 1) == []
107+
end
108+
109+
@tag :pending
110+
test "Student not added to same grade more than once" do
111+
students = [{"Blair", 2}, {"James", 2}, {"James", 2}, {"Paul", 2}]
112+
{_results, school} = make_school_with_students(students)
113+
114+
assert School.roster(school) == ["Blair", "James", "Paul"]
115+
end
116+
117+
@tag :pending
118+
test "Student not added to multiple grades" do
119+
students = [{"Blair", 2}, {"James", 2}, {"James", 3}, {"Paul", 3}]
120+
{_results, school} = make_school_with_students(students)
121+
122+
assert School.grade(school, 2) == ["Blair", "James"]
123+
assert School.grade(school, 3) == ["Paul"]
124+
end
125+
126+
@tag :pending
127+
test "Students are sorted by name in a grade" do
128+
students = [{"Franklin", 5}, {"Bradley", 5}, {"Jeff", 1}]
129+
{_results, school} = make_school_with_students(students)
130+
131+
assert School.grade(school, 5) == ["Bradley", "Franklin"]
87132
end
88133
end

0 commit comments

Comments
 (0)