module TestTaking;
from TestAdminister import ClassTests, TestView,
CurrentQuestion, QuestionView, QuestionText, Status;
from TestGeneration import Test, TestQuestion, PointsPossible;
from QuestionModule import Answer, ClassName, Question, ID,
Type, Difficulty, Time, CorrectAnswer,
Author, AverageScore, Created, Modified, LastUsed, Notes;
export StudentAnswer, AnsweredQuestion, AQStatus;
--OBJECTS
obj StudentAnswer is Answer;
obj AnsweredQuestion inherits from TestQuestion
components: sa:StudentAnswer, aqs:AQStatus;
description: (* A question once the student taking
it has supplied an answer or once the
question is submitted *);
end AnsweredQuestion;
obj AQStatus is string;
--TEST TAKING OPERATIONS
op ViewTest is
inputs: test:Test, tv:TestView;
outputs: tv':TestView;
post: (* TestView displays the test which
corresponds to n *)
(forall
(i:integer | i <= #(tv.qv))
(tv.qv[i].qt in test.qs[i].text));
description: (* The selected test name will show the
test in the TestView
window *);
end ViewTest;
op AnswerQuestion
inputs: t:Test, tq:TestQuestion, tv:TestView;
outputs: t':Test;
pre:
(*
* The test question to be
answered is in the test
*)
(tq in t.qs);
post:
(*
* The question is now
answered
*)
(SetQuestion(t,tq,(tv.qv[tv.cur].answer)) = t');
description: (*Answers a given question, converting
it to an aswered question*);
end AnswerQuestion;
op DisplayNextQuestion is
inputs: tv:TestView;
outputs: tv':TestView;
pre: (* not at last question *)
tv.cur < #(tv.qv);
post: (* TestView displays next question *)
tv'.cur = tv.cur+1;
description: (* The TestView will display the next
question in the test *);
end DisplayNextQuestion;
op DisplayPrevQuestion is
inputs: tv:TestView;
outputs: tv':TestView;
pre: (* not at first question *)
tv.cur > 1;
post: (* TestView displays previous question *)
tv'.cur = tv.cur-1;
description: (* The TestView will display the
previous question in the test
*);
end DisplayPrevQuestion;
op DisplayFirstQuestion is
inputs: tv:TestView;
outputs: tv':TestView;
pre: (* not at first question *)
tv.cur>1;
post: (* TestView displays first question *)
tv'.cur=1;
description: (* The TestView will display the first
question in the test *);
end DisplayFirstQuestion;
op DisplayLastQuestion is
inputs: tv:TestView;
outputs: tv':TestView;
pre: (* not at last question *)
tv.cur <
#(tv.qv);
post: (* TestView displays last question *)
tv'.cur =
#(tv.qv);
description: (* The TestView will display the last
question in the test*);
end DisplayLastQuestion;
op SkipToQuestion is
inputs: tv:TestView, question:integer;
outputs: tv':TestView;
pre: (* not at question already *)
tv.cur !=
question;
post: (* TestView displays specified question *)
tv'.cur =
question;
description: (* The TestView will display the
question selected *);
end SkipToQuestion;
op SubmitTest is
inputs: ct:ClassTests, tv:TestView;
outputs: ct':ClassTests;
pre: (* TestView status is not submitted
*)
tv.stat !=
"submitted";
post: (* There exists a test in class tests such
that all answers in it
match answers in
the test view *)
exists (t:Test |
t in ct'.t)
(forall
(i:integer | i <= #(tv.qv))
(t.aq[i].sa = tv.qv[i].answer)
and
(* Every
question in the test is answered *)
(SetQuestion(t,t.qs[i],tv.qv[i].answer) in ct'.t))
and
(* No more
test questions exist, only answered questions *)
(forall (t
in ct'.t)
(t.qs = nil) and (t.aq != nil) and (t.gq = nil));
description: (* SubmitTest will add an answered test
to the ClassTests object *);
end SubmitTest;
function SetQuestion(t:Test,tq:TestQuestion,a:StudentAnswer)->(Test)=
(
exists (aq in t.aq)
(
(*
* All fields in TestQuestion are in AnsweredQuestion
*)
aq.id = tq.id and
aq.type = tq.type and
aq.text = tq.text and
aq.difficulty = tq.difficulty and
aq.time = tq.time and
aq.ca = tq.ca and
aq.cn = tq.cn and
aq.topics = tq.topics and
aq.author = tq.author and
aq.as = tq.as and
aq.created = tq.created and
aq.modified = tq.modified and
aq.lu = tq.lu and
aq.notes = tq.notes and
aq.qt = tq.qt and
aq.points = tq.points and
aq.sa = a)
);
end TestTaking;
Prev: 5.7. TestGrading |
Up: 5. Formal Specifications |