Updated Registrar.
This commit is contained in:
@@ -9,6 +9,30 @@ class Examples {
|
||||
new Cons<Integer>(2, new Cons<Integer>(3, new Mt<Integer>()))
|
||||
);
|
||||
|
||||
Teacher singer;
|
||||
Teacher wormwood;
|
||||
|
||||
Course singing;
|
||||
Course arithmetic;
|
||||
Course clobbering;
|
||||
|
||||
Student calvin;
|
||||
Student hobbes;
|
||||
Student susie;
|
||||
|
||||
void init() {
|
||||
singer = new Teacher("Mr. Singer");
|
||||
wormwood = new Teacher("Ms. Wormwood");
|
||||
|
||||
singing = new Course("Singing", singer);
|
||||
arithmetic = new Course("Arithmetic", wormwood);
|
||||
clobbering = new Course("Introduction to Clobbering", wormwood);
|
||||
|
||||
calvin = new Student("Calvin");
|
||||
hobbes = new Student("Hobbes");
|
||||
susie = new Student("Susie Derkins");
|
||||
}
|
||||
|
||||
void testILoUniqAppend(Tester t) {
|
||||
t.checkExpect(testList.uniqAppend(2), testList);
|
||||
t.checkExpect(
|
||||
@@ -25,6 +49,90 @@ class Examples {
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
void testILoHas(Tester t) {
|
||||
t.checkExpect(testList.has(2), true);
|
||||
t.checkExpect(testList.has(6), false);
|
||||
}
|
||||
|
||||
void testILoDropFirst(Tester t) {
|
||||
t.checkExpect(
|
||||
testList.dropFirst(2),
|
||||
new Cons<Integer>(1, new Cons<Integer>(3, new Mt<Integer>()))
|
||||
);
|
||||
}
|
||||
|
||||
void testCourse(Tester t) {
|
||||
init();
|
||||
t.checkExpect(singing.teacher, singer);
|
||||
t.checkExpect(
|
||||
singer.courses,
|
||||
new Cons<Course>(singing, new Mt<Course>())
|
||||
);
|
||||
}
|
||||
|
||||
void testStudentEnroll(Tester t) {
|
||||
init();
|
||||
calvin.enroll(arithmetic);
|
||||
t.checkExpect(
|
||||
calvin.courses,
|
||||
new Cons<Course>(arithmetic, new Mt<Course>())
|
||||
);
|
||||
t.checkExpect(
|
||||
arithmetic.students,
|
||||
new Cons<Student>(calvin, new Mt<Student>())
|
||||
);
|
||||
t.checkExpect(calvin.takesCourse(arithmetic), true);
|
||||
calvin.enroll(arithmetic);
|
||||
t.checkExpect(
|
||||
calvin.courses,
|
||||
new Cons<Course>(arithmetic, new Mt<Course>())
|
||||
);
|
||||
t.checkExpect(
|
||||
arithmetic.students,
|
||||
new Cons<Student>(calvin, new Mt<Student>())
|
||||
);
|
||||
|
||||
singing.setTeacher(wormwood);
|
||||
t.checkExpect(singing.teacher, wormwood);
|
||||
t.checkExpect(
|
||||
wormwood.courses,
|
||||
new Cons<Course>(
|
||||
arithmetic,
|
||||
new Cons<Course>(
|
||||
clobbering,
|
||||
new Cons<Course>(singing, new Mt<Course>())
|
||||
)
|
||||
)
|
||||
);
|
||||
t.checkExpect(singer.courses, new Mt<Course>());
|
||||
}
|
||||
|
||||
void testStudentClassmates(Tester t) {
|
||||
init();
|
||||
|
||||
calvin.enroll(singing);
|
||||
hobbes.enroll(singing);
|
||||
susie.enroll(arithmetic);
|
||||
|
||||
t.checkExpect(calvin.classmates(hobbes), true);
|
||||
t.checkExpect(hobbes.classmates(calvin), true);
|
||||
t.checkExpect(calvin.classmates(susie), false);
|
||||
t.checkExpect(susie.classmates(hobbes), false);
|
||||
}
|
||||
|
||||
void testTeacherDejaVu(Tester t) {
|
||||
init();
|
||||
|
||||
calvin.enroll(arithmetic);
|
||||
calvin.enroll(clobbering);
|
||||
hobbes.enroll(clobbering);
|
||||
susie.enroll(singing);
|
||||
|
||||
t.checkExpect(wormwood.dejavu(calvin), true);
|
||||
t.checkExpect(singer.dejavu(susie), false);
|
||||
t.checkExpect(wormwood.dejavu(hobbes), false);
|
||||
}
|
||||
}
|
||||
|
||||
class School {
|
||||
@@ -46,7 +154,7 @@ class Course {
|
||||
Course(String name, Teacher teacher, ILo<Student> students) {
|
||||
this.name = name;
|
||||
this.teacher = teacher;
|
||||
this.teacher.assignCourse(this);
|
||||
teacher.assignCourse(this);
|
||||
this.students = students;
|
||||
}
|
||||
|
||||
@@ -54,6 +162,29 @@ class Course {
|
||||
Course(String name, Teacher teacher) {
|
||||
this(name, teacher, new Mt<Student>());
|
||||
}
|
||||
|
||||
// Effect: Adds a student.
|
||||
void addStudent(Student student) {
|
||||
// Make sure there's no way to add a student to a course without
|
||||
// being enrolled.
|
||||
if (!student.takesCourse(this)) student.enroll(this);
|
||||
this.students = this.students.uniqAppend(student);
|
||||
}
|
||||
|
||||
// Effect: Sets the teacher.
|
||||
void setTeacher(Teacher newTeacher) {
|
||||
if (!newTeacher.equals(this.teacher)) {
|
||||
this.teacher.removeCourse(this);
|
||||
this.teacher = newTeacher;
|
||||
this.teacher.assignCourse(this);
|
||||
}
|
||||
// If the teacher is the same, do nothing.
|
||||
}
|
||||
|
||||
// Is this Course taught by the Teacher?
|
||||
boolean taughtBy(Teacher teacher) {
|
||||
return this.teacher.equals(teacher);
|
||||
}
|
||||
}
|
||||
|
||||
class Teacher {
|
||||
@@ -73,11 +204,25 @@ class Teacher {
|
||||
|
||||
// Effect: Assigns the given Course to this Teacher.
|
||||
void assignCourse(Course course) {
|
||||
this.courses.uniqAppend(course);
|
||||
if (!course.taughtBy(this)) course.setTeacher(this);
|
||||
this.courses = this.courses.uniqAppend(course);
|
||||
}
|
||||
|
||||
// Effect: Enrolls the given Student in this Course.
|
||||
void enroll(Student student) {}
|
||||
// Does this Teacher teach the Course?
|
||||
boolean teaches(Course course) {
|
||||
return this.courses.has(course);
|
||||
}
|
||||
|
||||
// Effect: Removes a Course from this Teacher.
|
||||
// ASSUMES THIS TEACHER WILL BE REPLACED.
|
||||
void removeCourse(Course course) {
|
||||
this.courses = this.courses.dropFirst(course);
|
||||
}
|
||||
|
||||
// Is the Student in one or more of this Teacher's Courses?
|
||||
boolean dejavu(Student student) {
|
||||
return this.courses.moreMap(new StudentTakesCourse(student));
|
||||
}
|
||||
}
|
||||
|
||||
class Student {
|
||||
@@ -99,14 +244,53 @@ class Student {
|
||||
|
||||
// Effect: Enrolls this student in the given course.
|
||||
void enroll(Course course) {
|
||||
course.enroll(this);
|
||||
this.courses.uniqAppend(course);
|
||||
this.courses = this.courses.uniqAppend(course);
|
||||
course.addStudent(this);
|
||||
}
|
||||
|
||||
// Does the student take this course?
|
||||
boolean takesCourse(Course course) {
|
||||
return this.courses.has(course);
|
||||
}
|
||||
|
||||
// Are they in any of the same Courses as this Student?
|
||||
boolean classmates(Student student) {
|
||||
return this.courses.orMap(new StudentTakesCourse(student));
|
||||
}
|
||||
}
|
||||
|
||||
interface Question<A> {
|
||||
boolean ask(A a);
|
||||
}
|
||||
|
||||
class StudentTakesCourse implements Question<Course> {
|
||||
|
||||
Student student;
|
||||
|
||||
StudentTakesCourse(Student student) {
|
||||
this.student = student;
|
||||
}
|
||||
|
||||
public boolean ask(Course course) {
|
||||
return this.student.takesCourse(course);
|
||||
}
|
||||
}
|
||||
|
||||
interface ILo<A> {
|
||||
// Uniquely append an element (i.e., leaves list unchanged if element is already present.)
|
||||
ILo<A> uniqAppend(A a);
|
||||
|
||||
// Drop first instance of element from a list.
|
||||
ILo<A> dropFirst(A a);
|
||||
|
||||
// Does the list have this?
|
||||
boolean has(A a);
|
||||
|
||||
// Do any of the elements satisfy the predicate?
|
||||
boolean orMap(Question<A> question);
|
||||
|
||||
// Do more than one of the elements satisfy the predicate?
|
||||
boolean moreMap(Question<A> question);
|
||||
}
|
||||
|
||||
class Cons<A> implements ILo<A> {
|
||||
@@ -123,6 +307,23 @@ class Cons<A> implements ILo<A> {
|
||||
if (this.first.equals(a)) return this;
|
||||
else return new Cons<A>(this.first, this.rest.uniqAppend(a));
|
||||
}
|
||||
|
||||
public ILo<A> dropFirst(A a) {
|
||||
if (this.first.equals(a)) return this.rest;
|
||||
else return new Cons<A>(this.first, this.rest.dropFirst(a));
|
||||
}
|
||||
|
||||
public boolean has(A a) {
|
||||
return this.first.equals(a) || this.rest.has(a);
|
||||
}
|
||||
|
||||
public boolean orMap(Question<A> question) {
|
||||
return question.ask(this.first) || this.rest.orMap(question);
|
||||
}
|
||||
|
||||
public boolean moreMap(Question<A> question) {
|
||||
return question.ask(this.first) && this.rest.orMap(question);
|
||||
}
|
||||
}
|
||||
|
||||
class Mt<A> implements ILo<A> {
|
||||
@@ -130,4 +331,20 @@ class Mt<A> implements ILo<A> {
|
||||
public ILo<A> uniqAppend(A a) {
|
||||
return new Cons<A>(a, this);
|
||||
}
|
||||
|
||||
public ILo<A> dropFirst(A a) {
|
||||
throw new Error("Could not find element to drop in list.");
|
||||
}
|
||||
|
||||
public boolean has(A a) {
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean orMap(Question<A> question) {
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean moreMap(Question<A> question) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user