(* describes the student related portion of testtool *)
module Student;
from Question import QuestionDB, Question, TestQuestion, AnsweredQuestion, GradedQuestion, QuestionNumber;
from Test import Test, TakenTest, TestTime, Difficulty, TotalPoints, TestName;
export Student, TestServer, GradesServer;
(* 'students present' table in administer tools *)
object StudentsPresentTable is
components: studentlist:Student*;
description: (*
The students present table is a collection of Students. Each student takes 1 row of the table.
*);
end StudentsPresentTable;
object Student is
components: studentname:StudentName, studentid:StudentID, studentpassword:StudentPassword;
description: (*
A Student object represents a student. Consists of a Name, ID, and password unique to every student.
*);
end Student;
object StudentName is string;
object StudentID is string;
object StudentPassword is string;
operation StudentBeginsTest is
inputs: spt:StudentsPresentTable, s:Student;
outputs: spt':StudentsPresentTable;
precondition: (* student enters the testing environment *);
postcondition: (* output table consists of every student present in input table + entering student,
sorted by student ID *)
(spt' = spt + s)
and
(forall (i:integer | (i >= 1) and ( i < #(spt'.studentlist)))
spt'.studentlist[i].studentid < spt'.studentlist[i+1].studentid);
end StudentBeginsTest;
(* administration: starting and extending test time management details *)
object TimeRemaining is integer;
object TimeExtension is integer;
operation BeginTest is
inputs: test:Test;
outputs: tr:TimeRemaining;
precondition: ;
postcondition: (tr = test.testtime);
end BeginTest;
operation ExtendTime is
inputs: tr:TimeRemaining, te:TimeExtension;
outputs: tr':TimeRemaining;
precondition: ((tr > 0) and (te > 0));
postcondition: (tr' = tr + te);
end ExtendTime;
(* Students log in to take test*)
operation StudentLogin is
inputs: s:TestServer, studentid:StudentID, studentpassword:StudentPassword;
outputs: test:Test;
precondition: exists (stu in s.studentlist) (stu.studentid = studentid) and (stu.studentpassword = studentpassword);
postcondition: (test = s.test);
description: (*
Login to the server to access test. If the students' username and password
exist in the server's user list, return test, otherwise nil.
*);
end StudentLogin;
object TestServer is
components: studentlist:Student*, test:Test;
description: (*
A test server consists of a list of authentic users and a test. Access to the server
must be granted to take a test.
*);
end TestServer;
(* Students log in to check test results *)
operation StudentGradesLogin is
inputs: s:GradesServer, studentid:StudentID, studentpassword:StudentPassword;
outputs: tests:Test*;
precondition: exists (stu in s.studentlist) (stu.studentid = studentid) and (stu.studentpassword = studentpassword);
postcondition: (tests = s.tests);
description: (*
Login to the server to access grades. If the students' username and password exist
in the server's user list, returns the graded tests associated with that student.
*);
end StudentGradesLogin;
object GradesServer is
components: studentlist:Student*, tests:Test*;
description: (*
The grades server consists of a list of authentic users and the graded tests accosiated with those
users. Access to the server must be granted to view any graded material.
*);
end GradesServer;
(* question navigation in seperate questions view mode *)
object CurrentQuestion is integer;
operation NavBeginningOfTest is
inputs:;
outputs: cq:CurrentQuestion;
precondition:;
postcondition: (cq = 1);
end NavBeginningOfTest;
operation NavPrev is
inputs: cq:CurrentQuestion;
outputs: cq':CurrentQuestion;
precondition: (cq > 1);
postcondition: (cq' = cq - 1);
end NavPrev;
operation NavNext is
inputs: test:Test, cq:CurrentQuestion;
outputs: cq':CurrentQuestion;
precondition: (cq < #(test.testquestionlist));
postcondition: (cq' = cq - 1);
end NavNext;
operation NavEndOfTest is
inputs: test:Test;
outputs: cq:CurrentQuestion;
precondition:;
postcondition: (cq = #(test.testquestionlist));
end NavEndOfTest;
(* student responce and test submission *)operation AnswerQuestion is
inputs: tq:TestQuestion;
outputs: aq:AnsweredQuestion;
precondition: (* Student enters an answer *);
postcondition: (* aq.response = student input *);
end AnswerQuestion;
operation SubmitTest is
inputs: test:Test, answeredquestionlist:AnsweredQuestion*;
outputs: takentest:TakenTest;
precondition: (* for all AnsweredQuestion objects, question numbers must match test question numbers *)
(forall (i:integer | (i >= 1) and ( i < #(answeredquestionlist)))
answeredquestionlist[i].questionnumber = test.testquestionlist[i].questionnumber);
postcondition: (* test names are the same, total points are the same, difficulty is the same, and
every question in the TakenTest has the same question number as in the Test *)
(takentest.testname = test.testname)
and (takentest.totalpoints = test.totalpoints)
and (takentest.difficulty = test.difficulty)
and
(forall (i:integer | (i >= 1) and ( i < #(test.testquestionlist)))
takentest.answeredquestionlist[i].questionnumber = answeredquestionlist[i].questionnumber );
end SubmitTest;
end Student;