ICS 65 Fall 2012
Project #1: Letter Never Sent

Due date and time: Wednesday, October 24, 11:59pm


Introduction

Over my years of teaching, I've become quite fond of a grading scale that I jokingly refer to as the "Whatever I Want" scale. Of course, it's not quite as open-ended as my glib joke about it; it's a fair scale in the sense that any two students who perform at a particular level will receive the same grade — though it is neither a straight scale nor a curve, requiring me instead to decide, at the end of the quarter, where to set cutpoints that divide students who receive one grade from students who receive another. This is the grading scale that I'll employ at the end of the quarter in this course.

This project asks you to write a utility program that is given input via the console describing the set of graded artifacts for a course, the students enrolled in the course, and their scores on the various artifacts. Additionally, it is given a sequence of cutpoint sets describing the cutpoints (i.e., the number of total points necessary) dividing various grade levels. The program's output is twofold: the total score received by each student in the course and, for each cutpoint set, final course grades for each student.

Not surprisingly, you will need to write the program in C++, though there are some fairly heavy restrictions on what parts of C++ you're permitted to use, as we're still early in the process of learning it and I'd like you to gain some experience with some of the lower-level abstractions (most notably arrays, new, delete, and delete[ ]) before we layer less error-prone abstractions on top of them. Our goal in the early part of this course is to develop an understanding of what is happening behind the scenes in a C++ program, and it's impossible to develop this understanding if you sit at too high of a level of abstraction.


Getting started

It's not a bad idea to start by reading the Visual Studio 2012 tutorial, if you haven't already, and to use the pre-built ICS 65 Visual Studio 2012 solution as the starting point for each of your projects, as it's been set up to accommodate a properly-configured C++ console application compatible with our work this quarter.


The input

The program's input is to be read from the console (i.e., cin). It is separated into four sections:

Each section is described in more detail below.

Graded artifacts

The section describing graded artifacts begins with a positive integer, alone on a line, specifying the number of graded artifacts. This is followed, on another line, a sequence of integers, separated by spaces, indicating the total points possible on each graded artifact. Finally, on one more line, there will be a sequence of integers, separated by spaces, indicating the relative weight of each graded artifact. An example of this section would be:

7
15 15 15 15 15 50 50
12 12 12 12 12 15 25

This example describes seven graded artifacts, the first five having 15 points possible and relative weights of 12, the sixth having 50 points possible and a relative weight of 15, and the last having 50 points possible and a relative weight of 25.

Students

The next section of input describes the students enrolled in the course. It begins with a positive integer, alone on a line, specifying the number of students enrolled. Given that positive integer n, there will be n additional lines, each consisting of a non-negative integer student ID, followed by a space, followed by the student's name. Every character on the line after the student ID and space is considered to be part of the student's name. An example of this section would be:

5
123 Alex Thornton
234 Boo Thornton
345 Jane Student
456 Joe Student
567 Too-Many Courses

Student IDs do not necessarily have to be three digits, and they do not necessarily all have to be the same number of digits.

Raw scores

The next section of input describes the raw scores earned by students on each graded artifact. The section begins with a positive integer, alone on a line, specifying the number of students for which raw scores are listed. Given that positive integer n, there will be n additional lines, each consisting of a sequence of non-negative integers separated by spaces, the first of which is a student ID, and the rest of which are raw scores for each graded artifact. If there are m graded artifacts, you can assume each of these lines will contain m + 1 integers (one student ID, followed by m raw scores), and that the scores correspond, in order, to the graded artifacts listed in the first section. Example:

5
345 14 14 14 14 14 45 45
123 13 10 8 14 12 50 37
456 12 9 15 13 11 38 26
234 15 15 15 15 15 50 50
567 8 4 0 10 0 24 12

It is possible for a student to be listed in the previous section but not to be listed in this section. In that case, assume that the student's raw scores are all 0. It is also possible for a student to be listed in this section who does not appear in the previous section; in that case, ignore the student's raw scores, as the student is assumed to have dropped the course.

It is also possible for a raw scores to be higher than the number of points possible on a graded artifact. This is to be interpreted as extra credit, and fits into the formula below as-is.

Cutpoint sets

The last section of input is the cutpoint sets. This section begins with a positive integer, alone on a line, specifying the number of cutpoint sets. Given that positive integer n, the next n lines will consist of four non-negative numeric values (possibly including a decimal point and additional digits) that specify, respectively, the total points required for an A, B, C, or D in the course. Example:

3
90.0 80.0 70.0 60.0
85.0 75.0 65.0 55.0
80.0 70.0 60.0 50.0

You may assume that each of the cutpoint values can safely be read into a variable of type double.

A complete example input

A complete example input for the program follows. It should be possible to copy and paste this into the console window, or to save this into a file and use redirection to send the file's contents into your program as input.

7
15 15 15 15 15 50 50
12 12 12 12 12 15 25
5
123 Alex Thornton
234 Boo Thornton
345 Jane Student
456 Joe Student
567 Too-Many Courses
5
345 14 14 14 14 14 45 45
123 13 10 8 14 12 50 37
456 12 9 15 13 11 38 26
234 15 15 15 15 15 50 50
567 8 4 0 10 0 24 12
3
90.0 80.0 70.0 60.0
85.0 75.0 65.0 55.0
80.0 70.0 60.0 50.0

Note that there is nothing that explicitly separates one section of the input from the next, though you will always be able to tell from context (e.g., the number of graded artifacts, the number of students, etc.) where one section ends and the next begins.

Other requirements about the input

The program must not print prompts (e.g., "Enter the number of students") or any other output except for what is specified in the section titled The output below.

It is reasonable for your program to assume that the program's input will always be structured as specified here. It is fine for your program to misbehave or even crash if given input that does conform to these specifications.

It is safe to assume that all integers will be small enough that they will fit into an unsigned int or int variable (by Visual Studio 2012's definition, the largest value that would fit in both of these kinds of variables is 2,147,483,647).


Calculating the total points

The program's output is largely determined by the total score earned by each student in the course. In order to complete the program, you'll need to understand the correct formula to use.

In the example input above, there are seven graded artifacts defined:

  1. 15 points possible, with a relative weight of 12
  2. 15 points possible, with a relative weight of 12
  3. 15 points possible, with a relative weight of 12
  4. 15 points possible, with a relative weight of 12
  5. 15 points possible, with a relative weight of 12
  6. 50 points possible, with a relative weight of 15
  7. 50 points possible, with a relative weight of 25

From this example, we can see that simply adding together the raw scores on the various graded artifacts won't work, because, for example, artifact #6 is being graded on a 50-point scale, but is worth only slightly more, overall, than aritfact #5, wihch is being graded on a 15-point scale; summing the scores would give too much weight to artifact #6. So we'll need to scale each of the raw scores, then add the scaled scores together.

The total relative weight of all graded artifacts in this example is 100, which means that the total score for each student will range from 0.0 to 100.0. We calculate this by multiplying the percentage of points earned on each graded artifact by its relative weight, then summing the results. For example, suppose a student received these scores:

  1. 14
  2. 13
  3. 15
  4. 12
  5. 10
  6. 40
  7. 45

The calculations would proceed as follows:

  1. (14 / 15) * 12 = 11.2
  2. (13 / 15) * 12 = 10.4
  3. (15 / 15) * 12 = 12.0
  4. (12 / 15) * 12 = 9.6
  5. (10 / 15) * 12 = 8.0
  6. (40 / 50) * 15 = 12.0
  7. (45 / 50) * 25 = 22.5

Summing these together would yield a total of 11.2 + 10.4 + 12.0 + 9.6 + 8.0 + 12.0 + 22.5 = 85.7. So this student's total score is 85.7 out of a possible 100.

Scores that include extra credit (i.e., a raw score higher than the number of points possible on a graded artifact) do not need to be treated differently; they should be plugged into the formula the same way as any other.


Determining final course grades

The final course grade for a student is determined by comparing the total score earned by that student to the cutpoints for an A, B, C, or D.


The output

While reading the input, there are specified points at which output will be generated and printed to the console (i.e., cout). These are specified, along with the format of that output, below.

Student roster

After reading the raw scores on all graded artifacts, total scores are printed for all students. The format for this output is as follows:

Example:

TOTAL SCORES
123 Alex Thornton 79.1
234 Boo Thornton 100
345 Jane Student 92
456 Joe Student 72.4
567 Too-Many Courses 30.8

It is not necessary to format the total score to a particular number of decimal places, though you should not truncate it or round it to an integer. However the C++ iostream library formats a double value by default is fine here.

Course grades

After reading each cutpoint set, final course grades for that cutpoint set are printed. For the purposes of this output, cutpoint sets are numbered consecutively starting from 1. The format of this output is as follows:

Example:

CUTPOINT SET 1
123 Alex Thornton C
234 Boo Thornton A
345 Jane Student A
456 Joe Student C
567 Too-Many Courses F

Output timing

Do not store all of the output in memory and print it to the console only at the end of the program. Instead, you will be required to write output to the console at the points in time specified above.


A complete example of program execution

The following is a complete example of program execution, demonstrating how input and output are interleaved. Input is shown in a regular font weight; output is shown in bold.

7
15 15 15 15 15 50 50
12 12 12 12 12 15 25
5
123 Alex Thornton
234 Boo Thornton
345 Jane Student
456 Joe Student
567 Too-Many Courses
5
345 14 14 14 14 14 45 45
123 13 10 8 14 12 50 37
456 12 9 15 13 11 38 26
234 15 15 15 15 15 50 50
567 8 4 0 10 0 24 12
TOTAL SCORES
123 Alex Thornton 79.1
234 Boo Thornton 100
345 Jane Student 92
456 Joe Student 72.4
567 Too-Many Courses 30.8
3
90.0 80.0 70.0 60.0
CUTPOINT SET 1
123 Alex Thornton C
234 Boo Thornton A
345 Jane Student A
456 Joe Student C
567 Too-Many Courses F
85.0 75.0 65.0 55.0
CUTPOINT SET 2
123 Alex Thornton B
234 Boo Thornton A
345 Jane Student A
456 Joe Student C
567 Too-Many Courses F
80.0 70.0 60.0 50.0
CUTPOINT SET 3
123 Alex Thornton B
234 Boo Thornton A
345 Jane Student A
456 Joe Student B
567 Too-Many Courses F

Some rules and limitations

Because we're beginning our exploration of C++ by building our knowledge from some of its lowest-level abstractions, there are some fairly strict limitations on what features of the language you'll be permitted to use in this project. Those limitations will lift quickly as we move forward this quarter, so don't be concerned that you'll always be put into a tiny box, but this project has some very particular goals.

Here are the rules and limitations governing your work on this project.


Testing

While there is no explicit deliverable demonstrating that you tested your program, you are well-advised to run your program on test inputs other than the example here, since we will run a range of tests against your submission, which will partly determine your overall score on this project.

No additional test inputs and expected outputs are being provided, and we will not be sharing all of our test inputs and outputs. An important part of developing a facility with program is to develop your ability to construct a varied set of tests on your own, so we will (implicitly) be requiring you to do that. Note that, while you are not permitted to share code with one another, you can feel free to share test inputs with one another if you'd like.


Deliverables

Submit all of the source (.cpp) and header (.h) files that comprise your program. Afterward, take a moment to be sure that you submitted all of the files; if you missed one, we won't be able to compile and run your program, which can result in a substantial penalty, since we won't be able to evaluate your program's correctness.

Follow this link for a discussion of how to submit your project via Checkmate. Be aware that I'll be holding you to all of the rules specified in that document, including the one that says that you're responsible for submitting the version of the project that you want graded. We won't regrade a project simply because you accidentally submitted the wrong version.