ZAMYLA: Let's tackle Caesar. In Caesar, we allow the user to encode a secret message. So let's dive right in and look at our to-dos for this problem. So first, we get the key from the user. Then we get the plaintext that they want to encode. After that, we encipher it for them, and finally we print their ciphertext. So let's start with an example. Say you wanted to encode the entire alphabet with a key of two. Well, your entire alphabet would just be shifted to letters. So A would encode to C, B to D, C to E, so on and so forth, until you get to X, which encodes to Z or zed, depending on where you're from. Then Y would then shift all the way, wrap around the alphabet to get to A, and then finally the last letter of the alphabet, Z, zed, would encode to B. You got that? Let's look at some examples. The first example here is very similar to what we just explained above. So if I encode some section of the alphabet, A through L, by a key of two, then I just get my entire alphabet shifted two letters. Then, in my next example, the key is still two, so you should still know which letters to expect. But here it's a phrase. This is CS50. So you'll notice that I preserve the case of my letters, so any upper case letters are also upper case letters in the ciphertext. And any lowercase letters in the plaintext are also lowercase letters in the ciphertext. But I keep the letters and any exclamation marks or any other punctuation the same. So now that we have a sense for how the program works, feel free to go run some more examples of your own, if you wish. Let's start with getting the key from the user. Traditionally, with other problems, we've been accustomed to getting any numbers that we need by prompting the user with the function getint. But this time we're actually going to use the command line argument and a new function called atoi. When you run the main program in C, then it takes in two parameters-- int argc, which is the number of arguments passed in, and then argv, an array of strings which contains the list of all of the arguments passed. You don't explicitly have to declare these variables. They're computed for you by the compiler. Correct usage for this would be for argc to be two in this case, because the user has to pass in the call to the program, ./caesar, and then the key, whatever number they wish. So that means that argc must be two in order for a valid use of Caesar to be executed. So let's look at an example. Say I've already written and compiled a program called blastoff. So if I ran in the command line ./blastoff Team Rocket, well, then, argc would be three because I passed in three distinct arguments. Then argv would look like this. It's an array, and it would contain each of the three strings. ./blastoff in the first index, team in the next, and rocket in the last. Let's talk about arrays for a sec. Arrays are data structures that hold multiple values of the same type. This can come in handy when we have lists of integers or strings. Just remember they have to be the same type. In computer science, we love counting from zero, so remember that arrays are also zero-indexed. So the first element of my array is going to be at index zero. So in this case, when I have an array of length four, then the last index of the last element of my array is actually going to be at index three, not four. Because remember, we start counting at zero. Here's an example of how you might create an array of your own. So say I wanted to store my three favorite dog names. Then I would create an array of strings. So I would declare the type, string, and then put the name of the array, dogs, and then in those square brackets put the size of the array-- in this case, three. So my first entry is going to be dogs at index zero, and that's going to be Milo. Then dogs at index one is going to be goofy, darling Mochi, and then the last entry, the third entry at index two, is going to be cute, sweet Elphie. You'll notice that the format for filling in this array is very much like how you might declare any other variable where you have the variable name followed by the value that you want stored in it. The only difference in this case is that you have to remember to put the index of the value in square brackets. And there we have our three favorite dogs. But alas, it's time to get back to Caesar. Remember that correct usage for the user is going to be passing in not only the name of the program ./caesar, but also the key that they want to shift their plaintext by. So that means that argc must be two. They must pass in two-- no more, no less than two command line arguments. Now, what about argv? Well, we already know that the array is going to be of length two, but what's contained in each element? Well, the first element is going to be ./caesar, and then the next element is going to contain the key that the user typed in. Now, if they used it correctly for the usage of Caesar, then they're going to type in a number. But even though the character that they type is a number, it's of data type string. So how do we convert that string to an integer? So say I have num, a string, containing the string 50. If I want to convert that to an integer, then I simply declare a new variable, an integer i, calling atoi. I pass in my string variable, num, and then i will then contain the number 50. Make sure to check the man pages for the atoi function to check which library it's in, as well as what value it will return if the string passed in doesn't contain all numbers. So now that we've gotten the key, the next step is to get the plaintext from the user. Now, this is going to be less complicated than navigating around the command line arguments. All we have to do is call the getstring function to prompt the user to give us a string, but remember to check the specifications for how we might want to prompt the user for that. Now we come to the heart of the problem-- how to encipher the plaintext. Well, first, let's talk about how to encipher one character at a time, and then we'll address how to iterate over the entire plaintext. I've written some pseudocode for the Caesar problem. I encourage you to write your own as well. It might not look identical to mine, and that's OK, but as long as the general idea is the same. The first three steps we've already done. We've gotten the key from the command line argument, we've turned that key into an integer, and we've prompted the user for the plaintext that they want to encipher. So then the next big chunk is that for each character in the plaintext string, if it's alphabetic, we want to preserve its case and shift it. By preserve case, what I mean is that all upper case letters should remain upper case and all lowercase letters should remain lowercase. So then after we shift those, then we print the ciphertext. Here are three functions that are going to come in handy for this problem. Remember up above when I gave the example for shifting this is CS50? Remember that the 50 and the exclamation mark didn't shift? So how can we tell whether we need to shift a letter or not? Well, "is alpha," if you pass it a character, will return true if that character is a letter and false otherwise. To help you with preserving capitalization are the functions "is upper" and "is lower." These two functions also take in a single character as input and return you a Boolean, either true or false depending on whether that character is upper case or lower case. Because "is upper" and "is lower" are Boolean functions, meaning that they return you a Boolean, you can use these in your conditions. So here's a snippet of code that only prints a letter if it's upper case. So I've declared my character letter to be the upper case zed and then if "is upper" returns true, then I print that letter. Going back to our simple example of shifting the alphabet by a key of two, how do we actually get that to work? Well, it turns out that characters and integers are very closely related. Each character has an integer value associated with it found in the ASCII chart, where each character's ASCII value is displayed. So an upper case A corresponds to an ASCII value of 65 and a lowercase a to an ASCII value of 97. Feel free to look up any ASCII chart online to see these values for yourself. So what this means is that we can take the character of upper case A, add the integer two to it, and then get the character upper case C as a result. That's because 65, the ASCII value for capital A, plus 2, gives us 67, which corresponds to the character of upper case C. Unfortunately, things won't quite be so simple. We have an equation that we have to consider. Here it tells us that the ith ciphertext letter corresponds to the ith plaintext letter, plus the key-- all of that, modular 26. Why is that the case? Let's go back to our example from before, where capital A, plus 2, gives us capital C. So applying the equation that the specification gives us, then let's take capital A plus 2 and mod that by 26. So capital A, when I put it in those single quotation marks, allows me to treat it as an integer, so that allows me to cast it to its ASCII value, 65. 65 plus 2 is 67. 67 mod 26 gives us 15, but that doesn't really make sense because we know that the capital C ASCII value is 67, not 15. So how do we reconcile that? Well, here I'd like to posit the notion of an alphabetical index. So we've already talked about how each character has its ASCII value, but I'd like to say, well, let's think about each character also having an alphabetical index, where A for instance, as the first letter of the alphabet, has an alphabetical index of zero. So now let's apply the same equation as before, but using an alphabetical index. So A is zero, as we've defined. So then taking zero plus two, mod 26, that's two, mod 26, which gives us two. And well, in terms of an alphabetical index, C is the third letter in the alphabet, so that would correspond to an alphabetical index of two. So it seems that using the alphabetical index in this case actually gives us the correct result. So now let's check to see if the equation works with an alphabetical index. Y's alphabetical index is 24 as the second to last letter in the alphabet. So then 24 plus our key of two gives us 26. 26 mod 26 gives us 0, which, lucky for us, is the alphabetical index for A. So hopefully that's proof enough that the alphabetical index method works. If not, feel free to try out some examples of your own. In order to properly wrap around the alphabet and apply the Caesar equation, then we know that we need to deal with alphabetical indices. But we start with ASCII values, and only then do we then convert to the alphabetical index. From there, in order to print, we need to deal with the ASCII values again. So we need to figure out how to go from ASCII to alphabetical and from alphabetical to ASCII. So I leave it to you to figure out the pattern between a character and its alphabetical index and its ASCII value. Now, remember that even though this table right on the slide shows the capital letters, we also have to consider whether or not a different pattern applies for the lower case characters. So now that we've figured out how to shift a single character, then all we have to do is scale that up to go across the entire plaintext. So the plaintext is a string. Lucky for us, a string is really just an array of characters, so in order to access every character of a string, all you have to do is to use array notation. Say I have a variable of type string called "text='this is CS50.'" Well, then, in order to access each character, all I have to do with the variable text is to say well, text at index zero, that corresponds to capital T. Text at index one corresponds to the lower case h. Another useful function is the string length function. So passing in a string to that function will return an integer, the length of that string. Now that we've talked about all these different elements, let's put them back together. So return to either my pseudocode code or your pseudocode and go through and make sure that you know how to do every single thing. Getting the key using argc and argv, turning the key into an integer, a to i, prompting for plaintext, getstring, and then iterating over every character in the plaintext string, preserving the case of each character and shifting that character by the key, ensuring that you're wrapping around the alphabet, finally printing that ciphertext. My name is Amila, and this was Caesar.