INFORMATICS 41 • DAVID G. KAY • UC IRVINE • FALL 2011

Lab Assignment 9

This assignment is due at the end of lab on Friday, December 2.

Choose a partner for this assignment, someone you haven't worked with already. It will work best if you choose someone whose level of commitment to developing programming ability is close to your own (whether that's high or low).

Professor Andrea Anteater wants you to design a grade management system for her students in Applied Epistemology 101. This system will read and write students' scores from a file and allow the user to produce statistics and histograms (frequency graphs) of the scores.

Your task this week is to create this program from scratch. It's not really from scratch, though, so don't panic: We provide a set of specifications for you to implement and you can use all of the example programs we've seen all quarter. Hardly any programming today is totally from scratch; we have application frameworks (skeleton programs with all the infrastructure supplied), we have function libraries that provide commonly useful tasks, we have object libraries and class hierarchies that we can adopt and adapt to our own purposes.

To help you along, here are six pieces of development advice:

You'll be using Advanced Student Scheme for this program, with the advanced-file-io.ss teachpack. (Download the file; don't just copy and paste the code.)

One more thing before you get started: This assignment has two different starting points; you and your partner can choose either, and we'll make sure that either way, successful work is rewarded. If you're interested in software development, software engineering, or building your programming skills, start with part (a) below; that's the fully "from-scratch" approach, including building the input and output ("view") part. If you're less committed to software development, though, you can start with part (c), skipping parts (a) and (b) and using our "starter version" of the program; this will let you focus on the more substantial parts of the assignment and skip the input and output, which is important as a practical matter but kind of tedious to code up. If you choose the second approach, you'll still need to read through parts (a) and (b) below to understand what's involved, and read through the starter version of the program to understand how it works and how to modify it.

(a) Your program will handle these classes of data:

To start out, make sure you understand these data structures: Make up some examples; draw a picture; get comfortable with how they're organized. Then you'll want to define functions to display the information in an assignment and a student clearly; base these on rrant-print. Then, test out those functions with objects you construct using make-assignment and make-student. [Note on terminology]

(b) When your program starts, it will read the collection of assignments from a plain text file called Assignments.txt. (If you place your program file and these data files in the same directory/folder, DrScheme will find them without your having to do anything fancy.) Then it will read the collection of students from a text file called Students.txt. Since the user can create these files without knowing any Scheme, your program won't have to handle changes to the data (although that's an enhancement we discuss below).

The user can create these files using a plain ASCII text editor like NotePad (or from Word by using Save As and the Text Only format, which saves plain ASCII without the additional Word formatting information that your Scheme program can't read).

For a course with a 75-point midterm worth 40% of the grade and a 100-point final worth 60%, the assignments file would look like this:

2
Midterm Exam
40 75
Final Exam
60 100

The first line contains the number of assignments. Then each assignment has two lines, the first containing the assignment's name and the second containing two numbers, the weight followed by the possible points. [The code for creating one assignment should be similar to the rrant-get-info function, except that it's reading from a file instead of from the keyboard.]

A file of students for this course would look like this:

2
Aardvark, Aaron
11223344
68 85
Tapir, Tamara
44332211
74 92

The first line contains the number of students. Then each student has three lines, the first containing the student's name, the second containing the student's ID, and the third containing the student's scores on each assignment, in order.

Here are two lines of code to set up the reading from the two files listed above (in the same folder as your Scheme code):

(define assignment-port (open-input-file "Assignments.txt"))
(define student-port (open-input-file "Students.txt"))

Here are two examples of reading from the files:

(read assignment-port) ; Read one expression from the assignments file
(read-line student-port 'any) ; Read one line from the students file and return it as a string.

The 'any argument to read-line will handle files on both Windows and Mac; these systems use different characters to signal the end of a line.

As you read the input files, remember that the read-line function reads an entire line of input and returns a string (this is useful for reading strings that may contain blanks, without requiring the user to enclose the strings in quotation marks). The read function reads the next Scheme expression (e.g., a single number) from the input. You'll also want to call read-line (ignoring its return value) after reading numbers from a line; this will put you at the start of the next line so you're ready to read what's there. Some sample code using read-line is available.

[This organization of the input files should make it easy for you to use read and read-line to create the internal representation of the data in your program; your task is to fit these components together, and you should spend some time trying to do that. But if you decide you need some additional guidance, start by reading the assignments file, because it's simpler. As always when designing programs with more than one "layer" of data structures, you should treat one layer at a time. For the file of assignments, for example, you should have (a) a function to read the information for one assignment and create that assignment, and (b) a function to read the number of assignments (from the first line of the assignments file), call the single-assignment-creation function that number of times, and finally create the collection of assignments. Do make sure you understand how to use read and read-line: Choose the right function for the right kind of data, as described above.]

Define functions that will fill the assignment and student collections by reading these files. It will also be helpful to write functions that print out these collections legibly; they'll help you in testing.

(c) Since assignments don't necessarily all have the same number of points possible, it will be useful to compute and store a scaled score on each assignment (i.e., a number from 0 to 100, calculated from the student's raw score and the number of points possible on the assignment). It might be easiest to implement this by storing for each student a second, parallel vector of scaled scores.

You should also compute and store for each student the weighted overall score in the course, a number from 0 to 100 calculated from the scaled scores and the weights of each assignment.

To make the output look reasonable, use the function format-decimal. It takes two numbers (the first is the value to display, the second is the number of digits after the decimal point) and returns a string, suitable for use as an argument to display. So, (format-decimal 25 2) returns "25.00" and (format-decimal 17.9876 3) returns "17.988".

(d) Your program will have a text-based menu interface like the one in the restaurants programs. It should include commands to

[Your first step here should be to write the menu-handling code, based on the restaurants programs, before writing code to do anything when the user selects a given command. For each menu command besides Quit, just print out "Received command X," where X is the command; we call this a "program stub," a simple placeholder so you can see that the menu framework works before you write the code that actually performs each command. Then take each command, one by one, and code and test its implementation. You should use the restaurants code as a starting point, just changing the things you need to change for this task; don't try to create a new view/controller from scratch. Start with displaying the assignment information (because that's the easiest).]

(e) A histogram is a bar graph showing the distribution of all the students' scores, from highest to lowest. Given a list of scores, for example

(list 23 23 20 18 25 14 16 18 15 16 23)

the histogram should display

   25 *
   24
   23 ***
   22
   21
   20 *
   19
   18 **
   17
   16 **
   15 *
   14 *

Hints: You might find it particularly convenient to create a vector of frequencies where (vector-ref freqency-vector N) contains the number of students whose score was N. A simpler histogram would display the frequencies of scaled (0 to 100) scores, with 101 lines from 100 down to 0; start by implementing it that way. You'll want to use the predefined round function to convert all the scores to integers.

(f) Implement at least one of the following enhancements. In a comment at the top of your definitions, list which one(s) you implemented. Note that it is never acceptable (in class or in the real world) to submit buggy code. It is much better to deliver fewer features, but features that work correctly, than to provide fancier functionality that "almost works." [This doesn't mean that you have to implement every single aspect of a bullet item below, but it does mean that whatever you do implement must work correctly and consistently with the rest of your program.]

(g) Submit the file containing all your definitions as usual via Checkmate.

(h) Complete your last partner evaluation form at eee.uci.edu. Please do this by Saturday morning at the latest, or you won't get credit.

Written by David G. Kay for the innaugural Informatics Core Course, Fall 2004, and modified Fall 2005, Fall 2008, and Fall 2009. Modified Fall 2010 by David G. Kay to reflect the Picturing Programs text and Fall 2011 to include multiple starting points.


David G. Kay, kay@uci.edu
Wednesday, November 23, 2011 12:12 PM