<SYSTEM_TASK:>
Given the following text description, write Python code to implement the functionality described below step by step
<END_TASK>
<USER_TASK:>
Description:
 Sending Secret Messages with Python
This notebook will teach you how to send secret messages to your friends using a computer language called "Python." Python is used by thousands of programmers around the world to create websites and video games, to do science and math, even this web page is written using Python! 
Before we learn any Python, we need to learn just a bit about secret codes. One way to make your message secret is using a "substitution cipher." This means that we replace every letter in our message with a different letter. For example, all of the c's in our message might become j's. The message will look like garbled nonsense to anyone who doesn't know which letter has been substituted. By the time you're done with this page, you'll be able to make this message
this is a super secret message
Look like this
pkbm bm t mexuu mueuup nummtcu
Only someone who knows the password will be able to turn it back into the original message. (By the way, did you notice, above that everywhere there's an 's' in the original message, the coded message has an 'm'?)
To use a substitution cipher, the first thing to do is to decide which letter will replace which. We'll create a table like this one
Step1:  You can also change the code in the boxes before you run them. Try replacing "Levi" with your name in the box above. Now, while the cursor is still in the box, push Ctrl+Enter to see Python echo it back. From here on out, make a habit of executing each box in this notebook with Ctrl-Enter.
Now that you know a little bit about Jupyter notebooks, we're ready to learn some Python!
Python Dictionaries
To get Python to do this work for us, the first thing to do is to decide on a table and create a 'dictionary' in Python that keeps track of which letters get replaced by which new letters. A Python dictionary is a lot like the two-column table we've been talking about. We create an empty table like this
Step2:  Don't go on until you click into the box above and push Ctrl+Enter. You should see {} appear below the box. One more thing about Jupyter notebooks. Each time you execute a box, Python remembers what you've done. Here, we created a dictionary called "table." When we refer to "table" in the next box, Python will remember that "table" is an empty dictionary. The code in the box below adds one entry to your dictionary with the letter 'a' in the left column and 'n' in the right column. Try it out by pushing Ctrl-Enter in the box below.
Step3:  Don't be afraid to change the code in the boxes. You'll learn a lot by playing around, so don't be shy. Make some changes to the code in the boxes, then push Ctrl-Enter to see what you changed. You might get an error from Python. That's OK. See if you can figure out how to fix it. As you play around, remember that the notebook is remembering your changes. If you want to clear the notebook's memory and start again, look for the menu option above called "Kernel." Select "Restart" from that sub menu.
Quick tip
Step4:  The first line, newletter = table['a'], tells Python to read the entry we gave it for 'a' and call it by a new name, newletter. In this case, table['a'] is 'n'. After that, everytime we refer to newletter Python will remember that we told it newletter is 'n'. So, when we ask Python to print newletter, it remembers and prints 'n'. newletter is what programmers call a 'variable'--a name that refers, in your program, to some other value.
A few more things about our Python tables (also called 'dictionaries'). The values on the left hand side of the table are called the "keys." The right hand are called the "values." Let's add a few rows to our table, then ask Python some questions. Push Ctrl-Enter in the boxes below and see what Python answers.
Step5:  The colon (
Step6:  Python didn't like that and sent us back a KeyError. To avoid these errors, we can first check to see whether that table entry exists.
Step7:  We just asked Python, "Is d one of the keys in our table?" Python said, "No."
Now, let's create a table entry for 'd' and ask again.
Step8:  A key can only appear in the left column one time. If I try to assign one letter on the left column to two different letters on the right, the dictionary will store the last value.
Step9:  The old table entry for 'd' is lost and replaced by the new value. Note that more than one key can correspond to a single value. When we assigned 'd' to be changed to 'n', both 'a' and 'd' were being translated to 'n'. That's perfectly OK.
Python Lists
Way to go! Hopefully, you're feeling comfortable with dictionaries. Make sure to execute the code in the boxes as you go by clicking into the box and pushing Ctrl-Enter. 
Next, we'll take a look at lists. A python list is like a dictionary where the keys are numbers, specifically integers (i.e. 0,1,2,3,4,5...). We can create a list like this
Step10:  The list works a lot like a dictionary with numbers in the left column. We can ask for specific letters in the list by referring to their position in the list. Try this
Step11:  Wait, but isn't 'e' the third letter in the list? It's important to remember that computers start counting from zero.
Step12:  In a Python list, position 0 is the very start of the list. Now, there are 4 letters in the list. What do you think will happen if we ask for the letter in position 4?
Step13:  What do you think this error means? (Hint
Step14:  Our string acts just like a list
Step15:  The third letter in our string is 'e'. We ask Python for letter number 2 since Python starts counting from zero. 
Even the spaces in our string are considered letters.
Step16:  The output above just looks like two quote marks, but there's actually a space between them. The 4th "letter" in our string is actually a space. 
Take a minute to write some code yourself involving strings. You can edit the code in the box above and push Ctrl-Enter to execute it. Can you figure out which letter is 'q'? Or 'b'? What if you pick a number that's too large, like 100?
Creating a cipher table from a sentence
Let's create a table we can use to encode and decode our messages. I want to change all of my a's into t's. How can we create a Python dictionary to do that?
Step17:  Next, I'll add a row for changing all of the b's.
Step18:  In fact, what I'd like to do is to take an easy to remember phrase and use it to determine the right hand side of my table. I'd like to put 'abcdefghijklmnopqrstuvwxyz' down the left hand column and 'the quick brown fox jumped over the lazy dogs' down the right hand side. So 'a' changes to 't'. 'b' changes to 'h'. 'c' changes to 'e' and so on.
<html><table>
<tr><td>Old letter<br></td><td>New letter<br></td>
<tr><td>a</td><td>t</td>
<tr><td>b</td><td>h</td>
<tr><td>c</td><td>e</td>
<tr><td>d</td><td>q</td>
<tr><td>e</td><td>u</td>
<tr><td>f</td><td>i</td>
<tr><td>g</td><td>c</td>
<tr><td>h</td><td>k</td>
<tr><td>i</td><td>b</td>
<tr><td>...</td><td>...</td>
</table></html>
How can I do this in Python? We can write a loop to create a dictionary from two strings. Let's build the same string as before.
Step19:  Just like before, we can treat it like a list of letters.
Step20:  Now, let's create another string like this.
Step21:  We're going to use these two strings to create a table like this
<html><table>
<tr><td>Old letter<br></td><td>New letter<br></td>
<tr><td>a</td><td>t</td>
<tr><td>b</td><td>h</td>
<tr><td>c</td><td>e</td>
<tr><td>d</td><td>q</td>
<tr><td>e</td><td>u</td>
<tr><td>f</td><td>i</td>
<tr><td>g</td><td>c</td>
<tr><td>h</td><td>k</td>
<tr><td>i</td><td>b</td>
<tr><td>j</td><td>r</td>
<tr><td>k</td><td>o</td>
<tr><td>l</td><td>w</td>
<tr><td>m</td><td>n</td>
<tr><td>n</td><td>f</td>
<tr><td>o</td><td>o</td>
<tr><td>p</td><td>x</td>
<tr><td>q</td><td>j</td>
<tr><td>r</td><td>u</td>
<tr><td>s</td><td>m</td>
<tr><td>t</td><td>p</td>
<tr><td>u</td><td>e</td>
<tr><td>v</td><td>d</td>
<tr><td>w</td><td>o</td>
<tr><td>x</td><td>v</td>
<tr><td>y</td><td>e</td>
<tr><td>z</td><td>r</td>
</table></html>
To create this list in Python, we could do this
Step22:  But what if someone discovered our passphrase ("the quick brown fox...")? We'd have to change each of the individual letters. Instead, we can tell Python to read the letters from the strings, everyletter and sentence, that we created above. Take a look at this. We're using some fancier Python tricks that I'll explain in a minute.
Step23:  This requires some explanation. The first line, I think you'll remember, creates an empty table or dictionary. Then, when we write
table[ everyletter[0]] = sentence[0]
Python will look inside the square brackets, [], following "table[" to see which letter to put in the left hand column. Instead of a letter, Python sees everyletter[0]. To Python, this means the first letter in the string called "everyletter"--a. So, Python puts 'a' in the left hand column. 
Next, it looks for what to put in the right column after the equal sign. There, Python sees
    sentence[0]
which it knows means the first letter in the string "sentence" or 't'. So, Python creates a row in the table with 'a' in the left column and 't' in the right column. When we started encoding message, we'll turn all the a's into t's.
So, Python will act as if we wrote
 table['a'] = 't'
adding one entry to our translation table.
The line
table[ everyletter[1]] = sentence[1]
creates another new row with the second letter in "everyletter" and the second letter in "sentence." Can you figure out what will be in the left and right columns of this new row?
This is tricky. When learning new programming ideas, it's important to play around a little. Play around with adding rows to your table. What would happen if I wrote
Step24:  What changed? Why? This is another good chance to play around by writing your own code.
Loops in Python
Instead of writing 26 lines like table[ everyletter[14]] = sentence[14], I'd like to write it just once, then have the computer repeat it 26 times increasing the number each time. For this, we use a "for loop." Try this
Step25:  Don't worry if this isn't clear yet. We'll take a good look at this. The first line creates an empty dictionary. The next line is the loop
for num in range(26)
Step26:  Here, we gave Python a list of three names. For each name on the list, Python executes the commands that follow, replacing "name" with one of the names in the list. This is the first time we've seen + in Python, but it's an easy one. "Hi, " + name, just means that we add each name in the list to the end of "Hi, " and send that to print.
Try editing the loop above. Add your name (maybe it's Homer?). Make a list of your favorite sports teams and make Python cheer for them.
One tricky rule in Python involves indenting. It's possible to put lots of commands inside one for loop, but Python needs to be able to know which commands are in the loop and which are not. Each line that we want to be part of the loop, we indent, but we don't indent the for the loop statement itself. When Python sees a line that's not indented, it knows you've finished writing the loop. Take a look at this. Change the indenting and see what happens. What if you don't indent the "I'll stop you"? What if you do indent "You'll never get away with this"? Try it!
Step27:  The spaces before the print statements tell us whether they're part of the loop to be executed once for each villain, or just a lone command to be executed only once. 
What about this?
Step28:  Python didn't like that. The line that says print("I'll stop you!") was not indented. So, Python thought you were done with that loop. When it saw that print("You'll never get away with this.") was indented, it didn't know what loop it was part of. So, it sent an error message. Errors are part of programming. They can be intimidating, but it can help you to sort out the problem if you read the error message. Here, Python told us "unexpected indent" and referred to print("You'll never get away with this."). It clearly didn't expect that line to be indented.
Using Loops to make a table
Now let's use our loops to create a code table
Step29:  The "range" function just generates a list of numbers beginning with zero. The code below creates a list from 0 to 4 (5 total numbers), then prints each one.
Step30:  So, to make our table, we make a list of numbers from 0 to 25, then for each number, Python repeats the command
table[ everyletter[num] ] = sentence[num]
but it replaces 'num' with each of the numbers in the list. So it's exactly the same as writing
table[ everyletter[0] ] = sentence[0]
table[ everyletter[1] ] = sentence[1]
table[ everyletter[2] ] = sentence[2]
table[ everyletter[3] ] = sentence[3]
table[ everyletter[4] ] = sentence[4]
table[ everyletter[5] ] = sentence[5]
...
(skip a few)
...
table[ everyletter[25] ] = sentence[25]
except we only had to write those two lines. Much easier! (P.S. Why just 25? What happened to 26?)
We can combine everything we've done so far into one script. Read it through carefully and see if you can describe what each line does.
Step31:  BREAK TIME!
Congratulations! You're about halfway to the end. Take a minute to stand up, stretch your legs and savor your new  knowledge of Python dictionaries, lists and loops. Then, push Ctrl-Enter in the box below to watch the Minions. When you're done, we'll use the table we just created to encode our message.
Step32:  Using our table to encode
Welcome back! We're almost ready to encode our message using our table. Start with this for loop. Before you hit Ctrl-Enter, see if you can predict how Python will respond. Then run it and see if you were right.
Step33:  That's not very secret yet. This time, instead of printing our each letter of our message, let's look in the table, swap the letter, then print it out. Do the same as before with this code. Can you predict what Python will do?
Step34:  Oops! It seemed to be doing fine, but we crashed on the 5th letter. Python called it a "KeyError". What do you think that means? 
We'll need to do some "debugging." Try modifying your loop like this. This way, we'll see each letter before and after it's encoded. We won't leave this in out final program, but it will help us to find the problem.
Step35:  It's the space! Python is complaining because we asked for the table entry with a space, ' ', in the left column. But there is no such entry. Remember when we called the left hand column the "keys"? A KeyError means we asked for a key that isn't in the table. It even told us the incorrect key was ' '--the space! There are several ways to solve this. What would you do? Take a minute and try it.
One way to solve this is just to add a dictionary entry for ' '.
Step36:  Now, there is an entry for ' '. It just gets replaced by ' ' again. Now our original program works.
Step37:  We did it! This is just what we'd expect if we encoded this message by hand.
We can do a few things to improve it. First, we can create a new string rather than printing our encoded message with one letter on each line. We'll first create a string that has no letters in it. As we encode each letter, we'll add it to the string. Then we'll print it at the end.
Step38:  Let's look closer at this one, too. At the beginning, 
    coded_message
 had no letters at all. But at each step of the loop, instead of printing 
    table[letter]
 we add it to the end of
    coded_message
 by writing 
coded_message = coded_message + table[letter]
To Python, the equal sign means making a change. Whatever is to the left of the = is the thing we're replacing. To programmers, this 'thing' is called a 'variable'. A variable is a name that represents something else (a number, a word, a dictionary) in your program. In this case, Python knows we want to put something new into coded_message. And what is that something? It's the original coded_message plus table[letter].
Let's consider one more thing. The line print (coded_message) is not indented. Why? What would happen if we indented that? Try it!
We can put this all together to have a single program that creates our table and encrypts our message
Step39:  This is pretty slick. All we have to do is replace "this is a super secret message" with our own and Python does the rest of the work. Now, it's time to play around. Change the script above to encrypt a message of your own. One word of warning. We're not ready to use capital letters or punctuation yet. Use just lower case letters. 
You can also try replacing "thequickbrownfox.." with your own sentence. What if your sentence is all x's ("xxxxxxxxxxxxx")? 
Here are some other things to try
Step40:  Getting Input From the User
It's a lot of work to modify your program for every new message you want to encode. Let's give the message another name like "uncoded_message"
Step41:  Uh-oh! Can you find and fix the problem above?
We need to assign uncoded_messageto be something. We can add a line like this
Step42:  Important note for instructors
Step43:  Now, let's add this to our main program. One quick tip. For now, when our program asks for input, you might want to use all lower case letters--no capitals and no punctuation. You're welcome to try anything you want, but don't be frustrated by the error messages. We'll discuss the reason for those a little later.
Step44:  In the above code, we made a few other changes. Can you see them? We added some lines beginning with #. When we begin a line with #, we're telling Python that the line is just for other humans to read and Python ignores it. So, we can put whatever we want there and it won't affect our program. It's a good idea to put comments in your program so someone else knows what you're doing.
Decoding your message
Our encoded messages aren't much good if we can't decode them! To decode a message encoded with a substitution cipher, we switch the columns of the table. If during encoding, we replaced all the a's with t's, then to decode we should change the t's back into a's. But our table generated with the "quick brown fox" sentence creates a problem. Here it is below.
<html><table>
<tr><td>Old letter<br></td><td>New letter<br></td><td><br></td><td>Old letter<br></td><td>New letter</td>
<tr><td>A</td><td>T</td><td></td><td>N</td><td>F</td>
<tr><td>B</td><td>H</td><td></td><td>O</td><td>O</td>
<tr><td>C</td><td>E</td><td></td><td>P</td><td>X</td>
<tr><td>D</td><td>Q</td><td></td><td>Q</td><td>J</td>
<tr><td>E</td><td>U</td><td></td><td>R</td><td>U</td>
<tr><td>F</td><td>I</td><td></td><td>S</td><td>M</td>
<tr><td>G</td><td>C</td><td></td><td>T</td><td>P</td>
<tr><td>H</td><td>K</td><td></td><td>U</td><td>E</td>
<tr><td>I</td><td>B</td><td></td><td>V</td><td>D</td>
<tr><td>J</td><td>R</td><td></td><td>W</td><td>O</td>
<tr><td>K</td><td>O</td><td></td><td>X</td><td>V</td>
<tr><td>L</td><td>W</td><td></td><td>Y</td><td>E</td>
<tr><td>M</td><td>N</td><td></td><td>Z</td><td>R</td>
</table></html>
In this table, 'c', 'u' and 'y' are all being changed into 'e'. So, when my encoded message contains an 'e', how will I know whether if began as a c, u or y?
We can solve this by making sure each letter appears only once in 'sentence.' We could, for example, assign sentence to be 'thequickbrownfxjmpdvlazygs'. This is easy to do and gives a well-behaved table, but with just a little thought, we can get Python to remove the duplicate letters for us.
### 'if' statements
An 'if' statement will do the trick here. 'If' statements allow us to provide two sets of instructions and letting Python decide which set to run based on a test that we determine. In our program, we're going to tell Python to consider each letter of our sentence individually. If the letter is not already part of our table, then use it. If not, ignore it. But let's start with an easier one first. Run the box below with Ctrl-Enter.
Step45:  That looks easy enough.
Step46:  Aha. No message that time. Notice that the indenting rules are the same for "if" statements as for "for" statements. As long as you indent, Python will treat each new statement as part of the "if" clause and only execute it if the "if" condition is true. What if I'm not Luke?
Next, let's let the user decide her own name.
Step47:  You should get a message only if you tell Python your name is Luke. There's one new idea here. I used "==" instead of "is" here. In Python, these two mean almost the same thing. Usually you can get away with using either, but it's a good idea to always use == when comparing two strings. This is particularly true when one string is returned by input.
We could do this test for a list of names. Can you modify the code above to repeat this for a list of names, say 
["Leia", "Luke", "Anakin"]
and only greet Luke? It's a little bit tricky. If Python gives you an error message, be sure to read it. It often gives you a clue about how to fix the problem. If you give up, scroll down to see my answer.
<br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>
Step48:  We combined the for loop that we already know with the if statement we're just learning about. We made a list and for every name in the list we first checked if that name is "Luke", then sent a message only to Luke.
The indentation was tricky here. Look at the line that starts with print. We indented that one a long way! That's because we wanted that line to be part of the "if" code. But the "if" statement was already indented because it's in the for loop. So we indented it twice. If we don't indent enough, we'll get an error from Python. Try it. One rule about Python is that after a line that ends with a colon (like if and for statements) we always have to indent one more level.
Poor Leia. It's a shame to leave her out. (Spoiler alert
Step49:  The other way is to explicitly leave Anakin out. Python also understands "not", but in a funny way. Watch.
Step50:  Python first tests
name is "Anakin"
then the "not" tells Python to reverse that decision and execute the code only if the name is not Anakin.
Removing our duplicates with "if"
Now, let's use an if loop to remove the duplicates from our sentence. It looks a lot like our greeting loop above.
Step51:  That looks almost right. It would be perfect if not for that lousy space. To get rid of that, we can use "and" to test two different things. With "or" we only needed one of the two tests to be true ("either Luke OR Leia") but with "and", both statements must be true. Try this.
Step52:  Perfect. Let's incorporate this into our code. In the code below, I've left a tricky "bug". A "bug" is what programmers call a mistake in the code that causes the program not to work right. 
Because of our bug, we seem to be getting the very same output. Try using "cuy" as your message. Why are c and y both still being changed to 'e'? To get really confused, try making your message "jdatddr". What's going on there? You might want to add some "print" statements to help you see what's going on.
Step53:  Ouch! Errors again. Unfortunately, lots of computer programming is finding problems ("bugs") in your code. Try to solve the problem above. It might help to add some "print" statements.
If you couldn't find the problem above (which is OK. It's a hard bug to see), I'll tell you that we've gone to the trouble of creating a "passphrase" with no spaces or duplicates, but then we still used "sentence" to create our table. In place of the line
table[ everyletter[num]] = sentence[num]
write
table[ everyletter[num]] = passphrase[num]
See if you get better answers.
Decoding
At last, we're ready to do some decoding. Suppose your friend encoded a message with the program above and sent it to you. The message you got was "nuuv nu bf vku jtpo tv dby vkbpvg". How would you decode it?
Well, if we can build the same table, we can use it in reverse. In our new table m's become n's during encoding. So, during decoding, I change all the n's back to m's. All the e's became u's so I change all u's back to e's. The t's were changed to v's, so I change them back to t's and so on. Already I know that the first two words of the message are "meet me". Here's the full table so you can decode the rest of the message. Once you're done, we'll see how to do get Python to do it.
<html><table>
<tr><td>Old letter<br></td><td>New letter<br></td><td><br></td><td>Old letter<br></td><td>New letter</td>
<tr><td>A</td><td>T</td><td></td><td>N</td><td>F</td>
<tr><td>B</td><td>H</td><td></td><td>O</td><td>X</td>
<tr><td>C</td><td>E</td><td></td><td>P</td><td>J</td>
<tr><td>D</td><td>Q</td><td></td><td>Q</td><td>M</td>
<tr><td>E</td><td>U</td><td></td><td>R</td><td>P</td>
<tr><td>F</td><td>I</td><td></td><td>S</td><td>D</td>
<tr><td>G</td><td>C</td><td></td><td>T</td><td>V</td>
<tr><td>H</td><td>K</td><td></td><td>U</td><td>L</td>
<tr><td>I</td><td>B</td><td></td><td>V</td><td>A</td>
<tr><td>J</td><td>R</td><td></td><td>W</td><td>Z</td>
<tr><td>K</td><td>O</td><td></td><td>X</td><td>Y</td>
<tr><td>L</td><td>W</td><td></td><td>Y</td><td>G</td>
<tr><td>M</td><td>N</td><td></td><td>Z</td><td>S</td>
</table></html>
The hardest part of decoding was having to search through the "New letter" column for each letter. Other than that, it was exactly like encoding except that we're finding letters in the "New letter" column, then replacing them with the letter in the "Old letter" column. So, we can use python to decode by just switching the columns. In the language of Python dictionaries, we need to switch the "keys" and "values." Remember that, for a dictionary, the "keys" were always on the left side of the equal sign and in the parentheses. The values were to the right of the equal sign. So, instead of building our table like this
    for num in range(26)
Step54:  (Did you forget to switch "everyletter" and "passphrase"?)
Finishing up
As our final task, we're going to give the user the option to encode or decode with the same script. Let's use "input" to ask the user whether she's encoding or decoding. If she's decoding, let's leave the table just like it is above. If she's encoding, let's rebuild the table like we did originally. Try it yourself on the code below. My answer is beneath that.
<ASSISTANT_TASK:>
Python Code:
print ("Hello my name is Levi.")
Explanation: Sending Secret Messages with Python
This notebook will teach you how to send secret messages to your friends using a computer language called "Python." Python is used by thousands of programmers around the world to create websites and video games, to do science and math, even this web page is written using Python! 
Before we learn any Python, we need to learn just a bit about secret codes. One way to make your message secret is using a "substitution cipher." This means that we replace every letter in our message with a different letter. For example, all of the c's in our message might become j's. The message will look like garbled nonsense to anyone who doesn't know which letter has been substituted. By the time you're done with this page, you'll be able to make this message
this is a super secret message
Look like this
pkbm bm t mexuu mueuup nummtcu
Only someone who knows the password will be able to turn it back into the original message. (By the way, did you notice, above that everywhere there's an 's' in the original message, the coded message has an 'm'?)
To use a substitution cipher, the first thing to do is to decide which letter will replace which. We'll create a table like this one:
<html><table>
<tr><td>Old letter<br></td><td>New letter<br></td>
<tr><td>A</td><td>N</td>
<tr><td>B</td><td>F</td>
<tr><td>C</td><td>R</td>
<tr><td>D</td><td>L</td>
<tr><td>E</td><td>A</td>
<tr><td>F</td><td>T</td>
<tr><td>G</td><td>Z</td>
<tr><td>H</td><td>B</td>
<tr><td>I</td><td>Q</td>
<tr><td>...</td><td>...</td>
</table></html>
I've only shown part of the table. We'll see the rest later. 
The values in your table are not important except for a few rules:
1. Every letter in the alphabet must be in the left column. 
2. Every letter must be in the right column.
3. Both you and the person you're sending to must know this table. 
To encode using your table is easy. For each letter in your message, instead of writing that letter, find it in the left column of your table, then write down the letter in the same row, but in the right column. For example, if your message is 
    ABBA HIGH DEF,
using the table above, you would encode it as 
    NFFN BQZB LAT.
Take a minute to make sure I got it right. 
## How to use this notebook
This lesson is written as a Jupyter notebook. Notebooks are a convenient way to add Python to a website. Wherever you see a box with "In [ ]:" next to it, you can click inside the box, then hold down the Ctrl button and press the Enter button at the same time to make Python run the code inside. Try it with the box below.
End of explanation
table={}
print (table)
Explanation: You can also change the code in the boxes before you run them. Try replacing "Levi" with your name in the box above. Now, while the cursor is still in the box, push Ctrl+Enter to see Python echo it back. From here on out, make a habit of executing each box in this notebook with Ctrl-Enter.
Now that you know a little bit about Jupyter notebooks, we're ready to learn some Python!
Python Dictionaries
To get Python to do this work for us, the first thing to do is to decide on a table and create a 'dictionary' in Python that keeps track of which letters get replaced by which new letters. A Python dictionary is a lot like the two-column table we've been talking about. We create an empty table like this:
End of explanation
table={}
table['a'] = 'n'
print (table)
Explanation: Don't go on until you click into the box above and push Ctrl+Enter. You should see {} appear below the box. One more thing about Jupyter notebooks. Each time you execute a box, Python remembers what you've done. Here, we created a dictionary called "table." When we refer to "table" in the next box, Python will remember that "table" is an empty dictionary. The code in the box below adds one entry to your dictionary with the letter 'a' in the left column and 'n' in the right column. Try it out by pushing Ctrl-Enter in the box below.
End of explanation
newletter = table['a']
print(newletter)
Explanation: Don't be afraid to change the code in the boxes. You'll learn a lot by playing around, so don't be shy. Make some changes to the code in the boxes, then push Ctrl-Enter to see what you changed. You might get an error from Python. That's OK. See if you can figure out how to fix it. As you play around, remember that the notebook is remembering your changes. If you want to clear the notebook's memory and start again, look for the menu option above called "Kernel." Select "Restart" from that sub menu.
Quick tip: In the box above, make sure to put the quotation marks around your letters. 
Now that our table has some values in it, we can read from it like this:
End of explanation
table['b'] = 'f'
table['c'] = 'r'
print(table)
table.keys()
table.values()
print(table['c'])
print(table)
Explanation: The first line, newletter = table['a'], tells Python to read the entry we gave it for 'a' and call it by a new name, newletter. In this case, table['a'] is 'n'. After that, everytime we refer to newletter Python will remember that we told it newletter is 'n'. So, when we ask Python to print newletter, it remembers and prints 'n'. newletter is what programmers call a 'variable'--a name that refers, in your program, to some other value.
A few more things about our Python tables (also called 'dictionaries'). The values on the left hand side of the table are called the "keys." The right hand are called the "values." Let's add a few rows to our table, then ask Python some questions. Push Ctrl-Enter in the boxes below and see what Python answers.
End of explanation
print(table['d'])
Explanation: The colon (:) separates a "key" from its "value."  'a':'n' means that all the a's become n's during encoding.
What if we ask for a table entry that hasn't been set yet?
End of explanation
'd' in table.keys( )
Explanation: Python didn't like that and sent us back a KeyError. To avoid these errors, we can first check to see whether that table entry exists.
End of explanation
table['d'] = 'n'
'd' in table.keys()
Explanation: We just asked Python, "Is d one of the keys in our table?" Python said, "No."
Now, let's create a table entry for 'd' and ask again.
End of explanation
table['d'] = 'l'
print(table['d'])
Explanation: A key can only appear in the left column one time. If I try to assign one letter on the left column to two different letters on the right, the dictionary will store the last value.
End of explanation
myList=['t','h','e','q']
print(myList)
Explanation: The old table entry for 'd' is lost and replaced by the new value. Note that more than one key can correspond to a single value. When we assigned 'd' to be changed to 'n', both 'a' and 'd' were being translated to 'n'. That's perfectly OK.
Python Lists
Way to go! Hopefully, you're feeling comfortable with dictionaries. Make sure to execute the code in the boxes as you go by clicking into the box and pushing Ctrl-Enter. 
Next, we'll take a look at lists. A python list is like a dictionary where the keys are numbers, specifically integers (i.e. 0,1,2,3,4,5...). We can create a list like this:
End of explanation
myList[2] 
Explanation: The list works a lot like a dictionary with numbers in the left column. We can ask for specific letters in the list by referring to their position in the list. Try this:
End of explanation
myList[0]
Explanation: Wait, but isn't 'e' the third letter in the list? It's important to remember that computers start counting from zero.
End of explanation
myList[4]
Explanation: In a Python list, position 0 is the very start of the list. Now, there are 4 letters in the list. What do you think will happen if we ask for the letter in position 4?
End of explanation
myString = "the quick brown fox jumped over the lazy dogs"
myString
Explanation: What do you think this error means? (Hint: "index" is the number inside the square brackets.)
The first element in our list is number 0. The last is number 3.
A quick note: if Python starts responding to you with errors like 'myList' is not defined it usually means you missed executing one of the code boxes. Make sure you push Ctrl-Enter in each box with a In [ ] next to it.
Python strings are lists
A bunch of text all together in Python is called a "string." Here's a string
End of explanation
myString[2]
Explanation: Our string acts just like a list
End of explanation
myString[3]
Explanation: The third letter in our string is 'e'. We ask Python for letter number 2 since Python starts counting from zero. 
Even the spaces in our string are considered letters.
End of explanation
table={}
table['a']='t'
print(table)
Explanation: The output above just looks like two quote marks, but there's actually a space between them. The 4th "letter" in our string is actually a space. 
Take a minute to write some code yourself involving strings. You can edit the code in the box above and push Ctrl-Enter to execute it. Can you figure out which letter is 'q'? Or 'b'? What if you pick a number that's too large, like 100?
Creating a cipher table from a sentence
Let's create a table we can use to encode and decode our messages. I want to change all of my a's into t's. How can we create a Python dictionary to do that?
End of explanation
table['b']='h'
print(table)
Explanation: Next, I'll add a row for changing all of the b's.
End of explanation
sentence = "the quick brown fox jumped over the lazy dogs"
Explanation: In fact, what I'd like to do is to take an easy to remember phrase and use it to determine the right hand side of my table. I'd like to put 'abcdefghijklmnopqrstuvwxyz' down the left hand column and 'the quick brown fox jumped over the lazy dogs' down the right hand side. So 'a' changes to 't'. 'b' changes to 'h'. 'c' changes to 'e' and so on.
<html><table>
<tr><td>Old letter<br></td><td>New letter<br></td>
<tr><td>a</td><td>t</td>
<tr><td>b</td><td>h</td>
<tr><td>c</td><td>e</td>
<tr><td>d</td><td>q</td>
<tr><td>e</td><td>u</td>
<tr><td>f</td><td>i</td>
<tr><td>g</td><td>c</td>
<tr><td>h</td><td>k</td>
<tr><td>i</td><td>b</td>
<tr><td>...</td><td>...</td>
</table></html>
How can I do this in Python? We can write a loop to create a dictionary from two strings. Let's build the same string as before.
End of explanation
sentence[10]
Explanation: Just like before, we can treat it like a list of letters.
End of explanation
everyletter = "abcdefghijklmnopqrstuvwxyz"
Explanation: Now, let's create another string like this.
End of explanation
table={}
table['a']='t'
table['b']='h'
table['c']='e'
table['d']='q'
table['e']='u'
table['f']='i'
table['g']='c'
#And on and on...
table
Explanation: We're going to use these two strings to create a table like this
<html><table>
<tr><td>Old letter<br></td><td>New letter<br></td>
<tr><td>a</td><td>t</td>
<tr><td>b</td><td>h</td>
<tr><td>c</td><td>e</td>
<tr><td>d</td><td>q</td>
<tr><td>e</td><td>u</td>
<tr><td>f</td><td>i</td>
<tr><td>g</td><td>c</td>
<tr><td>h</td><td>k</td>
<tr><td>i</td><td>b</td>
<tr><td>j</td><td>r</td>
<tr><td>k</td><td>o</td>
<tr><td>l</td><td>w</td>
<tr><td>m</td><td>n</td>
<tr><td>n</td><td>f</td>
<tr><td>o</td><td>o</td>
<tr><td>p</td><td>x</td>
<tr><td>q</td><td>j</td>
<tr><td>r</td><td>u</td>
<tr><td>s</td><td>m</td>
<tr><td>t</td><td>p</td>
<tr><td>u</td><td>e</td>
<tr><td>v</td><td>d</td>
<tr><td>w</td><td>o</td>
<tr><td>x</td><td>v</td>
<tr><td>y</td><td>e</td>
<tr><td>z</td><td>r</td>
</table></html>
To create this list in Python, we could do this:
End of explanation
table={}
table[ everyletter[0]] = sentence[0]
table[ everyletter[1]] = sentence[1]
table[ everyletter[2]] = sentence[2]
table[ everyletter[3]] = sentence[3]
table[ everyletter[4]] = sentence[4]
#And on and on...
table
Explanation: But what if someone discovered our passphrase ("the quick brown fox...")? We'd have to change each of the individual letters. Instead, we can tell Python to read the letters from the strings, everyletter and sentence, that we created above. Take a look at this. We're using some fancier Python tricks that I'll explain in a minute.
End of explanation
table[ everyletter[1]] = sentence[0]
print(table)
Explanation: This requires some explanation. The first line, I think you'll remember, creates an empty table or dictionary. Then, when we write
table[ everyletter[0]] = sentence[0]
Python will look inside the square brackets, [], following "table[" to see which letter to put in the left hand column. Instead of a letter, Python sees everyletter[0]. To Python, this means the first letter in the string called "everyletter"--a. So, Python puts 'a' in the left hand column. 
Next, it looks for what to put in the right column after the equal sign. There, Python sees
    sentence[0]
which it knows means the first letter in the string "sentence" or 't'. So, Python creates a row in the table with 'a' in the left column and 't' in the right column. When we started encoding message, we'll turn all the a's into t's.
So, Python will act as if we wrote
 table['a'] = 't'
adding one entry to our translation table.
The line
table[ everyletter[1]] = sentence[1]
creates another new row with the second letter in "everyletter" and the second letter in "sentence." Can you figure out what will be in the left and right columns of this new row?
This is tricky. When learning new programming ideas, it's important to play around a little. Play around with adding rows to your table. What would happen if I wrote
End of explanation
table={}
for num in range(26):
    table[ everyletter[num]] = sentence[num]
table
Explanation: What changed? Why? This is another good chance to play around by writing your own code.
Loops in Python
Instead of writing 26 lines like table[ everyletter[14]] = sentence[14], I'd like to write it just once, then have the computer repeat it 26 times increasing the number each time. For this, we use a "for loop." Try this
End of explanation
for name in ["Bart", "Lisa", "Maggie"]:
    print ("Hi, " + name)
Explanation: Don't worry if this isn't clear yet. We'll take a good look at this. The first line creates an empty dictionary. The next line is the loop
for num in range(26):
In ordinary English, it tells Python to create a list of 26 numbers starting from zero. Then Python executes the next command (table[ everyletter[num]] = sentence[num]) one time for each number in the list. Each time it replaces 'num' with one of the numbers.
Of course, you don't have to use 'num.' You can use anything you want. You could use your name
for maria in range(26):
With this new version, it will replace 'maria' with each of the numbers.
As a side note, you can use any name you want, but in writing computer programs, it's best to be as clear as you can about what all the parts are doing. You never know when you'll have to read your own program to fix problems or add something new. Also, when you write larger programs, you're usually working with a team of programmers. It might be someone else reading and fixing your code. Make sure your program is clear enough for someone else to read and understand.
Let's do a simpler loop first
End of explanation
for villain in ["Kylo Ren", "The Joker", "Magneto", "Megamind"]:
    print ("Oh no! It's " + villain)
    print ("I'll stop you!")
print ("You'll never get away with this.")
Explanation: Here, we gave Python a list of three names. For each name on the list, Python executes the commands that follow, replacing "name" with one of the names in the list. This is the first time we've seen + in Python, but it's an easy one. "Hi, " + name, just means that we add each name in the list to the end of "Hi, " and send that to print.
Try editing the loop above. Add your name (maybe it's Homer?). Make a list of your favorite sports teams and make Python cheer for them.
One tricky rule in Python involves indenting. It's possible to put lots of commands inside one for loop, but Python needs to be able to know which commands are in the loop and which are not. Each line that we want to be part of the loop, we indent, but we don't indent the for the loop statement itself. When Python sees a line that's not indented, it knows you've finished writing the loop. Take a look at this. Change the indenting and see what happens. What if you don't indent the "I'll stop you"? What if you do indent "You'll never get away with this"? Try it!
End of explanation
for villain in ["Kylo Ren", "The Joker", "Magneto", "Megamind"]:
    print ("Oh no! It's " + villain)
print ("I'll stop you!")
    print ("You'll never get away with this.")
Explanation: The spaces before the print statements tell us whether they're part of the loop to be executed once for each villain, or just a lone command to be executed only once. 
What about this?
End of explanation
for num in range(26):
    table[ everyletter[num]] = sentence[num]
table
Explanation: Python didn't like that. The line that says print("I'll stop you!") was not indented. So, Python thought you were done with that loop. When it saw that print("You'll never get away with this.") was indented, it didn't know what loop it was part of. So, it sent an error message. Errors are part of programming. They can be intimidating, but it can help you to sort out the problem if you read the error message. Here, Python told us "unexpected indent" and referred to print("You'll never get away with this."). It clearly didn't expect that line to be indented.
Using Loops to make a table
Now let's use our loops to create a code table
End of explanation
for i in range(5):
    print(i)
Explanation: The "range" function just generates a list of numbers beginning with zero. The code below creates a list from 0 to 4 (5 total numbers), then prints each one.
End of explanation
table = {}
everyletter = "abcdefghijklmnopqrstuvwxyz"
sentence = "thequickbrownfoxjumpedoverthelazydogs"
for num in range(26):
    table[ everyletter[num]] = sentence[num]
table
Explanation: So, to make our table, we make a list of numbers from 0 to 25, then for each number, Python repeats the command
table[ everyletter[num] ] = sentence[num]
but it replaces 'num' with each of the numbers in the list. So it's exactly the same as writing
table[ everyletter[0] ] = sentence[0]
table[ everyletter[1] ] = sentence[1]
table[ everyletter[2] ] = sentence[2]
table[ everyletter[3] ] = sentence[3]
table[ everyletter[4] ] = sentence[4]
table[ everyletter[5] ] = sentence[5]
...
(skip a few)
...
table[ everyletter[25] ] = sentence[25]
except we only had to write those two lines. Much easier! (P.S. Why just 25? What happened to 26?)
We can combine everything we've done so far into one script. Read it through carefully and see if you can describe what each line does.
End of explanation
from IPython.display import YouTubeVideo
YouTubeVideo("rl6-zJharrs")
Explanation: BREAK TIME!
Congratulations! You're about halfway to the end. Take a minute to stand up, stretch your legs and savor your new  knowledge of Python dictionaries, lists and loops. Then, push Ctrl-Enter in the box below to watch the Minions. When you're done, we'll use the table we just created to encode our message.
End of explanation
for letter in "this is a super secret message":
    print (letter)
Explanation: Using our table to encode
Welcome back! We're almost ready to encode our message using our table. Start with this for loop. Before you hit Ctrl-Enter, see if you can predict how Python will respond. Then run it and see if you were right.
End of explanation
for letter in "this is a super secret message":
    print (table[letter])
Explanation: That's not very secret yet. This time, instead of printing our each letter of our message, let's look in the table, swap the letter, then print it out. Do the same as before with this code. Can you predict what Python will do?
End of explanation
for letter in "this is a super secret message":
    print ("old: " + letter)
    print ("new: " + table[letter])
Explanation: Oops! It seemed to be doing fine, but we crashed on the 5th letter. Python called it a "KeyError". What do you think that means? 
We'll need to do some "debugging." Try modifying your loop like this. This way, we'll see each letter before and after it's encoded. We won't leave this in out final program, but it will help us to find the problem.
End of explanation
table[' '] = ' '
Explanation: It's the space! Python is complaining because we asked for the table entry with a space, ' ', in the left column. But there is no such entry. Remember when we called the left hand column the "keys"? A KeyError means we asked for a key that isn't in the table. It even told us the incorrect key was ' '--the space! There are several ways to solve this. What would you do? Take a minute and try it.
One way to solve this is just to add a dictionary entry for ' '.
End of explanation
for letter in "this is a super secret message":
    print (table[letter])
    table[' '] = ' '
Explanation: Now, there is an entry for ' '. It just gets replaced by ' ' again. Now our original program works.
End of explanation
coded_message = ""
for letter in "this is a super secret message":
    coded_message = coded_message + table[letter]
print (coded_message)
Explanation: We did it! This is just what we'd expect if we encoded this message by hand.
We can do a few things to improve it. First, we can create a new string rather than printing our encoded message with one letter on each line. We'll first create a string that has no letters in it. As we encode each letter, we'll add it to the string. Then we'll print it at the end.
End of explanation
table = {}
everyletter = "abcdefghijklmnopqrstuvwxyz"
sentence = "thequickbrownfoxjumpedoverthelazydogs"
for num in range(26):
    table[ everyletter[num]] = sentence[num]
table[' '] = ' '
coded_message = ""
for letter in "this is a super secret message":
    coded_message = coded_message + table[letter]
print (coded_message)
Explanation: Let's look closer at this one, too. At the beginning, 
    coded_message
 had no letters at all. But at each step of the loop, instead of printing 
    table[letter]
 we add it to the end of
    coded_message
 by writing 
coded_message = coded_message + table[letter]
To Python, the equal sign means making a change. Whatever is to the left of the = is the thing we're replacing. To programmers, this 'thing' is called a 'variable'. A variable is a name that represents something else (a number, a word, a dictionary) in your program. In this case, Python knows we want to put something new into coded_message. And what is that something? It's the original coded_message plus table[letter].
Let's consider one more thing. The line print (coded_message) is not indented. Why? What would happen if we indented that? Try it!
We can put this all together to have a single program that creates our table and encrypts our message
End of explanation
table = {}
everyletter = "abcdefghijklmnopqrstuvwxyz"
sentence = "thequickbrownfoxjumpedoverthelazydogs"
for num in range(26):
    table[ everyletter[num]] = sentence[num]
print (table)
table[' '] = ' '
coded_message = ""
for letter in "my teacher is a handsome genius":
    coded_message = coded_message + table[letter]
print (coded_message)
Explanation: This is pretty slick. All we have to do is replace "this is a super secret message" with our own and Python does the rest of the work. Now, it's time to play around. Change the script above to encrypt a message of your own. One word of warning. We're not ready to use capital letters or punctuation yet. Use just lower case letters. 
You can also try replacing "thequickbrownfox.." with your own sentence. What if your sentence is all x's ("xxxxxxxxxxxxx")? 
Here are some other things to try:
- Try encoding "abcdefghijklmnopqrstuvwxyz" as your secret message? Where did the "lazy dogs" go?
- Encode your message twice to make it harder to crack. You can do this by putting your encoded output in as your secret message, but there's an easier way. What if you replace the line
    coded_message = coded_message + table[letter]
with
     coded_message = coded_message + table[table[letter]]
What do you expect it to do? See if you can predict the result for a short message like your name.
- Can you decode your message? What happens if your switch the alphabet and the sentence? Why?
Here's another copy of the same code so you'll still have a clean copy to refer to as you play around.
End of explanation
coded_message = ""
for letter in uncoded_message:
    coded_message = coded_message + table[letter]
print (coded_message)
Explanation: Getting Input From the User
It's a lot of work to modify your program for every new message you want to encode. Let's give the message another name like "uncoded_message"
End of explanation
name = input("What is your name? ")
print ("Well, hello, " + name)
Explanation: Uh-oh! Can you find and fix the problem above?
We need to assign uncoded_messageto be something. We can add a line like this:
uncoded_message = "this is a super secret message"
Add it to the program above and see how it works. Make sure to add it <i>before</i> the loop. Python runs your commands starting from the top. Before it can use the variable uncoded_message it needs you to tell it what uncoded_message is.
Instead of having the secret message in the program, there is a way to ask the user to provide the message. The command for this is "input." Try this.
End of explanation
uncoded_message = input("What message should I encode?")
coded_message = ""
for letter in uncoded_message:
    coded_message = coded_message + table[letter]
print (coded_message)
Explanation: Important note for instructors: If students are getting an error above, you may be using Python version 2.7. If you can switch to Python 3, it will work better. Otherwise, you can get around these errors by putting your answers to "input" in quotation marks. For example, when it asks, What is your name? type "Marcus" with the quotation marks.
Let use the same thing for getting a secret message. Modify the code below to use input to create uncoded_message.
End of explanation
#First, create our substitution table
table = {}
everyletter = "abcdefghijklmnopqrstuvwxyz"
sentence = "thequickbrownfoxjumpedoverthelazydogs"
for num in range(26):
    table[ everyletter[num]] = sentence[num]
table[' '] = ' '
#Get a message from the user
uncoded_message = input("Type your message here, then press enter: ")
#Encode and print the message
coded_message = ""
for letter in uncoded_message:
    coded_message = coded_message + table[letter]
print (coded_message)
Explanation: Now, let's add this to our main program. One quick tip. For now, when our program asks for input, you might want to use all lower case letters--no capitals and no punctuation. You're welcome to try anything you want, but don't be frustrated by the error messages. We'll discuss the reason for those a little later.
End of explanation
name = "Luke"
if name is "Luke":
    print ("May the force be with you, " + name)
Explanation: In the above code, we made a few other changes. Can you see them? We added some lines beginning with #. When we begin a line with #, we're telling Python that the line is just for other humans to read and Python ignores it. So, we can put whatever we want there and it won't affect our program. It's a good idea to put comments in your program so someone else knows what you're doing.
Decoding your message
Our encoded messages aren't much good if we can't decode them! To decode a message encoded with a substitution cipher, we switch the columns of the table. If during encoding, we replaced all the a's with t's, then to decode we should change the t's back into a's. But our table generated with the "quick brown fox" sentence creates a problem. Here it is below.
<html><table>
<tr><td>Old letter<br></td><td>New letter<br></td><td><br></td><td>Old letter<br></td><td>New letter</td>
<tr><td>A</td><td>T</td><td></td><td>N</td><td>F</td>
<tr><td>B</td><td>H</td><td></td><td>O</td><td>O</td>
<tr><td>C</td><td>E</td><td></td><td>P</td><td>X</td>
<tr><td>D</td><td>Q</td><td></td><td>Q</td><td>J</td>
<tr><td>E</td><td>U</td><td></td><td>R</td><td>U</td>
<tr><td>F</td><td>I</td><td></td><td>S</td><td>M</td>
<tr><td>G</td><td>C</td><td></td><td>T</td><td>P</td>
<tr><td>H</td><td>K</td><td></td><td>U</td><td>E</td>
<tr><td>I</td><td>B</td><td></td><td>V</td><td>D</td>
<tr><td>J</td><td>R</td><td></td><td>W</td><td>O</td>
<tr><td>K</td><td>O</td><td></td><td>X</td><td>V</td>
<tr><td>L</td><td>W</td><td></td><td>Y</td><td>E</td>
<tr><td>M</td><td>N</td><td></td><td>Z</td><td>R</td>
</table></html>
In this table, 'c', 'u' and 'y' are all being changed into 'e'. So, when my encoded message contains an 'e', how will I know whether if began as a c, u or y?
We can solve this by making sure each letter appears only once in 'sentence.' We could, for example, assign sentence to be 'thequickbrownfxjmpdvlazygs'. This is easy to do and gives a well-behaved table, but with just a little thought, we can get Python to remove the duplicate letters for us.
### 'if' statements
An 'if' statement will do the trick here. 'If' statements allow us to provide two sets of instructions and letting Python decide which set to run based on a test that we determine. In our program, we're going to tell Python to consider each letter of our sentence individually. If the letter is not already part of our table, then use it. If not, ignore it. But let's start with an easier one first. Run the box below with Ctrl-Enter.
End of explanation
name = "Anakin"
if name is "Luke":
    print ("May the force be with you, " + name)
Explanation: That looks easy enough.
End of explanation
name = input("What is your name? ")
if name == "Luke":
    print ("May the force be with you, " + name)
Explanation: Aha. No message that time. Notice that the indenting rules are the same for "if" statements as for "for" statements. As long as you indent, Python will treat each new statement as part of the "if" clause and only execute it if the "if" condition is true. What if I'm not Luke?
Next, let's let the user decide her own name.
End of explanation
for name in ["Luke", "Leia", "Anakin"]:
    if name is "Luke":
        print ("May the force be with you, " + name)
Explanation: You should get a message only if you tell Python your name is Luke. There's one new idea here. I used "==" instead of "is" here. In Python, these two mean almost the same thing. Usually you can get away with using either, but it's a good idea to always use == when comparing two strings. This is particularly true when one string is returned by input.
We could do this test for a list of names. Can you modify the code above to repeat this for a list of names, say 
["Leia", "Luke", "Anakin"]
and only greet Luke? It's a little bit tricky. If Python gives you an error message, be sure to read it. It often gives you a clue about how to fix the problem. If you give up, scroll down to see my answer.
<br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>
End of explanation
for name in ["Luke", "Leia", "Anakin"]:
    if name is "Luke" or name is "Leia":
        print ("May the force be with you, " + name)
Explanation: We combined the for loop that we already know with the if statement we're just learning about. We made a list and for every name in the list we first checked if that name is "Luke", then sent a message only to Luke.
The indentation was tricky here. Look at the line that starts with print. We indented that one a long way! That's because we wanted that line to be part of the "if" code. But the "if" statement was already indented because it's in the for loop. So we indented it twice. If we don't indent enough, we'll get an error from Python. Try it. One rule about Python is that after a line that ends with a colon (like if and for statements) we always have to indent one more level.
Poor Leia. It's a shame to leave her out. (Spoiler alert: she's Luke's sister). We can include her in one of two ways. Python understands the word "or", so we can give Python two names.
End of explanation
for name in ["Luke", "Leia", "Anakin"]:
    if not name is "Anakin":
        print ("May the force be with you, " + name)
Explanation: The other way is to explicitly leave Anakin out. Python also understands "not", but in a funny way. Watch.
End of explanation
sentence = "the quick brown fox jumped over the lazy dogs"
passphrase = ""
for letter in sentence:
    if not letter in passphrase:
        passphrase = passphrase + letter
print (passphrase)
Explanation: Python first tests
name is "Anakin"
then the "not" tells Python to reverse that decision and execute the code only if the name is not Anakin.
Removing our duplicates with "if"
Now, let's use an if loop to remove the duplicates from our sentence. It looks a lot like our greeting loop above.
End of explanation
sentence = "the quick brown fox jumped over the lazy dogs"
passphrase = ""
for letter in sentence:
    if letter not in passphrase and letter is not ' ':
        passphrase = passphrase + letter
print (passphrase)
Explanation: That looks almost right. It would be perfect if not for that lousy space. To get rid of that, we can use "and" to test two different things. With "or" we only needed one of the two tests to be true ("either Luke OR Leia") but with "and", both statements must be true. Try this.
End of explanation
#First, create our substitution table
table = {}
everyletter = "abcdefghijklmnopqrstuvwxyz"
sentence = "the quick brown fox jumped over the lazy dogs"
#Remove the duplicate letters 
passphrase=""
for letter in sentence:
    if letter not in passphrase and letter is not ' ':
        passphrase = passphrase + letter
print (passphrase)
#Build the table
for num in range(26):
    table[ everyletter[num]] = sentence[num]
table[' '] = ' '
#Get a message from the user
uncoded_message = input("Type your message here, then press enter: ")
#Encode and print the message
coded_message = ""
for letter in uncoded_message:
    coded_message = coded_message + table[letter]
print (coded_message)
Explanation: Perfect. Let's incorporate this into our code. In the code below, I've left a tricky "bug". A "bug" is what programmers call a mistake in the code that causes the program not to work right. 
Because of our bug, we seem to be getting the very same output. Try using "cuy" as your message. Why are c and y both still being changed to 'e'? To get really confused, try making your message "jdatddr". What's going on there? You might want to add some "print" statements to help you see what's going on.
End of explanation
#First, create our substitution table
table = {}
everyletter = "abcdefghijklmnopqrstuvwxyz"
sentence = "the quick brown fox jumped over the lazy dogs"
#Remove duplicate letters
passphrase=""
for letter in sentence:
    if letter not in passphrase and letter is not ' ':
        passphrase = passphrase + letter
print (passphrase)
#Build the table
for num in range(26):
    table[ everyletter[num]] = passphrase[num]
table[' '] = ' '
#Get a message from the user
uncoded_message = input("Type your message here, then press enter: ")
#Encode and print the message
coded_message = ""
for letter in uncoded_message:
    coded_message = coded_message + table[letter]
print (coded_message)
Explanation: Ouch! Errors again. Unfortunately, lots of computer programming is finding problems ("bugs") in your code. Try to solve the problem above. It might help to add some "print" statements.
If you couldn't find the problem above (which is OK. It's a hard bug to see), I'll tell you that we've gone to the trouble of creating a "passphrase" with no spaces or duplicates, but then we still used "sentence" to create our table. In place of the line
table[ everyletter[num]] = sentence[num]
write
table[ everyletter[num]] = passphrase[num]
See if you get better answers.
Decoding
At last, we're ready to do some decoding. Suppose your friend encoded a message with the program above and sent it to you. The message you got was "nuuv nu bf vku jtpo tv dby vkbpvg". How would you decode it?
Well, if we can build the same table, we can use it in reverse. In our new table m's become n's during encoding. So, during decoding, I change all the n's back to m's. All the e's became u's so I change all u's back to e's. The t's were changed to v's, so I change them back to t's and so on. Already I know that the first two words of the message are "meet me". Here's the full table so you can decode the rest of the message. Once you're done, we'll see how to do get Python to do it.
<html><table>
<tr><td>Old letter<br></td><td>New letter<br></td><td><br></td><td>Old letter<br></td><td>New letter</td>
<tr><td>A</td><td>T</td><td></td><td>N</td><td>F</td>
<tr><td>B</td><td>H</td><td></td><td>O</td><td>X</td>
<tr><td>C</td><td>E</td><td></td><td>P</td><td>J</td>
<tr><td>D</td><td>Q</td><td></td><td>Q</td><td>M</td>
<tr><td>E</td><td>U</td><td></td><td>R</td><td>P</td>
<tr><td>F</td><td>I</td><td></td><td>S</td><td>D</td>
<tr><td>G</td><td>C</td><td></td><td>T</td><td>V</td>
<tr><td>H</td><td>K</td><td></td><td>U</td><td>L</td>
<tr><td>I</td><td>B</td><td></td><td>V</td><td>A</td>
<tr><td>J</td><td>R</td><td></td><td>W</td><td>Z</td>
<tr><td>K</td><td>O</td><td></td><td>X</td><td>Y</td>
<tr><td>L</td><td>W</td><td></td><td>Y</td><td>G</td>
<tr><td>M</td><td>N</td><td></td><td>Z</td><td>S</td>
</table></html>
The hardest part of decoding was having to search through the "New letter" column for each letter. Other than that, it was exactly like encoding except that we're finding letters in the "New letter" column, then replacing them with the letter in the "Old letter" column. So, we can use python to decode by just switching the columns. In the language of Python dictionaries, we need to switch the "keys" and "values." Remember that, for a dictionary, the "keys" were always on the left side of the equal sign and in the parentheses. The values were to the right of the equal sign. So, instead of building our table like this
    for num in range(26):
        table[ everyletter[num]] = passphrase[num]
we swap "everyletter" and "passphrase"
    for num in range(26):
        table[ passphrase[num]] = everyletter[num]
It's just that easy and we've got a decoder. Make the change yourself here and check it with the message above ("nuuv nu bf vku jtpo tv dby vkbpvg"). What's the decoded message?
End of explanation
#First, create our substitution table
table = {}
everyletter = "abcdefghijklmnopqrstuvwxyz"
sentence = "the quick brown fox jumped over the lazy dogs"
#Remove duplicate letters
passphrase=""
for letter in sentence:
    if letter not in passphrase and letter is not ' ':
        passphrase = passphrase + letter
print (passphrase)
#Build the table
for num in range(26):
    table[ passphrase[num]] = everyletter[num]
table[' '] = ' '
#Get a message from the user
uncoded_message = input("Type your message here, then press enter: ")
#Encode and print the message
coded_message = ""
for letter in uncoded_message:
    coded_message = coded_message + table[letter]
print (coded_message)
#First, create our substitution table
table = {}
everyletter = "abcdefghijklmnopqrstuvwxyz"
sentence = "the quick brown fox jumped over the lazy dogs"
#Remove duplicates
passphrase=""
for letter in sentence:
    if letter not in passphrase and letter is not ' ':
        passphrase = passphrase + letter
print (passphrase)
#Build a table for decoding
for num in range(26):
    table[ passphrase[num]] = everyletter[num]
table[' '] = ' '
#****  This is the new part. If we're encoding, we rebuild the table
#         But we switch everyletter and passphrase
task = input("Are you encoding or decoding?")
if task == "encoding":
    #Build a table for encoding instead
    print ("Remaking table for encoding...")
    for num in range(26):
        table[ everyletter[num]] = passphrase[num]
        
print (table)
#Get a message from the user
uncoded_message = input("Type your message here, then press enter: ")
#Encode and print the message
coded_message = ""
for letter in uncoded_message:
    coded_message = coded_message + table[letter]
print (coded_message)
Explanation: (Did you forget to switch "everyletter" and "passphrase"?)
Finishing up
As our final task, we're going to give the user the option to encode or decode with the same script. Let's use "input" to ask the user whether she's encoding or decoding. If she's decoding, let's leave the table just like it is above. If she's encoding, let's rebuild the table like we did originally. Try it yourself on the code below. My answer is beneath that.
End of explanation
<END_TASK>