Machine Problem 2

Due Feb 15, on line

Part of the homework for CS:2820, Spring 2021
by Douglas W. Jones
THE UNIVERSITY OF IOWA Department of Computer Science


Our first step in designing an epidemic model is to grapple with a way to describe the population that is faced with the epidemic. The source file holding this description will end up fairly complicated -- since we also will need to describe the disease process as well as the population, but just the population will involve something like the following:

population 100000;
place home 3.5;
place work 25;
place school 1000;
role homemaker 0.3 home;
role worker 0.35 home work;
role teacher 0.05 home school;
role student 0.3 home school;
This describes a population of 100,000 people, where the following types of places are present:
  1. homes, with an average of 3.5 people per home.
  2. workplaces, with an average of 25 people (not employees) per workplace.
  3. 15 schools, with an average of 1000 people (not students) per school.

People are divided into the following mutually excusive roles:

  1. homemakers, 3/10 of the population, spend all their time at a home.
  2. workers, 35/100 of the population, each move between a home and a workplace.
  3. teachers, 5/100 of the population, each move between a home and a school.
  4. students, 3/10 of the population, each move between a home and a school.

Later, we will expand roles by making them more complex, with scheduling rules for when a person moves from here to there. This will allow teachers to get to their schools before the students get there and to go home later, like in real life.

For now, even the above is too complicated, so we'll back off. We gave too much detail, and we made the syntax too difficult because some tokens are not separated by whitespace.


Consider this simplified file format for a start:

population 10 ;
role homemaker 0.3 ;
role worker 0.4 ;
role student 0.3 ;

Here, we are describing a model with 10 people, and we can infer, from the fact that 3 are homemakers, 4 are workers and 3 are students. This file is the test file used to generate the output described later.

The numbers with each role need not add up to 1.0; rather, if the population is p, if the sum of all the roles is s, and if the input is rolename n, then there should be p × n/s people assigned to that role.

(The above rule means that, if the numbers do add up to 1.0, it acts as you'd expect, but it doesn't get picky if you have trouble with arithmetic. Furthermore if you simply give the actual number of homemakers, workers, etc., it will work just fine.)

The Assignment

Make a Java program that:


On or before the end of Monday, Feb. 8, you must submit your program using the following shell command on the fastx machine:

~dwjones/submit xxxx

Substitute your section number for xxxx above, but do not alter the text dwjones.

The program will confirm that you successfully submitted your solution with the message "submiter: succesfull submission of xxxx/HawkID" with xxxx replaced with your section number and HawkID replaced with your HawkID.

You may submit as many times as you want. The last successful submission is the one that will count. As such, it is a good idea to submit as soon as you have code that sort-of works, submit again when you have code that works the way you like, and perhaps submit again when you bring your code up to the highest standard of readability.


Code that executes correctly is worth half credit (2.0 out of 5 points). The remaining credit is all for readability. Expect demerits for style issues:

Student Questions

A student asked: How can I create people for each role if I need to sum the numbers for each role first?

You can't. You will need to read all the roles and sum their numbers before you go back to each role and create the people who fulfil that role. This means you will need to keep a collection of all roles so you can go back through the set of roles to create the people. Only after all the people are created should you go back through all the people and print them out.

Similarly, you'll need a collection of all people so you can go back through the population to print out the people.

A student asked: Where is the test file?

You will have to create your own test files. You should certainly try the test file given above so you can compare your output with the output given above, but you also need to check how your code works for malformed test files, and your code needs to work for any number of roles, for roles with any name, for any size population and for any division of population between roles. You cannot possibly test all possible inputs, but you will want to have tested a wide range.

A student asked: Are role names required to be one word?

Yes. More specifically, the role name should be a string returned by where sc is some Scanner. You don't need to check if the string is a word, but you might want to verify that it is not a semicolon.

A student asked: When I try to create a Scanner I get an error about FileNotFoundException.

The minimum Java program to open a Scanner to scan input from a file is as follows. This example does not do anything with the scanner, nor does it include code to report the exception if the file can't be opened. There are comments where that code goes.

import java.util.Scanner;
public class Demo {
    public static void main( String[] args ) {
        try {
            Scanner sc = new Scanner( new File( args[0] ) );
            // scan some input from sc
        } catch ( FileNotFoundException e ) {
            // report that file was not readable

Note that the control transfer to the catch clause is all you need to know to learn that the file couldn't be read. Any details in the exceptioin e are irrelevant. Class Scanner does not document any meaning for the value of e, although it may carry details of why the file couldn't be opened.

A student asked: Can we assume that each line of input begins with a keyword like population or role and ends with a semicolon?

Java's Scanner class makes line boundaries difficult to see, since the scanner views line breaks as just another kind of whitespace separating tokens. Code to require things to be line oriented is actually bigger and harder to write. Furthermore, in class Friday, we did an example where the material was broken up like this:

intersection A ;

Given that, you are not safe to assume things come at you in lines.

A student asked: Can we assume that the file begins with the line giving the population?

You don't need the population until all the roles have been defined, because you cannot compute the populations of any roles until you know the sum of the relative populations of all the roles. Therefore, enforcing the rule that the population must be given first seems to be adding an unnecessary constraint. Note that it makes just as much sense to give the population last.

A student asked: Can we assume that each item begins with either population or role?

Yes, for this assignment. Later, we'll add the keyword place, and even later, keywords pertaining to the progress of the disease. Note again, items aren't lines, they start with a keyword and end with a semicolon. If you don't find a semicolon where one is expected, report the fact and start looking for the next item.

A student asked: Do we use Javadoc @author tags on any line of code we copy from you?

No. Javadoc @author tags go only in class and method headers, not spread around in the code. If a substantial chunk of code is copied from some other author, credit it. If, however, you're just relying on someone to teach you how to do something basic, you don't need to give credit. For example, the code in listed above merely teaches how to create a Scanner and catch the exception it might raise. You don't need to give citations for that or for any equally trivial tutorial example. As I've said before, citing Hello World is not necessary. This falls in the same tutorial category.