Skip to main content

Section 14.9 Case Study: Quiz Grading

We have the key and a set of student answers for a multiple choice quiz. We deal with a lot of these quizzes and would like to write some code to help score quizzes and identify problems that may be too easy or hard.

Subsection 14.9.1 Understanding the problem

We are not really writing a full program here. Instead, we are just trying to build a toolbox that we can use on a certain type of data.
There are two different tasks we are looking to write code for. The first is to calculate the score for each student. The second is to calculate the average score for each question (how hard it was). The two tasks likely will share some logic, but it does not seem like either one depends on the other.
Both functions will depend on the same data, the key and the student answers. So letโ€™s start by thinking how to represent that data.

Subsection 14.9.2 Designing Data

The key for the quiz can be represented as a list of characters. The key for a 5 question quiz might look like:
A C C D B
And the student answers as a list where each โ€œrowโ€ is a different studentโ€™s responses to the. A set of four studentโ€™s responses to a 5 question quiz might look like this (where _ represents an unanswered question):
A C B D B
C C C C C
A C C D B
B C _ D B
The key looks like a single dimensional vector of characters. The student answers a 2-D grid of characters. Letโ€™s write some typedefs to name vectors with the appropriate dimensions:
typedef vector<char> Answers;
typedef vector<Answers> ResponseSet;
We could write our code without those definitions, but they should help make our code a little more readable.

Subsection 14.9.3 Student Grades

To compute student grades, we need to compare each studentโ€™s answers to the key and count how many match. I think that whenever I calculate the grades I will want to do so for all the students. So letโ€™s build a function that calculates all the grades and returns a vector of them.
This function will need to accept the grid of student answers and the key. It should return a vector of scores. We will represent the score as number of correct answers (not as percents) to avoid having to worry about rounding issues.

Checkpoint 14.9.1.

Most of this function is written. All that is missing (look for ???) are the indexes to use when comparing a studentโ€™s answer to the key. Fill in those blanks with the correct counting variable - either studentNumber or questionNumber.
Hint.
Remember that studentAnswers is a grid where each student is a row and each question is a column.

Note 14.9.1.

We did not do any error checking to make sure that each student has enough answers. If the key is longer than a studentโ€™s row of answers, we will end up going out of bounds on the student grid. In that case the vector will generate an exception. If we wanted, we could try to catch that exception. But it is not clear what we should do to fix the problem. So we will just let any possible exception propagate to whatever program calls this.

Subsection 14.9.4 Question Difficulty

Now we need to build a function to calculate the difficulty of questions. This time, letโ€™s build a function that just focuses on one function at a time. We will need to iterate through all of the students, but we will just be looking at one question. So we will only need a single loop.
Complete the code below. You will not need all of the blocks.

Checkpoint 14.9.2.

Most of this function is written. All that is missing (look for ???) are the indexes to use when comparing a studentโ€™s answer to the key. Fill in those blanks with the correct counting variable - either studentNumber or questionNumber.
You have attempted of activities on this page.