Updated Registrar.
This commit is contained in:
@@ -9,6 +9,30 @@ class Examples {
|
|||||||
new Cons<Integer>(2, new Cons<Integer>(3, new Mt<Integer>()))
|
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) {
|
void testILoUniqAppend(Tester t) {
|
||||||
t.checkExpect(testList.uniqAppend(2), testList);
|
t.checkExpect(testList.uniqAppend(2), testList);
|
||||||
t.checkExpect(
|
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 {
|
class School {
|
||||||
@@ -46,7 +154,7 @@ class Course {
|
|||||||
Course(String name, Teacher teacher, ILo<Student> students) {
|
Course(String name, Teacher teacher, ILo<Student> students) {
|
||||||
this.name = name;
|
this.name = name;
|
||||||
this.teacher = teacher;
|
this.teacher = teacher;
|
||||||
this.teacher.assignCourse(this);
|
teacher.assignCourse(this);
|
||||||
this.students = students;
|
this.students = students;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -54,6 +162,29 @@ class Course {
|
|||||||
Course(String name, Teacher teacher) {
|
Course(String name, Teacher teacher) {
|
||||||
this(name, teacher, new Mt<Student>());
|
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 {
|
class Teacher {
|
||||||
@@ -73,11 +204,25 @@ class Teacher {
|
|||||||
|
|
||||||
// Effect: Assigns the given Course to this Teacher.
|
// Effect: Assigns the given Course to this Teacher.
|
||||||
void assignCourse(Course course) {
|
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.
|
// Does this Teacher teach the Course?
|
||||||
void enroll(Student student) {}
|
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 {
|
class Student {
|
||||||
@@ -99,14 +244,53 @@ class Student {
|
|||||||
|
|
||||||
// Effect: Enrolls this student in the given course.
|
// Effect: Enrolls this student in the given course.
|
||||||
void enroll(Course course) {
|
void enroll(Course course) {
|
||||||
course.enroll(this);
|
this.courses = this.courses.uniqAppend(course);
|
||||||
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> {
|
interface ILo<A> {
|
||||||
// Uniquely append an element (i.e., leaves list unchanged if element is already present.)
|
// Uniquely append an element (i.e., leaves list unchanged if element is already present.)
|
||||||
ILo<A> uniqAppend(A a);
|
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> {
|
class Cons<A> implements ILo<A> {
|
||||||
@@ -123,6 +307,23 @@ class Cons<A> implements ILo<A> {
|
|||||||
if (this.first.equals(a)) return this;
|
if (this.first.equals(a)) return this;
|
||||||
else return new Cons<A>(this.first, this.rest.uniqAppend(a));
|
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> {
|
class Mt<A> implements ILo<A> {
|
||||||
@@ -130,4 +331,20 @@ class Mt<A> implements ILo<A> {
|
|||||||
public ILo<A> uniqAppend(A a) {
|
public ILo<A> uniqAppend(A a) {
|
||||||
return new Cons<A>(a, this);
|
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