Lab 8: Practice with Lists, Files, and Modules
Goals
After the lab, you should be proficient at
- solving problems with lists
- reading and processing data from files
- writing data to files
- creating our own modules
- reading numeric data from files
Objective: Review
Review the slides for today's lab.
Objective: Set Up
- Set up the help client: run labhelp
- Copy
(link to
instructions)
/csci/courses/cs111/handouts/lab8
and all of its contents, recursively, into yourcs111
directory. This way, you do not have to create thelab8
directory first.Alternatively, you could first create the
lab8
directory and then copy the contents of the/csci/courses/cs111/handouts/lab8
directory (i.e., add a * to thecp
command) into yourlab8
directory. And, then, create thedata
directory within your lab 8 directory and copy the contents of/csci/courses/cs111/handouts/lab8/data
in your data directory. But, that's a slower process. Let's just do it in one command!
Objective: Programming in Python
We'll practice writing several Python programs, each in their own text file. Name the files, as usual.
Your programs will be graded on correctness, style, efficiency, and how well you tested them. Make sure you adhere to the good development and testing practices we discussed in class. Your code should be readable and your output should be useful and well-formatted.
After you've developed a correct solution to each program, restart
IDLE or close and reopen the IDLE "shell" by running the program again
(using F5), demonstrate that the program works using
several good test cases, and save the output to a file named
lab8_x.out
, where x is the problem number.
- (10) Write a program that uses two different techniques to
create lists of length 5.
- First technique: create a list that contains the values
1,3,5,7,9 using only
range
and thelist
converter (in other words, only one line of code). Then, display a label for the list and display the list's contents, with each element of the list on its own line. - Second technique: create an empty list
and
append
multiples of 3, from 0 to 12 in a loop. Then, separately, display a label for that list and display that list all on one line, separated by spaces (i.e.,0 3 6 9 12
).
Reminder: In the Fibonacci sequence example programs, the Fibonacci sequence was displayed in several ways.
- First technique: create a list that contains the values
1,3,5,7,9 using only
- (15) Text Shorthand Generator. Create a text shorthand message
for a phrase using the first letters from a phrase/sentence. Some
example output, noting the desired casing of the output:
This program reads in a phrase and produces a text shorthand. Enter a phrase: Laughing out loud Shorthand is: lol
This program reads in a phrase and produces a text shorthand. Enter a phrase: This phrase doesn't stand for anything Shorthand is: tpdsfa
A Modern Family reference:
This program reads in a phrase and produces a text shorthand. Enter a phrase: Why the face? Shorthand is: wtf
- (15) Creating a module. Modules are a way that
we can make our code easier to reuse and share. We've used modules
but haven't made our own modules explicitly. That changes now.
- Copy
lab7_2.py
into this lab's directory, naming itcaesarcipher.py
. Review the code and make sure the code is correct, tested, and has appropriate comments on functions. Alternatively, you can use the code that was provided in the handouts directory, namedcaesarcipher_ss.py
. Rename itcaesarcipher.py
(If you don't use the provided file, you should delete it.) - Create a new file called
lab8_3.py
. Move themain
function and calling the main function fromcaesarcipher.py
intolab8_3.py
.Confirm:
caesarcipher.py
should contain the definitions of the encoding functions, the test functions, comments at the top that describe the module, and maybe constants. If you are missing any of those, copy them from the appropriate file. There should not be amain
in this file. - Near the top of
lab8_3.py
, import your module. - Run
lab8_3.py
to confirm that it still works as expected. - Modify
caesarcipher.py
to call your test functions at the bottom of the file. Runcaesarcipher.py
to confirm that it runs all of the tests. Next, runlab8_3.py
. What happened? - To handle that issue, we need to add some code
into
caesarcipher.py
: put the calls to the test functions into the body of anif
statement, specifically:if __name__ == "__main__":
- Run
caesarcipher.py
. What happens? - Run
lab8_3.py
. What happened?
Reflection: In comments near the top of
caesarcipher.py
, explain the effect of adding thatif
block of code on caesarcipher.py's and lab8_3.py's execution. You may want to review Section 6.8 of the textbook (in the "advanced topic" section, in the version of the book where you don't need to login).For your .out file, demonstrate that
lab8_3.py
works as expected. - Copy
- (20) Add new functionality to
caesarcipher.py
such that it also encrypts many phrases using the Caesar Cipher. Specifically, you will add a function calledencryptFile
that takes as parameters a filename (as astr
) and a key (an integer) and returns the whole file content encrypted, as a string, preserving new line characters.Consider how this functionality would improve a user's productivity if they have a very long message that you want to encode.
Note that, if the file contains characters that your function can't encrypt (e.g., capital letters or numbers), you'll get back a funny result. We're not going to worry about that level of error handling. Instead, state the requirements to use this function in your function's docstring. If the caller of the function violates your preconditions/requirements, then they have no guarantees about what happens.
Write a function to test this new functionality. For example, process the
data/message.txt
file that you copied from thehandouts
directory. However, even better than starting withdata/message.txt
, you should create your own (simpler) files to test the encoding. What would be good, smaller files that would help show that your code works?Note: We're keeping the data/input files in a separate directory (data/
) from the Python programs, which is good practice. I did that in the example programs as well.Your code can assume that all the files are in the
data
directory, similar to how the Wheel of Fortune program does with the puzzle files (see examples), so that the user doesn't need to prepend the filename withdata/
.Save/copy
lab8_3.py
aslab8_4.py
. Then, modify the new program'smain
function such that it prompts the user for (1) the name of a file that contains phrases that need to be encrypted and (2) a key, reads the file of phrases to be encoded, and outputs the encrypted phrase. You don't need to callisEncryptableString
in this problem.Example final output:
This program will encrypt a file using Caesar ciphers. Enter the name of a file to encrypt: data/song.txt Enter an encoder key (an integer between -25 and 25): 1 The encrypted file is uijt pof hpft pvu up uif pof j mpwf uijt pof hpft pvu up uif pof j mfgu cfijoe
- (15) That's pretty cool, but it would be better if we could
encrypt files that you can give to others to decrypt (and vice versa).
Sooo...
Add new functionality to
caesarcipher.py
such that it saves the encrypted file to a file. Specifically, add theencryptAndSaveFile
function that takes three parameters: the name of the file to encode, the key, and the name of the file (as a string) to write the encrypted file to. The function also returns the encrypted file's text. As always, you should leverage functionality you already wrote to make this task easier.Note that we can't (easily) use test.testEqual to test that the written file is correct. How can you test that your program works?
Copy
lab8_4.py
aslab8_5.py
and modify themain
function such that it also takes as input the encrypted message output file's name. You may want to enforce that the files always get read from/written to thedata
directory so that you don't clutter yourlab8
directory with files. It is not recommended that you overwrite the existing text files with the encoded output.Example output:
What is the name of your file to encode? song.txt What is the name of the file to output the encrypted file to? encrypted_song.txt What is the key to use to encrypt? 1 The encrypted file is uijt pof hpft pvu up uif pof j mpwf uijt pof hpft pvu up uif pof j mfgu cfijoe Your encrypted file has been written to data/encrypted_song.txt
- (25) Olympics Gynmastics Scoring. The system of scoring
an Olympic gymnast is based on two separate panels of scores. The D
panel judges the requirements, difficulty, and
connections of a routine. The scoring starts at zero and then adds
points accordingly. The E panel judges
the execution of a routine. The scoring starts at
10 with points deducted accordingly for execution and for any
applicable violations such as stepping out of bounds or being over
the time limit. Panel D judges reach consensus on the final
difficulty score. For the execution score, the lowest and highest
scores are dropped--to disincentivize judges from biasing the
results--and then averaged. This is known as a trimmed
average. The scores from the two panels are then added
together for the final score. A very good score will range in the
15s and 16s.
Your task: Given a file of "raw" gymnastics scores, display the gymnast's results, as shown below. (The file name can be a constant in your program, although you should show your program running with multiple files.)
Scores File Format: The first line of the file is Panel D's difficulty score, which was reached by consensus. The remaining six lines are the Panel E judges' execution scores. (You should not assume that the execution scores are sorted.) Example scores input file:
5.7 8.3 9.1 8.0 8.9 8.8 8.5
Example scores files in the
data
directory end with.dat
.Example output:
Gymnastics Scores for data/scores.dat -------------------------------------------------------- Difficulty Score: 5.7 Judges Execution Scores: 8.3 9.1 8.0 8.9 8.8 8.5 Average Execution Score: 8.625 The Final Score: 14.325
Your output does not need to display the execution scores in sorted order. However, the output should be formatted as above.
Breaking Down the Problem: Your final program should have at least 3 functions:
- A function that takes as a parameter the name of the file, whose format is one number on each line, and returns a list of the numbers (as floats) that are in the file.
- A function that takes as a parameter a list of floats and returns the trimmed average of the list.
- A
main
function
Note that framing the first two functions in this way makes them reusable, i.e., other programs may want to read in a file of floats on separate lines or compute the trimmed average.
Write the functions and test them. Then, use the functions to solve the original problem.
Review your module with Professor Sprenkle to make sure you're good to go with the remainder of the lab. (You can continue; just make sure you're in the lab help queue.)
In the remainder of the lab, you should not change the "existing" functionality/functions (the functionality currently in the module). Those functions are already tested and working. All new functionality should be in the new functions that you're creating.
Reflection on Caesar Cipher
Your caesarcipher
module gathers related
functionality together (as well as tests that confirm that the
functionality works) that multiple programs can import, call, and
use. Helpfully, the code in your "main" programs
(i.e., lab8_x.py
programs) are much shorter, easier
to read, and don't have repeated code from the caesar cipher
functionality. If you want to change the implementation of one of
your functions, you can change it (and test it) in the module. If
someone wants to use this functionality, you could give them this
module, which neatfully packages up the functionality.
I broke up the large problem of encoding files using a Caesar cipher and writing the result into another file into multiple, smaller problems, each of which is easier to tackle than tackling the whole problem all at once. This is an important problem-solving skill to develop. You may feel like breaking the problem into smaller problems slows you down, but it usually doesn't because you spend less time debugging the smaller pieces than if you had tackled it all at once. You'll get lots of practice solving problems in this class--including on the next problem!
Finishing up: What to turn in for this lab
Delete caesarcipher_ss.py
- Create the printable lab assignment, using the
createPrintableLab
command. - View your file using the
evince
command. - Check that the PDF contains all (and only) the necessary files.
- Print the file from evince. You can print to other printers if there are issues with the computer science printers (which do not cost you anything to print computer science work).
- Submit
your lab directory into your
turnin
directory. - Log out of your machine when you are done.
Note that each command links to a page with more information about using the command.
Labs are due at the beginning of Friday's class.
Ask well before the deadline if you need help turning in your assignment!
Grading (100 pts)
- Python programs: 100 pts; see above for breakdown