This week's assignment will focus on the data structures you already know: the list and the dictionary,
Question:
This week's assignment will focus on the data structures you already know: the list and the dictionary, as well as reading and writing to text files. Since it's a bit challenging, we'll break it down into three manageable steps, building on each step as we go along. There's a video demonstration of how each step should work at the bottom of this page.
The application is a comment manager for a forum. Each comment will include a user and a time stamp. Together, each comment will be stored in a dictionary with the date, name and comment as the keys. Collectively, the dictionaries will be stored in a list. In order to make the data persistent - remembered each time the application runs - we'll store it in a tab delimited file, which is a simple kind of spreadsheet. For extra credit, you can write the data to a JSON file (extra Step 4).
Remember to include header comments in each file you submit:
#
# SEC290.
#
#
#
#
Be sure to do this week's exercises first, which will include the techniques you'll need to complete the homework assignment.
Step 1: 50 points
In this step, we'll focus on creating the user interface and the data structures.
1. Create your program file as step_1.py.
2. Import the time module and use the ctime() function to create the time stamp.
3. Create an empty list for the records as the first line of code.
4. Create a menu as follows:
Forum Comments
==============
0: Exit
1: Display Comments
2: Add Comment
5. Create a while loop with an if-elif-else construct to implement each of the menu selections.
6. If the user selects 0, exit the while loop and display a message thanking the user for participating.
7. If the user selects 1, use a for loop to iterate through the elements in the records list. Since each element in the list is a dictionary, the for loop variable will contain a dictionary.
8. Inside the for loop, display the items of the dictionary. The keys are "date", "name" and "comment". The values for the date and the name should be displayed on one line and the comment on another line. Display a separator line after each record, such as "------------------------", to make the output easier to read. If you have problems, add a print statement inside the for loop and print the for loop variable. You should see a dictionary - verify that the keys are what you expect.
9. If the user selects 2,
- Create a time stamp string, using ctime() from the time module, e.g. ts = time.ctime().
- Prompt the user for his/her name.
- Prompt the user for a one line comment.
- Create a dictionary with "date", "name" and "comment" keys and assign the applicable values.
- Append the dictionary to the records list.
- If you have problems with this step, add a print statement to see what's in the list. The list should contain a record for each entry and each record should be a dictionary.
10. Run your program and verify that you are able to add records and that the list of records grows.
11. If all goes well, congratulations!
Step 2: 25 points
In this step, we'll begin by reading a text file of records and populating the records list with these records before entering the while loop. Text file to use: step2_data.txtDownload step2_data.txt
1. Copy step_1.py to step_2.py to use as a starting point.
2. Store the name of the text file in a variable.
3. Use a try/except/else block to open the file.
4. If a FileNotFoundError exception is thrown, display a message to the user indicating that the file could not be found and quit the program with the quit() function. If this happens, it's either because the text file is not in the same folder as your program file or there's a spelling error in the file name.
5. In the else block, which we only get to if we have successfully opened the file:
- Read and discard the first line of the file using readline(). This is the column heading line and we don't need it.
- In a for loop, read each line of the file and strip the trailing line break. Split the line using the split() method and a tab as the delimiter, "\t".
- The split should return three fields, which are the values for the timestamp, the name and the comment.
- Create a dictionary with keys of "date", "name" and "timestamp" and use the values provided by the strip() call.
- Append the dictionary to the records list.
6. Test your program.
- First choose Menu Selection 1. You should see each record from the file displayed.
- Choose Menu Selection 2 and add another entry.
- Choose Menu Selection 1 again and you should see the original records, along with the one you have added.
7. Note that if you run the program again, none of the new records you entered via Menu Selection 2 will show because we haven't updated the text file. That's part of the final step.
8. If everything goes as planned, take a bow! Well done!
Step 3: 25 points
Now we're going to make our new data entries persist from one running of the program to the next. We'll also handle the initial case where the text file doesn't yet exist.
1. Create step_3.py as a copy of step_2.py as an initial starting point.
2. At the top of the file, change the text file name to something that doesn't yet exist, e.g. step3_data.txt.
3. Modify the try/except/else block. Failing to open the file is not a problem, since we'll be creating/re-creating the file later. We just need to know if there are records to be read.
- If an exception is thrown, rather than quitting the application, fail silently - replace the quit() command with the pass keyword.
4. After the while loop is exited via Menu Selection 0, do the following.
- Open the file for writing, not appending. We want to blow away whatever was there and create a fresh new file because doing so is easier and less subject to problems.
- Write the column heading to the file as a string with tabs between the column names and a trailing newline.
- Use a for loop to step through the records list.
- Write the date, name and comment, each separated by a tab, and ending with a new line to the file.
- When the for loop exits, be sure to close the file in order to ensure data integrity.
5. Run the program and select Menu Selection 1 to display the records, which should be empty. If you are already seeing records, verify that you did, in fact, change the file name to something that doesn't already exist. You might not be working with the right file.
6. Choose Menu Selection 2 a number of times and add a few records.
7. Choose Menu Selection 1 again and display the records. You should see each record you entered.
8. Choose Menu Select 0 to exit the program.
9. When you run the program again, you should be able to pick up where you left off. Choose menu selection 1. You should the same records that were there when you last exited the program.
10. Congratulate yourself on a job well done!
Extra Credit - 10 points
While tab-delimited text files are handy, JSON is a more elegant way to go. JSON allows you to 'serialize' your data structures into a string and dump it to a file or send it over a network. The JSON data can then be loaded back from the file and de-serialized into the original data structures. Rather than formatting our data to write it to a tab delimited text file, instead we'll encapsulate it as a dictionary element and dump it to a JSON file. The json module does the heavy lifting for us.
1. Copy step_3.py to step_4.py as a starting point.
2. import the json module
3. Modify the 'else' block of the try/except/else to remove the text file processing and instead call json.load() with the open file object and store the results in a variable, which we can call 'ds'. Note that the results are a dictionary, with a single item named "records" and a records list as a value. Overwrite your records list with the value from ds["records"]. Remember to close the file.
4. When the while loop exits, remove the code for writing to the text file, but leave the call to open the file for writing.
5. Re-create the ds dictionary with a single item. The item's key should be "records" and it's value should be your records list.
6. Call json.dump, passing ds and your file object as arguments.
7. Remember to close the file.
8. Test your work as you did for Step 3.
9. If all goes well, give yourself a pat on the back. Well done!
Computer Architecture A Quantitative Approach
ISBN: 978-0123704900
4th edition
Authors: John L. Hennessy, David A. Patterson