(**** * * Module QuestionManagement defines the objects and operations related to managing * a question database including adding, deleting, and editing questions. * *) module QuestionManagement; export all; object QuestionDatabase is components: qs:Question* and FileName; description: (* QuestionDatabase is a collection of questions that may be added to, deleted from or edited using the QuestionManager *); end QuestionDatabase; object FileName is components: string; description: (* FileName the string that stores the value for where the question database is stored. *); end FileName; object Question is components: t:Type and qt:QuestionText* and qa:QuestionAnswer and time:Time and author:Author and diff:Difficulty and keywords:Keyword* and class:Class and lu:LastUsed; description: (* Question is the object where all the information in a question is stored, the type object defines how to parse QuestionText and Question Answer. A test is composed of several Questions. *); end Question; object Type is components: integer; description: (* Type is the integer that defines what kind of question this is, in other words, is it Mult. Choice, T/F, Fill in the blank.... *); end Type; object QuestionText is components: string; description: (* QuestionText is the text for the actual question, for each type of question this may need to be parsed differently because there are more than one question text fields. *); end QuestionText; object QuestionAnswer is string; object Time is components: integer; description: (* Time is the number of seconds that the user has specified for a particular question. *); end Time; object Author is components: string; description: (* Author is the string representing who wrote the question. *); end Author; object Difficulty is components: integer; description: (* Difficulty is the number the user specified to indicate how difficult the problem is. *); end Difficulty; object Keyword is components: string; description: (* Keyword is the word or words that the user entered for the keywords in a question. *); end Keyword; object Class is components: string; description: (* Class is the string indicating which class the question is for. *); end Class; object LastUsed is components: integer; description: (* LastUsed is the string indicating when the question was last used on a test. *); end LastUsed; object ClassDB is components: Class*; description: (* The collection of Classes that are displayed in the drop down menu *); end ClassDB; operation AddQuestion is inputs: q:Question, qdb:Question*; outputs: qdb':Question*; precondition: (* * the new question is not exactly the same as any of the existing questions *) forall (x in qdb) NotEqual(q, x); postcondition: (* * A question is in the oputput database if and only if it is in the input database or it is the new question *) forall (x in qdb') (x in qdb) iff ((x = q) or (x in qdb)); description: (* This operation adds the specified question to the question database and ONLY that question, nothing else changes about the question database. *); end AddQuestion; function NotEqual(q1:Question, q2:Question) = (* * This function returns true if the true questions are not EXACTLY the same *) (q1.qt != q2.qt) and (q1.qa != q2.qa) and (q1.t != q2.t) and (q1.time != q2.time) and (q1.author != q2.author) and (q1.diff != q2.diff)and (q1.class != q2.class) and (q1.keywords != q2.keywords); operation DeleteQuestion is inputs: q:Question, qdb:Question*; outputs: qdb':Question*; precondition: (* * q exists in qdb *) exists (x in qdb) Equal(x,q); postcondition: (* * qbd' is the same as qdb except that q is no longer in it *) forall (x in qdb') (x in qdb) and NotEqual(x,q); description: (* This operation removes the given Question from the given QuestionDatabase. *); end DeleteQuestion; function Equal(q1:Question, q2:Question) = (* * This function returns true if the true questions are EXACTLY the same *) (q1.qt = q2.qt) and (q1.qa = q2.qa) and (q1.t = q2.t) and (q1.time = q2.time) and (q1.author = q2.author) and (q1.diff = q2.diff)and (q1.class = q2.class) and (q1.keywords = q2.keywords); operation AddClass is inputs: c:Class, cdb:Class*; outputs: cdb':Class*; precondition: (* * c must not already exist in cdb *) forall (x in cdb) x != c; postcondition: (* * c must exist in cdb' and everything else from cdb should be in cdb' too *) forall (x in cdb) (x in cdb') or (x = c); description: (* This operation adds the given Class to the Class database. *); end AddClass; operation DeleteClass is inputs: c:Class, cdb:Class*; outputs: cdb':Class*; precondition: (* * c must exist in cdb already *) exists (x in cdb) x = c; postcondition: (* * c must not exist in cdb' and however everything else from cdb should *) forall (x in cdb') (x in cdb) and (x != c); description: (* This operation removes the given Class from the Class database. *); end AddClass; operation SearchDB is inputs: s:string, qdb:Question*; outputs: qdb':Question*; precondition:(* * no preconditions....s may be anything and qdb may be anything including empty *); postcondition: (* * qbd' only contains questions which contain s as a substring in any of its fields *) (* * Not so sure how to do the substring issue here..... *); description: (* This operation searches the given QuestionDatabase for the given string, all questions in the output Question database contain the string in at least one of their values. *); end SearchDB; operation EditQuestionText is inputs: qt:QuestionText*, q:Question; outputs: q':Question; precondition:(* * To edit the question text there is no precondition all fields may be empty. *); postcondition:(* * q' is the same as q except that q.qt is now equal to qt *) (q.t = q'.t) and (q.qa = q'.qa) and (q.time = q'.time) and (q.author = q'.author) and (q.diff = q'.diff) and (q.keywords = q'.keywords) and (q.class = q'.class) and (q.lu = q'.lu) and (qt = q'.qt); description: (* This operation replaces the QuestionText of the given Question with the given QuestionText. *); end EditQuestionText; operation EditQuestionAnswer is inputs: qa:QuestionAnswer, q:Question; outputs: q':Question; precondition: (* * To edit the question answer there is no precondition all fields may be empty. *); postcondition: (* * q' is the same as q except that q.qa is now equal to qa *) (q.t = q'.t) and (qa = q'.qa) and (q.time = q'.time) and (q.author = q'.author) and (q.diff = q'.diff) and (q.keywords = q'.keywords) and (q.class = q'.class) and (q.lu = q'.lu) and (q.qt = q'.qt); description: (* *This operation replaces the QuestionAnswer of the given Question with the given QuestionAnswer. *); end EditQuestionAnswer; operation EditQuestionTime is inputs: time:Time, q:Question; outputs: q':Question; precondition: (* * To edit the time there is no precondition all fields may be empty. *); postcondition: (* * q' is the same as q except that q.time is now equal to time *) (q.t = q'.t) and (q.qa = q'.qa) and (time = q'.time) and (q.author = q'.author) and (q.diff = q'.diff) and (q.keywords = q'.keywords) and (q.class = q'.class) and (q.lu = q'.lu) and (q.qt = q'.qt); description: (* This operation replaces the Timeof the given Question with the given Time. *); end EditQuestionTime; operation EditQuestionAuthor is inputs: author:Author, q:Question; outputs: q':Question; precondition: (* * To edit the author there is no precondition all fields may be empty. *); postcondition: (* * q' is the same as q except that q.author is now equal to author *) (q.t = q'.t) and (q.qa = q'.qa) and (q.time = q'.time) and (author = q'.author) and (q.diff = q'.diff) and (q.keywords = q'.keywords) and (q.class = q'.class) and (q.lu = q'.lu) and (q.qt = q'.qt); description: (* This operation replaces the Authorof the given Question with the given Author. *); end EditQuestionAuthor; operation EditQuestionDifficulty is inputs: diff:Difficulty, q:Question; outputs: q':Question; precondition: (* * To edit the difficulty there is no precondition all fields may be empty. *); postcondition: (* * q' is the same as q except that q.diff is now equal to diff *) (q.t = q'.t) and (q.qa = q'.qa) and (q.time = q'.time) and (q.author = q'.author) and (diff = q'.diff) and (q.keywords = q'.keywords) and (q.class = q'.class) and (q.lu = q'.lu) and (q.qt = q'.qt); description: (* This operation replaces the Difficultyof the given Question with the given Difficulty. *); end EditQuestionDifficulty; operation EditQuestionKeywords is inputs: keywords:Keyword*, q:Question; outputs: q':Question; precondition: (* * To edit the keywords there is no precondition all fields may be empty. *); postcondition: (* * q' is the same as q except that q.keywords is now equal to qa *) (q.t = q'.t) and (q.qa = q'.qa) and (q.time = q'.time) and (q.author = q'.author) and (q.diff = q'.diff) and (keywords = q'.keywords) and (q.class = q'.class) and (q.lu = q'.lu) and (q.qt = q'.qt); description: (* This operation replaces the Keywordof the given Question with the given Keyword. *); end EditQuestionKeyword; operation EditQuestionClass is inputs: class:Class, q:Question; outputs: q':Question; precondition: (* * To edit the class there is no precondition all fields may be empty. *); postcondition: (* * q' is the same as q except that q.class is now equal to class *) (q.t = q'.t) and (q.qa = q'.qa) and (q.time = q'.time) and (q.author = q'.author) and (q.diff = q'.diff) and (q.keywords = q'.keywords) and (class = q'.class) and (q.lu = q'.lu) and (q.qt = q'.qt); description: (* This operation replaces the Classof the given Question with the given Class. *); end EditQuestionClass; operation EditQuestionLastUsed is inputs: lu:LastUsed, q:Question; outputs: q':Question; precondition: (* * To edit last used there is no precondition all fields may be empty. *); postcondition: (* * q' is the same as q except that q.lu is now equal to lu *) (q.t = q'.t) and (q.qa = q'.qa) and (q.time = q'.time) and (q.author = q'.author) and (q.diff = q'.diff) and (q.keywords = q'.keywords) and (q.class = q'.class) and (lu = q'.lu) and (q.qt = q'.qt); description: (* This operation replaces the LastUsed of the given Question with the given LastUsed. *); end EditQuestionLastUsed ; operation SortQuestion is inputs: qdb:Question*; outputs: qdb':Question*; precondition:(* * qdb must have at least 2 questions in it *) #qdb >= 2; postcondition:(* * The questions are in order based on the question text field *) forall (i:integer | (i>=1) and (i <#qdb)) (qdb[i].qt <= qdb[i+1].qt); description: (* This operation will sort the Database by the Question text field *); end SortQuestion; operation SortClass is inputs: qdb:Question*; outputs: qdb':Question*; precondition:(* * qdb must have at least 2 questions in it *) #qdb >= 2; postcondition:(* * The questions are in order based on the class field *) forall (i:integer | (i>=1) and (i <#qdb)) (qdb[i].class <= qdb[i+1].class); description: (* This operation will sort the Database by the Class text field *); end SortClass; operation SortAuthor is inputs: qdb:Question*; outputs: qdb':Question*; precondition:(* * qdb must have at least 2 questions in it *) #qdb >= 2; postcondition:(* * The questions are in order based on the author field *) forall (i:integer | (i>=1) and (i <#qdb)) (qdb[i].author <= qdb[i+1].author); description: (* This operation will sort the Database by the Author text field *); end SortAuthor; operation SortType is inputs: qdb:Question*; outputs: qdb':Question*; precondition:(* * qdb must have at least 2 questions in it *) #qdb >= 2; postcondition:(* * The questions are in order based on the type field *) forall (i:integer | (i>=1) and (i <#qdb)) (qdb[i].t <= qdb[i+1].t); description: (* This operation will sort the Database by the Type text field *); end SortType; operation SortTime is inputs: qdb:Question*; outputs: qdb':Question*; precondition:(* * qdb must have at least 2 questions in it *) #qdb >= 2; postcondition:(* * The questions are in order based on the time field *) forall (i:integer | (i>=1) and (i <#qdb)) (qdb[i].time <= qdb[i+1].time); description: (* This operation will sort the Database by the Time text field *); end SortTime; operation SortDifficulty is inputs: qdb:Question*; outputs: qdb':Question*; precondition:(* * qdb must have at least 2 questions in it. *) #qdb >= 2; postcondition:(* * The questions are in order based on the difficulty field. *) forall (i:integer | (i>=1) and (i <#qdb)) (qdb[i].diff <= qdb[i+1].diff); description: (* This operation will sort the Database by the Difficulty text field *); end SortDifficulty; operation SortKeywords is inputs: qdb:Question*; outputs: qdb':Question*; precondition:(* * qdb must have at least 2 questions in it. *) #qdb >= 2; postcondition:(* * The questions are in order based on the keywords field. *) forall (i:integer | (i>=1) and (i <#qdb)) (qdb[i].keywords <= qdb[i+1].keywords); description: (* This operation will sort the Database by the Keywords text field *); end SortKeywords; end QuestionManagement;