# Machine Problem 2

## Background

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.

## Simplified

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:

• Is in a single file called Epidemic.java, with the class holding the main method named as Java requires.
• The shell command javac Epidemic.java compiles your program.
• The shell command java Epidemic testfile runs your program to read a population description from a file called testfile.
• If run with no additional command line arguments, it outputs the message Epidemic: File name missing from command line.
• If run with extra arguments, it outputs the mesage Epidemic: Extra command line arguments.
• If the file given on the command line (eg testfile above) exists, and if that file is correctly formatted, it outputs the "name" of each person and their role, one person per line. Note that the names of people can be arbitrary. The default Java toString method on any object create an arbitrary name that will suffice. All that matters is that the names are unique. For the example test file given above, you might get:
```Person@292BA5F4 homemaker
Person@292A12B0 homemaker
Person@291E193B homemaker
Person@291BA33E worker
Person@291AB16C worker
Person@292E69B3 worker
Person@291004B7 worker
Person@2910E72D student
Person@2923FEB5 student
Person@29210B3D student
```
• If the file contains any input that does not work, the program must give appropriate error messages. Appropriate error messages identify what went wrong. If there are any errors in the input file, the program must not attempt to output the population.
• The program must not throw an exception, no matter what input you get.
• On inspection, the code must be well formatted, following the usual rules for Java style.
• On inspection, the code must create one object of class Person per person, where each person has, as an attribute, the Role they play. There must be one Role object per role, where the role object has the name of the role as an attribute. All of the population must be created before the population is output.

## Submission

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 Epidemic.java
```

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:

• Overlength lines
• Sloppy indenting
• Excessive whitespace
• Insufficient whitespace

## 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 sc.next() 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.

```// Demo.java
import java.io.File;
import java.io.FileNotFoundException;
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 ;
intersection
B
;
```

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 Demo.java 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.