Lab 7: Strings, ASCII Encoding, and Formatting

Goals

After the lab, you should be proficient at

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.

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 lab7_x.out, where x is the problem number.

  1. (10 pts) Using a for loop, display a diagonal line that looks like:
    \
     \
      \
       \
        \
    

    Think about the pattern of what is getting printed.

    After you have that working, have the user enter the size of the diagonal line and draw a line of the appropriate size.

  2. Caesar Cipher. A Caesar cipher is a simple substitution cipher based on the idea of shifting each letter of a text message a fixed number (called the key) of positions in the alphabet. Recall that the alphabet wraps around. For example, 'z' with a key of 5 is encoded as 'e'.

    Rhetorical question: why is the limit on keys between -25 and +25?

    Pedagogical Overview: We're going to build up the Caesar cipher code in a couple of steps but all in one file. By the end of the term, you should feel comfortable with breaking up a problem yourself. In the meantime, we'll go through a few examples of breaking up a program into components that are easier to solve. You can peek at the last step in this problem to see where we're going.

    • (15) Write a function called encryptLetter that takes as parameters a lowercase letter and a key and returns the letter encrypted. For example, if you call the function encryptLetter('a', 1), the function should return 'b'. Similarly, if you call the function encryptLetter('b', -1), the function should return 'a'.

      As we've been doing, write the function and then test it using the test.testEqual function in a test function called testEncryptLetter. What are good test cases for this function? You can and should have a good variety of tests for this function. You want to make sure that this function works because you're building on it for the rest of the problem.

    • (15) Add a function called encryptMessage that takes a message containing only lowercase letters, spaces, and punctuation to encrypt and a key as parameters and returns the encrypted message. (Do not delete any of the code from the last problem.) For example, if you call encryptMessage("w and l!", 1), the function should return "x boe m!". As before, create a function that tests this function. What are good test cases for this function?

      The function you created in the last step will likely be helpful to call. (Read: you should call that function in this function.) You should NOT modify the function you wrote in the previous problem. You should have already tested that function thoroughly, so you know that it's working, so don't modify that function. Of course, if you find problems with that function, then fix the function and improve your test function to verify the correctness of the function.

    • (16) Add a function that checks that a string is valid input for encryption. Your function is called isEncryptableString. It takes as a parameter the string to encrypt. It returns True if the string is a valid string for encoding, i.e., it contains only lowercase letters, spaces, and punctuation. Otherwise, it returns False. Leverage appropriate str methods and operations.

      Note how the problem is phrased. It is not sufficient to check if there are digits or uppercase letters in the message. There are characters that you may not have thought about. The important part is that you want the string to only contain lowercase letters, spaces, and punctuation.

      Example test cases:

          test.testEqual( isEncryptableString("z"), True )
          test.testEqual( isEncryptableString(" "), True )
          test.testEqual( isEncryptableString("this"), True )
          test.testEqual( isEncryptableString("this is"), True )
          test.testEqual( isEncryptableString("this!"), True )
          test.testEqual( isEncryptableString("1"), False )
          test.testEqual( isEncryptableString("this is not valid1"), False )
          test.testEqual( isEncryptableString("Valid"), False )
          test.testEqual( isEncryptableString("invalid\nmessage"), False )

      You should put these test cases and more into a function that tests this function.

      If you are struggling with this problem, consider making a function called isValidCharacter that takes as a parameter a single character and returns True only if the character is valid for the encryptMessage function; otherwise, it returns False. Then, call this function in your isEncryptableString function.

    • (16) Implement an interactive interface to the Caesar Cipher functionality. The program's main function will take as input a phrase to encrypt and a key and will display the encrypted phrase.

      After making sure the "typical" behavior works, add error handling:

      • Your program should enforce that the user enters an "encryptable" string (by our rules) by repeatedly prompting for the string until it is valid.
      • Your program should handle the error case where the user-supplied key is not in the valid range by repeatedly prompting for the key until it is valid.

      Give your neighbor a message to decrypt, along with the original key used to encrypt the message. Put your neighbor's name, the original message, and the decrypted message in comments in your finished program, right under the high-level description. If others aren't around, decrypt this message, which I generated using the key 12: bkftaz ue yk rmhadufq bdasdmyyuzs xmzsgmsq! When you demonstrate your program, include decoding the message in your saved output.

      Your program should produce the following interaction with the user:

      This program encrypts and decrypts Ceasar ciphers.
      
      Enter message: i like the lions at the zoo.
      Enter an integer key (between -25 and +25): 1
      The encrypted text is: j mjlf uif mjpot bu uif app. 
      
      This program encrypts and decrypts Ceasar ciphers.
      
      Enter message: j mjlf uif mjpot bu uif app. 
      Enter an integer key (between -25 and +25): -1
      The encrypted text is: i like the lions at the zoo. 
      
      This program encrypts and decrypts Ceasar ciphers.
      
      Enter message: I like the lions at the zoo.
      Error: Provided text is not encryptable.
      It can only contain lowercase letters, spaces, and punctuation.
      
      Please enter message: I like the lions at the zoo!
      Error: Provided text is not encryptable.
      It can only contain lowercase letters, spaces, and punctuation.
      
      Please enter message: i like the lions at the zoo.
      Enter an integer key (between -25 and +25): 26
      Error: key is not valid. Key must be between -25 and 25.
      
      Enter an integer key (between -25 and +25): 1
      The encrypted text is: j mjlf uif mjpot bu uif app. 
      
  3. (10 pts) Copy lab2/lab2_2.py into this directory and name it appropriately for this lab. Update the high-level description appropriately. Modify it such that the program always displays the money values to 2 decimal places. Note the change in how the output looks (e.g., the use of the $).

    (You may want to "clean up" your original program to get rid of extra output.)

    Example program runs should look like:

    Bill amount in dollars: 162.29
    Percent tip: 15
    Number of people: 8
    
    The tip is $24.34.
    The total cost is $186.63.
    The cost per person is $23.33.
    

    Bill amount in dollars: 20
    Percent tip: 20
    Number of people: 3
    
    The tip is $4.00.
    The total cost is $24.00.
    The cost per person is $8.00.
    
  4. (18 pts) Write a program that creates a table of Olympic competition running distances in meters, kilometers, yards, and miles. The following distances should be used: 100 m, 200 m, 400 m, 800 m, and 1600m.

    Note that 1 m = .001 km = 1.094 yds = .0006215 mi

    Calculate and display the results, formatted in the following manner:

    
    Meters   Kilometers     Yards    Miles
    ---------------------------------------
       100        0.100     109.4    0.062
       200        -----     -----    -----
       400        -----     -----    -----
       800        -----     -----    -----
      1600        -----    ------    -----
    

    Note: Make sure your output is formatted exactly as above except that you will have all the converted values filled in. Note the spacing of the columns, the justification of the columns, the precision, ...

    Your final solution should not have a lot of repeated code. How can you solve this problem without repeated code? Notice the pattern.

    (You should not use a list to solve this problem.)

Extra Credit

Vignere Cipher (up to 8 pts)

We can provide problem clarifications, but try to solve extra credit problems on your own.

Write a program that implements a Vigenere cipher. Name the Python file vignere_ec.py. You should be able to leverage your previous code to help you solve this problem. Some example output:

This program encrypts Vignere ciphers.

Enter some text: the eagle flies at midnight
Enter a keyword: key

Encrypted text: dlc iyqpc jjsiq er qgnrgqlr

More points will be awarded for programs that demonstrate good programming practices (e.g., use of functions, code reuse, programmatic testing).

Finishing up: What to turn in for this lab

    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.

Ask well before the deadline if you need help turning in your assignment!

Grading (100 pts)