Lab 8: Practice with Lists, Files, and Modules

Goals

After the lab, you should be proficient at

  1. solving problems with lists
  2. reading and processing data from files
  3. writing data to files
  4. creating our own modules
  5. reading numeric data from files

Objective: Review

Review the slides for today's lab.

Objective: Set Up

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.

  1. (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 the list 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.

  2. (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
    
  3. (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.
    1. Copy lab7_2.py into this lab's directory, naming it caesarcipher.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, named caesarcipher_ss.py. Rename it caesarcipher.py (If you don't use the provided file, you should delete it.)
    2. Create a new file called lab8_3.py. Move the main function and calling the main function from caesarcipher.py into lab8_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 a main in this file.

    3. Near the top of lab8_3.py, import your module.
    4. Run lab8_3.py to confirm that it still works as expected.

    5. Modify caesarcipher.py to call your test functions at the bottom of the file. Run caesarcipher.py to confirm that it runs all of the tests. Next, run lab8_3.py. What happened?
    6. To handle that issue, we need to add some code into caesarcipher.py: put the calls to the test functions into the body of an if statement, specifically: if __name__ == "__main__":
    7. Run caesarcipher.py. What happens?
    8. Run lab8_3.py. What happened?

    Reflection: In comments near the top of caesarcipher.py, explain the effect of adding that if 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.

  4. 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.

  5. (20) Add new functionality to caesarcipher.py such that it also encrypts many phrases using the Caesar Cipher. Specifically, you will add a function called encryptFile that takes as parameters a filename (as a str) 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 the handouts directory. However, even better than starting with data/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 with data/.

    Save/copy lab8_3.py as lab8_4.py. Then, modify the new program's main 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 call isEncryptableString 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
    
  6. (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 the encryptAndSaveFile 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 as lab8_5.py and modify the main 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 the data directory so that you don't clutter your lab8 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
    
  7. 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!

  8. (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.

Finishing up: What to turn in for this lab

Delete caesarcipher_ss.py

    Note that each command links to a page with more information about using the command.

  1. Create the printable lab assignment, using the createPrintableLab command.
  2. View your file using the evince command.
  3. Check that the PDF contains all (and only) the necessary files.
  4. 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).
  5. Submit your lab directory into your turnin directory.
  6. Log out of your machine when you are done.

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)