(* * Author: Michael Shelley *) object Student is components: stuName:StudentName and stuID:StudentID and EMPLID and GraderID and PhoneNumber and EmailAddress and Notes and gilist:StudentGI*, totalpts:Total; description: (* A Student represents an individual unique member of the Class they are contained in. The StudentName component is the alphabetical name of the student as given to the teacher by the school's student information/administration department (SIS). The StudentID component in this case is the Student's Cal Poly UNIX username, for other instituitions the StudentID would be the institutional issued unique identifier. The GraderID component is a five-digit integer chosen randomly by the grader tool from the interval (00000, 99999). The PhoneNumber component is the Student's telephone number as given to the teacher by the school's student information/administration department (SIS). The EmailAddress component is the Student's electronic mailing address as given to the teacher by the school's student information/administration department (SIS). The Note component holds any additional textual descriptions/information/reminders/markups otherwise not accounted for in the components above. *); end Student; object StudentName is string; object StudentID is string; object EMPLID is integer; object GraderID is integer; object PhoneNumber is string; object EmailAddress is string; object Notes is string; object SISRoster is Student*; object RosterDiffs is Student*; operation AddStudent is description: (* Adds a new student to the input Class. A new student cannot have the same StudentID as an existing Student in the input Class. *); inputs: cls:Class, stu:Student; outputs: cls':Class; precondition: (* * The StudentName of the given Student is not empty. *) (stu.stuName != nil) and (* * The StudentID of the given Student is not empty. *) (stu.stuID != nil) and (* * There is no Student in the input Class with the same StudentID as the record to be added. *) (not (exists (stu' in cls.stus) stu'.stuID = stu.stuID)); postcondition: (* * A student is in the output cls if and only if it is the new * student to be added or it is in the input class. *) forall (stu':Student) (stu' in cls'.stus) iff ((stu' = stu) or (stu' in cls.stus)); end AddStudent; operation EditStudent is description: (* Modifies an existing student in the input Class. If the StudentID is changed to a StudentID already present in the input Class the modification is rejected. *); inputs: cls:Class, stuOld:Student, stuNew:Student; outputs: cls':Class; precondition: (* * The old Student and the new Student are not the same. *) (stuOld != stuNew) and (* * The old student is in the given Class. *) (stuOld in cls.stus) and (* * The StudentName of the new Student is not empty. *) (stuNew.stuName != nil) and (* * The StudentID of the new Student is not empty. *) (stuNew.stuID != nil); postcondition: (* * A Student is in the output Class if and only if it is the new * Student to be added or it is in the input Class and it is not * the old record. *) forall (stu':Student) (stu' in cls'.stus) iff (((stu' = stuNew) or (stu' in cls.stus)) and (stu' != stuOld)); end EditStudent; operation DeleteStudent is description: (* Delete the given Student from the input class. The given student must already be in the input class. *); inputs: cls:Class, stu:Student; outputs: cls':Class; precondition: (* * The given Student is in the given Class. *) (stu in cls.stus); postcondition: (* * A Student is in the output Class if and only if it is not the * Student to be deleted and it is in the input Class. *) forall (stu':Student) ((stu' in cls'.stus) iff ((stu' != stu) and (stu' in cls.stus))); end DeleteStudent; operation Synchronize is description: (* Synchronize the active Class's roster with the roster obtained from Student Information Services (SIS). *); inputs: cls:Class, SISRstr:SISRoster; outputs: cls':Class, rstrDiffs:RosterDiffs; precondition: (* * cls is not an empty Class and SISRstr is not empty. *) ((#(cls.stus)) > 0) and ((#(SISRstr)) > 0); postcondition: (* * A student is in rstrDiffs if and only if the student isn't * found in SISRstr. A student is in cls' * if and only if they were in cls or the SISRstr. *) forall(stu:Student) (stu in rstrDiffs) iff not( exists(str:Student) exists(str in SISRstr) str = stu) and forall (stu:Student) ((stu in cls'.stus) iff (stu in cls.stus) and (stu in SISRstr)); end Synchronize; operation Preserve is description: (* * Removes the Student(s) from the Student RosterDiffs list. *); inputs: stus:Student*, rstrDiffs:RosterDiffs; outputs: rstrDiffs':RosterDiffs; precondition: (* * rstrDiffs is not an empty Student list. *) (#(rstrDiffs) > 0); postcondition: (* * A student is in rstrDiffs' if and only if they were in * rstrDiffs and their StudentID does not equal * stus[n].StudentID *) forall (stu:Student) (stu in rstrDiffs') iff ( not( exists(str:Student) exists(str in stus) str = stu)); end Preserve; operation ShowStuInfo is description: (* * Adds a Student "Information" column to the Gradebook that * displays Student info found in the add/edit Student dialogs *); inputs: cls:Class; outputs: cls':Class; precondition: (* * cls is not an empty class. *) ((#(cls.stus) > 0)); end ShowStuInfo;