(**** * * Module GradedTestPackage defines the object GradedTest and GradedQuestion that og with the graded test. * *) module GradedTestPackage; from StudentTestTool import all; from TestPackage import all; from QuestionManagement import all; export all; object gradedTest inherits from TakenTest components: gradedQuestion*, tp:totalPoints, o:outOf, itg:isTestGraded; description: (* Test composed of graded questions and points and the amount of points it is out of. *); end gradedTest; object totalPoints is integer; object outOf is integer; object isQuestionGraded is boolean; object isTestGraded is boolean; object pointsAwarded is integer; object gql is gradedQuestion*; object comment is string; object isGraded is boolean; object gradedQuestion inherits from AnsweredQuestion components: pa:pointsAwarded, com:comment, ig:isGraded; description:(* A gradedQuestion has all the components of a answered question, but has extra components that hold a grade for the question, and comments from the instructor. *); end; object postingSummary is components: gradedTest*; description: (* This object gives a summary when the "Post All Tests" or "Post Student Test" button is pressed, showing which tests were successfully posted to the server. *); end postingSummary; object openedTest is components: gradedTest; description: (* This object is the main screen for when a test is opened for viewing and grading. *); end openedTest; object markPoints is integer; object markOutOf is integer; operation markCorrect is inputs: gq:gradedQuestion; outputs: gq':gradedQuestion; precondition: gq.qpts > 0; postcondition: (*The points field of graded question coming in must be greater than zero, and going out pointsAwarded will be set to the maximum value, which is gq.Points and the isGraded boolean object is set to true, meaning the question is graded and marked correct.*) gq'.pa = gq'.qpts and gq'.ig = true; description: (* Marks a question correct and awards full points to the gradedQuestion. The maximum points allowed for the question will be the points awarded when the question is marked correct. pointsAwarded is set equal to points inherited from testQuestion. *); end markCorrect; operation markIncorrect is inputs: gq:gradedQuestion; outputs: gq':gradedQuestion; precondition: gq.qpts > 0; postcondition: (*The points field of graded question coming in must be greater than zero, and going out pointsAwarded will be set to the minimum value, 0, and the isGraded boolean object is set to true, meaning the question is graded and marked incorrect.*) gq'.pa = 0 and gq'.ig = true; description: (* Marks a question incorrect and awards zero points to the gradedQuestion. int pointsAwarded is set to 0 for the gradedQuestion object. *); end markIncorrect; operation markPartial is inputs: gq:gradedQuestion, mp:markPoints, mo:markOutOf; outputs: gq':gradedQuestion; precondition: (*The user must mark the question with at least 0 points and no more than the maximum points allowed (markOutOf)*) mp >= 0 and mo >= mp; postcondition: (*pointsAwarded is set to the exact amount of points that the user specifies in the gui and gq.Points is set to the markOutOf that the user specifies.*) gq'.pa = mp and gq'.qpts = mo; description: (* Marks a question with partial credit. This operation requires the user to input the points to be awarded to the student according to the correctness of the gradedQuestion. int pointsAwarded in the gradedQuestion object must be set at or above 0, and less than or equal to int points inherited from TestQuestion. *); end markPartial; object userComment is string; operation addComment is inputs: gq:gradedQuestion, uc:userComment; outputs: gq':gradedQuestion; precondition: (*The comment field must not be null and must have a vlue associated with it.*); postcondition: (*comment is set to the value the user specifies in the gui which is userComment.*) gq.com = uc; description: (* Adds a comment to a gradedQuestion. The comment is a string and is set according to the user's comment on the question's answer, answer's correctness, etc. *); end addComment; operation postAllTests is inputs: gtl:gradedTest*; outputs: gtl':gradedTest*, ps:postingSummary; precondition: (*There must be a test in the grading window for this operation to run and one test must be graded and its isGraded field must be set to true.*) exists(x in gtl) (x.itg = true) and (#gtl > 0); postcondition: (*The gradedTest is only added to the postingSummary and sent to the server if gq.isGraded boolean is set to true.*) forall(x in gtl') ((x in ps) iff (x.itg = true)); description: (* This operation posts all tests to a set database where students can open and view their graded tests with comments and grade. This operation only posts tests that are finished with grading and the gradedTest object's isTestGraded for each test is set to true. If the test is not done being graded, it will not be sent out, but all graded test will be sent out. *); end postAllTests; operation postSingleTest is inputs: gt:gradedTest; outputs: gt':gradedTest, ps:postingSummary; precondition: (*The test mut be already graded and its isGraded value must be set to true in order for the operation to run.*) (gt.itg = true); postcondition: (gt'.itg = true) and (gt' in ps); description: (* This operation posts a single test, according to which test is selected. This will only post the test if had been graded and the gradedTest object's isTestGraded is set to true. *); end postSingleTest; operation gradeAllTests is inputs: gtl:gradedTest*, gql:gradedQuestion*; outputs: gtl':gradedTest*; precondition: forall (x in gtl) (exists (i in gql) ((i.t = 0) or (i.t = 1) or (i.t = 2))); postcondition: forall (x in gtl') (forall (i in gql) (if ((i.t = 0) or (i.t = 1) or (i.t = 2)) then ((i.qpts = i.pa) iff (i.sa = i.qa)) else (i.pa = 0))); description: (* This operation takes every ungraded test and grades each question that can be automatically graded. It will automatically grade all multiple choice, true/false, fill-in the blank and all stdout format coding questions. After automatically grading all of these questions, it procoeeds to a question by question format, where the user grades each question, one student at a time. *); end gradeAllTests; operation gradeSingleTest is inputs: gq:gradedQuestion*; outputs: gq':gradedQuestion*, openedTest; precondition: exists (x in gq) ((x.t = 0) or (x.t = 1) or (x.t = 2)); postcondition: forall (x in gq') (if (((x.t = 0) or (x.t = 1) or (x.t = 2)) and (x.sa = x.qa)) then (x.qpts = x.pa) else (x.pa = 0)); description: (* This operation takes a single selected ungraded test and grades each question that can be automatically graded. It will automatically grade all multiple choice, true/false, fill-in the blank and all stdout format coding questions. After automatically grading all of these questions, it procoeeds to the essay and coding syntax format questions. The grading will proceed to the essay questions and coding questionts for manual grading. *); end gradeSingleTests; operation openTest is inputs: gt:gradedTest; outputs: gt':gradedTest, ot:openedTest; precondition: ; postcondition: ; description: (* This operation opens a single selected test for grading or viewing. Questions can be selected and graded manaully from here. The automatic grading feature will not operate in the open test method. The open test method is for viewing and manual grading only. *); end openTest; operation calculateGrade is inputs: gt:gradedTest, gql:gradedQuestion; outputs: tp':totalPoints, o':outOf; precondition: ; postcondition: (*The total points for the specific gradedTest will be set to the sum of each questions maximum point value and the amount of points awarded will be set to the sum of the pointsAwarded for each question and set to the value of the specified gradedTest.*) (tp' = sumTestPoints(gql)) and (o' = sumOutOfPoints(gql)); description: (* This operation takes the gradedTest and each gradedQuestions and adds up the pointsAwarded from each gradedQuestion and this value is set to the totalPoints integer of gradedTest. The points value from each gradedQuestion is added up and set as the gradedTest's outOf integer. *); end calculateGrade; object gradePercentage is integer; object addedPoints is integer; operation calculatePercentage is inputs: gt:gradedTest, gql:gradedQuestion*; outputs: gp':gradePercentage; precondition: (*The gradedTest's total points must be equal to the sum of each questions pointsAwarded field, and the outOf points must be equal to the sum of each questions maximum point value.*) (gt.tp = sumTestPoints(gql)) and (gt.o = sumOutOfPoints(gql)); postcondition: (*gradePercentage will equal to the percentage of points the student has been awarded relative to the total points.*) (gp' = (gt.tp / gt.o)); description: (* This function inputs totalPoints for the test, and outOf for the test, and calculates the grade percentage. *); end calculatePercentage; function sumTestPoints(l:gradedQuestion*) = if (#l = 0) then 0 else l[1].pa + sumTestPoints(l[2:#l]); function sumOutOfPoints(l:gradedQuestion*) = if (#l = 0) then 0 else l[1].qpts + sumOutOfPoints(l[2:#l]); end GradedTestPackage;