(* * * Module Proctoring defines the objects and operations related to a proctor * distributing and controlling test. * *) module Proctoring; from TestPackage import all; from StudentTestTool import all; export all; object AnsweredTestDirectory is FileDirectory description: (* The file directory where students' taken tests * should be saved. *); end AnsweredTestDirectory; object AdditionalTime is integer description: (* The number of minutes a proctor may add to * students' testing sessions. *); end AdditionalTime; object DirectoryPath is string description: (* The string representation of the file path * of a file directory. *); end DirectoryPath; object TakenTestFile is File description: (* A file that stores the data of a taken test. *); end TakenTestFile; (* NOTE: FileData should really be "TakenTest" but * by doing so it really messes up the heirarchy generated * by rls-doc -- putting everything under TakenTest under * AnsweredTestDirectory. *) object FileData is string description: (* The data of a file. Should be a TakenTest... *); end FileData; object File is components: fd:FileData; description: (* A file in the file system which * contains a name and data. *); end File; object FileDirectory is components: fs:File* and dp:DirectoryPath; description: (* A directory or folder in the file system. *); end FileDirectory; operation DistributeTest is inputs: tt:TakenTest, atd:AnsweredTestDirectory; outputs: ts':TestSession*; precondition: (* Test must not be nil. * Directory must have a valid path. *) (tt != nil) and (atd.dp != nil) ; postcondition: (* Each test session must have the input test. * Each test session must start unpaused and unfinished. * Each test session starts with the time on the test. *) forall (t in ts') ( (t.tt = tt) and (t.ip = false) and (t.itf = false) and (t.tr = tt.tt) ); (* "TestSession.TimeRemaining = TakenTest.TotalTime" *) description: (* Distributes a blank "taken test" to all the * students' computers on the LAN. *); end DistributeTest; operation PauseResumeStudentTest is inputs: ts:TestSession; outputs: ts':TestSession; precondition: (ts != nil); postcondition: if (ts.ip = false) then ts.ip = true else ts.ip = false; description: (* Pauses a test if it's not paused. Resumes a test * if it is paused. *); end PauseStudentTest; operation StopStudentTest is inputs: ts:TestSession; outputs: ts':TestSession; precondition: ts.itf = false; postcondition: ts.itf = true; description: (* Stops a test session. Finishes (submits) the test * of that session. *); end StopStudentTest; operation AddAdditionalTime is inputs: ts:TestSession* and at:AdditionalTime; outputs: ts':TestSession*; precondition: forall (t in ts) t.tt != nil; postcondition: forall (t in ts) if (t.itf = false) then t.tr = t.tr + at; description: (* Adds additional time to each student's testing session. *); end AddAdditionalTime; operation SaveTakenTest inputs: ts:TestSession and atd:AnsweredTestDirectory; outputs: ttf:TakenTestFile and atd':AnsweredTestDirectory; precondition: (* The test must exist to be saved. * The test session must be finished. * Must have valid directory. *) (ts.tt != nil) and (ts.itf = true) and (atd != nil); postcondition: (* The taken test file data must be the taken test. * The directory must contain the input taken test. (ttf.fd = ts.tt) and exists (f in atd'.fs) f.fd = ts.tt *); description: (* Saves a student's taken test to the specified file directory. *); end SaveTakenTests; end Proctoring;