In this lab, you're going to open a file and read and process data from it in a loop.
The file contains tuition data from some number of states, where every three lines are data for a single state of the form:
State name
2002 public institution tuition
2012 public institution tuition
You will process each record and produce output in the form of a table like the one below for the six New England states and a few statistics, including 2012 largest tuition, 2012 smallest tuition, average tuition, and largest increase. You may not assume that the file contains data, but you may assume it exists and you may assume each record of the file is complete. (In other words, if there is a state name, there will be the two lines after it of 2002 and 2012 tuition values.)
State Name | 2002 Tuition | 2012 Tuition | Change |
Connecticut | 11066 | 19842 | 8776 |
Massachusetts | 9361 | 20328 | 10967 |
Maine | 10292 | 18631 | 8339 |
New Hampsphire | 12343 | 23314 | 10971 |
Rhode Island | 11575 | 20649 | 9074 |
Vermont | 13426 | 22504 | 9078 |
Think about how you would solve this problem before reading through the step-by-step instructions and hints below, and solve as much as you can on your own. You have learned everything you need to know to solve this problem in lessons 1-4.
To begin, open your Python program template and give it a new name, such as lab4.py or state_tuition.py. Write a docstring at the top that describes what the program does and that includes the date. The basic outline of the program will be to open the file, process the file data and print table rows, and print the summary statistics, so write comments in the program for each of these logical blocks.
We will need to have a text file of sample data to work with. Because our program must work with a text file of any length, we should create several text files and test each version of our program on all of them. Below is the data for the six New England states shown in the table above. We can create a text file called six_states.txt, we can create an empty text file called empty.txt, and we can create a text file with just one state's data, called one_state.txt. When we get to the testing step, we will create a few other variations. To create a text file, in IDLE, choose File -> New File, and when you save the file, choose "Text files (*.txt)" from the Save as type box.
Be sure to save the text files in the same directory as your program.
Copy/paste or type the data for the six states exactly as it is below for the six_states file, do not put anything in the empty file, and put only the three lines of data for Connecticut in the one state file.
Connecticut
11066
19842
Massachusetts
9361
20328
Maine
10292
18631
New Hampshire
12343
23314
Rhode Island
11575
20649
Vermont
13426
22504
Now that you have some text files in the same directory as your program, you can open a text file with your program and read it.
There are different ways to break this program up into smaller pieces to develop incrementally. You do not have to develop the program in the order it is developed here, but if you take a different development path, be sure that your program meets all of the requirements and gives correct output for all of the final test cases.
We will begin by obtaining a file name from the user. This will make it easier for us to test our program on many test cases, as we can place the different test cases in different text files and simply type the name in at the prompt to test a specific test case. Once we have obtained the file name from the user, we will open the file. (We will assume the user has typed the name correctly and the file exists.)
We will then read the first line from the file and check to see if it's the end of file. If it isnt, well print the header for our table. If it is, well print the message "< file name> contains no data," for example, empty.txt contains no data.
Follow these steps:
State Name 2002 Tuition 2012 Tuition Change
Formatting hint: This code prints the first two columns of the table header:
print("{:20s}{:20s}".format("State Name","2002 Tuition"))
If you run your program on the empty file and then on the file with six states, your executions should look like this:
>>>
RESTART: D:\ lesson4_lab_sample_solution.py
Please enter the file name with the .txt extension: empty.txt
empty.txt contains no data.
>>>
RESTART: D:\ lesson4_lab_sample_solution.py
Please enter the file name with the .txt extension: six_states.txt
State Name 2002 Tuition 2012 Tuition Change
>>>
To produce the table with the state name, the two tuition values, and the change between the tuition values, we will have to read the records of state data one at a time. Think about how you read a multi-line record in a loop. A loop has an initializer, a loop entry condition, and an updater. The loop entry condition is whether we have reached the end of file. The initializer and updater read the first line of the record, and within the loop, we must read the rest of the record. See if you can write the loop before reading the hints below.
Hints:
This might be the trickiest part of the program, but there are examples in the book and the videos of reading multi- line records and it's very good practice for learning loops. If youre having trouble, step through your program in the debugger to see what youre reading into each variable.
Once you have this loop written, test on the multi-record file and the one-record file. Your output should look like this for each test case: see image.
After the table, the program must display the largest 2012 tuition, the smallest 2012 tuition, the average 2012 tuition, and largest increase. Refresh your memory on loop patterns / variable roles to see if you can solve this part of the problem without reading the hints.
Hints:
Before we get to more extensive testing, test your program on the three files that you have already created. Your output should look like this: see image.
Test your program thoroughly! We have tested the empty file and files with just one record and several records. How else might we test the program?
We might consider that the maximum tuition, minimum tuition, and maximum change are found in different locations at the file, since off-by-one errors are common. (A programmer might accidentally miss checking the first or last record in the file if they didn't write their loop correctly.) We can move the record for the largest tuition and largest change (New Hampshires record) to the beginning and end of the text file, and we can move the record for the smallest tuition (Maines record) to the beginning and end of the text file. Create two more text files accordingly: largest_first_smallest_last.txt, largest_last_smallest_first.txt and test your program on all five test cases:
Output from the final two test cases will look like: see image.
Paste your program running at the bottom of the program file as a comment with each test case described, for example: see image.