Submission Details
In the last several years, you’ve undoubtedly gotten more experience taking exams and quizzes on computers. But even before then, I bet nearly everyone has taken some kind of personality quiz, whether it be on Buzzfeed, Facebook, etc.. Your job this week is to build an automated quiz taking and scoring system. In this exercise, you’ll be writing structs (with subtyping) and methods. The end product is an automated “quiz” system that gives a score after the user completes the questions.
Getting User Input in ASL
As we move into writing code that interacts with a user more, you might find it useful to reference the Racket documentation. While you won't need to actually use thePart 1. Implementing a Quiz
We’re going to take an object-oriented approach to creating an online quiz in ASL. What are quizzes made up of? Questions! So first we need to implementing a basic question struct. While in real life you have quite a bit of flexibility in the design of an object, your struct will need to follow our specifications exactly. The attribute and method names must match exactly, and the attributes have to be written in the listed order.
Note that in the starter code, we have provided an example question (q1) and some tests to be sure that you defined the question struct and its methods properly.
"I Don't Like Wicked."
The built-in example questions are based on the musical Wicked which has a sequel movie-version coming out soon. If you don't like Wicked, we'll try to provide some examples from a Marvel Cinematic Universe based quiz in the assignment below. You're also welcome to create your own questions, just be very careful when defining those questions that they follow the assignment description exactly. Additionally, keep in mind the built-in
Example (MCU)
(define q1
(make-question
"What is the home country of the Black Panther?"
"wakanda"
15))
Activity 1.1: type: question
The attributes of question should be (in the listed order):
| Name | Type | Description |
|---|---|---|
text | string | the text of the question itself |
answer | string | the correct answer to the question |
point-value | number | the point value of the question |
Note: for this part, the
answerattribute always stores strings. For parts 2, 3, and 4, theanswerattribute will stores numbers instead.
Activity 1.2: methods
Define the methods print-question, check-answer, and get-point for the question type.
-
print-question : question -> voidThis takes a
questionobject and prints the given question in the following format.Question (NN%): TEXT⏎Here,
NNis the points in thepoint-valueattribute,TEXTis the question text in thetextattribute, and⏎stands for a newline character at the end (i.e. it’s not an actual arrow character).The output of
print-questionmust match the described format, including the spaces, the parentheses, and the colon, etc. The providedcheck-expectvalidates the output ofprint-questionfor you. -
check-answer : question string-or-number -> booleanThis method takes a
questionobject and a user response, and returns#trueif the response equals the answer (use theequal?predicate to test equality here) and#falseotherwise.You can assume that the type of the user response received by
check-answeralways equals the type of theanswerof the givenquestion. In particular, for this partcheck-answeralways receives a string as the user response. For the next part, (the same)check-answeralways receives a number. -
get-point : question string-or-number -> numberThis methods takes the same inputs as
check-answerand usescheck-answerto assess the user response. Theget-pointmethod returnspoint-valuewhen the answer is correct and 0 otherwise.
Activity 1.3: Evaluating Quiz Responses
grade-quiz : (listof question) (listof string-or-number) -> number
Write an ordinary function grade-quiz (not a method!) that evaluates quiz responses. The grade-quiz function takes a list of questions and a list of answers. Then, it uses get-point to calculate and return the overall score. During the process, grade-quiz should print the title Missed Questions and then print the questions for which check-answer is #false using print-question. Additionally, the title and each printed question should be separate by the separator, ===== (that’s 5 equals signs).
- The questions in the list can be just the
questiontype or any of its subtypes (i.e.multichoice-question,numeric-question,partialcredit-question(all 3 of which you’ll define in later parts), or other autograder-defined subtypes) - You can assume that the answers have correct types (i.e. either strings or numbers, depending on the type of the corresponding question – in other words users will follow the instructions)
- The list of questions and the list of answers have equal lengths
Testing Tips
This function is really subtle so make sure all of the following are true:
- The function correctly loops (uses for-each) across all the questions in a quiz. You could double check by introducing something like a counter variable or by printing each of the questions as you grade it while debugging
- Check that the function correctly sums the total number of available points in a particular quiz.
- Make sure it prints out the details of all incorrectly answered questions.
- Make sure you use the
get-point andcheck-answer methods to calculate the final score!.
Example (Wicked)
To give an example, running
Missed Questions
=====
Question (5%): Where does the Wizard live?
=====
Question (15%): What is the first name of the Wicked Witch of the West?
Example (MCU)
If you make; an example "quiz" (a list of questions)
(define myquiz1 (list (make-question
"What does MCU stand for?"
"The Marvel Cinematic Universe"
5)
q1))
Missed Questions
=====
Question (5%): What does MCU stand for?
=====
Question (15%): What is the home country of the Black Panther?
Part 2. multichoice-question sub-type
A multiple-choice question differs from a regular question in that we need to tell the user what the possible choices are, displaying numerical labels next to each choice, starting at 1. However, it still has some text, answer, and point-value associated with it.
Implement a multichoice-question struct as a subtype of the question struct.
In the starter code, we’ve provided an example question (q2) and some suggested tests to be sure that you defined the multichoice-question struct and its methods properly.
Example (MCU)
(make-multichoice-question
"In the post-credits scene of The Avengers movie, what food do the six Avengers go to eat?"
1 ;; answer
10 ;; point-value
4 ;; count
(list "Shawarma" "Kabobs" "Manakish" "None of the above"))
Activity 2.1: subtype: multichoice-question
Define multichoice-question as a subtype of question.
In addition to the attributes inherited from the question type, multichoice-question should add the following attributes (in the listed order):
| Name | Type | Description |
|---|---|---|
count | number | the count of choices presented as possible answers to the question |
choices | (listof string) | the possible answers |
Note: Unlike
question, themultichoice-questiontype will have numbers in itsanswerattribute. You can assume that its (inherited)check-answermethod will only receive numbers as the user response.
Details on Test 7 in the Template
For Test 7, the intent is for you to check that the actual number of choices in theActivity 2.2: (override) method: print-question
print-question: multichoice-question -> void
Since multichoice-questions need to be printed differently than questions, we need to override the method print-question in multichoice-question. It should print the given multiple-choice question in the following format.
Question (NN%): TEXT⏎
Enter a number between 1 and M.⏎
1. CHOICE1⏎
2. CHOICE2⏎
...
M. CHOICEM⏎
Here, NN is the points in the point-value attribute, TEXT is the question text in the text attribute, and M is the count of the choices in the count attribute. The output of print-question must match the described format exactly, including the period, the spaces, and the parentheses, etc.
Example Output (Wicked)
As an example, the following expression(print-question
(make-multichoice-question
"Which of the following is a song from Wicked?"
1 ;; answer
10 ;; point-value
4 ;; count
(list "Defying Gravity" "Wait For It" "Tomorrow" "None of the above")))
Question (10%): Which of the following is a song from Wicked?
Enter a number between 1 and 4.
1. Defying Gravity
2. Wait For It
3. Tomorrow
4. None of the above
Example Output (MCU)
As an example, the following expression(print-question
(make-multichoice-question
"In the post-credits scene of The Avengers movie, what food do the six Avengers go to eat?"
1 ;; answer
10 ;; point-value
4 ;; count
(list "Shawarma" "Kabobs" "Manakish" "None of the above")))
Question (10%): In the post-credits scene of The Avengers movie, what food do the six Avengers go to eat?
Enter a number between 1 and 4.
1. Shawarma
2. Kabobs
3. Manakish
4. None of the above
The provided check-expect validates the output of print-question for you.
Part 3. numeric-question sub-type
A numeric question is displayed just like a question but differs in how we assess the users’ response. That is, we might be a bit forgiving and allow some bit of error in the numeric answer that they give.
In the starter code, we’ve provided an example question (q3) and some suggested tests to be sure that you defined the numeric-question struct and its methods properly.
Example (MCU)
(define q3
(make-numeric-question
"What version or mark armor does Tony Stark use during the Battle of Earth featured in Avengers: Endgame?"
85
10
2))
Activity 3.1: subtype: numeric-question
Define numeric-question as a subtype of question.
In addition to the attributes inherited from the question type, numeric-question should add one new attribute:
| Name | Type | Description |
|---|---|---|
epsilon | number | the allowable difference from the correct answer |
Unlike question, the numeric-question type always has numbers in its answer attribute. You can assume that its check-answer method will only receive numbers as the user response.
Activity 3.2: (override) method: check-answer
check-answer : numeric-question number -> boolean
Override the method check-answer in numeric-question and check whether the user response is strictly within within the allowable error from the expected answer. That is, if is the answer, is the allowable difference in the epsilon attribute, and is the user response, check-answer should output #true if and only if .
Part 4. partialcredit-question subtype
A partialcredit question is just like a multiple-choice question but with the ability to assign “partial credit” to some responses. That is, we print a partial-credit question and assess the users’ response the same way as we do for a multiple-choice question, but specifically allow certain answers to receive half of the points.
In the starter code, we’ve provided an example question (q4) and some suggested tests to be sure that you defined the partialcredit-question struct and its methods properly.
Example (MCU)
(define q4
(make-partialcredit-question
"After J.A.R.V.I.S were uploaded into Vision, who became the user interface program that Tony Stark uses with his Iron Man suits?"
3
15
4
(list "e.d.i.t.h" "T.A.D.A.S.H.I" "F.R.I.D.A.Y" "J.O.C.A.S.T.A")
(list 2 4))) ;; other (partial-credit) answers
Activity 4.1: subtype: partialcredit-question
Define partialcredit-question as a subtype of multichoice-question.
In addition to the attributes inherited from the multichoice-question type, partialcredit-question should add one new attribute:
| Name | Type | Description |
|---|---|---|
others | (listof number) | the list of answers that should receive half of the points |
Activity 4.2: (override) method: get-point
get-point : partialcredit-question number -> number
Override the method get-point in partialcredit-question. If check-answer returns true, get-point should still return full credit. Otherwise, if the user response is any of the choices in the others attribute, get-point should return half of the points. If none of the above is true, get-point returns 0 as usual.
Part 5. Testing your quiz
Once you’ve implemented all of parts 1, 2, 3 and 4, run the line (runquiz myquiz) in the Interactions Window to take the quiz. You should see something like the interaction shown below (this one shows the MCU version).
Want to change the title / narrator name?
Go for it! You'll see in the screenshot we've changed the "narrator" to "J.A.R.V.I.S." and the title to "Ultimate MCU Fan Quiz".You can leave this line commented or uncommented when you submit; it will not affect the autograder either way.
Double Checking your Work
Make sure you’ve followed the process outlined in the introduction for every function, and that you’ve thoroughly tested your functions for all possible edge cases.
Before turning your assignment in, run the file one last time to make sure that it runs properly and doesn’t generate any exceptions, and all the tests pass. Make sure you’ve also spent some time writing your OWN check-expect calls to test your code.
Assuming they do, submit only your exercise_7.rkt file on Canvas.