Updating the Repo

This commit is contained in:
2016-09-03 09:53:54 -05:00
parent ec45e6b2eb
commit 739f3c3e2b
21 changed files with 969 additions and 5 deletions

53
go/grade-school/README.md Normal file
View File

@@ -0,0 +1,53 @@
# Grade School
Write a small archiving program that stores students' names along with the grade that they are in.
In the end, you should be able to:
- Add a student's name to the roster for a grade
- "Add Jim to grade 2."
- "OK."
- Get a list of all students enrolled in a grade
- "Which students are in grade 2?"
- "We've only got Jim just now."
- Get a sorted list of all students in all grades. Grades should sort
as 1, 2, 3, etc., and students within a grade should be sorted
alphabetically by name.
- "Who all is enrolled in school right now?"
- "Grade 1: Anna, Barb, and Charlie. Grade 2: Alex, Peter, and Zoe.
Grade 3…"
Note that all our students only have one name. (It's a small town, what
do you want?)
## For bonus points
Did you get the tests passing and the code clean? If you want to, these
are some additional things you could try:
- If you're working in a language with mutable data structures and your
implementation allows outside code to mutate the school's internal DB
directly, see if you can prevent this. Feel free to introduce additional
tests.
Then please share your thoughts in a comment on the submission. Did this
experiment make the code better? Worse? Did you learn anything from it?
To run the tests simply run the command `go test` in the exercise directory.
If the test suite contains benchmarks, you can run these with the `-bench`
flag:
go test -bench .
For more detailed info about the Go track see the [help
page](http://exercism.io/languages/go).
## Source
A pairing session with Phil Battos at gSchool [http://gschool.it](http://gschool.it)
## Submitting Incomplete Problems
It's possible to submit an incomplete solution so you can see how others have completed the exercise.

View File

@@ -0,0 +1,173 @@
// API:
//
// type Grade struct {
// int, []string
// }
//
// type School
// func New() *School
// func (s *School) Add(string, int)
// func (s *School) Grade(int) []string
// func (s *School) Enrollment() []Grade
package school
import (
"fmt"
"math/rand"
"strconv"
"testing"
)
func TestNewSchoolIsEmpty(t *testing.T) {
if len(New().Enrollment()) != 0 {
t.Error("New school not empty")
}
}
func list(e []Grade) (s string) {
for _, l := range e {
s += fmt.Sprintln(l)
}
return s
}
func TestAddStudent(t *testing.T) {
exp := list([]Grade{{2, []string{"Aimee"}}})
s := New()
s.Add("Aimee", 2)
got := list(s.Enrollment())
if got != exp {
t.Errorf(`Add Aimee level 2, got
%sexpected:
%s`, got, exp)
}
}
func TestAddMoreSameGrade(t *testing.T) {
exp := list([]Grade{{2, []string{"Blair James Paul"}}})
s := New()
s.Add("Blair", 2)
s.Add("James", 2)
s.Add("Paul", 2)
got := list(s.Enrollment())
if got != exp {
t.Errorf(`Add more same grade, got
%sexpected:
%s`, got, exp)
}
}
func TestAddDifferentGrades(t *testing.T) {
exp := list([]Grade{
{3, []string{"Chelsea"}},
{7, []string{"Logan"}},
})
s := New()
s.Add("Chelsea", 3)
s.Add("Logan", 7)
got := list(s.Enrollment())
if got != exp {
t.Errorf(`Add different grades, got
%sexpected:
%s`, got, exp)
}
}
func TestGetGrade(t *testing.T) {
exp := []string{"Bradley", "Franklin"}
s := New()
s.Add("Bradley", 5)
s.Add("Franklin", 5)
s.Add("Jeff", 1)
got := s.Grade(5)
if len(got) == len(exp) {
if got[0] == exp[0] && got[1] == exp[1] ||
got[0] == exp[1] && got[1] == exp[0] { // accept out of order
return
}
}
t.Errorf(`Get grade, got
%v
expected
%v`, got, exp)
}
func TestNonExistantGrade(t *testing.T) {
s := New()
got := s.Grade(1)
if len(got) != 0 {
t.Errorf(`Get non-existant grade, got
%v
expected
[]`, got)
}
}
func TestSortedEnrollment(t *testing.T) {
exp := list([]Grade{
{3, []string{"Kyle"}},
{4, []string{"Christopher Jennifer"}},
{6, []string{"Kareem"}},
})
s := New()
s.Add("Jennifer", 4)
s.Add("Kareem", 6)
s.Add("Christopher", 4)
s.Add("Kyle", 3)
got := list(s.Enrollment())
if got != exp {
t.Errorf(`Sorted enrollment, got
%sexpected:
%s`, got, exp)
}
}
const (
minLevel = 1
maxLevel = 9
enrollment = 400
)
func BenchmarkAddStudents(b *testing.B) {
const pool = 1e6 // pool of students
names := make([]string, pool)
levels := make([]int, pool)
for i := range names {
names[i] = strconv.Itoa(rand.Intn(1e5))
levels[i] = minLevel + rand.Intn(maxLevel-minLevel+1)
}
p := 0
b.ResetTimer()
for i := 0; i < b.N; i++ {
// bench combined time to create a school and add
// a number of students, drawn from a pool of students
s := New()
for t := 0; t < enrollment; t++ {
s.Add(names[p], levels[p])
p = (p + 1) % pool
}
}
}
func BenchmarkEnrollment(b *testing.B) {
const pool = 1000 // pool of schools
ss := make([]*School, pool)
for i := range ss {
s := New()
for t := 0; t < enrollment; t++ {
s.Add(
strconv.Itoa(rand.Intn(1e5)),
minLevel+rand.Intn(maxLevel-minLevel+1))
}
ss[i] = s
}
p := 0
b.ResetTimer()
for i := 0; i < b.N; i++ {
// bench time to get enrollment of a full school,
// averaged over a pool of schools.
ss[p].Enrollment()
p = (p + 1) % pool
}
}

53
go/grade-school/school.go Normal file
View File

@@ -0,0 +1,53 @@
package school
import "sort"
// A Grade is just the grade number and a list of students
type Grade struct {
Num int
Students []string
}
// AddStudent adds a student name to a grades roster
func (g *Grade) AddStudent(name string) {
g.Students = append(g.Students, name)
}
// School is just a collection of Grades
type School struct {
grades map[int]Grade
}
// New returns a new School object
func New() *School {
return &School{
grades: make(map[int]Grade),
}
}
// Add add student 'name' to grade 'grade'
func (s *School) Add(name string, grade int) {
g := s.grades[grade]
g.Num = grade
g.AddStudent(name)
s.grades[grade] = g
}
// Grade returns a sorted list of all students in 'grade'
func (s *School) Grade(grade int) []string {
g := s.grades[grade]
sort.Strings(g.Students)
return g.Students
}
// Enrollment returns the full school's enrollment, sorted by grade then name
func (s *School) Enrollment() []Grade {
var ret []Grade
for k := 1; k <= 12; k++ {
grRoster := s.Grade(k)
if len(grRoster) > 0 {
ret = append(ret, Grade{Num: k, Students: grRoster})
}
}
return ret
}