(****** * This file defines objects and operation in the ITEM menu * * *) (* Operations from the Item menu *) module Item; from Gradesheet import GradeSheet, Column, Title; object TypeDataItem; object TypeGradedItem; object ColumnType is TypeDataItem or TypeGradedItem; operation AddNewItem is inputs: gs:GradeSheet, co:Column, ctp:ColumnType, ti:Title, tdi:TypeDataItem, tgi:TypeGradedItem; outputs: gs':GradeSheet; precondition: (* There is a title and it does not already exist in the gradesheet*) ti != nil and (not(exists(ti' in gs.columnlist) ti = ti')) (* The column is either a Graded Item or a Data Item *) and (ctp = tdi or ctp = tgi) (* If a Graded Item, the maximum score must be 0 or positive *) and (if(ctp = tgi) then (co.maxscore >= 0)) (* If a graded item, the weight must be between 0 and 1 inclusive *) and (if(ctp = tgi) then (co.weight >= 0)) and (if(ctp = tgi) then(co.weight <= 1)) (* If a data item, weight and maxscore are disabled, represented as a sentinel (-1) *) and (if (ctp = tdi) then (co.weight = -1 and co.maxscore = -1)) (* If there are subcolumns, maxscore is disabled *) and (if(#(co.columnlist) != 0) then (co.maxscore = -1)); postcondition: (* The only columns in the gradesheet were either already there, or the column being added *) forall(co': Column)(co' in gs'.columnlist) iff ((co' = co) or (co' in gs.columnlist)); description: (* The user adds a new column to the gradesheet. There must be a unique non-emtpy title, and the only change to the gradesheet is that the new, acceptable item is added *) ; end AddNewItem; operation EditItem is inputs: gs:GradeSheet, old_co:Column, new_co:Column, ctp:ColumnType, ti:Title, tdi:TypeDataItem, tgi:TypeGradedItem; outputs: gs':GradeSheet; precondition: (* new column is not the same as the old column *) (old_co != new_co) (* the old column is in the gradesheet *) and (old_co in gs) (* there is no column in the gradesheet with the same title as the new one *) and (not exists(new_co' in gs)(new_co'.title = new_co.title)) (* The column is either a Graded Item or a Data Item *) and (ctp = tdi or ctp = tgi) (* If a Graded Item, the maximum score must be 0 or positive *) and (if(ctp = tgi) then (new_co.maxscore >= 0)) (* If a graded item, the weight must be between 0 and 1 inclusive *) and (if(ctp = tgi) then (new_co.weight >= 0)) and (if(ctp = tgi) then(new_co.weight <= 1)) (* If a data item, weight and maxscore are disabled, represented as a sentinel (-1) *) and (if (ctp = tdi) then (new_co.weight = -1 and new_co.maxscore = -1)) (* If there are subcolumns, maxscore is disabled *) and (if(#(new_co.columnlist) != 0) then (new_co.maxscore = -1)); postcondition: (* column is in the gradesheet only if it was already in the gradesheet, except for the old column, which is replaced by the new column *) forall(co' :Column)(co' in gs'.columnlist) iff ((co' = new_co) or ((co' in gs.columnlist) and (co' != old_co))); description: (* User must select column from editable column list. The old column must already be in the Gradesheet. Change the given old column to the new one. *); end EditItem; operation DeleteItem is inputs: gs:GradeSheet, co:Column; outputs: gs':GradeSheet; precondition: (co in gs); postcondition: (* column is in the gradesheet only if it was already in the gradesheet, and is not the column removed *) forall(co' : Column)(co' in gs'.columnlist) iff ((co' in gs.columnlist) and (co' != co)); description: (* User must select column from deletable column list. The column to be deleted must already be in the Gradesheet. All columns that are subcolumns of the column to be deleted will also be removed. *); end DeleteItem; end Item;