1 00:00:00,000 --> 00:00:02,000 [Section 4] [Less Comfortable] 2 00:00:02,000 --> 00:00:04,000 [Nate Hardison] [Harvard University] 3 00:00:04,000 --> 00:00:07,000 [This is CS50.] [CS50.TV] 4 00:00:07,000 --> 00:00:10,000 >> All right, welcome back to section. 5 00:00:10,000 --> 00:00:13,000 In this week's section we're going to do a couple of things. 6 00:00:13,000 --> 00:00:17,000 We're going to first recap Problem Set 2, 7 00:00:17,000 --> 00:00:20,000 which is the Caesar and Vigenère problem set. 8 00:00:20,000 --> 00:00:23,000 And then we're going to dive into Quiz 0 review 9 00:00:23,000 --> 00:00:26,000 and spend a little bit of time recapping what we've talked about 10 00:00:26,000 --> 00:00:30,000 in each of the lectures so far, and we'll also do a few problems 11 00:00:30,000 --> 00:00:32,000 from previous year's quizzes. 12 00:00:32,000 --> 00:00:36,000 That way you guys have a good way to prepare for that. 13 00:00:36,000 --> 00:00:40,000 >> To start, I've booted up a couple of good solutions 14 00:00:40,000 --> 00:00:45,000 for the previous problem set, Problem Set 2, into this space. 15 00:00:45,000 --> 00:00:48,000 If you guys all hit this link, 16 00:00:48,000 --> 00:00:53,000 and if you click my name and click on my first revision 17 00:00:53,000 --> 00:00:56,000 you'll see caesar.c, which is exactly what I'm looking at. 18 00:00:56,000 --> 00:01:00,000 Let's talk about this really quickly. 19 00:01:00,000 --> 00:01:02,000 This is just a sample solution. 20 00:01:02,000 --> 00:01:05,000 This is not necessarily the perfect solution. 21 00:01:05,000 --> 00:01:08,000 There are many different ways to write this, 22 00:01:08,000 --> 00:01:10,000 but there are a few things that I wanted to highlight 23 00:01:10,000 --> 00:01:13,000 that I saw as I was grading, common mistakes that I think 24 00:01:13,000 --> 00:01:18,000 this solution does a very good job of handling. 25 00:01:18,000 --> 00:01:22,000 >> The first is having some sort of header comment at the top. 26 00:01:22,000 --> 00:01:25,000 On lines 1 through 7 you see the details, 27 00:01:25,000 --> 00:01:28,000 what exactly this program is doing. 28 00:01:28,000 --> 00:01:32,000 A good standard practice when you're writing C code 29 00:01:32,000 --> 00:01:35,000 regardless if your program is contained within a single file or 30 00:01:35,000 --> 00:01:38,000 whether it's split over multiple files is to have some sort of 31 00:01:38,000 --> 00:01:40,000 orienting comment at the top. 32 00:01:40,000 --> 00:01:43,000 This is also for people who go out and write code in the real world. 33 00:01:43,000 --> 00:01:47,000 This is where they'll put copyright information. 34 00:01:47,000 --> 00:01:50,000 Below are the #includes. 35 00:01:50,000 --> 00:01:55,000 On line 16 there's this #define, which we'll come back to in just a bit. 36 00:01:55,000 --> 00:01:59,000 And then once the function starts, once main starts, 37 00:01:59,000 --> 00:02:03,000 because this program has been all contained in a single function 38 00:02:03,000 --> 00:02:09,000 the very first thing that happens—and this is very idiomatic and typical of a C program 39 00:02:09,000 --> 00:02:14,000 that takes in command line arguments—is that it immediately checks 40 00:02:14,000 --> 00:02:18,000 >> for the argument count, argc. 41 00:02:18,000 --> 00:02:24,000 Right here we see that this program is expecting 2 arguments exactly. 42 00:02:24,000 --> 00:02:27,000 Remember there's that first argument that's the special one 43 00:02:27,000 --> 00:02:29,000 that's always the name of the program that's being run, 44 00:02:29,000 --> 00:02:31,000 the name of the executable file. 45 00:02:31,000 --> 00:02:36,000 And so what this does is it prevents the user from running the program 46 00:02:36,000 --> 00:02:42,000 with more or fewer arguments. 47 00:02:42,000 --> 00:02:44,000 The reason we want to check for this right away is because 48 00:02:44,000 --> 00:02:52,000 we can't actually access this argv array right here reliably 49 00:02:52,000 --> 00:02:55,000 until we've checked to see how big it is. 50 00:02:55,000 --> 00:02:58,000 >> One of the common errors I saw was people would immediately go in 51 00:02:58,000 --> 00:03:01,000 and grab argv[1]. 52 00:03:01,000 --> 00:03:06,000 They'd grab the key argument out of the array and do the a to i check on it, 53 00:03:06,000 --> 00:03:11,000 and then they'd do the test for argc as well as the next test, 54 00:03:11,000 --> 00:03:16,000 whether or not the first argument was indeed an integer at the same time, 55 00:03:16,000 --> 00:03:20,000 and that doesn't work because in the case that there are no arguments supplied 56 00:03:20,000 --> 00:03:26,000 you'll be grabbing an argument that isn't there or attempting to grab one that isn't there. 57 00:03:26,000 --> 00:03:29,000 >> The other big thing that you should notice is that 58 00:03:29,000 --> 00:03:32,000 you always want to print out some sort of helpful error message 59 00:03:32,000 --> 00:03:34,000 to the user to orient them. 60 00:03:34,000 --> 00:03:37,000 I'm sure you've all run programs where all of a sudden it crashes, 61 00:03:37,000 --> 00:03:41,000 and you get this ridiculous little dialog that pops up and says 62 00:03:41,000 --> 00:03:44,000 something horribly cryptic and maybe gives you an error code or something like that 63 00:03:44,000 --> 00:03:47,000 that makes no sense. 64 00:03:47,000 --> 00:03:50,000 This is where you really want to provide something helpful 65 00:03:50,000 --> 00:03:54,000 and targeted to the user so that when they run it they go "Oh," face palm. 66 00:03:54,000 --> 00:03:58,000 "I know exactly what to do. I know how to fix this." 67 00:03:58,000 --> 00:04:01,000 >> If you don't print a message, then you end up actually 68 00:04:01,000 --> 00:04:04,000 leaving the user to go examine your source code 69 00:04:04,000 --> 00:04:07,000 to figure out what went wrong. 70 00:04:07,000 --> 00:04:11,000 There are also some times that you'll use different error codes. 71 00:04:11,000 --> 00:04:14,000 Here we just used one to say there was an error, 72 00:04:14,000 --> 00:04:16,000 there was an error, there was an error. 73 00:04:16,000 --> 00:04:20,000 Bigger programs, often programs that are called by other programs, 74 00:04:20,000 --> 00:04:25,000 will return some sort of special error codes in different scenarios 75 00:04:25,000 --> 00:04:28,000 to programmatically communicate what you would otherwise 76 00:04:28,000 --> 00:04:32,000 just use a nice English message for. 77 00:04:32,000 --> 00:04:35,000 Cool. 78 00:04:35,000 --> 00:04:37,000 As we work down, you can see we pull the key out. 79 00:04:37,000 --> 00:04:40,000 We test to see if the key fits. 80 00:04:40,000 --> 00:04:42,000 We get a message from the user. 81 00:04:42,000 --> 00:04:46,000 The reason we do it in this do while loop—and this is something that we will cover 82 00:04:46,000 --> 00:04:50,000 in a little bit—but it turns out that if you type control D 83 00:04:50,000 --> 00:04:54,000 when you get that GetString prompt on the terminal 84 00:04:54,000 --> 00:04:59,000 what that actually does is it sends a special character 85 00:04:59,000 --> 00:05:01,000 to the program. 86 00:05:01,000 --> 00:05:05,000 It's called the ELF or the end of file character. 87 00:05:05,000 --> 00:05:08,000 And in that case, our message string will be null, 88 00:05:08,000 --> 00:05:14,000 so this wasn't something we checked for in the problem set itself. 89 00:05:14,000 --> 00:05:17,000 >> But as we go on, now that we've started to talk about pointers 90 00:05:17,000 --> 00:05:21,000 and dynamic memory allocation on the heap, 91 00:05:21,000 --> 00:05:25,000 checking for null whenever you have a function that might 92 00:05:25,000 --> 00:05:30,000 return null as a value is something that you'll want to get in the habit of doing. 93 00:05:30,000 --> 00:05:33,000 This is here primarily for illustration. 94 00:05:33,000 --> 00:05:36,000 But when you do see GetString in the future, 95 00:05:36,000 --> 00:05:41,000 so from Problem Set 4 on, you'll want to keep this in mind. 96 00:05:41,000 --> 00:05:44,000 Again, this is not an issue for Problem Set 3 either since we hadn't covered it yet. 97 00:05:44,000 --> 00:05:53,000 Finally, we get to this part where we get to the main encryption loop, 98 00:05:53,000 --> 00:05:57,000 and there are a couple of things going on here. 99 00:05:57,000 --> 00:06:02,000 First, we iterate over the entire message string itself. 100 00:06:02,000 --> 00:06:07,000 Here we've kept the strlen call in the condition, 101 00:06:07,000 --> 00:06:12,000 which a number of you have pointed out is not a great way to go. 102 00:06:12,000 --> 00:06:15,000 It turns out in this case it's also not great, 103 00:06:15,000 --> 00:06:20,000 partly because we're modifying the contents of the message itself 104 00:06:20,000 --> 00:06:27,000 inside the for loop, so if we have a message that's 10 characters long, 105 00:06:27,000 --> 00:06:32,000 the first time we start that for loop strlen will return what? 106 00:06:32,000 --> 00:06:35,000 10. 107 00:06:35,000 --> 00:06:40,000 >> But if we then modify message, say we modify its 5th character, 108 00:06:40,000 --> 00:06:46,000 and we throw in a \0 character in the 5th position, 109 00:06:46,000 --> 00:06:49,000 on a subsequent iteration strlen(message) won't return what it did 110 00:06:49,000 --> 00:06:52,000 the very first time we iterated, 111 00:06:52,000 --> 00:06:56,000 but it will instead return 5 because we threw in that null terminator, 112 00:06:56,000 --> 00:06:59,000 and the string's length is defined 113 00:06:59,000 --> 00:07:03,000 by the position of that \0. 114 00:07:03,000 --> 00:07:09,000 In this case, this is a great way to go because we're modifying it in place. 115 00:07:09,000 --> 00:07:13,000 But you notice that this is actually surprisingly simple to encrypt 116 00:07:13,000 --> 00:07:16,000 if you can get the math correct. 117 00:07:16,000 --> 00:07:19,000 All that's required is to check whether or not the letter that you're looking at 118 00:07:19,000 --> 00:07:21,000 is uppercase or lowercase. 119 00:07:21,000 --> 00:07:24,000 >> The reason we only have to check for that and we don't have to check for 120 00:07:24,000 --> 00:07:27,000 the is alpha case is because 121 00:07:27,000 --> 00:07:30,000 if a character is uppercase or if it's lowercase 122 00:07:30,000 --> 00:07:33,000 then it's definitely an alphabetic character, 123 00:07:33,000 --> 00:07:38,000 because we don't have uppercase and lowercase digits. 124 00:07:38,000 --> 00:07:41,000 The other thing we do—and this is a little tricky— 125 00:07:41,000 --> 00:07:45,000 is we've modified the standard Caesar cipher formula 126 00:07:45,000 --> 00:07:49,000 that we gave in the problem set specification. 127 00:07:49,000 --> 00:07:52,000 What's different here is that we subtracted 128 00:07:52,000 --> 00:07:58,000 in the uppercase case capital A, and then we added capital A 129 00:07:58,000 --> 00:08:02,000 back in at the end. 130 00:08:02,000 --> 00:08:05,000 >> I know a few of you have done this in your code. 131 00:08:05,000 --> 00:08:09,000 Did any of you do this in your submissions? 132 00:08:09,000 --> 00:08:13,000 You did this. Can you explain what this does, Sahb? 133 00:08:13,000 --> 00:08:18,000 By subtracting it out, because you did a mod right after it, 134 00:08:18,000 --> 00:08:21,000 you have to take it out, so that way you get [coughing] position. 135 00:08:21,000 --> 00:08:25,000 And then by adding it back later you shifted over the one that you wanted. 136 00:08:25,000 --> 00:08:27,000 Yeah, exactly. 137 00:08:27,000 --> 00:08:32,000 What Sahb said was that when we want to add 138 00:08:32,000 --> 00:08:36,000 our message and our key together 139 00:08:36,000 --> 00:08:42,000 and then mod that, mod that by NUM_LETTERS, 140 00:08:42,000 --> 00:08:50,000 if we don't scale our message into the appropriate 0 to 25 range first, 141 00:08:50,000 --> 00:08:54,000 then we might end up getting a really weird number 142 00:08:54,000 --> 00:08:59,000 because the values that we're looking at when we look at message[i], 143 00:08:59,000 --> 00:09:03,000 when we look at the ith character of our plain-text message, 144 00:09:03,000 --> 00:09:08,000 is a value somewhere in this 65 to 122 range 145 00:09:08,000 --> 00:09:13,000 based on the ASCII values for uppercase A through lowercase z. 146 00:09:13,000 --> 00:09:18,000 And so when we mod it by 26 or by NUM_LETTERS, 147 00:09:18,000 --> 00:09:23,000 since that was our #define at the top right up here, 148 00:09:23,000 --> 00:09:28,000 that's going to give us a value that's in the 0 to 25 range, 149 00:09:28,000 --> 00:09:30,000 and we need a way to then scale that back up 150 00:09:30,000 --> 00:09:32,000 and get it in the appropriate ASCII range. 151 00:09:32,000 --> 00:09:36,000 The easiest way to do that is to just scale everything down 152 00:09:36,000 --> 00:09:39,000 into the 0 to 25 range to begin with, 153 00:09:39,000 --> 00:09:43,000 and then shift everything back up at the end. 154 00:09:43,000 --> 00:09:46,000 >> Another common error that I saw people run into is that 155 00:09:46,000 --> 00:09:50,000 if you don't actually do this scaling right away 156 00:09:50,000 --> 00:09:53,000 and you add message and key together and you add them, say, 157 00:09:53,000 --> 00:09:58,000 into a char variable, the problem with that 158 00:09:58,000 --> 00:10:01,000 is since message[i] is a relatively big number to begin with— 159 00:10:01,000 --> 00:10:05,000 remember it's at least 65 if it's an uppercase character— 160 00:10:05,000 --> 00:10:09,000 if you have a large key, say, something like 100, 161 00:10:09,000 --> 00:10:13,000 and you add those 2 together into a signed char you're going to get an overflow. 162 00:10:13,000 --> 00:10:17,000 You're going to get a value that's larger than 127, 163 00:10:17,000 --> 00:10:22,000 which is the largest value that a char variable can hold. 164 00:10:22,000 --> 00:10:26,000 Again, that's why you'd want to do that sort of thing to begin with. 165 00:10:26,000 --> 00:10:29,000 Some people got around that case by doing an if else and testing 166 00:10:29,000 --> 00:10:33,000 to see if it would overflow before doing that, 167 00:10:33,000 --> 00:10:36,000 but this way gets around that. 168 00:10:36,000 --> 00:10:40,000 And then in this solution we printed out the whole string at the very end. 169 00:10:40,000 --> 00:10:45,000 Other people printed out a character at a time. Both are awesome. 170 00:10:45,000 --> 00:10:51,000 At this point, do you guys have any questions, any comments about this? 171 00:10:51,000 --> 00:10:56,000 Things you like, things you don't like? 172 00:10:56,000 --> 00:10:58,000 >> I had a question. 173 00:10:58,000 --> 00:11:01,000 Maybe I missed it during your explanation, but how does this program 174 00:11:01,000 --> 00:11:07,000 skip the spaces for connecting the key to the length of the text? 175 00:11:07,000 --> 00:11:10,000 This is just Caesar cipher.>>Oh, sorry, yeah. 176 00:11:10,000 --> 00:11:13,000 Yeah, we'll see that. 177 00:11:13,000 --> 00:11:16,000 In the Caesar cipher we got around that because 178 00:11:16,000 --> 00:11:18,000 we only flipped characters. 179 00:11:18,000 --> 00:11:27,000 We only rotated them if they were uppercase or lowercase. 180 00:11:27,000 --> 00:11:32,000 You guys feeling pretty good about this? 181 00:11:32,000 --> 00:11:34,000 Feel free to copy this home, take it, 182 00:11:34,000 --> 00:11:37,000 compare it to what you guys wrote. 183 00:11:37,000 --> 00:11:42,000 Definitely feel free to send questions about it too. 184 00:11:42,000 --> 00:11:46,000 And again, realize that the goal here with your problem sets 185 00:11:46,000 --> 00:11:50,000 is not to get you guys to write perfect code for your problem sets. 186 00:11:50,000 --> 00:11:57,000 It's a learning experience. Yeah. 187 00:11:57,000 --> 00:12:01,000 >> Back to the do while loop, if it equals null, 188 00:12:01,000 --> 00:12:06,000 so null just means nothing, they just hit enter? 189 00:12:06,000 --> 00:12:12,000 Null is a special pointer value, 190 00:12:12,000 --> 00:12:17,000 and we use null when we want to say 191 00:12:17,000 --> 00:12:23,000 we have a pointer variable that is pointing to nothing. 192 00:12:23,000 --> 00:12:28,000 And so typically it means that this variable, this message variable 193 00:12:28,000 --> 00:12:35,000 is empty, and here, because we're using the CS50 special string type, 194 00:12:35,000 --> 00:12:37,000 what is the CS50 string type? 195 00:12:37,000 --> 00:12:42,000 Have you seen what it is when David pulled back the hood in lecture? 196 00:12:42,000 --> 00:12:44,000 It's a funky—it's a pointer, right? 197 00:12:44,000 --> 00:12:48,000 Okay, yeah.>>It's a char*. 198 00:12:48,000 --> 00:12:52,000 And so really we could replace this 199 00:12:52,000 --> 00:12:56,000 right here with char* message, 200 00:12:56,000 --> 00:13:04,000 and so the GetString function, if it doesn't successfully get a string from the user, 201 00:13:04,000 --> 00:13:08,000 it can't parse a string, and the one case in which it can't parse a string 202 00:13:08,000 --> 00:13:11,000 is if the user types the end of file character, the control D, 203 00:13:11,000 --> 00:13:17,000 which is not something you typically do, but if that happens 204 00:13:17,000 --> 00:13:20,000 then the function will return this null value as a way of saying 205 00:13:20,000 --> 00:13:23,000 "Hey, I didn't get a string." 206 00:13:23,000 --> 00:13:27,000 What would happen if we don't put message = null, 207 00:13:27,000 --> 00:13:30,000 which is something that we haven't been doing yet? 208 00:13:30,000 --> 00:13:32,000 Why would that be a problem here? 209 00:13:32,000 --> 00:13:38,000 Because I know that we talked a little bit in lecture about memory leaks. 210 00:13:38,000 --> 00:13:42,000 Yeah, let's do that, and let's see what happens. 211 00:13:42,000 --> 00:13:44,000 >> Basil's question was what happens if we don't actually have 212 00:13:44,000 --> 00:13:48,000 this message = null test? 213 00:13:48,000 --> 00:13:51,000 Let's scroll up to the top. 214 00:13:51,000 --> 00:13:53,000 You guys can comment this out. 215 00:13:53,000 --> 00:13:55,000 Actually, I'll save it in a revision. 216 00:13:55,000 --> 00:13:58,000 This will be Revision 3. 217 00:13:58,000 --> 00:14:02,000 What you'll have to do to run this program is you'll have to click this gear icon up here, 218 00:14:02,000 --> 00:14:04,000 and you'll have to add an argument to it. 219 00:14:04,000 --> 00:14:10,000 You'll have to give it the key argument since we want to pass in a command line argument. 220 00:14:10,000 --> 00:14:13,000 Here I'm going to give it the number 3. I like 3. 221 00:14:13,000 --> 00:14:19,000 Now zooming back out, running the program. 222 00:14:19,000 --> 00:14:24,000 It's running, compiling, building. 223 00:14:24,000 --> 00:14:27,000 Here we go. It's waiting to be prompted. 224 00:14:27,000 --> 00:14:33,000 If I type in something like hello—where did that go? 225 00:14:33,000 --> 00:14:38,000 Oh, my program took too long to run. I was jawing for too long. 226 00:14:38,000 --> 00:14:40,000 Here it goes. 227 00:14:40,000 --> 00:14:43,000 Now I type in hello. 228 00:14:43,000 --> 00:14:46,000 We see that it encrypts appropriately. 229 00:14:46,000 --> 00:14:52,000 Now what happens if we do prompt GetString to return null? 230 00:14:52,000 --> 00:14:57,000 Remember, I said that we did that by pressing control D at the same time. 231 00:14:57,000 --> 00:14:59,000 I'll scroll up here. We'll run it again. 232 00:14:59,000 --> 00:15:01,000 Building. There it goes. 233 00:15:01,000 --> 00:15:04,000 Now when I hit control D 234 00:15:04,000 --> 00:15:12,000 I got this line that says opt/sandbox50/bin/run.sh, Segmentation fault. 235 00:15:12,000 --> 00:15:15,000 Have you guys seen that before? 236 00:15:15,000 --> 00:15:17,000 >> [Student] Why is there no—>>Sorry? 237 00:15:17,000 --> 00:15:20,000 [Student] Why is there no core dump in this case? 238 00:15:20,000 --> 00:15:26,000 The core dump is—the question is why is there no core dump here? 239 00:15:26,000 --> 00:15:29,000 The question is that there may be, but the core dump is a file 240 00:15:29,000 --> 00:15:31,000 that gets stored on the hard drive. 241 00:15:31,000 --> 00:15:34,000 In this case we've disabled core dumps 242 00:15:34,000 --> 00:15:37,000 on the run server so that we don't have people seg faulting 243 00:15:37,000 --> 00:15:40,000 and building up tons of core dumps. 244 00:15:40,000 --> 00:15:46,000 But you may get one. 245 00:15:46,000 --> 00:15:48,000 Core dumps are the sort of thing that you can often disable, 246 00:15:48,000 --> 00:15:52,000 and sometimes you do. 247 00:15:52,000 --> 00:15:55,000 The segmentation fault, to answer your question, Basil, 248 00:15:55,000 --> 00:16:00,000 is saying that we tried to access a pointer 249 00:16:00,000 --> 00:16:05,000 that wasn't set to point to anything. 250 00:16:05,000 --> 00:16:09,000 Remember Binky in the video when Binky tries to 251 00:16:09,000 --> 00:16:12,000 go access a pointer that's not pointing to anything? 252 00:16:12,000 --> 00:16:16,000 In this case I guess technically the pointer is pointing to something. 253 00:16:16,000 --> 00:16:20,000 It's pointing to null, which is technically 0, 254 00:16:20,000 --> 00:16:25,000 but that is defined to be in a segment that is not accessible 255 00:16:25,000 --> 00:16:28,000 by your program, so you get a segmentation fault 256 00:16:28,000 --> 00:16:31,000 because you're not accessing memory that's in a valid segment 257 00:16:31,000 --> 00:16:38,000 like the heap segment or the stack segment or the data segment. 258 00:16:38,000 --> 00:16:40,000 Cool. 259 00:16:40,000 --> 00:16:48,000 Any more questions about Caesar? 260 00:16:48,000 --> 00:16:51,000 >> Let's move on. Let's look at Revision 2 really quickly. 261 00:16:51,000 --> 00:17:00,000 That's Vigenère. 262 00:17:00,000 --> 00:17:04,000 Here in Vigenère 263 00:17:04,000 --> 00:17:06,000 we'll walk through this one pretty quickly because, again, 264 00:17:06,000 --> 00:17:10,000 Vigenère and Caesar are quite similar. 265 00:17:10,000 --> 00:17:12,000 Header comment is before, 266 00:17:12,000 --> 00:17:17,000 #define is before to avoid using these magic numbers. 267 00:17:17,000 --> 00:17:21,000 The nice thing is say we wanted to move to 268 00:17:21,000 --> 00:17:23,000 a different alphabet or something like that. 269 00:17:23,000 --> 00:17:26,000 Rather than having to go manually change all the 26's in the code 270 00:17:26,000 --> 00:17:30,000 we could change this to 27 or drop it down 271 00:17:30,000 --> 00:17:34,000 if we were using different alphabets, different languages. 272 00:17:34,000 --> 00:17:38,000 Again, we've got this check of the argument count, 273 00:17:38,000 --> 00:17:42,000 and really you can almost take this as a template. 274 00:17:42,000 --> 00:17:46,000 Pretty much every program you write should have— 275 00:17:46,000 --> 00:17:50,000 if it takes command line arguments—some sequence of lines 276 00:17:50,000 --> 00:17:55,000 that reads like this at the very beginning. 277 00:17:55,000 --> 00:17:59,000 That's one of the first sanity tests you want to do. 278 00:17:59,000 --> 00:18:03,000 >> Here what we did was we made sure that 279 00:18:03,000 --> 00:18:06,000 the keyword was valid, and that was the second check that we did. 280 00:18:06,000 --> 00:18:11,000 Notice again that we separated this from argc and 2. 281 00:18:11,000 --> 00:18:14,000 Note that in this case one thing that we had to do was instead 282 00:18:14,000 --> 00:18:18,000 of using a to i we wanted to validate the entire string, 283 00:18:18,000 --> 00:18:21,000 and in order to do that you actually have to go character by character 284 00:18:21,000 --> 00:18:23,000 over the string. 285 00:18:23,000 --> 00:18:29,000 There's no good way to call something on it 286 00:18:29,000 --> 00:18:31,000 because even, for example, a to i will return 0 287 00:18:31,000 --> 00:18:37,000 if it can't parse an integer, so that doesn't even work. 288 00:18:37,000 --> 00:18:42,000 Again, nice message telling the user exactly what happened. 289 00:18:42,000 --> 00:18:45,000 Then here, again, we also handle the case where 290 00:18:45,000 --> 00:18:50,000 the user types in a control D random character. 291 00:18:50,000 --> 00:18:54,000 >> And then Charlotte had a question earlier about how we manage to skip spaces 292 00:18:54,000 --> 00:18:57,000 in our string here. 293 00:18:57,000 --> 00:19:00,000 This was kind of similar to what we did with the Myspace program 294 00:19:00,000 --> 00:19:04,000 that we did in section, and the way this worked 295 00:19:04,000 --> 00:19:08,000 is that we tracked the number of letters that we'd seen. 296 00:19:08,000 --> 00:19:13,000 As we walked over the message string, as we walked over character by character, 297 00:19:13,000 --> 00:19:16,000 we tracked the index as part of our for loop, and then we also tracked 298 00:19:16,000 --> 00:19:21,000 the number of letters, so non-special characters, non-digits, non-white space 299 00:19:21,000 --> 00:19:27,000 that we'd seen in the separate variable. 300 00:19:27,000 --> 00:19:33,000 And then this solution modifies the key 301 00:19:33,000 --> 00:19:41,000 to get an actual key integer, and it does that on the fly, 302 00:19:41,000 --> 00:19:47,000 right before it then goes to encrypt the actual message character. 303 00:19:47,000 --> 00:19:50,000 There are some solutions that were perfectly great too 304 00:19:50,000 --> 00:19:58,000 that would modify the key up when testing for the key's validity. 305 00:19:58,000 --> 00:20:01,000 In addition to making sure that the character and the keyword 306 00:20:01,000 --> 00:20:05,000 was an alphabetic character it also turned that into an integer 307 00:20:05,000 --> 00:20:13,000 in the 0 to 25 range to then skip having to do that later on in this for loop. 308 00:20:13,000 --> 00:20:18,000 Again, you see here this is really the exact same code 309 00:20:18,000 --> 00:20:22,000 that we used in Caesar at this point. 310 00:20:22,000 --> 00:20:25,000 You're doing the exact same thing, so the real trick is figuring out 311 00:20:25,000 --> 00:20:30,000 how to turn the keyword into an integer. 312 00:20:30,000 --> 00:20:35,000 >> One thing that we did here that is a little dense 313 00:20:35,000 --> 00:20:39,000 is we repeated this phrase, I guess you could call it, 314 00:20:39,000 --> 00:20:45,000 3 separate times on lines 58, 59, and 61. 315 00:20:45,000 --> 00:20:52,000 Can somebody explain what exactly this phrase does? 316 00:20:52,000 --> 00:20:55,000 It's accessing a character, like you said. 317 00:20:55,000 --> 00:20:59,000 Yeah, it's [inaudible] a character in the keyword, 318 00:20:59,000 --> 00:21:04,000 and so it's number of letters seen because you're only moving along 319 00:21:04,000 --> 00:21:06,000 the keyword once you've seen the letter, 320 00:21:06,000 --> 00:21:10,000 so that's going to effectively skip spaces and stuff like that. 321 00:21:10,000 --> 00:21:12,000 Yeah, exactly. 322 00:21:12,000 --> 00:21:16,000 And then once you've seen the keyword blank you just mod so you move back around. 323 00:21:16,000 --> 00:21:18,000 Exactly. That's a perfect explanation. 324 00:21:18,000 --> 00:21:23,000 What Kevin said is that we want to index into the keyword. 325 00:21:23,000 --> 00:21:28,000 We want to get the num_letters_seen character, if you will, 326 00:21:28,000 --> 00:21:32,000 but if num_letters_seen exceeds the length of the keyword, 327 00:21:32,000 --> 00:21:37,000 the way we get back into the appropriate range is we use the mod operator 328 00:21:37,000 --> 00:21:40,000 to effectively wrap around. 329 00:21:40,000 --> 00:21:43,000 For example, like in the short, our keyword is bacon, 330 00:21:43,000 --> 00:21:46,000 and it's 5 letters long. 331 00:21:46,000 --> 00:21:50,000 But we've seen 6 letters in our plain text at this point 332 00:21:50,000 --> 00:21:52,000 and encrypted 6. 333 00:21:52,000 --> 00:21:57,000 We will end up accessing the num_letters_seen, 334 00:21:57,000 --> 00:22:00,000 which is 6, mod the length of the keyword, 5, 335 00:22:00,000 --> 00:22:04,000 and so we'll get 1, and so what we'll do is we'll 336 00:22:04,000 --> 00:22:14,000 access the first character inside of our keyword at that point. 337 00:22:14,000 --> 00:22:21,000 >> All right, any questions on Vigenère 338 00:22:21,000 --> 00:22:26,000 before we move on? 339 00:22:26,000 --> 00:22:31,000 You guys feeling pretty good about this? 340 00:22:31,000 --> 00:22:35,000 Cool, great. 341 00:22:35,000 --> 00:22:38,000 I want to make sure that you guys are getting the chance to see code 342 00:22:38,000 --> 00:22:48,000 that we think looks good and have the chance to learn from it. 343 00:22:48,000 --> 00:22:53,000 This is going to be the last we'll be using spaces for the time being, 344 00:22:53,000 --> 00:22:59,000 and we're going to transition now, and I'm going to go to cs50.net/lectures 345 00:22:59,000 --> 00:23:06,000 so we can do a little bit of quiz review. 346 00:23:06,000 --> 00:23:10,000 The best way I think to start doing quiz review 347 00:23:10,000 --> 00:23:15,000 is to come to this Lectures page, cs50.net/lectures, 348 00:23:15,000 --> 00:23:20,000 and underneath each of the week headings, so if I look here at Week 0, 349 00:23:20,000 --> 00:23:27,000 I see that we have a list of topics that we covered in Week 0. 350 00:23:27,000 --> 00:23:31,000 >> If any of these topics seem unfamiliar to you 351 00:23:31,000 --> 00:23:34,000 you'll definitely want to go back and scour the lecture notes and possibly 352 00:23:34,000 --> 00:23:39,000 even skim through the lectures, watch them again if you want 353 00:23:39,000 --> 00:23:44,000 to get a feel for what's going on with each of those topics. 354 00:23:44,000 --> 00:23:49,000 I will say additionally this year one of the cool resources we've got 355 00:23:49,000 --> 00:23:55,000 is these shorts that we've created, and if you look at Week 0, 356 00:23:55,000 --> 00:24:00,000 we don't have all of the topics covered, but we've got quite a few of them, 357 00:24:00,000 --> 00:24:03,000 some of the trickier ones, so watching these shorts again 358 00:24:03,000 --> 00:24:08,000 is a good way to get you up to speed. 359 00:24:08,000 --> 00:24:15,000 In particular, I'm going to put in a plug for the 3 on the bottom, since I did those. 360 00:24:15,000 --> 00:24:20,000 But if you're struggling with binary, bits, hex, that kind of stuff, 361 00:24:20,000 --> 00:24:22,000 binary is a great place to start. 362 00:24:22,000 --> 00:24:25,000 ASCII is another one that's good to view too. 363 00:24:25,000 --> 00:24:31,000 You can even watch me at 1.5x speed if I'm going too slow for you. 364 00:24:31,000 --> 00:24:35,000 Since it's review, feel free to do that. 365 00:24:35,000 --> 00:24:40,000 >> Just to start really quickly, we're going to go through a couple of these quiz problems 366 00:24:40,000 --> 00:24:44,000 just to quickly churn through these. 367 00:24:44,000 --> 00:24:50,000 For example, let's look at problem 16 that I've got right up here on the board. 368 00:24:50,000 --> 00:24:54,000 We've got this following calculation in binary, 369 00:24:54,000 --> 00:24:56,000 and we want to show any work. 370 00:24:56,000 --> 00:24:59,000 Okay, I'm going to give this a shot. 371 00:24:59,000 --> 00:25:01,000 You guys should follow along with paper, 372 00:25:01,000 --> 00:25:04,000 and we'll do this really quickly. 373 00:25:04,000 --> 00:25:06,000 We want to perform the following calculation in binary. 374 00:25:06,000 --> 00:25:16,000 I've got 00110010. 375 00:25:16,000 --> 00:25:27,000 And I'm going to add to it 00110010. 376 00:25:27,000 --> 00:25:30,000 For the math geniuses following along at home, 377 00:25:30,000 --> 00:25:35,000 this is effectively multiplying by 2. 378 00:25:35,000 --> 00:25:37,000 Let's start. 379 00:25:37,000 --> 00:25:39,000 We're going to follow the same addition algorithm that we do 380 00:25:39,000 --> 00:25:43,000 when we add decimal numbers together. 381 00:25:43,000 --> 00:25:46,000 Really the only difference here is that we loop back around 382 00:25:46,000 --> 00:25:51,000 once we have 1 + 1 instead of once we get to 10. 383 00:25:51,000 --> 00:25:53,000 >> If we start from the right, really quickly, what's the first digit? 384 00:25:53,000 --> 00:25:55,000 [Student] 0.>>[Nate H.] 0. 385 00:25:55,000 --> 00:25:58,000 Great, the second digit? 386 00:25:58,000 --> 00:26:00,000 [Student] 1. 387 00:26:00,000 --> 00:26:02,000 [Nate H.] Is it a 1? 1 + 1 is? 388 00:26:02,000 --> 00:26:04,000 [Student] 10. 389 00:26:04,000 --> 00:26:08,000 [Nate H.] Exactly, so what is the digit that I write right beneath the 2 ones added together? 390 00:26:08,000 --> 00:26:11,000 [Student] 1, 0, or 0 and then carry the 1. 391 00:26:11,000 --> 00:26:15,000 [Nate H.] 0 and carry a 1, exactly. 392 00:26:15,000 --> 00:26:18,000 Next one up, Basil, you're up. 393 00:26:18,000 --> 00:26:20,000 What's the third?>>[Basil] 1. 394 00:26:20,000 --> 00:26:23,000 [Nate H.] 1, perfect. Kevin? 395 00:26:23,000 --> 00:26:27,000 [Kevin] 0.>>[Nate H.] 0, Charlotte? 396 00:26:27,000 --> 00:26:30,000 [Charlotte] 0.>>[Nate H.] Yeah, and what do I do? 397 00:26:30,000 --> 00:26:32,000 [Student] The 1. 398 00:26:32,000 --> 00:26:34,000 [Nate H.] And what do I do? And then I carry the 1. 399 00:26:34,000 --> 00:26:36,000 Perfect, Sahb?>>[Sahb] Now you have 1. 400 00:26:36,000 --> 00:26:40,000 [Nate H.] And do I do anything here? 401 00:26:40,000 --> 00:26:43,000 [Sahb] Then for the next one you have 1 because you carried over 1. 402 00:26:43,000 --> 00:26:49,000 [Nate H.] Great, so here we can finish it up. 403 00:26:49,000 --> 00:26:51,000 Cool. 404 00:26:51,000 --> 00:26:54,000 [Student] Does 0 + 0 = 0? 405 00:26:54,000 --> 00:26:56,000 0 + 0 = 0. 406 00:26:56,000 --> 00:27:01,000 1 + 1, like you said, is 10, or 1, 0, rather. 407 00:27:01,000 --> 00:27:07,000 10 is a misnomer because to me 10 means the number 10, 408 00:27:07,000 --> 00:27:12,000 and it's the quirk of how we're representing it when we're writing it. 409 00:27:12,000 --> 00:27:20,000 We represent the number 2 by 1, 0, and the number 10 is slightly different. 410 00:27:20,000 --> 00:27:23,000 >> What's kind of nice about binary is that there really aren't that many 411 00:27:23,000 --> 00:27:25,000 cases you need to learn. 412 00:27:25,000 --> 00:27:30,000 There's 0 + 0 = 0, 0 + 1 = 1, 413 00:27:30,000 --> 00:27:34,000 1 + 1 is 0, and then carry a 1, 414 00:27:34,000 --> 00:27:37,000 and then you can see here on the third column from the right 415 00:27:37,000 --> 00:27:40,000 we had this 1, 1, and 1. 416 00:27:40,000 --> 00:27:43,000 And 1 + 1 + 1 is a 1, 417 00:27:43,000 --> 00:27:45,000 and you carry another 1. 418 00:27:45,000 --> 00:27:48,000 When you're doing binary addition, pretty simple. 419 00:27:48,000 --> 00:27:51,000 I'd do a couple more of these to sanity check yourselves 420 00:27:51,000 --> 00:27:54,000 before you go in because this is 421 00:27:54,000 --> 00:28:00,000 probably something that we'll see on the quiz. 422 00:28:00,000 --> 00:28:03,000 Now let's do this next one as well. 423 00:28:03,000 --> 00:28:06,000 Let's do problem 17. 424 00:28:06,000 --> 00:28:12,000 We're going to convert the following binary number to decimal. 425 00:28:12,000 --> 00:28:28,000 I've got 10100111001. 426 00:28:28,000 --> 00:28:33,000 Remember in the binary video that I did 427 00:28:33,000 --> 00:28:36,000 I walked through a couple of examples, and I showed how 428 00:28:36,000 --> 00:28:41,000 everything works when you're doing it in decimal. 429 00:28:41,000 --> 00:28:45,000 When you're working in decimal representation I think we're 430 00:28:45,000 --> 00:28:48,000 at this point in our lives so fluent in it that 431 00:28:48,000 --> 00:28:53,000 it's pretty easy to gloss over the mechanics of how it actually works. 432 00:28:53,000 --> 00:28:59,000 >> But to do a quick recap, if I have the number 137 433 00:28:59,000 --> 00:29:06,000 this really means—and again, this is in decimal representation— 434 00:29:06,000 --> 00:29:19,000 the number 137 in decimal means that I have 1 x 100 + 3 x 10 + 7 x 1. 435 00:29:19,000 --> 00:29:22,000 This is all staying on the screen. 436 00:29:22,000 --> 00:29:29,000 And then if you look at these numbers right here, 437 00:29:29,000 --> 00:29:34,000 100, 10 and 1, you see that they're actually all powers of 10. 438 00:29:34,000 --> 00:29:43,000 I have 10², 10¹, and 10 to the zero. 439 00:29:43,000 --> 00:29:48,000 We have a similar sort of thing in binary, 440 00:29:48,000 --> 00:29:55,000 except that our base, as we call it, is 2 instead of 10. 441 00:29:55,000 --> 00:29:58,000 These 10s that I wrote down here at the bottom, 442 00:29:58,000 --> 00:30:02,000 this 10², 10¹, 10 to the zero, 10 is our base, 443 00:30:02,000 --> 00:30:08,000 and the exponent, 0, 1, or 2, 444 00:30:08,000 --> 00:30:14,000 is implied by the position of the digit in the number that we write. 445 00:30:14,000 --> 00:30:21,000 1, if we look at it, this 1 is in the 2nd position. 446 00:30:21,000 --> 00:30:27,000 The 3 is in the 1st position, and the 7 is in the 0th position. 447 00:30:27,000 --> 00:30:35,000 That's how we get the various exponents below for our bases. 448 00:30:35,000 --> 00:30:40,000 >> Following all of this we'll—actually, you know what? 449 00:30:40,000 --> 00:30:43,000 We'll do—where did my undo button go? 450 00:30:43,000 --> 00:30:45,000 There it goes. 451 00:30:45,000 --> 00:30:47,000 I love this undo thing. 452 00:30:47,000 --> 00:30:51,000 Following this I think for me at least 453 00:30:51,000 --> 00:30:54,000 the easiest way to start converting a binary number 454 00:30:54,000 --> 00:30:57,000 or a hexadecimal number where the base is 16 455 00:30:57,000 --> 00:31:02,000 and not 10 or 2 is to go ahead and write out 456 00:31:02,000 --> 00:31:09,000 the bases and exponents for all of the numbers in my binary number at the top. 457 00:31:09,000 --> 00:31:14,000 If we start from left to right again, 458 00:31:14,000 --> 00:31:17,000 which is kind of counterintuitive, 459 00:31:17,000 --> 00:31:23,000 I'll change back to black here, we have the 2 to the 0th position, 460 00:31:23,000 --> 00:31:27,000 and then we have 2¹, 2², 461 00:31:27,000 --> 00:31:33,000 and then 2 to the 3, 2 to the 4, 2 to the 5, 6, 462 00:31:33,000 --> 00:31:39,000 7, 8, 9, and 10. 463 00:31:39,000 --> 00:31:41,000 These numbers I've written out are all the exponents. 464 00:31:41,000 --> 00:31:48,000 I only wrote the bases here in the first 3 just for space. 465 00:31:48,000 --> 00:31:50,000 >> At this point I'm going to go ahead and I'm actually going to erase 466 00:31:50,000 --> 00:31:53,000 the stuff that we did in decimal, if that's okay. 467 00:31:53,000 --> 00:31:57,000 You've all got that. 468 00:31:57,000 --> 00:32:05,000 Those of you watching online I'm sure will be able to rewind me if you'd like. 469 00:32:05,000 --> 00:32:07,000 Switching back to the pen. 470 00:32:07,000 --> 00:32:12,000 Now, what we can do—if you guys aren't totally up to speed on your powers of 2, 471 00:32:12,000 --> 00:32:15,000 that's totally cool. 472 00:32:15,000 --> 00:32:18,000 It happens. I understand. 473 00:32:18,000 --> 00:32:23,000 I once had a job interview where I was told I should know all powers of 2 474 00:32:23,000 --> 00:32:26,000 up through 2 to the 30th. 475 00:32:26,000 --> 00:32:29,000 It was not a job I got. 476 00:32:29,000 --> 00:32:32,000 Anyway, you guys can go ahead and do the math here, 477 00:32:32,000 --> 00:32:35,000 but with binary it doesn't really make sense, 478 00:32:35,000 --> 00:32:38,000 and nor does it make sense with decimal or hexadecimal either, 479 00:32:38,000 --> 00:32:43,000 to do the math out where you have zeros. 480 00:32:43,000 --> 00:32:49,000 You can see I have 0 here, a 0 here, 0 here, 0 here, 0 here, 0 here. 481 00:32:49,000 --> 00:32:52,000 Why might it not make sense to do the actual math 482 00:32:52,000 --> 00:32:56,000 to calculate the appropriate power of 2 for that position? 483 00:32:56,000 --> 00:32:59,000 Exactly, like Charlotte said, it will be 0. 484 00:32:59,000 --> 00:33:05,000 Might as well save yourself the time if calculating powers of 2 isn't your strong suit. 485 00:33:05,000 --> 00:33:10,000 In this case we only need to calculate it for 2 to the 0 which is—? 486 00:33:10,000 --> 00:33:12,000 [Student] 1. 487 00:33:12,000 --> 00:33:14,000 [Nate H.] 1, 2 to the 3 which is—? 488 00:33:14,000 --> 00:33:16,000 [Student] 8.>>[Nate H.] 8. 489 00:33:16,000 --> 00:33:18,000 2 to the 4? 490 00:33:18,000 --> 00:33:21,000 [Student] 2. I'm sorry, 1. 491 00:33:21,000 --> 00:33:26,000 [Nate H.] 2 to the 4 is 16, exactly. 492 00:33:26,000 --> 00:33:28,000 2 to the 5, Kevin?>>32. 493 00:33:28,000 --> 00:33:32,000 [Nate H.] 32, 2 to the 8? 494 00:33:32,000 --> 00:33:38,000 [Student] 32 x 8, 256. 495 00:33:38,000 --> 00:33:41,000 [Nate H.] Perfect. 496 00:33:41,000 --> 00:33:43,000 And 2 to the 10? 497 00:33:43,000 --> 00:33:45,000 [Student] 1024. 498 00:33:45,000 --> 00:33:49,000 [Nate H.] Yeah, 1024. 499 00:33:49,000 --> 00:33:57,000 >> Once we've got these numbers we can sum them all up. 500 00:33:57,000 --> 00:34:01,000 And this is where it's really important to do a couple of things. 501 00:34:01,000 --> 00:34:07,000 One is go slow and check your work. 502 00:34:07,000 --> 00:34:10,000 You can tell that there's a 1 at the end of this number, 503 00:34:10,000 --> 00:34:15,000 so I should definitely get an odd number as my result, 504 00:34:15,000 --> 00:34:18,000 because all the other ones are going to be even numbers 505 00:34:18,000 --> 00:34:21,000 given that it's a binary number. 506 00:34:21,000 --> 00:34:24,000 The other thing to do is if you get to this point on the test 507 00:34:24,000 --> 00:34:27,000 and you've written it out this far 508 00:34:27,000 --> 00:34:30,000 and you're running out of time 509 00:34:30,000 --> 00:34:33,000 look at the number of points that this problem is worth. 510 00:34:33,000 --> 00:34:40,000 This problem, as you can see—if I flip back to my laptop really quickly— 511 00:34:40,000 --> 00:34:44,000 this problem is worth 2 points, so this is not the sort of addition 512 00:34:44,000 --> 00:34:47,000 you should be going through if you're really pressed for time. 513 00:34:47,000 --> 00:34:52,000 But we'll switch back to the iPad, and we'll go through it really quickly. 514 00:34:52,000 --> 00:34:54,000 >> I like doing the small numbers first 515 00:34:54,000 --> 00:34:56,000 because I find that easier. 516 00:34:56,000 --> 00:35:00,000 I like 32 and 8 because they go together pretty easily, and we get 50. 517 00:35:00,000 --> 00:35:03,000 16 and 1 gets 17. 518 00:35:03,000 --> 00:35:05,000 There we get 57, 519 00:35:05,000 --> 00:35:14,000 and then we can do the rest of this, so we can do 57, 156. 520 00:35:14,000 --> 00:35:16,000 Come on. 521 00:35:16,000 --> 00:35:19,000 Man, well, let's see. 522 00:35:19,000 --> 00:35:27,000 We had 57, 256, and 1024. 523 00:35:27,000 --> 00:35:31,000 At this point, I'd rather just go through. 524 00:35:31,000 --> 00:35:35,000 I have no clue. I clearly need to read up on this. 525 00:35:35,000 --> 00:35:40,000 7, 6, and 4, you get 17. 526 00:35:40,000 --> 00:35:42,000 1, 5, 5, 2, 13. 527 00:35:42,000 --> 00:35:45,000 Then we get 3, and then we get 1. 528 00:35:45,000 --> 00:35:52,000 1337. 529 00:35:52,000 --> 00:35:55,000 Easter egg, anybody? 530 00:35:55,000 --> 00:35:59,000 Anybody recognize this number? 531 00:35:59,000 --> 00:36:02,000 Chris recognizes the number. What does it mean, Chris? 532 00:36:02,000 --> 00:36:04,000 [Chris] Leet. 533 00:36:04,000 --> 00:36:11,000 Leet, so if you look at this, it looks like leet. 534 00:36:11,000 --> 00:36:15,000 Hacker stuff. Watch out for that kind of stuff on the midterm or the quiz, rather. 535 00:36:15,000 --> 00:36:19,000 If you see that kind of stuff and you're wondering "Huh," 536 00:36:19,000 --> 00:36:22,000 that might actually mean something. 537 00:36:22,000 --> 00:36:24,000 I don't know. David likes putting it in. 538 00:36:24,000 --> 00:36:26,000 It's a good way to sanity check it. 539 00:36:26,000 --> 00:36:30,000 Like okay, I can see what's going on. 540 00:36:30,000 --> 00:36:34,000 >> That's Week 0/Week 1 stuff. 541 00:36:34,000 --> 00:36:39,000 If we switch back to our laptop now, 542 00:36:39,000 --> 00:36:46,000 zoom out, and a couple of other things. 543 00:36:46,000 --> 00:36:50,000 There's ASCII, which we've been doing a lot of with the problem sets. 544 00:36:50,000 --> 00:36:55,000 This notion of capital A. What is that really? 545 00:36:55,000 --> 00:36:57,000 Knowing it's the decimal integer. 546 00:36:57,000 --> 00:37:00,000 65 is what it's mapped to in the ASCII table, 547 00:37:00,000 --> 00:37:03,000 and that's therefore how the computer writes it, 548 00:37:03,000 --> 00:37:06,000 and that's how we've been getting away with actually writing 549 00:37:06,000 --> 00:37:09,000 the character capital A and the character lowercase a 550 00:37:09,000 --> 00:37:14,000 in some of these solutions and problem sets that you've been doing. 551 00:37:14,000 --> 00:37:16,000 A couple of other things. 552 00:37:16,000 --> 00:37:25,000 We've got statements, boolean expressions, conditions, loops, variables and threads. 553 00:37:25,000 --> 00:37:29,000 >> Those all seem to make sense for the most part? 554 00:37:29,000 --> 00:37:35,000 Some of this terminology is a little funky at times. 555 00:37:35,000 --> 00:37:46,000 I like to think of a statement as for the most part something that ends with a semicolon. 556 00:37:46,000 --> 00:37:51,000 Statements such as x = 7, which sets a variable, 557 00:37:51,000 --> 00:37:54,000 presumably called x = 7. 558 00:37:54,000 --> 00:38:01,000 Presumably x is also a type that can store the number 7, 559 00:38:01,000 --> 00:38:05,000 so it's an int or possibly a float or a short or a char, 560 00:38:05,000 --> 00:38:07,000 something like that. 561 00:38:07,000 --> 00:38:12,000 A boolean expression is using these double equals 562 00:38:12,000 --> 00:38:17,000 and the bang equals or the not equals, less than, greater than, 563 00:38:17,000 --> 00:38:22,000 less than or equal to, all that kind of stuff. 564 00:38:22,000 --> 00:38:28,000 Conditions then are if else statements. 565 00:38:28,000 --> 00:38:32,000 I would remember that you can't have an else without a corresponding if. 566 00:38:32,000 --> 00:38:37,000 Likewise, you can't have an else if without a corresponding if. 567 00:38:37,000 --> 00:38:40,000 Loops, recall the 3 kinds of loops we've been hammering into you 568 00:38:40,000 --> 00:38:43,000 for the last couple of sections and problem sets. 569 00:38:43,000 --> 00:38:46,000 Using do while when you're getting user input, 570 00:38:46,000 --> 00:38:51,000 using while loops until a particular condition is true, 571 00:38:51,000 --> 00:38:56,000 and then using those for loops if you need to 572 00:38:56,000 --> 00:39:01,000 know which iteration of the loop you're currently on is how I think about it. 573 00:39:01,000 --> 00:39:07,000 Or if you're doing a for each character in a string I want to do something, 574 00:39:07,000 --> 00:39:15,000 for each element in an array I want to do something to that element. 575 00:39:15,000 --> 00:39:18,000 >> Threads and events. 576 00:39:18,000 --> 00:39:21,000 These we haven't covered so explicitly in C, 577 00:39:21,000 --> 00:39:23,000 but remember this from Scratch. 578 00:39:23,000 --> 00:39:26,000 This is the notion of having different scripts. 579 00:39:26,000 --> 00:39:32,000 This is also this notion of broadcasting an event. 580 00:39:32,000 --> 00:39:37,000 Some people didn't use broadcasting in their projects initially, 581 00:39:37,000 --> 00:39:40,000 which is totally cool, 582 00:39:40,000 --> 00:39:46,000 but these are 2 different ways of handling this larger issue called concurrency, 583 00:39:46,000 --> 00:39:49,000 which is how do you get programs to execute 584 00:39:49,000 --> 00:39:54,000 or seemingly execute at the same time? 585 00:39:54,000 --> 00:39:59,000 Different tasks running while other tasks are also running. 586 00:39:59,000 --> 00:40:01,000 This is how your operating system seems to work. 587 00:40:01,000 --> 00:40:04,000 This is why even though, for example, 588 00:40:04,000 --> 00:40:10,000 I've got my browser running, I can also turn on Spotify and play a song. 589 00:40:10,000 --> 00:40:14,000 That's more of a conceptual thing to understand. 590 00:40:14,000 --> 00:40:17,000 I would take a look at the threads short 591 00:40:17,000 --> 00:40:21,000 if you'd like to learn more about that. 592 00:40:21,000 --> 00:40:26,000 >> Let's see, I believe there might have been 593 00:40:26,000 --> 00:40:31,000 a problem on this in one of these. 594 00:40:31,000 --> 00:40:35,000 Again, I think threads and events are not something that we will cover in C 595 00:40:35,000 --> 00:40:41,000 just because it's significantly more difficult than in Scratch. 596 00:40:41,000 --> 00:40:44,000 You shouldn't worry about it there, but definitely understand the concepts, 597 00:40:44,000 --> 00:40:47,000 understand what's going on. 598 00:40:47,000 --> 00:40:52,000 Before we move on, any questions on Week 0 material? 599 00:40:52,000 --> 00:40:55,000 Everybody feeling pretty good? 600 00:40:55,000 --> 00:41:03,000 Understanding variables and what a variable is? 601 00:41:03,000 --> 00:41:08,000 >> Moving on. Week 1. 602 00:41:08,000 --> 00:41:12,000 A couple of things here that weren't particularly covered 603 00:41:12,000 --> 00:41:21,000 in the quiz review necessarily and also are more conceptual things to think about. 604 00:41:21,000 --> 00:41:30,000 The first is this notion of what source code, compilers and object code are. 605 00:41:30,000 --> 00:41:32,000 Anybody? Basil. 606 00:41:32,000 --> 00:41:37,000 Is object code—I mean source code is what you put into clang, 607 00:41:37,000 --> 00:41:42,000 and object code is what clang puts out so that your computer can read the program. 608 00:41:42,000 --> 00:41:44,000 Exactly. 609 00:41:44,000 --> 00:41:47,000 Source code is the C code that you actually type up. 610 00:41:47,000 --> 00:41:50,000 Object code is what you get out of clang. 611 00:41:50,000 --> 00:41:54,000 It's the 0s and 1s in that binary format. 612 00:41:54,000 --> 00:41:59,000 Then what happens is when you have a bunch of object files, 613 00:41:59,000 --> 00:42:04,000 say you're compiling a project or a program that uses multiple source code files, 614 00:42:04,000 --> 00:42:09,000 which by convention are given the .c file extension. 615 00:42:09,000 --> 00:42:13,000 That's why we have caesar.c, vigenère.c. 616 00:42:13,000 --> 00:42:18,000 If you're writing Java programs you give them the extension .java. 617 00:42:18,000 --> 00:42:24,000 Python programs have the extension .py often. 618 00:42:24,000 --> 00:42:26,000 >> Once you have multiple .c files, you compile them. 619 00:42:26,000 --> 00:42:29,000 Clang spits out all this binary junk. 620 00:42:29,000 --> 00:42:33,000 Then because you only want 1 program 621 00:42:33,000 --> 00:42:37,000 you have the linker link all of these object files together 622 00:42:37,000 --> 00:42:40,000 into 1 executable file. 623 00:42:40,000 --> 00:42:45,000 This is also what happens when you use the CS50 library, for example. 624 00:42:45,000 --> 00:42:50,000 The CS50 library is both that .h header file 625 00:42:50,000 --> 00:42:53,000 that you read, that #includecs50.h. 626 00:42:53,000 --> 00:42:58,000 And then it's also a special binary library file 627 00:42:58,000 --> 00:43:02,000 that's been compiled that is 0s and 1s, 628 00:43:02,000 --> 00:43:08,000 and that -l flag, so if we go back to our Spaces and we look really quickly 629 00:43:08,000 --> 00:43:11,000 at what's going on here when we look at our clang command, 630 00:43:11,000 --> 00:43:15,000 what we've got is this is our source code file right here. 631 00:43:15,000 --> 00:43:18,000 These are a bunch of compiler flags. 632 00:43:18,000 --> 00:43:22,000 And then at the very end, these -l flags link in 633 00:43:22,000 --> 00:43:30,000 the actual binary files for these 2 libraries, the CS50 library and then the math library. 634 00:43:30,000 --> 00:43:35,000 >> Understanding each type of files' purpose 635 00:43:35,000 --> 00:43:38,000 in the compilation process is something you'll want to be able to 636 00:43:38,000 --> 00:43:43,000 give at least a high level overview of. 637 00:43:43,000 --> 00:43:46,000 Source code comes in. Object code comes out. 638 00:43:46,000 --> 00:43:53,000 Object code files link together, and you get a beautiful, executable file. 639 00:43:53,000 --> 00:43:55,000 Cool. 640 00:43:55,000 --> 00:43:58,000 This is also where you can get errors at multiple points 641 00:43:58,000 --> 00:44:00,000 in the compilation process. 642 00:44:00,000 --> 00:44:04,000 This is where, for example, if you take out this linking flag, 643 00:44:04,000 --> 00:44:10,000 the CS50 flag, and you omit it in Spaces or when you're running your code, 644 00:44:10,000 --> 00:44:13,000 this is where you'll get an error in the linking phase, 645 00:44:13,000 --> 00:44:18,000 and the linker will say, "Hey, you called a function GetString 646 00:44:18,000 --> 00:44:20,000 that's in the CS50 library." 647 00:44:20,000 --> 00:44:25,000 "You told me it was in the CS50 library, and I can't find the code for it." 648 00:44:25,000 --> 00:44:28,000 That's where you have to link it in, and that's separate 649 00:44:28,000 --> 00:44:33,000 from a compiler error because the compiler is looking at syntax and that kind of stuff. 650 00:44:33,000 --> 00:44:38,000 It's good to know what's going on when. 651 00:44:38,000 --> 00:44:42,000 >> Other things to know about. 652 00:44:42,000 --> 00:44:49,000 I would say you definitely want to take a look at the short on typecasting done by Jordan 653 00:44:49,000 --> 00:44:55,000 to understand what ints are under the hood, 654 00:44:55,000 --> 00:44:58,000 what chars are under the hood. 655 00:44:58,000 --> 00:45:02,000 When we talk about ASCII and we actually look at the ASCII table, 656 00:45:02,000 --> 00:45:07,000 what that's doing is giving us an under the hood look 657 00:45:07,000 --> 00:45:13,000 at how the computer actually represents capital A and the digit 7 658 00:45:13,000 --> 00:45:17,000 and a comma and a question mark. 659 00:45:17,000 --> 00:45:20,000 The computer also has special ways to represent 660 00:45:20,000 --> 00:45:23,000 the number 7 as an integer. 661 00:45:23,000 --> 00:45:27,000 It has a special way to represent the number 7 as a floating point number, 662 00:45:27,000 --> 00:45:29,000 and those are very different. 663 00:45:29,000 --> 00:45:32,000 Typecasting is how you tell the computer "Hey, I want you to convert 664 00:45:32,000 --> 00:45:37,000 from one representation to another representation." 665 00:45:37,000 --> 00:45:40,000 Why don't we take a look at that. 666 00:45:40,000 --> 00:45:44,000 >> I would also take a look at the short on libraries and the short on compilers. 667 00:45:44,000 --> 00:45:47,000 Those talk about the process of compilation, 668 00:45:47,000 --> 00:45:53,000 what a library is, and go over some of these questions that you might get asked. 669 00:45:53,000 --> 00:45:55,000 Questions on Week 1 material? 670 00:45:55,000 --> 00:46:03,000 Are there any topics in here that seem daunting you'd like to cover? 671 00:46:03,000 --> 00:46:07,000 I'm trying to blow through most of these earlier topics so that we can get to 672 00:46:07,000 --> 00:46:13,000 pointers and do a little bit of recursion. 673 00:46:13,000 --> 00:46:15,000 Thoughts? 674 00:46:15,000 --> 00:46:19,000 Anything to cover? 675 00:46:19,000 --> 00:46:21,000 Time for some chocolate maybe? 676 00:46:21,000 --> 00:46:23,000 You guys are working through it. 677 00:46:23,000 --> 00:46:26,000 I'm going to keep sipping on my coffee. 678 00:46:26,000 --> 00:46:31,000 Week 2. 679 00:46:31,000 --> 00:46:34,000 Good call, good call. 680 00:46:34,000 --> 00:46:38,000 In Week 2 we talked a little bit more about functions. 681 00:46:38,000 --> 00:46:43,000 >> In the first few problem sets we didn't really write any functions at all 682 00:46:43,000 --> 00:46:45,000 other than which function? 683 00:46:45,000 --> 00:46:47,000 [Student] Main.>>Main, exactly. 684 00:46:47,000 --> 00:46:51,000 And so we've seen the different costumes that main wears. 685 00:46:51,000 --> 00:46:54,000 There's the one in which it takes no arguments, 686 00:46:54,000 --> 00:46:58,000 and we just say void in between the parentheses, 687 00:46:58,000 --> 00:47:01,000 and then there's the other one where we do want to take command line arguments, 688 00:47:01,000 --> 00:47:08,000 and as we saw, that's where you have int argc and string argv array 689 00:47:08,000 --> 00:47:13,000 or now that we've actually exposed string to be the char* that it is 690 00:47:13,000 --> 00:47:20,000 we're going to start writing it as char* argv and then brackets. 691 00:47:20,000 --> 00:47:22,000 In Problem Set 3, you guys saw a bunch of functions, 692 00:47:22,000 --> 00:47:27,000 and you implemented a bunch of functions, draw, look up, scramble. 693 00:47:27,000 --> 00:47:31,000 The prototypes were all written there for you. 694 00:47:31,000 --> 00:47:33,000 >> What I wanted to talk about here with functions really quickly 695 00:47:33,000 --> 00:47:38,000 is that there are 3 parts to them whenever you write a function. 696 00:47:38,000 --> 00:47:43,000 You have to specify the return type of the function. 697 00:47:43,000 --> 00:47:46,000 You have to specify a name for the function, and then you have to specify 698 00:47:46,000 --> 00:47:51,000 the argument list or the parameter list. 699 00:47:51,000 --> 00:47:57,000 For example, if I were to write a function to sum up a bunch of integers 700 00:47:57,000 --> 00:48:03,000 and then return to me the sum what would be my return type 701 00:48:03,000 --> 00:48:06,000 if I wanted to sum integers and then return the sum? 702 00:48:06,000 --> 00:48:12,000 Then the name of the function. 703 00:48:12,000 --> 00:48:27,000 If I go ahead and write in green, this part is the return type. 704 00:48:27,000 --> 00:48:34,000 This part is the name. 705 00:48:34,000 --> 00:48:40,000 And then in between parentheses 706 00:48:40,000 --> 00:48:46,000 is where I give the arguments, 707 00:48:46,000 --> 00:48:56,000 often abbreviated as args, sometimes called params for parameters. 708 00:48:56,000 --> 00:49:00,000 And if you have one, you just specify the one. 709 00:49:00,000 --> 00:49:06,000 If you have multiple you separate each one with a comma. 710 00:49:06,000 --> 00:49:13,000 And for each argument you give it 2 things which are—Kevin? 711 00:49:13,000 --> 00:49:18,000 [Kevin] You have to give the type and then the name. 712 00:49:18,000 --> 00:49:21,000 And then the name, and the name is the name that you're going to use 713 00:49:21,000 --> 00:49:25,000 to refer to that argument within the sum function, 714 00:49:25,000 --> 00:49:27,000 within the function that you're currently writing. 715 00:49:27,000 --> 00:49:32,000 >> You don't have to—for example, if I'm going to sum up, 716 00:49:32,000 --> 00:49:41,000 say, an array of integers—we'll do int array, 717 00:49:41,000 --> 00:49:46,000 and I'll give myself some curly braces there— 718 00:49:46,000 --> 00:49:51,000 then when I pass an array to the sum function 719 00:49:51,000 --> 00:49:55,000 I pass it in the first position of the argument list. 720 00:49:55,000 --> 00:49:59,000 But the array that I pass in doesn't have to have the name arr. 721 00:49:59,000 --> 00:50:07,000 Arr is going to be how I refer to that argument within the body of the function. 722 00:50:07,000 --> 00:50:10,000 The other thing that we need to take into account, 723 00:50:10,000 --> 00:50:14,000 and this is slightly different from functions, but I think it's an important point, 724 00:50:14,000 --> 00:50:20,000 is that in C when I'm writing a function like this 725 00:50:20,000 --> 00:50:29,000 how do I know how many elements are in this array? 726 00:50:29,000 --> 00:50:31,000 This is somewhat of a trick question. 727 00:50:31,000 --> 00:50:35,000 We talked about this a little bit in last week's section. 728 00:50:35,000 --> 00:50:40,000 How do I know the number of elements inside an array in C? 729 00:50:40,000 --> 00:50:44,000 Is there a way? 730 00:50:44,000 --> 00:50:49,000 >> It turns out that there's no way to know. 731 00:50:49,000 --> 00:50:52,000 You have to pass it in separately. 732 00:50:52,000 --> 00:50:55,000 There is a trick that you can do 733 00:50:55,000 --> 00:51:00,000 if you're in the same function in which the array has been declared, 734 00:51:00,000 --> 00:51:04,000 and you're working with a stack array. 735 00:51:04,000 --> 00:51:06,000 But that only works if you're in the same function. 736 00:51:06,000 --> 00:51:09,000 Once you pass an array to another function or if you've declared an array 737 00:51:09,000 --> 00:51:12,000 and you put that array on the heap, you've used malloc 738 00:51:12,000 --> 00:51:15,000 and that kind of stuff, then all bets are off. 739 00:51:15,000 --> 00:51:18,000 Then you actually have to pass around 740 00:51:18,000 --> 00:51:21,000 a special argument or another parameter 741 00:51:21,000 --> 00:51:23,000 telling you how big the array is. 742 00:51:23,000 --> 00:51:28,000 In this case, I'd want to use a comma—I'm sorry, it's going off the screen here— 743 00:51:28,000 --> 00:51:32,000 and I'd pass in another argument 744 00:51:32,000 --> 00:51:40,000 and call it int len for the length. 745 00:51:40,000 --> 00:51:44,000 >> One thing that might come up on the quiz 746 00:51:44,000 --> 00:51:49,000 is asking you to write or implement a particular function called something. 747 00:51:49,000 --> 00:51:54,000 If we don't give you the prototype, so this whole thing here, 748 00:51:54,000 --> 00:51:58,000 this whole mess is called the function declaration or the function prototype, 749 00:51:58,000 --> 00:52:01,000 this is one of the first things that you'll want to nail down if it's not given 750 00:52:01,000 --> 00:52:03,000 to you right away on the quiz. 751 00:52:03,000 --> 00:52:06,000 The other trick I've learned is that 752 00:52:06,000 --> 00:52:11,000 say we do give you a prototype for a function, and we say, "Hey, you've got to write it." 753 00:52:11,000 --> 00:52:16,000 Inside the curly braces that you have on the quiz 754 00:52:16,000 --> 00:52:20,000 if you notice that there is a return type and you notice that the return type 755 00:52:20,000 --> 00:52:25,000 is something other than void, which means that the function doesn't return anything, 756 00:52:25,000 --> 00:52:28,000 then one thing you definitely want to do is write 757 00:52:28,000 --> 00:52:33,000 some sort of return statement at the very end of the function. 758 00:52:33,000 --> 00:52:40,000 Return, and in this case, we'll put a blank because we want to fill in the blank. 759 00:52:40,000 --> 00:52:44,000 But this gets you thinking in the right way about how am I going to approach this problem? 760 00:52:44,000 --> 00:52:49,000 And it reminds you you're going to have to return a value 761 00:52:49,000 --> 00:52:51,000 to the caller of the function. 762 00:52:51,000 --> 00:52:54,000 >> Yeah.>>[Student] Does style apply when we're writing code on the quiz? 763 00:52:54,000 --> 00:52:58,000 Such as indentation and that kind of stuff?>>[Student] Yeah. 764 00:52:58,000 --> 00:53:00,000 No, not as much. 765 00:53:00,000 --> 00:53:09,000 I think a lot of—this is something we'll clarify on the quiz on the day of, 766 00:53:09,000 --> 00:53:15,000 but typically worrying about #includes and that kind of stuff, it's kind of outside. 767 00:53:15,000 --> 00:53:17,000 [Student] Do you need to comment your handwritten code? 768 00:53:17,000 --> 00:53:19,000 Do you need to comment your handwritten code? 769 00:53:19,000 --> 00:53:24,000 Commenting is always good if you're worried about partial credit 770 00:53:24,000 --> 00:53:29,000 or you want to communicate your intent to the grader. 771 00:53:29,000 --> 00:53:33,000 But I, again, will clarify on the quiz itself and on the quiz day, 772 00:53:33,000 --> 00:53:39,000 but I don't believe that you'll be required to write comments, no. 773 00:53:39,000 --> 00:53:42,000 Typically not, but it's definitely the sort of thing where 774 00:53:42,000 --> 00:53:45,000 you can communicate your intent, like "Hey, this is where I'm going with it." 775 00:53:45,000 --> 00:53:49,000 And sometimes that can help with partial credit. 776 00:53:49,000 --> 00:53:51,000 Cool. 777 00:53:51,000 --> 00:53:53,000 >> Basil. 778 00:53:53,000 --> 00:53:56,000 [Basil] What's the difference between declaring, say, int lang 779 00:53:56,000 --> 00:54:03,000 in the arguments or parameters versus declaring a variable within the function? 780 00:54:03,000 --> 00:54:05,000 Wow, coffee went down the windpipe. 781 00:54:05,000 --> 00:54:07,000 [Basil] Like which things we want to put in arguments. 782 00:54:07,000 --> 00:54:09,000 Yeah, that's a great question. 783 00:54:09,000 --> 00:54:11,000 How do you choose what things you want to put in the arguments 784 00:54:11,000 --> 00:54:17,000 versus what things you should do inside of the function? 785 00:54:17,000 --> 00:54:24,000 In this case we included both of these as arguments 786 00:54:24,000 --> 00:54:29,000 because they're something that whoever is going to use the sum function 787 00:54:29,000 --> 00:54:32,000 needs to specify those things. 788 00:54:32,000 --> 00:54:35,000 >> The sum function, like we talked about, has no way of knowing 789 00:54:35,000 --> 00:54:40,000 how big the array is it gets from its caller or whoever is using the sum function. 790 00:54:40,000 --> 00:54:44,000 It has no way of knowing how big that array is. 791 00:54:44,000 --> 00:54:48,000 The reason we pass in this length right here as an argument 792 00:54:48,000 --> 00:54:51,000 is because that's something that we're basically telling the caller of the function, 793 00:54:51,000 --> 00:54:55,000 whoever is going to use the sum function, "Hey, not only do you have to give us an array 794 00:54:55,000 --> 00:54:59,000 of ints, you also have to tell us how big the array that you've given us is." 795 00:54:59,000 --> 00:55:03,000 [Basil] Those will both be command line arguments? 796 00:55:03,000 --> 00:55:06,000 No, these are actual arguments that you would pass to the function. 797 00:55:06,000 --> 00:55:10,000 >> Let me do a new page here. 798 00:55:10,000 --> 00:55:13,000 [Basil] Like name would pass— 799 00:55:13,000 --> 00:55:24,000 [Nate H.] If I have int main (void), 800 00:55:24,000 --> 00:55:27,000 and I'm going to put in my return 0 down here at the bottom, 801 00:55:27,000 --> 00:55:31,000 and say I want to call the sum function. 802 00:55:31,000 --> 00:55:42,000 I want to say int x = sum( ); 803 00:55:42,000 --> 00:55:46,000 To use the sum function I have to pass in both the array that I want to sum up 804 00:55:46,000 --> 00:55:51,000 and the length of the array, so this is where 805 00:55:51,000 --> 00:55:54,000 assuming I had an array of ints, 806 00:55:54,000 --> 00:56:12,000 say I had int numbaz [ ] = 1, 2, 3, 807 00:56:12,000 --> 00:56:16,000 kind of use that hacked up syntax right there, 808 00:56:16,000 --> 00:56:21,000 then what I would do is in sum I would want to pass in 809 00:56:21,000 --> 00:56:27,000 both numbaz and the number 3 810 00:56:27,000 --> 00:56:30,000 to tell the sum function "Okay, here's the array I want you to sum." 811 00:56:30,000 --> 00:56:34,000 "Here's its size." 812 00:56:34,000 --> 00:56:39,000 Does that make sense? Does that answer your question? 813 00:56:39,000 --> 00:56:42,000 >> In many ways it does parallel what we're doing with main 814 00:56:42,000 --> 00:56:44,000 when we have the command line arguments. 815 00:56:44,000 --> 00:56:47,000 A program like Caesar cipher, for example, that needed 816 00:56:47,000 --> 00:56:53,000 command line arguments would not be able to do anything. 817 00:56:53,000 --> 00:56:57,000 It wouldn't know how to encrypt if you didn't tell it what key to use 818 00:56:57,000 --> 00:57:03,000 or if you didn't tell it what string you wanted to encrypt. 819 00:57:03,000 --> 00:57:08,000 Prompting for input, this is where we've got 2 different mechanisms 820 00:57:08,000 --> 00:57:14,000 for taking input in from the user, for taking information in from the user. 821 00:57:14,000 --> 00:57:19,000 For Problem Set 1 we saw this GetInt, GetString, GetFloat way 822 00:57:19,000 --> 00:57:26,000 of prompting for input, and that's called using the standard input stream. 823 00:57:26,000 --> 00:57:28,000 It's slightly different. 824 00:57:28,000 --> 00:57:31,000 It's something that you can do at one time as opposed to 825 00:57:31,000 --> 00:57:35,000 when you invoke the program, when you start the program running. 826 00:57:35,000 --> 00:57:41,000 The command line arguments all are specified when you start the program running. 827 00:57:41,000 --> 00:57:47,000 We've been mixing the two of those. 828 00:57:47,000 --> 00:57:52,000 When we use arguments to a function, it's much like command line arguments to main. 829 00:57:52,000 --> 00:57:56,000 It's when you invoke the function you need to tell it 830 00:57:56,000 --> 00:58:05,000 what exactly it needs in order to perform its tasks. 831 00:58:05,000 --> 00:58:08,000 Another good thing to look at—and I'll let you look at it in your spare time, 832 00:58:08,000 --> 00:58:11,000 and it was covered in the quiz—was this notion of scope 833 00:58:11,000 --> 00:58:15,000 and local variables versus global variables. 834 00:58:15,000 --> 00:58:18,000 Do pay attention to that. 835 00:58:18,000 --> 00:58:23,000 >> Now that we're getting on to this other stuff, 836 00:58:23,000 --> 00:58:27,000 in Week 3 we started talking about searching and sorting. 837 00:58:27,000 --> 00:58:32,000 Searching and sorting, at least in CS50, 838 00:58:32,000 --> 00:58:39,000 is very much an introduction to some of the more theoretical parts of computer science. 839 00:58:39,000 --> 00:58:42,000 The problem of searching, the problem of sorting 840 00:58:42,000 --> 00:58:46,000 are big, canonical problems. 841 00:58:46,000 --> 00:58:52,000 How do you find a particular number in an array of billions of integers? 842 00:58:52,000 --> 00:58:55,000 How do you find a particular name inside a phone book 843 00:58:55,000 --> 00:58:59,000 that's stored on your laptop? 844 00:58:59,000 --> 00:59:04,000 And so we introduce this notion of asymptotic run times 845 00:59:04,000 --> 00:59:11,000 to really quantify how long, how hard these problem are, 846 00:59:11,000 --> 00:59:14,000 how long they take to solve. 847 00:59:14,000 --> 00:59:20,000 In, I believe, 2011's quiz there's a problem that I think merits 848 00:59:20,000 --> 00:59:27,000 covering very quickly, which is this one, problem 12. 849 00:59:27,000 --> 00:59:32,000 O no, it's Omega. 850 00:59:32,000 --> 00:59:41,000 >> Here we're talking about the fastest possible run time 851 00:59:41,000 --> 00:59:46,000 for a particular algorithm and then the slowest possible run time. 852 00:59:46,000 --> 00:59:52,000 This Omega and O are really just shortcuts. 853 00:59:52,000 --> 00:59:55,000 They're notational shortcuts for saying 854 00:59:55,000 --> 00:59:59,000 how fast in the best possible case will our algorithm run, 855 00:59:59,000 --> 01:00:06,000 and how slow in the worst possible case will our algorithm run? 856 01:00:06,000 --> 01:00:10,000 Let's do a couple of these, and these were also covered 857 01:00:10,000 --> 01:00:13,000 in the short on asymptotic notation, which I highly recommend. 858 01:00:13,000 --> 01:00:17,000 Jackson did a really good job. 859 01:00:17,000 --> 01:00:23,000 With binary search, we talk about binary search as being an algorithm, 860 01:00:23,000 --> 01:00:28,000 and we usually talk about it in terms of its big O. 861 01:00:28,000 --> 01:00:30,000 What is the big O? 862 01:00:30,000 --> 01:00:34,000 What is the slowest possible run time of binary search? 863 01:00:34,000 --> 01:00:36,000 [Student] N²? 864 01:00:36,000 --> 01:00:41,000 Close, I guess similar to that. 865 01:00:41,000 --> 01:00:43,000 It's a lot faster than that. 866 01:00:43,000 --> 01:00:45,000 [Student] Binary?>>Yeah, binary search. 867 01:00:45,000 --> 01:00:47,000 [Student] It's log n. 868 01:00:47,000 --> 01:00:49,000 Log n, so what does log n mean? 869 01:00:49,000 --> 01:00:51,000 It halves it each iteration. 870 01:00:51,000 --> 01:00:56,000 Exactly, so in the slowest possible case, 871 01:00:56,000 --> 01:01:00,000 say if you have a sorted array 872 01:01:00,000 --> 01:01:08,000 of a million integers and the number you're looking for 873 01:01:08,000 --> 01:01:14,000 is either the very first element in the array or the very last element in the array. 874 01:01:14,000 --> 01:01:18,000 Remember, the binary search algorithm works by looking at the middle element, 875 01:01:18,000 --> 01:01:21,000 seeing if that's the match that you're looking for. 876 01:01:21,000 --> 01:01:23,000 If it is, then great, you found it. 877 01:01:23,000 --> 01:01:27,000 >> In the best possible case, how fast does binary search run? 878 01:01:27,000 --> 01:01:29,000 [Students] 1. 879 01:01:29,000 --> 01:01:32,000 1, it's constant time, big O of 1. Yeah. 880 01:01:32,000 --> 01:01:36,000 [Student] I have a question. When you say log of n, you mean with respect to base 2, right? 881 01:01:36,000 --> 01:01:40,000 Yes, so that's the other thing. 882 01:01:40,000 --> 01:01:44,000 We say log n, and I guess when I was in high school 883 01:01:44,000 --> 01:01:48,000 I always assumed that log was base 10. 884 01:01:48,000 --> 01:01:57,000 Yeah, so yes, log base 2 typically is what we use. 885 01:01:57,000 --> 01:02:02,000 Again, going back to binary search, if you're searching for either 886 01:02:02,000 --> 01:02:05,000 the element at the very end or the element at the very beginning, 887 01:02:05,000 --> 01:02:08,000 because you start in the middle and then you discard 888 01:02:08,000 --> 01:02:13,000 whichever half doesn't meet the criteria that you're looking for, 889 01:02:13,000 --> 01:02:15,000 and you go to the next half and the next half and the next half. 890 01:02:15,000 --> 01:02:19,000 If I'm searching for the largest element in the million integer array 891 01:02:19,000 --> 01:02:25,000 I'm going to halve it at most log of 1 million times 892 01:02:25,000 --> 01:02:28,000 before I finally test and see that the element I'm looking for 893 01:02:28,000 --> 01:02:33,000 is in the biggest or in the highest index of the array, 894 01:02:33,000 --> 01:02:38,000 and that will take log of n, log of 1 million times. 895 01:02:38,000 --> 01:02:40,000 >> Bubble sort. 896 01:02:40,000 --> 01:02:43,000 Do you guys remember the bubble sort algorithm? 897 01:02:43,000 --> 01:02:47,000 Kevin, can you give me a quick recap of what happened in the bubble sort algorithm? 898 01:02:47,000 --> 01:02:50,000 [Kevin] Basically it goes through everything in the list. 899 01:02:50,000 --> 01:02:52,000 It looks at the first two. 900 01:02:52,000 --> 01:02:55,000 If the first one is bigger than the second one it swaps them. 901 01:02:55,000 --> 01:02:58,000 Then it compares second and third, same thing, swaps, 902 01:02:58,000 --> 01:03:00,000 third and fourth, all the way down. 903 01:03:00,000 --> 01:03:03,000 Bigger numbers will follow up to the end. 904 01:03:03,000 --> 01:03:07,000 And after however many loops you're done. 905 01:03:07,000 --> 01:03:11,000 Exactly, so what Kevin said is that we'll watch bigger numbers 906 01:03:11,000 --> 01:03:15,000 bubble up to the end of the array. 907 01:03:15,000 --> 01:03:19,000 For example, do you mind walking us through this example if this is our array? 908 01:03:19,000 --> 01:03:21,000 [Kevin] You'll take 2 and 3. 909 01:03:21,000 --> 01:03:23,000 3 is bigger than 2, so you swap them. 910 01:03:23,000 --> 01:03:29,000 [Nate H.] Right, so we swap these, and so we get 2, 3, 6, 4, and 9. 911 01:03:29,000 --> 01:03:31,000 [Kevin] Then you compare the 3 and 6. 912 01:03:31,000 --> 01:03:33,000 3 is smaller than 6, so you leave them, 913 01:03:33,000 --> 01:03:37,000 and 6 and 4, you'd swap them because 4 is smaller than 6. 914 01:03:37,000 --> 01:03:42,000 [Nate H.] Right, so I get 2, 3, 4, 6, 9. 915 01:03:42,000 --> 01:03:46,000 [Kevin] And 9 is bigger than 6, so you leave it. 916 01:03:46,000 --> 01:03:48,000 And you'd go back through it again. 917 01:03:48,000 --> 01:03:50,000 >> [Nate H.] Am I done at this point?>>[Kevin] No. 918 01:03:50,000 --> 01:03:52,000 And why am I not done at this point? 919 01:03:52,000 --> 01:03:54,000 Because it looks like my array is sorted. I'm looking at it. 920 01:03:54,000 --> 01:03:57,000 [Kevin] Go through it again and make sure that there are no more swaps 921 01:03:57,000 --> 01:04:00,000 before you can fully stop. 922 01:04:00,000 --> 01:04:04,000 Exactly, so you need to keep going through and make sure that there are no swaps 923 01:04:04,000 --> 01:04:06,000 that you can make at this point. 924 01:04:06,000 --> 01:04:08,000 It was really just lucky, like you said, that we ended up 925 01:04:08,000 --> 01:04:12,000 only having to make 1 pass through and we're sorted. 926 01:04:12,000 --> 01:04:16,000 But to do this in the general case we'll actually have to do this over and over again. 927 01:04:16,000 --> 01:04:20,000 And in fact, this was an example of the best possible case, 928 01:04:20,000 --> 01:04:24,000 like we saw in the problem. 929 01:04:24,000 --> 01:04:28,000 We saw that the best possible case was n. 930 01:04:28,000 --> 01:04:32,000 We went through the array 1 time. 931 01:04:32,000 --> 01:04:35,000 What is the worst possible case for this algorithm? 932 01:04:35,000 --> 01:04:37,000 [Kevin] N². 933 01:04:37,000 --> 01:04:41,000 And what does that look like? What would an array look like that would take n² time? 934 01:04:41,000 --> 01:04:43,000 [Kevin] [inaudible] sorted. 935 01:04:43,000 --> 01:04:51,000 Exactly, so if I had the array 9, 7, 6, 5, 2, 936 01:04:51,000 --> 01:04:54,000 first the 9 would bubble all the way up. 937 01:04:54,000 --> 01:04:59,000 After 1 iteration we'd have 7, 6, 5, 2, 9. 938 01:04:59,000 --> 01:05:07,000 Then the 7 would bubble up, 6, 5, 2, 7, 9, and so on and so forth. 939 01:05:07,000 --> 01:05:13,000 >> We'd have to go through the entire array n times, 940 01:05:13,000 --> 01:05:16,000 and you can actually get slightly more precise than this 941 01:05:16,000 --> 01:05:23,000 because once we've moved the 9 all the way up into its last possible position 942 01:05:23,000 --> 01:05:26,000 we know that we never have to compare against that element again. 943 01:05:26,000 --> 01:05:29,000 Once we start bubbling the 7 up 944 01:05:29,000 --> 01:05:35,000 we know that we can stop once the 7 is right before the 9 945 01:05:35,000 --> 01:05:37,000 since we've already compared the 9 to it. 946 01:05:37,000 --> 01:05:46,000 If you do this in a smart way it's not truly, I guess, that much time. 947 01:05:46,000 --> 01:05:49,000 You're not going to compare all the possible [inaudible] combinations 948 01:05:49,000 --> 01:05:55,000 every single time you go through each iteration. 949 01:05:55,000 --> 01:05:59,000 But still, when we talk about this upper bound we say that 950 01:05:59,000 --> 01:06:04,000 you are looking at n² comparisons all the way through. 951 01:06:04,000 --> 01:06:12,000 >> Let's go back, and since we're starting to get a little short on time 952 01:06:12,000 --> 01:06:15,000 I would say you should definitely go through the rest of this table, 953 01:06:15,000 --> 01:06:17,000 fill it all out. 954 01:06:17,000 --> 01:06:20,000 Think of examples. Think of concrete examples. 955 01:06:20,000 --> 01:06:22,000 That's really handy and helpful to do. 956 01:06:22,000 --> 01:06:25,000 Draw it out. 957 01:06:25,000 --> 01:06:28,000 This is the sort of table that as you go through in computer science 958 01:06:28,000 --> 01:06:32,000 you should really start to know these by heart. 959 01:06:32,000 --> 01:06:34,000 These are the kinds of questions you get in interviews. 960 01:06:34,000 --> 01:06:36,000 These are sorts of things that are good to know, 961 01:06:36,000 --> 01:06:41,000 and think about those edge cases, really figuring out how to think about 962 01:06:41,000 --> 01:06:45,000 knowing that for bubble sort the worst possible array 963 01:06:45,000 --> 01:06:52,000 to sort with that is one that's in reverse order. 964 01:06:52,000 --> 01:06:58,000 >> Pointers. Let's talk a little bit about pointers. 965 01:06:58,000 --> 01:07:03,000 In the last few minutes we have here 966 01:07:03,000 --> 01:07:11,000 I know this is something along with file I/O that is rather new. 967 01:07:11,000 --> 01:07:19,000 When we talk about pointers the reason we want to talk about pointers 968 01:07:19,000 --> 01:07:24,000 is because, one, when we're working in C 969 01:07:24,000 --> 01:07:33,000 we are really at a fairly low level compared to most modern programming languages. 970 01:07:33,000 --> 01:07:38,000 We're actually able to manipulate the variables in memory, 971 01:07:38,000 --> 01:07:43,000 figure out where they're actually located within our RAM. 972 01:07:43,000 --> 01:07:46,000 Once you've gone on to take operating system classes you'll see 973 01:07:46,000 --> 01:07:48,000 that that's, again, kind of an abstraction. 974 01:07:48,000 --> 01:07:50,000 That's not actually the case. 975 01:07:50,000 --> 01:07:52,000 We've got virtual memory that's hiding those details from us. 976 01:07:52,000 --> 01:07:58,000 >> But for now you can assume that when you have a program, 977 01:07:58,000 --> 01:08:02,000 for example, when you start running your Caesar cipher program— 978 01:08:02,000 --> 01:08:06,000 I'll switch back to my iPad really quickly— 979 01:08:06,000 --> 01:08:12,000 that at the very beginning your program, if you have, say, 980 01:08:12,000 --> 01:08:15,000 4 gigabytes of RAM on your laptop, 981 01:08:15,000 --> 01:08:21,000 you get set aside this chunk, and we'll call this RAM. 982 01:08:21,000 --> 01:08:25,000 And it starts in a place we're going to call 0, 983 01:08:25,000 --> 01:08:30,000 and it ends at a place that we'll call 4 gigabytes. 984 01:08:30,000 --> 01:08:37,000 I really can't write. Man, that is hacked. 985 01:08:37,000 --> 01:08:40,000 When your program executes 986 01:08:40,000 --> 01:08:44,000 the operating system carves up RAM, 987 01:08:44,000 --> 01:08:51,000 and it specifies different segments for different parts of your program to live in. 988 01:08:51,000 --> 01:08:58,000 Down here this area is kind of a no man's land. 989 01:08:58,000 --> 01:09:02,000 When you go up a little farther here 990 01:09:02,000 --> 01:09:05,000 you've got actually the place where 991 01:09:05,000 --> 01:09:09,000 the code for your program lives. 992 01:09:09,000 --> 01:09:13,000 That actual binary code, that executable file actually gets loaded into memory 993 01:09:13,000 --> 01:09:17,000 when you run a program, and it lives in the code segment. 994 01:09:17,000 --> 01:09:22,000 And as your program executes the processor looks at this code segment 995 01:09:22,000 --> 01:09:24,000 to figure out what is the next instruction? 996 01:09:24,000 --> 01:09:27,000 What is the next line of code I need to execute? 997 01:09:27,000 --> 01:09:31,000 >> There's also a data segment, and this is where those string constants 998 01:09:31,000 --> 01:09:34,000 get stored that you've been using. 999 01:09:34,000 --> 01:09:42,000 And then farther up there's this place called the heap. 1000 01:09:42,000 --> 01:09:46,000 We access memory in there by using malloc, 1001 01:09:46,000 --> 01:09:49,000 and then towards the very top of your program 1002 01:09:49,000 --> 01:09:52,000 there's the stack, 1003 01:09:52,000 --> 01:09:57,000 and that's where we've been playing for most of the beginning. 1004 01:09:57,000 --> 01:09:59,000 This isn't to scale or anything. 1005 01:09:59,000 --> 01:10:03,000 A lot of this is very machine dependent, 1006 01:10:03,000 --> 01:10:10,000 operating system dependent, but this is relatively how things get chunked up. 1007 01:10:10,000 --> 01:10:17,000 When you run a program and you declare a variable called x— 1008 01:10:17,000 --> 01:10:27,000 I'm going to draw another box down below, and this is going to be RAM as well. 1009 01:10:27,000 --> 01:10:29,000 And I'm going to look. 1010 01:10:29,000 --> 01:10:34,000 We'll draw jagged lines to indicate this is just a small section of RAM 1011 01:10:34,000 --> 01:10:38,000 and not all of it as we draw at the top. 1012 01:10:38,000 --> 01:10:43,000 >> If I declare an integer variable called x, 1013 01:10:43,000 --> 01:10:49,000 then what I actually get is a mapping 1014 01:10:49,000 --> 01:10:54,000 that is stored in the symbol table of my program 1015 01:10:54,000 --> 01:11:00,000 that connects the name x to this region of memory that I've drawn 1016 01:11:00,000 --> 01:11:03,000 right here between the vertical bars. 1017 01:11:03,000 --> 01:11:08,000 If I have a line of code in my program that says x = 7 1018 01:11:08,000 --> 01:11:15,000 the processor knows "Oh, okay, I know that x lives at this location in memory." 1019 01:11:15,000 --> 01:11:25,000 "I'm going to go ahead and write a 7 there." 1020 01:11:25,000 --> 01:11:28,000 How does it know what location this is in memory? 1021 01:11:28,000 --> 01:11:30,000 Well, that's all done at compile time. 1022 01:11:30,000 --> 01:11:34,000 The compiler takes care of allocating where each of the variables are going to go 1023 01:11:34,000 --> 01:11:40,000 and creating a special mapping or rather connecting the dots 1024 01:11:40,000 --> 01:11:43,000 between a symbol and where it's going, a variable's name 1025 01:11:43,000 --> 01:11:46,000 and where it's going to live in memory. 1026 01:11:46,000 --> 01:11:50,000 But it turns out that we can actually access it in our programs as well. 1027 01:11:50,000 --> 01:11:55,000 This gets important when we start talking about some of the data structures, 1028 01:11:55,000 --> 01:11:58,000 which is a concept that we're going to introduce later on. 1029 01:11:58,000 --> 01:12:09,000 >> But for now, what you can know is that I can create a pointer to this location, x. 1030 01:12:09,000 --> 01:12:12,000 For example, I can create a pointer variable. 1031 01:12:12,000 --> 01:12:16,000 When we create a pointer variable we use the star notation. 1032 01:12:16,000 --> 01:12:21,000 In this case, this says I'm going to create a pointer to an int. 1033 01:12:21,000 --> 01:12:24,000 It's a type just like any other. 1034 01:12:24,000 --> 01:12:27,000 We give it a variable like y, 1035 01:12:27,000 --> 01:12:32,000 and then we set it equal to the address, to an address. 1036 01:12:32,000 --> 01:12:38,000 In this case, we can set y to point to x 1037 01:12:38,000 --> 01:12:43,000 by taking the address of x, which we do with this ampersand, 1038 01:12:43,000 --> 01:12:55,000 and then we set y to point to it. 1039 01:12:55,000 --> 01:12:59,000 What this essentially does is if we look at our RAM 1040 01:12:59,000 --> 01:13:02,000 this creates a separate variable. 1041 01:13:02,000 --> 01:13:04,000 It's going to call it y, 1042 01:13:04,000 --> 01:13:06,000 and when this line of code executes 1043 01:13:06,000 --> 01:13:13,000 it's actually going to create a little pointer which we typically draw as an arrow, 1044 01:13:13,000 --> 01:13:15,000 and it sets y to point to x. 1045 01:13:15,000 --> 01:13:17,000 Yes. 1046 01:13:17,000 --> 01:13:19,000 [Student] If x is already a pointer, would you just do 1047 01:13:19,000 --> 01:13:22,000 int *y = x instead of having the ampersand? 1048 01:13:22,000 --> 01:13:24,000 Yes. 1049 01:13:24,000 --> 01:13:27,000 If x is already a pointer, then you can set 2 pointers equal to each other, 1050 01:13:27,000 --> 01:13:30,000 in which case y would not point to x, 1051 01:13:30,000 --> 01:13:34,000 but it would point to whatever x is pointing to. 1052 01:13:34,000 --> 01:13:37,000 Unfortunately, we're out of time. 1053 01:13:37,000 --> 01:13:44,000 >> What I would say at this point, we can talk about this offline, 1054 01:13:44,000 --> 01:13:49,000 but I would say start working through this problem, #14. 1055 01:13:49,000 --> 01:13:53,000 You can see there's already a little bit filled in for you here. 1056 01:13:53,000 --> 01:13:57,000 You can see that when we declare 2 pointers, int *x and *y, 1057 01:13:57,000 --> 01:14:01,000 and note that pointing the * next to the variable was something that was done last year. 1058 01:14:01,000 --> 01:14:05,000 It turns out that this is similar to what we're doing this year. 1059 01:14:05,000 --> 01:14:11,000 It doesn't matter where you write the * when you're declaring the pointer. 1060 01:14:11,000 --> 01:14:17,000 But we have written the * next to the type 1061 01:14:17,000 --> 01:14:24,000 because that makes it very clear that you're declaring a pointer variable. 1062 01:14:24,000 --> 01:14:27,000 You can see that declaring the 2 pointers gives us 2 boxes. 1063 01:14:27,000 --> 01:14:31,000 Here when we set x equal to malloc 1064 01:14:31,000 --> 01:14:34,000 what this is saying is setting aside memory in the heap. 1065 01:14:34,000 --> 01:14:41,000 This little box right here, this circle, is located on the heap. 1066 01:14:41,000 --> 01:14:43,000 X is pointing to it. 1067 01:14:43,000 --> 01:14:46,000 Note that y is still not pointing to anything. 1068 01:14:46,000 --> 01:14:50,000 To get memory—to store the number 42 into x 1069 01:14:50,000 --> 01:14:55,000 we would use what notation? 1070 01:14:55,000 --> 01:14:59,000 [Student] *x = 42. 1071 01:14:59,000 --> 01:15:01,000 Exactly, *x = 42. 1072 01:15:01,000 --> 01:15:06,000 That means follow the arrow and throw 42 in there. 1073 01:15:06,000 --> 01:15:09,000 Here where we set y and x we have y pointing to x. 1074 01:15:09,000 --> 01:15:13,000 Again, this is just like what Kevin said where we set y equal to x. 1075 01:15:13,000 --> 01:15:15,000 Y is not pointing to x. 1076 01:15:15,000 --> 01:15:19,000 Rather, it's pointing to what x is pointing to as well. 1077 01:15:19,000 --> 01:15:24,000 >> And then finally in this last box there are 2 possible things that we could do. 1078 01:15:24,000 --> 01:15:28,000 One is we could say *x = 13. 1079 01:15:28,000 --> 01:15:33,000 The other thing is we could say—Alex, do you know what we could do here? 1080 01:15:33,000 --> 01:15:37,000 You could say *x = 13 or— 1081 01:15:37,000 --> 01:15:41,000 [Student] You could say int whatever. 1082 01:15:41,000 --> 01:15:45,000 [Nate H.] If this were referred to as an int variable we could do that. 1083 01:15:45,000 --> 01:15:49,000 We could also say *y = 13 because they're both pointing to the same place, 1084 01:15:49,000 --> 01:15:51,000 so we could use either variable to get there. 1085 01:15:51,000 --> 01:15:56,000 Yeah.>>[Student] What would it look like if we just say int x is 13? 1086 01:15:56,000 --> 01:16:00,000 That would be declaring a new variable called x, which wouldn't work. 1087 01:16:00,000 --> 01:16:04,000 We'd have a collision because we declared x to be a pointer up here. 1088 01:16:04,000 --> 01:16:10,000 [Student] If we just had that statement by itself what would it look like in terms of the circle? 1089 01:16:10,000 --> 01:16:14,000 If we had x = 13 then we'd have a box, and rather than having an arrow 1090 01:16:14,000 --> 01:16:16,000 coming out of the box we'd draw it as just a 13. 1091 01:16:16,000 --> 01:16:19,000 [Student] In the box. Okay. 1092 01:16:19,000 --> 01:16:24,000 >> Thank you for watching, and good luck on Quiz 0. 1093 01:16:24,000 --> 01:16:28,000 [CS50.TV]