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 that each contain the values 1,2,3,4,5.
    • First method: create the list using only range and the list converter (in other words, only one line of code).
    • Second method: create an empty list and append the values in a loop.

    Display and label both lists. Do not display the list "as a list", i.e., do not display the list so that it looks like [1, 2, 3, 4, 5]. In the Fibonacci sequence example programs, the Fibonacci sequence was displayed in other 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.

    Copy lab7_6.py and name it caesarcipher.py. 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 can delete it.)

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

    Near the top of lab8_3.py, import your module.

    Run lab8_3.py to confirm that it still works as expected.

    Next, modify caesarcipher.py to call your test functions at the bottom of the file. Run lab8_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 an if 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 that if block of code, on both caesarcipher.py and lab8_3.py.

    For your .out file, demonstrate that lab8_3.py works as expected.

  4. In the remainder of the lab, you should not change the existing functionality/functions. Those functions are already tested and working. Don't change them.

  5. (20) Add new functionality to caesarcipher.py such that it also encodes many phrases using the Caesar Cipher. Specifically, you will add a function called encodeFile that takes as parameters a filename (as a str) and a key and returns the whole file content encoded, as a string, preserving new line characters.

    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.

    Copy lab8_3.py into lab8_4.py. Then, modify its main function such that it prompts the user for (1) the name of a file that contains phrases that need to be encoded and (2) a key, reads the file of phrases to be encoded, and outputs the encoded phrase.

    Example final output:

    This program will encode a whole file using Caesar ciphers.
    
    Enter the name of a file to encode: data/song.txt
    Enter an encoder key (an integer between -25 and 25): 1
    The encoded file is
    uijt pof hpft pvu up uif pof j mpwf
    uijt pof hpft pvu up uif pof j mfgu cfijoe
    

    Consider how this functionality would improve efficiency if you have a very long message that you want to encode.

    You could have your code assume that all the files are in the data directory, like the Wheel of Fortune program does with the puzzle files.

  6. (20) Add new functionality to caesarcipher.py so that it has a function called writeEncodedFile that takes as parameters the encoded message and the name of the file to write to, both as strings. (The function does not return anything.) Note that we can't write use test.testEqual to test the writing of a file. 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 encoded 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 yoursfil lab8 directory with files. It is not recommended that you overwrite the existing text files with the encoded output.

    The idea is that now you can encode files that you can give to others to decode (and vice versa).

    Example output:

    What is the name of your file to encode? song.txt
    What is the name of the file to output the encoded file to? encoded_song.txt
    What is the key to use to encode? 12
    The encoded file is
    uijt pof hpft pvu up uif pof j mpwf
    uijt pof hpft pvu up uif pof j mfgu cfijoe
    Your message has been successfully written to data/encoded_message.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 problems!

  8. (30) 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 and returns a list of the scores (as floats) that are in the file.
    • A function that takes as a parameter the list of scores (as floats) and returns the trimmed average.
    • A main function

Finishing up: What to turn in for this lab

If you didn't use caesarcipher_ss.py, you can delete that file.

    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:
    createPrintableLab <labdirname>
  2. View your file using the evince command.
  3. Submit your lab directory into your turnin directory.
  4. 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 (110 pts)