Assignment #2: Coded Messages¶
With the amount of information flowing across the internet, keeping data secure is an important concern. Keeping usernames, passwords, bank accounts, health records, etc. safe requires constant work.
Encryption refers to any process that converts information into a secret code that hides its meaning from prying eyes. For example, messages can be encrypted on one user’s device, sent to another user, and then changed back into plain text on the second device. Anyone spying on the message mid-stream will see unreadable content.
For this assignment, you will create a program that changes plain text messages into coded ones. Your program will also decode messages to produce readable text.
Note
If your teacher added you to a repl.it classroom or a Trinket course, complete Assignment #2 there.
If you are NOT enrolled in a repl.it classroom or Trinket course, you can find a copy of the starter code here:
Requirements¶
By the end of this assignment, your program will:
Prompt the user for a message and a shift value.
Ask the user to either encrypt or translate the message.
Convert the user’s plain text message to a coded one (or vice versa).
Display the original message and the changed one.
Part 1: Simple Letter Shift¶
You will use a basic encryption tool, called the Caesar Cipher, to encode a message. This process takes each letter in a message and replaces it with a different one. The new letters are all shifted a certain number of spaces in the alphabet compared to the originals.
Open a new project in your code editor and complete the following tasks.
The alphabet_position
Function¶
Define a function called
alphabet_position
with one parameter. The parameter receives a string containing a single letter.The function returns the index of that letter within the alphabet.
The function should be case-insensitive. Capital and lowercase letters return the same result.
¶ letter
Return Value
a or A
0
d or D
3
z or Z
25
Don’t forget to test your function! In the
main()
function, callalphabet_position
and send in different letters as arguments. Be sure to print the returned result to check your code.
Tip
You can assume the argument sent to the function will be a single letter. Do not worry about what to do with longer strings or non-letter characters.
alphabet_position
should NOT print anything. It needs to return a value instead.
The shift_character
Function¶
Define the function
shift_character(char, shift)
with two parameters.char
accepts a character (a string of length 1) andshift
accepts an integer value.If
char
is a letter, the function returns a different one. The new letter will beshift
places to the right in the alphabet.The case of the original letter and the returned value should match. For example,
shift_character("A", 1)
returns"B"
, instead of"b"
.If
char
is NOT a letter, then the function returns the same character.¶ char
shift
Return Value
a
13
n
D
4
H
z
3
c
J
30
N
?, 6, &, etc.
(any integer)
?, 6, &, etc. (no change for non-letter characters)
Test your function! In
main()
, callshift_character
and send in different characters and shift values. Be sure to print the letter returned to make sure your code works properly before moving on.
Tip
You should make use of your
alphabet_position
function! Thinking in terms of index values helps.Notice in the Sample Results table that the function wraps around when it reaches the end of the alphabet. If a shift moves the program past the letter
'z'
(index value25
), it moves back to the start of the alphabet and continues counting with'a'
(index value0
).The modulus operator will be a BIG help here to keep the index values in the range
0 - 25
.
The build_code_dict
Function¶
Define the function
build_code_dict
that takes one parameter (an integer).The function will build and return a dictionary. Each of the keys will be a letter from the alphabet. Each of the values will also be a letter, but shifted to the right a certain number of places. How many places? That depends on the integer sent to the function.
Hints: The accumulator pattern strikes again! Also, think about calling the
shift_character
function to keep your code DRY.The returned dictionary should include keys for BOTH lower and uppercase letters.
Test your function! In
main()
, callbuild_code_dict
and send in different integer values. Be sure to print the returned dictionary to check the results.¶ Function Call
Returned Dictionary
build_code_dict(1)
{‘a’: ‘b’, ‘b’: ‘c’, ‘c’: ‘d’, ‘d’: ‘e’, ‘e’: ‘f’, ‘f’: ‘g’, ‘g’: ‘h’, ‘h’: ‘i’, ‘i’: ‘j’, ‘j’: ‘k’, ‘k’: ‘l’, ‘l’: ‘m’, ‘m’: ‘n’, ‘n’: ‘o’, ‘o’: ‘p’, ‘p’: ‘q’, ‘q’: ‘r’, ‘r’: ‘s’, ‘s’: ‘t’, ‘t’: ‘u’, ‘u’: ‘v’, ‘v’: ‘w’, ‘w’: ‘x’, ‘x’: ‘y’, ‘y’: ‘z’, ‘z’: ‘a’, ‘A’: ‘B’, ‘B’: ‘C’, ‘C’: ‘D’, ‘D’: ‘E’, ‘E’: ‘F’, ‘F’: ‘G’, ‘G’: ‘H’, ‘H’: ‘I’, ‘I’: ‘J’, ‘J’: ‘K’, ‘K’: ‘L’, ‘L’: ‘M’, ‘M’: ‘N’, ‘N’: ‘O’, ‘O’: ‘P’, ‘P’: ‘Q’, ‘Q’: ‘R’, ‘R’: ‘S’, ‘S’: ‘T’, ‘T’: ‘U’, ‘U’: ‘V’, ‘V’: ‘W’, ‘W’: ‘X’, ‘X’: ‘Y’, ‘Y’: ‘Z’, ‘Z’: ‘A’}
build_code_dict(10)
{‘a’: ‘k’, ‘b’: ‘l’, ‘c’: ‘m’, ‘d’: ‘n’, ‘e’: ‘o’, ‘f’: ‘p’, ‘g’: ‘q’, ‘h’: ‘r’, ‘i’: ‘s’, ‘j’: ‘t’, ‘k’: ‘u’, ‘l’: ‘v’, ‘m’: ‘w’, ‘n’: ‘x’, ‘o’: ‘y’, ‘p’: ‘z’, ‘q’: ‘a’, ‘r’: ‘b’, ‘s’: ‘c’, ‘t’: ‘d’, ‘u’: ‘e’, ‘v’: ‘f’, ‘w’: ‘g’, ‘x’: ‘h’, ‘y’: ‘i’, ‘z’: ‘j’, ‘A’: ‘K’, ‘B’: ‘L’, ‘C’: ‘M’, ‘D’: ‘N’, ‘E’: ‘O’, ‘F’: ‘P’, ‘G’: ‘Q’, ‘H’: ‘R’, ‘I’: ‘S’, ‘J’: ‘T’, ‘K’: ‘U’, ‘L’: ‘V’, ‘M’: ‘W’, ‘N’: ‘X’, ‘O’: ‘Y’, ‘P’: ‘Z’, ‘Q’: ‘A’, ‘R’: ‘B’, ‘S’: ‘C’, ‘T’: ‘D’, ‘U’: ‘E’, ‘V’: ‘F’, ‘W’: ‘G’, ‘X’: ‘H’, ‘Y’: ‘I’, ‘Z’: ‘J’}
build_code_dict(33)
{‘a’: ‘h’, ‘b’: ‘i’, ‘c’: ‘j’, ‘d’: ‘k’, ‘e’: ‘l’, ‘f’: ‘m’, ‘g’: ‘n’, ‘h’: ‘o’, ‘i’: ‘p’, ‘j’: ‘q’, ‘k’: ‘r’, ‘l’: ‘s’, ‘m’: ‘t’, ‘n’: ‘u’, ‘o’: ‘v’, ‘p’: ‘w’, ‘q’: ‘x’, ‘r’: ‘y’, ‘s’: ‘z’, ‘t’: ‘a’, ‘u’: ‘b’, ‘v’: ‘c’, ‘w’: ‘d’, ‘x’: ‘e’, ‘y’: ‘f’, ‘z’: ‘g’, ‘A’: ‘H’, ‘B’: ‘I’, ‘C’: ‘J’, ‘D’: ‘K’, ‘E’: ‘L’, ‘F’: ‘M’, ‘G’: ‘N’, ‘H’: ‘O’, ‘I’: ‘P’, ‘J’: ‘Q’, ‘K’: ‘R’, ‘L’: ‘S’, ‘M’: ‘T’, ‘N’: ‘U’, ‘O’: ‘V’, ‘P’: ‘W’, ‘Q’: ‘X’, ‘R’: ‘Y’, ‘S’: ‘Z’, ‘T’: ‘A’, ‘U’: ‘B’, ‘V’: ‘C’, ‘W’: ‘D’, ‘X’: ‘E’, ‘Y’: ‘F’, ‘Z’: ‘G’}
Note
Remember that dictionaries are unordered collections. The key/value pairs in your results might be in a different order than the examples, and that is OK.
Part 2: Code and Decode Messages¶
Now that your Part 1 functions all work, you are ready to create coded
messages! Before you dive in, however, remove any print
statements you used
to test those functions.
The encrypt_with_shift
Function¶
Define the function
encrypt_with_shift(text, shift)
. Thetext
parameter accepts a string andshift
accepts an integer.text
will be the message to convert to code, andshift
will be the number of spaces to shift each letter in the alphabet.Just in case no
shift
value gets sent to the function, set its default value to be1
.Inside the function, call
build_code_dict
and useshift
as the argument. Assign the returned dictionary to a variable.Use the accumulator pattern to build up the coded message.
Define a variable to hold the coded message.
Loop through each character in
text
.If the character is a key in the code dictionary, add its value to the coded message. If the character is NOT a key in the dictionary, add the original character to the message.
Return the final, coded message.
The decrypt
Function¶
The encrypt_with_shift
function codes a message by shifting all of the
letters to the right in the alphabet. To translate a coded message back into
clear text, you must shift the letters to the left the same number of steps.
Define a
decrypt
function that takes a coded message and a shift value as the parameters.The function returns the translated message.
Make this happen.
Hints:
There’s no rule that says shift values have to be positive.
Remember that functions can call other functions.
The
decrypt
function can be completed with only a small number of statements.
Test Your Functions!¶
In
main()
, define themessage
andshift_by
variables. Assign values to each one.Call the
encrypt_with_shift
function and use the two variables as the arguments. Assign the returned (coded) message to another variable.Print the coded message.
Call the
decrypt
function and send in the coded message andshift_by
as the arguments. Assign the returned (translated) message to another variable.Print the translated message.
Message |
Function |
Shift |
Returned Message |
---|---|---|---|
LaunchCode |
|
13 |
YnhapuPbqr |
Hello, World! |
|
5 |
Mjqqt, Btwqi! |
Ktocji MJXFN! |
|
21 |
Python ROCKS! |
Hsz dljd T’x yze l nzopc? Hlens xp aczgp espx hczyr! |
|
11 |
Who says I’m not a coder? Watch me prove them wrong! |
Part 3: Add User Input¶
The next step is to make your program interactive.
In
main()
, code someinput
statements so the user can enter a message and a shift value.Ask the user to choose to encrypt or translate the message.
Print the original message and the result.
Part 4: Create a Module¶
The alphabet_position
and shift_character
functions might be useful
for other programs. Move them into a module!
Create a new file in your project. Remember to add
.py
to the end of the filename.Cut and paste the two functions into the new file.
alphabet_position
andshift_character
should no longer appear in themain.py
file!Try running your program. It should NOT work! Read the error message carefully.
In
main.py
import the required function from the module, then run your program again. Use any error messages to guide you as you get your code working again.
Sample Output¶
Your output does not have to look exactly like the samples, but it should be close.
Enter a message: LaunchCode
Enter a shift value: 13
Would you like to [e]ncrypt or [t]ranslate the message? e
Original message: LaunchCode
New message: YnhapuPbqr
Enter a message: Ktocji MJXFN!
Enter a shift value: 21
Would you like to [e]ncrypt or [t]ranslate the message? T
Original message: Ktocji MJXFN!
New message: Python ROCKS!
Bonus Mission¶
The Caesar Cipher works fine, but it is VERY easy to decode. Add another function to your program that takes a coded message and returns all possible outcomes for how the message can be translated back into English.
For example:
Coded Message: Udymts fuuwjsynhj, dtz fwj.
Translations:
Shift 1: Tcxlsr ettvirxmgi, csy evi.
Shift 2: Sbwkrq dssuhqwlfh, brx duh.
Shift 3: Ravjqp crrtgpvkeg, aqw ctg.
Shift 4: Qzuipo bqqsfoujdf, zpv bsf.
Shift 5: Python apprentice, you are. <-- Scan output for clear text.
Shift 6: Oxsgnm zooqdmshbd, xnt zqd.
Shift 7: Nwrfml ynnpclrgac, wms ypc.
etc.
Back in main()
call the function, send it a coded message, and print each
result so you can spot the correct translation.
Q iu bpm Xgbpwv axg uiabmz.
Final Checks¶
Before submitting your assignment, make sure your program:
Works.
Only displays the expected output and NOT any of the function test results.
Contains no loose code statements (statements placed outside of any function).
Includes enough comments to describe to a non-coder what each part of the program does.
Survives unexpected inputs (e.g. if the user enters a letter instead of a number when asked for a shift value).