object File components: name:FileName and permissions:FilePermissions and file_type:FileType and size:FileSize and data:FileData; description: (* A File is an abstraction of a file stored in the file space. It has a name, permissions, type, and data. These are the components sufficient to specify the behavior of EasyGrader file operations. *); end File; object FileName = string description: (* The name of a file. The string representation here is an abstraction of file names used in specific operating environments. Implementations may obey any syntactic or semantic constraints imposed by a particular environment. *); end; object FileSpace = File* description: (* A FileSpace is an abstract model of a file space in the operating environment in which the EasyGrader is run. The FileSpace is simply a collection of zero or more Files, with no other properties modeled here. *); end; object FilePermissions = is_readable:IsReadable and is_writable:IsWritable description: (* FilePermissions indicate whether a file is readable and/or writable. *); end; object IsReadable = boolean description: (* Flag indicating whether a file is readable, which is required to be true by the FileOpen operation. *); end; object IsWritable = boolean description: (* Flag indicating whether a file is writable, which is required to be true by the FileSave operation. *); end; object FileType = gradebook_type:GraderType or other_type:OtherType description: (* The type of file data is either GraderType data, TemplateType data , or any other type of data. *); end FileType; object GraderType description: (* File data typing tag indicating that a file contains grader data created by the grader Tool. *); end GraderType; object OtherType description: (* File data typing tag indicating that a file contains data other than grader data created by the EasyGrader. *); end OtherType; object FileSize = integer description: (* The size in megabytes of a file. *); end FileSize; object FileData = Gradebook description: (* The abstract representation of grader-type FileData is a Gradebook object. EasyGrader implementors may use any concrete file data representation that accurately holds all Gradebook components. *); end FileData; operation new inputs: eg:EasyGrader; outputs: eg':EasyGrader; description: (* Add a new empty Gradebook to the EasyGrader. *); precondition: ; postcondition: (exists (gb:Gradebook) (gb.sections = nil) and (gb = eg'.gradebooks[1]) and (gb.items = nil) and (gb.FinalGrade = nil) and (gb.name = nil) and (gb.sortedByItem = nil) and (gb.curve = nil) and (gb.userCredentials = nil)); end new; operation open inputs: fs:FileSpace, fn:FileName, eg:EasyGrader; outputs: eg':EasyGrader; precondition: (* * file extension is correct * file is readable * file name is right *) (exists (file in fs) (file.name = fn) and file.permissions.is_readable and file.file_type?.gradebook_type ); postcondition: (exists (gb:Gradebook) (gb = eg'.gradebooks[1]) and (exists (file in fs) (file.name = fn) and (gb = file.data) ) and (forall (i:integer | (i >= 2) and (i <= #(eg.gradebooks))) eg'.gradebooks[i+1] = eg.gradebooks[i+1] ) ); description: (* Reads from a .egb file and set it up as a gradebook *); end open; operation save inputs: fs:FileSpace, eg:EasyGrader; outputs: fs':FileSpace, eg':EasyGrader; precondition: (exists (file in fs) (file.name = eg.gradebooks[1].filename) and (file.data != eg.gradebooks[1]) and (file.permissions.is_writable)); postcondition: (* * Current Gradebook is saved *) (exists (file in fs') (file.name = eg'.gradebooks[1].filename) and (file.data = eg'.gradebooks[1]) and (file.permissions.is_writable) and (file.file_type?.gradebook_type) ); description: (* * Write the current gradebook into a file; * Replace the older file; *); end save; operation saveAs inputs: fs:FileSpace, eg:EasyGrader, filename:string; outputs: fs':FileSpace, eg':EasyGrader; precondition: (not exists (file in fs) (file.name = eg.gradebooks[1].filename) and (file.data != eg.gradebooks[1]) and (file.permissions.is_writable)); postcondition: (* * Current Gradebook is saved *) (exists (file in fs') (filename = eg'.gradebooks[1].filename) and (file.data = eg'.gradebooks[1]) and (file.permissions.is_writable) and (file.file_type?.gradebook_type) ); description: (* * Write the current gradebook into a file on the specified path; * Prompt to replace file if the file name exists; *); end saveAs; operation dlRoster inputs: c:Credentials; outputs: gb:Gradebook; precondition: (* * The Credentials are correct and no fields are left blank to first * connect to SIS. *) (c.userName != nil) and (c.password != nil) and (c.server != nil); postcondition: ; description: (* * The instructor downloads the roster to create a Gradebook. *); end dlRoster; operation syncRoster inputs: gb:Gradebook, c:Credentials; outputs: gb':Gradebook; precondition: (* * The Credentials are correct and no fields are left blank to first connect to SIS. * Displays the current and updated roster. * For all students not on the updated roster, their names are in * red on the current roster. For all students not on the current * roster, their names are in red on the updated roster. *) ((c.userName != nil) and (c.password != nil) and (c.server != nil)); postcondition: (* The instructor has an updated roster *); description: (* * The current roster and the updated roster from SIS are available for the instructor to compare. * This is used for the instructor to add new students from the updated roster, drop old students from the * old roster, or keep students the instructor personally added that the updated roster does not have. *); end syncRoster; operation merge inputs: fs:FileSpace, fn:FileName*, eg:EasyGrader; outputs: eg':EasyGrader; precondition: (* * file extension is correct * files are readable * file names are right *) (forall (i: integer | (i >= 1) and (i <= #fn)) (exists (file in fs) (file.name = fn[i]) and file.permissions.is_readable and file.file_type?.gradebook_type ) ); postcondition: (exists (gb:Gradebook) (gb = eg'.gradebooks[1]) and (forall (j:integer | (j >= 1) and (j <= #fn)) (exists (file in fs) (file.name = fn[j]) (* file.data is element of gb*) ) ) and (forall (k:integer | (k >=2) and (k <= #(eg.gradebooks))) eg'.gradebooks[k+1] = eg.gradebooks[k+1] ) ); description: (* Reads from multiple .egb files and set it up as one single gradebook *); end merge; operation submitGrades inputs: gb:Gradebook, c:Credentials; outputs: gb':Gradebook; precondition: (* The Credentials are correct and no fields are left blank *) ((c.userName != nil) and (c.password != nil) and (c.server != nil)); postcondition: ; description: (* Students' final grades are uploaded to the SIS server. *); end submitGrades; operation post_grades inputs: c:Credentials; outputs: gb':Gradebook; precondition: (* The Credentials are correct and no fields are left blank *) (c.userName != nil) and (c.password != nil) and (c.server != nil); postcondition: ; description: (* * The current gradebook in focus in uploaded to department server. *); end post_grades; operation fetch inputs: c:Credentials; outputs: eg':EasyGrader; precondition: (* The Credentials are correct and no fields are left blank *) (c.userName != nil) and (c.password != nil) and (c.server != nil); postcondition: (* For each roster downloaded, a Gradebook is created *) (exists (gb:Gradebook) (gb = eg'.gradebooks[1]) and (forall (i:integer | (i >= 2) and (i <= #(eg.gradebooks))) eg'.gradebooks[i+1] = eg.gradebooks[i+1] ) ); description: (* * Creates a Gradebook for each roster that is downloaded. *); end fetch; operation pageSetup inputs: ps:PageSetup; outputs: ps':PageSetup; precondition: (* * ps:PageSetup is the previous PageSetup being passed in. *); postcondition: (* * The user changes the old page setup and save it. *) (ps = ps'); description: (* Sets up the printer settings *); end pageSetup; operation printPreview inputs: gb:Gradebook; outputs: gb':Gradebook; precondition: ; postcondition: (* Nothing is changed in preview *) (gb = gb'); description: (* * Preview for the printed format of the Gradebook *); end printPreview; operation print inputs: gb:Gradebook; outputs: gb':Gradebook; precondition: ; postcondition: ; description: (* * Prints the current Gradebook *); end print;