1 00:00:08,119 --> 00:00:11,630 DAVID J. MALAN: All right, this is CS50, and this is the 2 00:00:11,630 --> 00:00:14,790 start of week two. 3 00:00:14,790 --> 00:00:16,300 Thank you. 4 00:00:16,300 --> 00:00:19,000 Let us begin here with a phone call. 5 00:00:19,000 --> 00:00:30,005 I'm about to dial 617-BUG-CS50. 6 00:00:30,005 --> 00:00:31,230 CS50: This is CS50. 7 00:00:31,230 --> 00:00:33,930 For Shuttle Boy, press 1. 8 00:00:33,930 --> 00:00:36,660 To start over, press 9. 9 00:00:36,660 --> 00:00:38,180 DAVID J. MALAN: So he said for Shuttle Boy, press 1. 10 00:00:38,180 --> 00:00:41,560 So we're going to press 1. 11 00:00:41,560 --> 00:00:43,230 CS50: What is your origin? 12 00:00:43,230 --> 00:00:45,340 For quad, press 1. 13 00:00:45,340 --> 00:00:47,080 Mather, press 2. 14 00:00:47,080 --> 00:00:49,240 Boylston, press 3. 15 00:00:49,240 --> 00:00:51,280 Lamont, press 4. 16 00:00:51,280 --> 00:00:53,210 Mem Hall, press 5. 17 00:00:53,210 --> 00:00:55,660 To start over, press 0. 18 00:00:55,660 --> 00:00:59,590 DAVID J. MALAN: We'll press 1 for quad. 19 00:00:59,590 --> 00:01:03,610 CS50: Next shuttle leaves this very minute at 1:10 PM, and 20 00:01:03,610 --> 00:01:09,820 then at 1:20 PM, 1:30 PM, 1:40 PM. 21 00:01:09,820 --> 00:01:12,030 This is CS50. 22 00:01:12,030 --> 00:01:15,570 >> DAVID J. MALAN: So this is CS50's voice. 23 00:01:15,570 --> 00:01:18,030 And it's an example of the sorts of final projects, for 24 00:01:18,030 --> 00:01:19,500 instance, you can bite off toward 25 00:01:19,500 --> 00:01:20,600 the end of the semester. 26 00:01:20,600 --> 00:01:23,840 For instance, that shuttleboy.cs50.net exists-- 27 00:01:23,840 --> 00:01:28,200 actually a project that I first wrote after taking CS51 28 00:01:28,200 --> 00:01:29,740 back when I was an undergraduate. 29 00:01:29,740 --> 00:01:32,250 And the inspiration here was back then, all they had was 30 00:01:32,250 --> 00:01:34,320 the printed shuttle bus schedules, and there was no 31 00:01:34,320 --> 00:01:35,970 notion of looking things up online. 32 00:01:35,970 --> 00:01:38,730 And so I sort of dove in one weekend, poured through the 33 00:01:38,730 --> 00:01:41,460 printed schedule, and ported it to a computer program. 34 00:01:41,460 --> 00:01:43,790 At the time, the computer program happened to be written 35 00:01:43,790 --> 00:01:47,110 in C. And you actually ran it by typing Shuttle Boy at a 36 00:01:47,110 --> 00:01:48,600 blinking prompt like we've been doing thus far. 37 00:01:48,600 --> 00:01:50,450 But over the years, it's evolved into an instant 38 00:01:50,450 --> 00:01:51,390 messaging bot. 39 00:01:51,390 --> 00:01:53,970 It's evolved more recently into this website, into an 40 00:01:53,970 --> 00:01:57,720 SMS-based tool, as well as into this voice-based tool. 41 00:01:57,720 --> 00:02:00,170 And this is to hint at the sorts of things that you can 42 00:02:00,170 --> 00:02:02,380 do for yourself by semester's end. 43 00:02:02,380 --> 00:02:05,490 >> For instance, there, the SMS version of Shuttle Boy happens 44 00:02:05,490 --> 00:02:06,510 to operate as follows. 45 00:02:06,510 --> 00:02:10,880 If, on your cell phone, you send a text message to 41411 and 46 00:02:10,880 --> 00:02:14,300 then send the special symbol sboy, for Shuttle Boy, 47 00:02:14,300 --> 00:02:18,350 followed by A and B, where A is an origin and B is a 48 00:02:18,350 --> 00:02:19,070 destination-- 49 00:02:19,070 --> 00:02:21,030 for instance, Boylston Space Quad-- 50 00:02:21,030 --> 00:02:23,330 what you should get back within a few seconds is a text 51 00:02:23,330 --> 00:02:25,820 message from Shuttle Boy telling you exactly when the 52 00:02:25,820 --> 00:02:28,990 next few shuttles are, from that point A going to that 53 00:02:28,990 --> 00:02:29,640 point B. 54 00:02:29,640 --> 00:02:32,510 And this is a more general example of what's known as 55 00:02:32,510 --> 00:02:33,920 using an API. 56 00:02:33,920 --> 00:02:36,930 >> So for instance, this here is just shuttleboy.cs50.net, the 57 00:02:36,930 --> 00:02:39,300 actual web-based incarnation of this. 58 00:02:39,300 --> 00:02:42,480 But the data that underlines this and other apps that CS50 59 00:02:42,480 --> 00:02:45,560 has developed are all exposed to everyone here in the form 60 00:02:45,560 --> 00:02:49,340 of APIs, application programming interfaces. 61 00:02:49,340 --> 00:02:52,220 And that's just a fancy way of saying that people like we on 62 00:02:52,220 --> 00:02:56,010 the Internet and others have spent some time creating 63 00:02:56,010 --> 00:02:59,970 software that you can use in order to grab data from us and 64 00:02:59,970 --> 00:03:02,510 then build your own applications on top 65 00:03:02,510 --> 00:03:03,840 of that data set. 66 00:03:03,840 --> 00:03:06,610 So for instance, this Shuttle Boy API page here, which 67 00:03:06,610 --> 00:03:09,390 happens to be in the CS50 manual, essentially documents 68 00:03:09,390 --> 00:03:13,080 how you can go about asking CS50 servers for data. 69 00:03:13,080 --> 00:03:16,240 For instance, if you're familiar with CSV files, comma 70 00:03:16,240 --> 00:03:18,940 separated values, these are just sort of quick and dirty 71 00:03:18,940 --> 00:03:20,310 Excel-like files. 72 00:03:20,310 --> 00:03:23,110 So you can ask Shuttle Boy for all of the data on all of the 73 00:03:23,110 --> 00:03:25,090 houses and their GPS coordinates, and you'll get 74 00:03:25,090 --> 00:03:27,300 back, essentially, a spreadsheet like that that 75 00:03:27,300 --> 00:03:30,820 you can then read into a program of your own and then 76 00:03:30,820 --> 00:03:33,250 generate results, like Shuttle Boy itself 77 00:03:33,250 --> 00:03:34,160 happens to be doing. 78 00:03:34,160 --> 00:03:37,030 For those more familiar, more modern data representations 79 00:03:37,030 --> 00:03:39,420 include JSON, JavaScript Object Notation. 80 00:03:39,420 --> 00:03:40,620 Something will come back to you toward 81 00:03:40,620 --> 00:03:41,720 the end of the semester. 82 00:03:41,720 --> 00:03:45,440 >> But again, this is just one of several of CS50's own APIs. 83 00:03:45,440 --> 00:03:48,320 And the exciting thing is now, these days, Facebook and 84 00:03:48,320 --> 00:03:51,110 Twitter and Google and pretty much every popular website out 85 00:03:51,110 --> 00:03:54,130 there has some sort of API, which means if you read the 86 00:03:54,130 --> 00:03:56,620 documentation on their website, you sign up for an 87 00:03:56,620 --> 00:03:59,980 account, you can then start writing software on top of 88 00:03:59,980 --> 00:04:03,680 whatever tools or data that company there provides. 89 00:04:03,680 --> 00:04:06,210 And so one of our own teaching fellows a couple years back 90 00:04:06,210 --> 00:04:07,620 wrote a Mac version of this. 91 00:04:07,620 --> 00:04:10,990 So at the link titled Mac here at top left, you can actually 92 00:04:10,990 --> 00:04:13,940 download a Mac OS widget that runs on your own Mac to do the 93 00:04:13,940 --> 00:04:15,040 same kinds of things. 94 00:04:15,040 --> 00:04:17,970 So it's all about building on top of data sets like these. 95 00:04:17,970 --> 00:04:21,839 But more on that toward the end of the semester. 96 00:04:21,839 --> 00:04:25,780 >> So let's dive in real quick to a bug, just to kind of get 97 00:04:25,780 --> 00:04:27,990 things warmed up today, and think back on some of the 98 00:04:27,990 --> 00:04:29,660 things we looked at last week. 99 00:04:29,660 --> 00:04:32,840 In particular, let me go ahead and pull up, say, 100 00:04:32,840 --> 00:04:34,080 this example here. 101 00:04:34,080 --> 00:04:37,500 Buggy1.c, this is available on the course's website if you'd 102 00:04:37,500 --> 00:04:40,250 like to download it and poke around yourself. 103 00:04:40,250 --> 00:04:43,520 But let's zoom in here at this fairly short program, and just 104 00:04:43,520 --> 00:04:46,550 a super-fast recap of some of the basic building blocks that 105 00:04:46,550 --> 00:04:48,880 we really are going to just start taking for granted. 106 00:04:48,880 --> 00:04:51,860 >> So the blue stuff, in lines 1 through 9, are just 107 00:04:51,860 --> 00:04:53,670 softball questions. 108 00:04:53,670 --> 00:04:54,590 So these are just comments. 109 00:04:54,590 --> 00:04:56,230 They have no functional meaning. 110 00:04:56,230 --> 00:04:58,460 But they're comments in the sense that they're notes that 111 00:04:58,460 --> 00:05:02,010 I, the human, made to myself so that in lecture and after 112 00:05:02,010 --> 00:05:04,340 lecture, I can actually remember what this program 113 00:05:04,340 --> 00:05:07,120 does without having to read through it line by line and 114 00:05:07,120 --> 00:05:08,990 recreating history in my mind. 115 00:05:08,990 --> 00:05:11,000 Moreover, if I hand this program to someone else like 116 00:05:11,000 --> 00:05:14,420 you, it's much clearer to you, because of comments like this, 117 00:05:14,420 --> 00:05:16,680 what the program's actually doing, or at least what the 118 00:05:16,680 --> 00:05:18,210 program's supposed to be doing. 119 00:05:18,210 --> 00:05:20,760 Whether or not it's correct is another matter altogether. 120 00:05:20,760 --> 00:05:25,040 Now, in C, with multi-line comments, recall that on line 121 00:05:25,040 --> 00:05:27,880 one here is the magic symbol, /*. 122 00:05:27,880 --> 00:05:30,380 It means here comes the start of a comment. 123 00:05:30,380 --> 00:05:34,560 And nothing else matters until you reach the end terminator, 124 00:05:34,560 --> 00:05:36,700 which is */, the opposite. 125 00:05:36,700 --> 00:05:39,120 So the fact that I have 80-some odd stars here from 126 00:05:39,120 --> 00:05:41,550 left to right is really just an aesthetic detail. 127 00:05:41,550 --> 00:05:43,370 It has no functional meaning. 128 00:05:43,370 --> 00:05:44,490 >> Now how about line 11? 129 00:05:44,490 --> 00:05:46,940 What does this do in layman's terms? 130 00:05:51,560 --> 00:05:52,540 What's that? 131 00:05:52,540 --> 00:05:54,280 AUDIENCE: Includes the standard. 132 00:05:54,280 --> 00:05:54,740 DAVID J. MALAN: OK, good. 133 00:05:54,740 --> 00:05:57,500 So it includes the stdio.h library. 134 00:05:57,500 --> 00:05:58,230 So what does that mean? 135 00:05:58,230 --> 00:06:01,570 Well, inside that file, stdio.h, are a whole bunch of 136 00:06:01,570 --> 00:06:03,320 function declarations-- 137 00:06:03,320 --> 00:06:05,290 that is, code that someone else wrote. 138 00:06:05,290 --> 00:06:08,160 And a perfect example of a function that's declared in 139 00:06:08,160 --> 00:06:10,250 stdio.h is-- 140 00:06:10,250 --> 00:06:11,980 which favorite by now? 141 00:06:11,980 --> 00:06:14,300 So printf, one of the most common ones to use, certainly 142 00:06:14,300 --> 00:06:15,840 early on, from that library is there. 143 00:06:15,840 --> 00:06:19,290 If I exclude that line of code, Clang is going to yell 144 00:06:19,290 --> 00:06:22,550 at me something about using an undeclared symbol. 145 00:06:22,550 --> 00:06:24,930 Something undeclared is probably the keyword, because 146 00:06:24,930 --> 00:06:27,770 we haven't informed the compiler what printf looks 147 00:06:27,770 --> 00:06:29,230 like unless we include that line. 148 00:06:29,230 --> 00:06:31,830 And more down to Earth, really, what that line is saying is 149 00:06:31,830 --> 00:06:34,890 open up that file, stdio.h, wherever it is on the server's 150 00:06:34,890 --> 00:06:38,200 hard drive, or the appliance's hard drive, and copy-paste it 151 00:06:38,200 --> 00:06:40,240 right there into my file, without my 152 00:06:40,240 --> 00:06:41,730 having to do that manually. 153 00:06:41,730 --> 00:06:44,420 >> Now, once we get down here to main, before long we'll start 154 00:06:44,420 --> 00:06:46,900 teasing apart what int and what void is. 155 00:06:46,900 --> 00:06:48,430 But for now, let's look at the three lines 156 00:06:48,430 --> 00:06:50,350 within 15 through 17. 157 00:06:50,350 --> 00:06:52,250 This here I claim as buggy. 158 00:06:52,250 --> 00:06:54,900 Line 7 in my comments says "Should print 10 159 00:06:54,900 --> 00:06:59,410 asterisks but does not." Why does this not print, in fact, 160 00:06:59,410 --> 00:07:01,097 10 such stars? 161 00:07:01,097 --> 00:07:02,347 AUDIENCE: [INAUDIBLE]. 162 00:07:05,210 --> 00:07:05,800 DAVID J. MALAN: Exactly. 163 00:07:05,800 --> 00:07:08,720 So notice that we're starting to count from 0. 164 00:07:08,720 --> 00:07:10,780 And this is actually a convention in programming and 165 00:07:10,780 --> 00:07:13,230 computer science more generally, starting to count 166 00:07:13,230 --> 00:07:14,610 from 0 instead of 1. 167 00:07:14,610 --> 00:07:16,690 And this really just derives from the fact that, for 168 00:07:16,690 --> 00:07:18,940 instance, when we had eight people up on the stage, when 169 00:07:18,940 --> 00:07:20,680 no one was raising their hand, they were 170 00:07:20,680 --> 00:07:22,340 all effectively zeros. 171 00:07:22,340 --> 00:07:24,260 And so it's just kind of a computer convention so, 172 00:07:24,260 --> 00:07:26,030 therefore, to start counting from 0. 173 00:07:26,030 --> 00:07:29,130 If that's the lowest number you can represent in binary. 174 00:07:29,130 --> 00:07:32,270 >> So here we've started initializing i to 0. 175 00:07:32,270 --> 00:07:34,230 We've set i equal to 0. 176 00:07:34,230 --> 00:07:37,780 But then I made this mistake here, saying i is less than or 177 00:07:37,780 --> 00:07:38,820 equal to 10. 178 00:07:38,820 --> 00:07:41,700 But if you think that through, if I start at 0 and then I go 179 00:07:41,700 --> 00:07:46,410 up to 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, I'm actually going to 180 00:07:46,410 --> 00:07:49,980 print out 11 stars to the screen, because I've gone up 181 00:07:49,980 --> 00:07:52,410 to and equal to 10. 182 00:07:52,410 --> 00:07:55,090 So the easy fix here then is what? 183 00:07:55,090 --> 00:07:56,070 AUDIENCE: [INAUDIBLE]. 184 00:07:56,070 --> 00:07:57,350 DAVID J. MALAN: Just change it to less than. 185 00:07:57,350 --> 00:07:59,700 If you really want, you could do this. 186 00:07:59,700 --> 00:08:01,370 But in general, that's frowned upon. 187 00:08:01,370 --> 00:08:04,020 And so starting to count from 0 is just something you should 188 00:08:04,020 --> 00:08:05,510 typically get used to. 189 00:08:05,510 --> 00:08:07,810 Now, what about this whole construct in and of itself? 190 00:08:07,810 --> 00:08:10,640 This line 15 demarks a for loop. 191 00:08:10,640 --> 00:08:12,510 So for is not a function. 192 00:08:12,510 --> 00:08:13,640 It's just a statement. 193 00:08:13,640 --> 00:08:16,180 It's a looping construct, like we saw in Scratch. 194 00:08:16,180 --> 00:08:17,600 And it has three parts. 195 00:08:17,600 --> 00:08:19,740 Notice that there is the first part to 196 00:08:19,740 --> 00:08:21,350 the left of the semicolon. 197 00:08:21,350 --> 00:08:24,200 There's the middle part in between the two semicolons. 198 00:08:24,200 --> 00:08:26,250 And then there's the right-hand part to the right 199 00:08:26,250 --> 00:08:27,640 of the second semicolon. 200 00:08:27,640 --> 00:08:31,822 Now, the first of these does what? 201 00:08:31,822 --> 00:08:33,679 AUDIENCE: [INAUDIBLE]. 202 00:08:33,679 --> 00:08:34,270 DAVID J. MALAN: Back there? 203 00:08:34,270 --> 00:08:34,816 Yeah? 204 00:08:34,816 --> 00:08:35,980 AUDIENCE: Initialization. 205 00:08:35,980 --> 00:08:36,850 >> DAVID J. MALAN: Initialization. 206 00:08:36,850 --> 00:08:37,840 So what does this mean? 207 00:08:37,840 --> 00:08:40,690 We have declared a variable called i. 208 00:08:40,690 --> 00:08:43,840 It is of type int, because I've specified int i. 209 00:08:43,840 --> 00:08:46,470 And I'm initializing i to the value of 0. 210 00:08:46,470 --> 00:08:47,730 So what's this really saying? 211 00:08:47,730 --> 00:08:50,680 It's effectively saying to the computer hey, give me enough 212 00:08:50,680 --> 00:08:53,660 memory, enough RAM, to fit a number, and then put the 213 00:08:53,660 --> 00:08:56,130 number 0 in that chunk of RAM. 214 00:08:56,130 --> 00:08:59,100 And as an aside, how big is an int typically, at least inside 215 00:08:59,100 --> 00:09:00,280 of the appliance? 216 00:09:00,280 --> 00:09:01,000 AUDIENCE: 32 bit. 217 00:09:01,000 --> 00:09:01,670 DAVID J. MALAN: 32 bits. 218 00:09:01,670 --> 00:09:04,890 So that means give me 32 bits, otherwise known as 4 bytes, 219 00:09:04,890 --> 00:09:07,250 and put the value 0 in it, which is pretty easy because 220 00:09:07,250 --> 00:09:09,110 it just means set all the bits to 0. 221 00:09:09,110 --> 00:09:11,690 >> So now, the second part here is the condition. 222 00:09:11,690 --> 00:09:14,590 And the condition, as the name suggests, is what is checked 223 00:09:14,590 --> 00:09:18,100 again and again and again as to whether it's true or false. 224 00:09:18,100 --> 00:09:21,410 So this is just saying do the following lines of code-- 225 00:09:21,410 --> 00:09:23,950 namely line 16, because that's the only one indented 226 00:09:23,950 --> 00:09:24,820 underneath-- 227 00:09:24,820 --> 00:09:26,980 so long as i is less than 10. 228 00:09:26,980 --> 00:09:30,520 And after each iteration through this loop, do the 229 00:09:30,520 --> 00:09:33,840 incrementation, which in this case is i++. 230 00:09:33,840 --> 00:09:35,580 Now, it doesn't have to be i++. 231 00:09:35,580 --> 00:09:37,610 It could be i--. 232 00:09:37,610 --> 00:09:39,860 But if I did this, what's the behavior going 233 00:09:39,860 --> 00:09:41,370 to be of this program? 234 00:09:41,370 --> 00:09:42,290 AUDIENCE: It's going to be an infinite loop. 235 00:09:42,290 --> 00:09:44,060 DAVID J. MALAN: It's going to be some kind of infinite loop, 236 00:09:44,060 --> 00:09:47,720 unless we get lucky after negative 2 billion or so. 237 00:09:47,720 --> 00:09:51,320 Maybe things will wrap around, just by nature of the finite 238 00:09:51,320 --> 00:09:53,930 number of bits that we have allocated for an int. 239 00:09:53,930 --> 00:09:56,270 But it's certainly going to iterate far more than 10 and 240 00:09:56,270 --> 00:09:58,630 certainly more than 11 times here. 241 00:09:58,630 --> 00:10:02,240 >> And now, just as an aside, realize that i++ and i-- 242 00:10:02,240 --> 00:10:04,420 are really just syntactic sugar. 243 00:10:04,420 --> 00:10:07,210 It's just shorthand notation for what's a little more 244 00:10:07,210 --> 00:10:08,720 explicitly written as follows: 245 00:10:08,720 --> 00:10:11,200 i = i + 1. 246 00:10:11,200 --> 00:10:13,460 That is identical to i++. 247 00:10:13,460 --> 00:10:15,860 It just kind of looks prettier to say i++. 248 00:10:15,860 --> 00:10:17,490 It's more succinct, more readable. 249 00:10:17,490 --> 00:10:19,030 And so most people do that instead. 250 00:10:19,030 --> 00:10:21,840 But this is identical functionally to 251 00:10:21,840 --> 00:10:22,900 what we just saw. 252 00:10:22,900 --> 00:10:27,770 So in short, the quick fix here is just to say iterate i 253 00:10:27,770 --> 00:10:30,690 from 0 all the way up to less than 10. 254 00:10:30,690 --> 00:10:32,700 And then we'll indeed get 10 stars. 255 00:10:32,700 --> 00:10:33,430 >> So let's try this. 256 00:10:33,430 --> 00:10:35,310 Let me open up the terminal at the bottom. 257 00:10:35,310 --> 00:10:37,420 Let me go into the directory that this is in. 258 00:10:37,420 --> 00:10:40,030 And I'm going to compile it manually with Clang for now. 259 00:10:40,030 --> 00:10:44,880 And I'm going to compile this as buggy1.c, Enter. 260 00:10:44,880 --> 00:10:50,280 And now buggy1, why is there no such file or directory 261 00:10:50,280 --> 00:10:52,026 called buggy1? 262 00:10:52,026 --> 00:10:53,850 AUDIENCE: [INAUDIBLE]. 263 00:10:53,850 --> 00:10:54,240 DAVID J. MALAN: Yeah. 264 00:10:54,240 --> 00:10:55,420 So it's actually called a.out. 265 00:10:55,420 --> 00:10:57,480 So recall if you just run Clang, where Clang is the 266 00:10:57,480 --> 00:11:00,420 compiler, and you don't specify the name you want to 267 00:11:00,420 --> 00:11:03,550 give to your program, it's going to default to a.out. 268 00:11:03,550 --> 00:11:05,030 So indeed if I do ls-- 269 00:11:05,030 --> 00:11:05,510 oops. 270 00:11:05,510 --> 00:11:07,680 And I didn't--the black-and-white issue some of 271 00:11:07,680 --> 00:11:08,840 you faced has been fixed. 272 00:11:08,840 --> 00:11:10,670 But let me do this. 273 00:11:10,670 --> 00:11:14,570 There we have a.out on the left-hand side there. 274 00:11:14,570 --> 00:11:17,360 So we have to run a.out instead of buggy1. 275 00:11:17,360 --> 00:11:19,140 >> So let me go ahead and do this. 276 00:11:19,140 --> 00:11:22,840 ./a.out, Enter. 277 00:11:22,840 --> 00:11:26,160 And I apparently did not do what? 278 00:11:26,160 --> 00:11:26,620 AUDIENCE: Save. 279 00:11:26,620 --> 00:11:27,390 DAVID J. MALAN: Save my file. 280 00:11:27,390 --> 00:11:31,520 So that is easily solved by hitting Control S, or going to 281 00:11:31,520 --> 00:11:33,450 File, Save, like in most programs. 282 00:11:33,450 --> 00:11:36,360 Let me go down here, clear the screen, run it again. 283 00:11:36,360 --> 00:11:37,960 And there's still a bug. 284 00:11:37,960 --> 00:11:41,618 So what is going-- 285 00:11:41,618 --> 00:11:42,980 AUDIENCE: You didn't compile. 286 00:11:42,980 --> 00:11:44,040 DAVID J. MALAN: Ah, good. 287 00:11:44,040 --> 00:11:45,010 I didn't compile it. 288 00:11:45,010 --> 00:11:47,250 Like an idiot, I'm looking at the code to see what's wrong. 289 00:11:47,250 --> 00:11:51,275 So clang buggy1.c, now a.out. 290 00:11:51,275 --> 00:11:52,640 And phew, saved. 291 00:11:52,640 --> 00:11:55,090 >> So it looks a little ugly because there's no new line 292 00:11:55,090 --> 00:11:55,970 anywhere in the program. 293 00:11:55,970 --> 00:11:57,390 But again, that's just an aesthetic detail. 294 00:11:57,390 --> 00:11:59,430 And at least if we count those out, we should 295 00:11:59,430 --> 00:12:01,160 now see 10 such stars. 296 00:12:01,160 --> 00:12:03,260 Well, what about this second warm-up example? 297 00:12:03,260 --> 00:12:07,750 So in buggy2, I claim that this version, too, will print 298 00:12:07,750 --> 00:12:10,110 10 stars, one per line. 299 00:12:10,110 --> 00:12:12,340 So this time, I have a newline character, just to make 300 00:12:12,340 --> 00:12:13,520 things a little prettier. 301 00:12:13,520 --> 00:12:15,410 But instead what I get is this. 302 00:12:15,410 --> 00:12:19,590 So let me do clang buggy2.c, Enter. 303 00:12:19,590 --> 00:12:21,790 Now it's again called a.out. 304 00:12:21,790 --> 00:12:23,130 Enter. 305 00:12:23,130 --> 00:12:26,900 I only see one new line, only the very last new line that 306 00:12:26,900 --> 00:12:29,370 moves my prompt to the next line. 307 00:12:29,370 --> 00:12:32,660 And yet clearly I've been printing *, then a new line, 308 00:12:32,660 --> 00:12:33,990 *, then a new line. 309 00:12:33,990 --> 00:12:35,490 But what's the bug here? 310 00:12:35,490 --> 00:12:35,974 Yeah? 311 00:12:35,974 --> 00:12:37,224 AUDIENCE: [INAUDIBLE]. 312 00:12:39,850 --> 00:12:40,470 >> DAVID J. MALAN: Exactly. 313 00:12:40,470 --> 00:12:44,110 So unlike some languages, like Python, where indentation 314 00:12:44,110 --> 00:12:46,030 actually has functional meaning, in a 315 00:12:46,030 --> 00:12:47,150 language like C-- 316 00:12:47,150 --> 00:12:49,140 as we'll see, PHP, JavaScript-- 317 00:12:49,140 --> 00:12:51,940 the indentation is really just for humans' benefit. 318 00:12:51,940 --> 00:12:55,690 So the fact that I've indented line 16 and 17 looks great, 319 00:12:55,690 --> 00:12:57,530 but it has no functional meaning here. 320 00:12:57,530 --> 00:13:00,700 If I want both lines to execute as part of the for 321 00:13:00,700 --> 00:13:05,140 loop, then I must enclose them in curly braces by doing this. 322 00:13:05,140 --> 00:13:08,540 You can only cut that corner and omit the curly braces if 323 00:13:08,540 --> 00:13:10,036 what's the case? 324 00:13:10,036 --> 00:13:10,410 AUDIENCE: Just one line. 325 00:13:10,410 --> 00:13:11,130 DAVID J. MALAN: Just one line. 326 00:13:11,130 --> 00:13:15,280 So that's just sort of a nice sort of syntax detail so that 327 00:13:15,280 --> 00:13:17,900 you don't waste time writing three lines, two of which are 328 00:13:17,900 --> 00:13:20,040 curly braces, just to write a single line of code. 329 00:13:20,040 --> 00:13:21,650 But if you have two or more lines, we 330 00:13:21,650 --> 00:13:22,860 indeed need to do this. 331 00:13:22,860 --> 00:13:24,210 >> So now let me save this. 332 00:13:24,210 --> 00:13:27,140 Let me go ahead and re-run Clang. 333 00:13:27,140 --> 00:13:31,375 Then let me rerun a.out, and now I get them one per line. 334 00:13:31,375 --> 00:13:33,670 Now, a.out again is kind of a dumb name for a program. 335 00:13:33,670 --> 00:13:37,500 How can I tell Clang to actually give me a file name 336 00:13:37,500 --> 00:13:39,820 that's more user-friendly, like buggy2 itself? 337 00:13:43,200 --> 00:13:44,466 A little more clearly? 338 00:13:44,466 --> 00:13:45,220 AUDIENCE: [INAUDIBLE]. 339 00:13:45,220 --> 00:13:47,810 DAVID J. MALAN: OK, so I can actually take the very 340 00:13:47,810 --> 00:13:51,000 user-friendly shortcut and just write make buggy2. 341 00:13:51,000 --> 00:13:53,840 I don't specify .c in this case, and hit Enter. 342 00:13:53,840 --> 00:13:58,530 And what make does is it compiles buggy2.c for me by 343 00:13:58,530 --> 00:14:00,260 asking Clang to do it. 344 00:14:00,260 --> 00:14:05,100 Specifically, it calls Clang, it runs Clang using way more 345 00:14:05,100 --> 00:14:08,540 command-line arguments or switches than I actually need. 346 00:14:08,540 --> 00:14:11,270 In time, we'll come back to what all of these various 347 00:14:11,270 --> 00:14:13,810 cryptic hyphenated expressions means. 348 00:14:13,810 --> 00:14:16,910 But for now, that's just saving me the trouble of 349 00:14:16,910 --> 00:14:19,600 having to remember and having to type out all of those 350 00:14:19,600 --> 00:14:21,150 various hyphenated expressions. 351 00:14:21,150 --> 00:14:23,240 And the upside of it ultimately is 352 00:14:23,240 --> 00:14:25,900 that now I have buggy2. 353 00:14:25,900 --> 00:14:27,480 If I want to do this manually, though, I 354 00:14:27,480 --> 00:14:28,775 can instead do this-- 355 00:14:28,775 --> 00:14:34,110 clang -o buggy2 and then buggy2.c. 356 00:14:34,110 --> 00:14:37,980 And that will similarly give me a file called buggy2. 357 00:14:37,980 --> 00:14:39,710 >> So in short, Clang's the compiler. 358 00:14:39,710 --> 00:14:43,080 Make is just a user-friendly tool that we'll be using more 359 00:14:43,080 --> 00:14:44,420 and more, because it just starts to 360 00:14:44,420 --> 00:14:47,330 simplify things for us. 361 00:14:47,330 --> 00:14:49,430 And we return 0, lastly. 362 00:14:49,430 --> 00:14:51,890 For now, just because, but we'll start teasing that part 363 00:14:51,890 --> 00:14:52,930 today and on Wednesday. 364 00:14:52,930 --> 00:14:55,560 Any questions on any of this? 365 00:14:55,560 --> 00:14:56,450 Yeah? 366 00:14:56,450 --> 00:14:58,234 AUDIENCE: [INAUDIBLE] 367 00:14:58,234 --> 00:15:00,020 ls in quotes there? 368 00:15:00,020 --> 00:15:01,710 DAVID J. MALAN: OK. 369 00:15:01,710 --> 00:15:05,880 When I typed ls in quotes, that was me doing some magic 370 00:15:05,880 --> 00:15:07,160 behind the scenes to fix a bug. 371 00:15:07,160 --> 00:15:09,370 I forgot, like we've been telling many of you on the 372 00:15:09,370 --> 00:15:11,600 discussion boards, to do-- 373 00:15:11,600 --> 00:15:17,220 we'll do this now--sudo yum -y update appliance50. 374 00:15:17,220 --> 00:15:19,790 Whoops, that that's spelled right. 375 00:15:19,790 --> 00:15:23,240 So the appliance is like an operating system. 376 00:15:23,240 --> 00:15:25,650 It's running this operating system called Fedora. 377 00:15:25,650 --> 00:15:27,450 And now because of my slow Internet connection, I've 378 00:15:27,450 --> 00:15:28,260 really hosed it. 379 00:15:28,260 --> 00:15:31,620 So running sudo yum update, as we tell you to do in the 380 00:15:31,620 --> 00:15:34,080 problem set, is essentially like running automatic updates 381 00:15:34,080 --> 00:15:35,420 in Mac OS or Windows. 382 00:15:35,420 --> 00:15:37,280 And the reason for running this at the very start of the 383 00:15:37,280 --> 00:15:39,640 problem set is because when we created the appliance, I 384 00:15:39,640 --> 00:15:42,480 messed up, and I accidentally made all of your programs look 385 00:15:42,480 --> 00:15:45,210 black on a black screen, which is why you're not seeing them 386 00:15:45,210 --> 00:15:45,860 by default. 387 00:15:45,860 --> 00:15:48,020 But the latest version of the appliance fixes this. 388 00:15:48,020 --> 00:15:50,500 And I'll fix that during break once I have Internet 389 00:15:50,500 --> 00:15:51,280 connectivity. 390 00:15:51,280 --> 00:15:54,630 >> So the quotes just hides my mistake, very discreetly, 391 00:15:54,630 --> 00:15:55,730 apparently. 392 00:15:55,730 --> 00:15:56,980 Other questions? 393 00:15:59,750 --> 00:16:00,668 Yes? 394 00:16:00,668 --> 00:16:02,012 AUDIENCE: Where does make come from? 395 00:16:02,012 --> 00:16:03,810 [INAUDIBLE] 396 00:16:03,810 --> 00:16:04,280 DAVID J. MALAN: Good question. 397 00:16:04,280 --> 00:16:05,460 Where does make come from? 398 00:16:05,460 --> 00:16:09,390 It is a Linux program that has existed for many years, long 399 00:16:09,390 --> 00:16:10,570 before CS50. 400 00:16:10,570 --> 00:16:12,930 And it comes with an operating system like Fedora. 401 00:16:12,930 --> 00:16:14,830 It does not come from the CS50 library. 402 00:16:14,830 --> 00:16:17,560 In fact, the only things that come from the CS50 library 403 00:16:17,560 --> 00:16:20,470 thus far, that we've seen, are GetString, GetInt, all of 404 00:16:20,470 --> 00:16:25,550 those Get functions, and the word string, and to some 405 00:16:25,550 --> 00:16:26,575 extent, the word bool. 406 00:16:26,575 --> 00:16:29,180 But we'll tease that apart when we dive into the CS50 407 00:16:29,180 --> 00:16:30,580 appliance itself. 408 00:16:30,580 --> 00:16:32,820 >> So yes, one more question here. 409 00:16:32,820 --> 00:16:36,636 AUDIENCE: When you said make and then buggy, how does the 410 00:16:36,636 --> 00:16:39,980 computer know [INAUDIBLE]? 411 00:16:39,980 --> 00:16:40,520 DAVID J. MALAN: Good question. 412 00:16:40,520 --> 00:16:43,830 So when you just run make buggy1 or make buggy2, how 413 00:16:43,830 --> 00:16:45,220 does make know? 414 00:16:45,220 --> 00:16:49,900 So by default, if you type make buggy1, make looks for a 415 00:16:49,900 --> 00:16:52,330 file called buggy1.c. 416 00:16:52,330 --> 00:16:55,570 And then it executes the appropriate Clang commands, 417 00:16:55,570 --> 00:17:00,380 thereby overriding the default output file called a.out. 418 00:17:00,380 --> 00:17:03,670 In fact, if we look at what make, what-- 419 00:17:03,670 --> 00:17:04,839 let's quit this. 420 00:17:04,839 --> 00:17:09,530 If we look at what make was actually doing, make buggy2, 421 00:17:09,530 --> 00:17:10,470 it's already up to date. 422 00:17:10,470 --> 00:17:13,020 So let me remove the rm command, the 423 00:17:13,020 --> 00:17:14,319 program I wrote before. 424 00:17:14,319 --> 00:17:17,319 Typing Y-E-S to confirm that I want to remove it. 425 00:17:17,319 --> 00:17:20,480 If I now do make, notice that in this very long line, 426 00:17:20,480 --> 00:17:22,980 there's this last thing here, -o buggy2. 427 00:17:22,980 --> 00:17:26,959 All make is doing is passing that argument, so to speak, to 428 00:17:26,959 --> 00:17:29,665 Clang, so that I don't have to type it myself. 429 00:17:29,665 --> 00:17:32,660 >> All right, so a quick couple of administrative 430 00:17:32,660 --> 00:17:33,470 announcements. 431 00:17:33,470 --> 00:17:36,940 So for sections, which officially began this coming 432 00:17:36,940 --> 00:17:38,970 Sunday, you'll always want to bring, if 433 00:17:38,970 --> 00:17:40,120 you have one, a laptop. 434 00:17:40,120 --> 00:17:42,570 If you don't have a laptop, do reach out to me by 435 00:17:42,570 --> 00:17:43,580 dropping me an email. 436 00:17:43,580 --> 00:17:44,810 And we'll figure out a workflow. 437 00:17:44,810 --> 00:17:47,100 What generally you'll find in section is that they're part 438 00:17:47,100 --> 00:17:48,770 conceptual, part hands-on. 439 00:17:48,770 --> 00:17:52,190 We'll specifically use the section of questions, part of 440 00:17:52,190 --> 00:17:54,110 the week's problem set, to walk through some of the 441 00:17:54,110 --> 00:17:55,820 conceptual material from lecture. 442 00:17:55,820 --> 00:17:57,480 And that's all in the current problem set. 443 00:17:57,480 --> 00:18:00,010 And we'll also dive into some hands-on activities, sometimes 444 00:18:00,010 --> 00:18:02,190 of which will be required to be submitted, sometimes of 445 00:18:02,190 --> 00:18:02,830 which will not. 446 00:18:02,830 --> 00:18:04,630 For instance, this first week, they're meant just as a 447 00:18:04,630 --> 00:18:05,780 warm-up exercise. 448 00:18:05,780 --> 00:18:07,800 And you'll find that those problems are really just that. 449 00:18:07,800 --> 00:18:10,220 They're meant to be fairly small, but not necessarily 450 00:18:10,220 --> 00:18:13,100 trivial programs to write, that aren't necessarily 451 00:18:13,100 --> 00:18:16,230 exciting in and of themselves but are good opportunities to 452 00:18:16,230 --> 00:18:19,620 practice with syntax, with new functions, in the comfort of a 453 00:18:19,620 --> 00:18:21,900 section where you have a few of your classmates present as 454 00:18:21,900 --> 00:18:22,870 well as your TF. 455 00:18:22,870 --> 00:18:26,210 >> And what we'll do over time is use a tool called CS50 Spaces, 456 00:18:26,210 --> 00:18:28,940 whereby instead of just using the CS50 Appliance, you'll 457 00:18:28,940 --> 00:18:32,450 instead go to a web page in a browser, where you'll be able 458 00:18:32,450 --> 00:18:35,610 to write code in a browser window during section. 459 00:18:35,610 --> 00:18:38,240 And then if you opt in, your teaching fellow can then show 460 00:18:38,240 --> 00:18:40,980 whatever it is you're typing on your screen in your browser 461 00:18:40,980 --> 00:18:43,930 window up at the front of the class, whether anonymously or 462 00:18:43,930 --> 00:18:47,250 publicly, so that he or she can then walk through with 463 00:18:47,250 --> 00:18:50,080 your classmates what you did well, what you didn't do well. 464 00:18:50,080 --> 00:18:52,750 And again, rest assured all of this can be nicely anonymized. 465 00:18:52,750 --> 00:18:54,410 But it'll be a nice opportunity for much more 466 00:18:54,410 --> 00:18:56,810 interactivity than something like lecture allows. 467 00:18:56,810 --> 00:18:58,910 >> In the meantime, we'll have these things called super 468 00:18:58,910 --> 00:19:01,610 sections, which are optional but are open to everyone in 469 00:19:01,610 --> 00:19:04,030 the class, so that you can do this more collectively for 470 00:19:04,030 --> 00:19:05,190 problem set one. 471 00:19:05,190 --> 00:19:06,010 Here's the schedule. 472 00:19:06,010 --> 00:19:08,870 This is also posted on the homepage at cs50.net. 473 00:19:08,870 --> 00:19:10,850 Notice that there'll be a hacker-specific 474 00:19:10,850 --> 00:19:12,430 one tomorrow afternoon. 475 00:19:12,430 --> 00:19:15,460 And we will film one today and one tomorrow and post those 476 00:19:15,460 --> 00:19:16,720 online within 24 hours. 477 00:19:16,720 --> 00:19:19,370 So if you can't make any of these times, not to worry. 478 00:19:19,370 --> 00:19:22,720 And again, the schedule is online now at cs50.net. 479 00:19:22,720 --> 00:19:25,350 >> In terms of sectioning itself, you should have gotten an 480 00:19:25,350 --> 00:19:28,520 email instructing you to go to the course's homepage to find 481 00:19:28,520 --> 00:19:29,610 out your section. 482 00:19:29,610 --> 00:19:32,890 If life has changed and you need to change your section, 483 00:19:32,890 --> 00:19:33,560 not a problem. 484 00:19:33,560 --> 00:19:37,900 Go back to that same URL, cs50.net/section, singular, 485 00:19:37,900 --> 00:19:40,090 and you'll fill out the similar form so that you can 486 00:19:40,090 --> 00:19:41,260 then give us your preferences. 487 00:19:41,260 --> 00:19:43,360 And we will follow up by week's end as to what we can 488 00:19:43,360 --> 00:19:44,240 accommodate. 489 00:19:44,240 --> 00:19:49,530 Last week, recall that we proposed using CS50 Discuss, 490 00:19:49,530 --> 00:19:51,370 the course's discussion tool, in lecture. 491 00:19:51,370 --> 00:19:53,680 So we had 40 questions that were asked and 492 00:19:53,680 --> 00:19:54,720 answered during lecture. 493 00:19:54,720 --> 00:19:56,280 So it seemed to work well, so we'll continue 494 00:19:56,280 --> 00:19:57,180 trying to do this. 495 00:19:57,180 --> 00:19:59,600 If, during lecture, you don't just feel comfortable raising 496 00:19:59,600 --> 00:20:00,780 your hand, not a problem. 497 00:20:00,780 --> 00:20:04,640 Go to cs50.net/discuss, post there, and one of our teaching 498 00:20:04,640 --> 00:20:07,270 fellows will either answer it electronically or raise their 499 00:20:07,270 --> 00:20:10,620 hand on your behalf anonymously to ask, depending 500 00:20:10,620 --> 00:20:12,470 on the nature of the question. 501 00:20:12,470 --> 00:20:15,000 And in terms of feedback, generally psets will be 502 00:20:15,000 --> 00:20:16,760 returned within a week. 503 00:20:16,760 --> 00:20:19,080 Because it takes a little while for sections to achieve 504 00:20:19,080 --> 00:20:22,430 equilibrium, the first pset, 0 and 1, will be a little bit 505 00:20:22,430 --> 00:20:24,130 delayed as things settle down. 506 00:20:24,130 --> 00:20:27,130 But stay tuned for that in the weeks to come. 507 00:20:27,130 --> 00:20:29,750 >> All right, so let me put on my serious 508 00:20:29,750 --> 00:20:31,040 voice for just a moment. 509 00:20:31,040 --> 00:20:32,690 So this is actually an interesting climate to be 510 00:20:32,690 --> 00:20:35,210 having this discussion, what with all of the other things 511 00:20:35,210 --> 00:20:37,310 going on on campus related thereto. 512 00:20:37,310 --> 00:20:40,220 But CS50 has certainly had its history of this particular 513 00:20:40,220 --> 00:20:43,360 topic, in as much as every year, this course, for many 514 00:20:43,360 --> 00:20:46,910 years, Ad-Boards roughly 3% of the class. 515 00:20:46,910 --> 00:20:51,620 This most recent year, 2011, CS50 Ad-Boarded 35 students. 516 00:20:51,620 --> 00:20:54,120 This is not, I think, due to lack of clarity. 517 00:20:54,120 --> 00:20:56,760 Realize that in the course's syllabus, there is a page of 518 00:20:56,760 --> 00:20:59,020 statement explaining where the lines are. 519 00:20:59,020 --> 00:21:01,350 That same statement is repeated on every one of the 520 00:21:01,350 --> 00:21:03,070 problem sets on page one. 521 00:21:03,070 --> 00:21:05,760 >> So I mention this today really just to make 522 00:21:05,760 --> 00:21:07,030 folks mindful of this. 523 00:21:07,030 --> 00:21:08,080 And we've tried different things. 524 00:21:08,080 --> 00:21:10,630 And what I thought we would do today is just take a moment to 525 00:21:10,630 --> 00:21:13,830 actually look at some of past cases that have come up. 526 00:21:13,830 --> 00:21:16,160 Rather than keep these as dirty little secrets, actually 527 00:21:16,160 --> 00:21:19,170 point out what students have done and how we have detected 528 00:21:19,170 --> 00:21:21,630 it and really what the overarching motivation is for 529 00:21:21,630 --> 00:21:23,950 even having this conversation. 530 00:21:23,950 --> 00:21:27,060 So with that said, the line essentially is this-- 531 00:21:27,060 --> 00:21:29,200 per the syllabus, you're welcome, you are encouraged, to 532 00:21:29,200 --> 00:21:30,210 talk with classmates. 533 00:21:30,210 --> 00:21:31,910 That's the whole purpose of having these collaborative 534 00:21:31,910 --> 00:21:34,470 office hours in Annenberg and encouraging people for the 535 00:21:34,470 --> 00:21:35,755 final project to work together. 536 00:21:35,755 --> 00:21:38,590 But the line is drawn when it comes time to actually write 537 00:21:38,590 --> 00:21:39,790 your final solution. 538 00:21:39,790 --> 00:21:42,590 Speaking in English, totally fine, speaking in pseudo code, 539 00:21:42,590 --> 00:21:43,400 totally fine. 540 00:21:43,400 --> 00:21:46,340 Emailing a classmate your pset, letting them look over 541 00:21:46,340 --> 00:21:48,610 the screen as the hands continue typing, 542 00:21:48,610 --> 00:21:50,110 over the line as well. 543 00:21:50,110 --> 00:21:52,250 Do look to the syllabus for the particular lines. 544 00:21:52,250 --> 00:21:55,850 >> But just to paint a picture of how this is unfortunately a 545 00:21:55,850 --> 00:21:58,370 reality, realize that there are websites out there that 546 00:21:58,370 --> 00:22:01,490 have solutions from this class and many other classes. 547 00:22:01,490 --> 00:22:04,940 The fact that you or some 3% of you know that this exists 548 00:22:04,940 --> 00:22:07,240 means that we know that this exists. 549 00:22:07,240 --> 00:22:09,340 The fact that there are websites like this where you 550 00:22:09,340 --> 00:22:11,540 can pay someone to actually do your problem sets-- this was 551 00:22:11,540 --> 00:22:13,450 an actual case that came up last year. 552 00:22:13,450 --> 00:22:15,790 This is a website called odesk.com. 553 00:22:15,790 --> 00:22:20,090 And Tim was the name of the person here who was posting on 554 00:22:20,090 --> 00:22:24,580 this website and asked someone to do his pset 7 in 555 00:22:24,580 --> 00:22:25,570 this particular case. 556 00:22:25,570 --> 00:22:28,350 Well, odesk.com is very Google-able, and we too are 557 00:22:28,350 --> 00:22:30,310 very good at Googling. 558 00:22:30,310 --> 00:22:32,360 Here, too, there are sites-- and this one's rather 559 00:22:32,360 --> 00:22:34,234 atrocious, frankly. 560 00:22:34,234 --> 00:22:38,050 [LAUGHTER] 561 00:22:38,050 --> 00:22:39,610 DAVID J. MALAN: The funny thing about this site is if 562 00:22:39,610 --> 00:22:41,970 you read the About page, they talk about their corporate 563 00:22:41,970 --> 00:22:44,390 culture and how customer service is their number-one 564 00:22:44,390 --> 00:22:46,190 priority, to make sure that your assignments get 565 00:22:46,190 --> 00:22:47,890 turned in on time. 566 00:22:47,890 --> 00:22:50,580 >> But in all seriousness, again, the fact that these sites 567 00:22:50,580 --> 00:22:52,910 exist, realize we, too, are cognizant of 568 00:22:52,910 --> 00:22:53,730 these kinds of sites. 569 00:22:53,730 --> 00:22:55,890 And to give you a sense of what forms this generally 570 00:22:55,890 --> 00:22:58,570 takes, we generally don't have great scandals where people 571 00:22:58,570 --> 00:23:01,080 are collaborating on any kind of massive scale, but rather 572 00:23:01,080 --> 00:23:04,540 it's these late-night moments of weakness, where you have so 573 00:23:04,540 --> 00:23:07,550 much to do, it's 4:00 AM, you're exhausted, and you 574 00:23:07,550 --> 00:23:09,770 think to yourself, well, let me just take a look at my 575 00:23:09,770 --> 00:23:11,770 roommate's or my friend's code or the like. 576 00:23:11,770 --> 00:23:14,800 And the manifestations of this unfortunately involve Student 577 00:23:14,800 --> 00:23:17,640 A submitting something like this and Student B submitting 578 00:23:17,640 --> 00:23:20,370 something like this, which certainly, in a computer 579 00:23:20,370 --> 00:23:23,830 science class, is remarkably easy for computer scientists 580 00:23:23,830 --> 00:23:25,690 to detect with software. 581 00:23:25,690 --> 00:23:28,410 This is another common paradigm, where you've sort of 582 00:23:28,410 --> 00:23:31,010 been working alongside of someone, maybe talking in 583 00:23:31,010 --> 00:23:32,360 English, just fine, pseudocode. 584 00:23:32,360 --> 00:23:35,080 But then it comes time to actually submit, and the psets 585 00:23:35,080 --> 00:23:37,910 just get exchanged via email or Dropbox or the like. 586 00:23:37,910 --> 00:23:41,120 But in an attempt to make it less apparent that this is 587 00:23:41,120 --> 00:23:44,830 what has happened, then this is what's submitted. 588 00:23:44,830 --> 00:23:47,880 This, too, does not trip up well-written pieces of 589 00:23:47,880 --> 00:23:50,360 software like we have to actually detect 590 00:23:50,360 --> 00:23:51,280 these kinds of things. 591 00:23:51,280 --> 00:23:53,760 And indeed what we do is run software that compares all of 592 00:23:53,760 --> 00:23:55,540 this year's submissions against all of past year's 593 00:23:55,540 --> 00:23:57,380 submissions, against everything we found on the 594 00:23:57,380 --> 00:24:00,060 Internet, against every job website out there. 595 00:24:00,060 --> 00:24:01,710 It's all very automated. 596 00:24:01,710 --> 00:24:05,665 And so we do this really in great fairness to the 97% who 597 00:24:05,665 --> 00:24:07,760 are really working their asses off in this and in other 598 00:24:07,760 --> 00:24:11,530 classes and putting in all of that effort so that the work 599 00:24:11,530 --> 00:24:13,030 they ultimately submit is their own. 600 00:24:13,030 --> 00:24:14,220 And I can go on for ages. 601 00:24:14,220 --> 00:24:16,030 >> These are just a handful of last year's cases. 602 00:24:16,030 --> 00:24:19,350 A few students submitted these files identically for pset 2, 603 00:24:19,350 --> 00:24:22,460 pset 3, pset 4, pset 5, pset 6, pset 9. 604 00:24:22,460 --> 00:24:26,360 In this case, this was quiz 0 and in last year, where two 605 00:24:26,360 --> 00:24:29,570 students submitted identically this sentence among many 606 00:24:29,570 --> 00:24:32,210 others, "The request of type--" dot, dot, dot. 607 00:24:32,210 --> 00:24:34,530 So even in a class of 600 did we detect this 608 00:24:34,530 --> 00:24:36,310 on submitted quizzes. 609 00:24:36,310 --> 00:24:39,080 So in short, this--frankly, I hate having this kind of 610 00:24:39,080 --> 00:24:41,300 conversation--but this is really a deliberate effort 611 00:24:41,300 --> 00:24:43,540 this year to try to drive down that number. 612 00:24:43,540 --> 00:24:45,650 Because even though we say these kinds of things every 613 00:24:45,650 --> 00:24:48,100 year, I think the reality of having dwelled on it for a few 614 00:24:48,100 --> 00:24:50,800 more seconds than usual and actually just pointing out 615 00:24:50,800 --> 00:24:53,600 that what might seem like, eh, not such a big deal, at least 616 00:24:53,600 --> 00:24:56,390 think back to this particular moment, both in fairness to 617 00:24:56,390 --> 00:25:00,100 yourself and to your classmates here. 618 00:25:00,100 --> 00:25:02,480 So if you ever have any questions as to where the line 619 00:25:02,480 --> 00:25:04,290 is, please just reach out to me personally. 620 00:25:04,290 --> 00:25:07,190 But the answer is always, completely stressed at the 621 00:25:07,190 --> 00:25:09,090 last minute, cash in a late day. 622 00:25:09,090 --> 00:25:11,080 Or if it's a matter of not having any late days, 623 00:25:11,080 --> 00:25:12,900 honestly, email me personally. 624 00:25:12,900 --> 00:25:14,110 We'll figure something out. 625 00:25:14,110 --> 00:25:17,480 Please do not put your time here at Harvard at risk. 626 00:25:17,480 --> 00:25:18,570 >> Now, I thought we should lighten the mood, so I 627 00:25:18,570 --> 00:25:20,264 included this as the next slide. 628 00:25:20,264 --> 00:25:22,770 [LAUGHTER] 629 00:25:22,770 --> 00:25:23,630 DAVID J. MALAN: This website was great. 630 00:25:23,630 --> 00:25:24,820 I actually got a little distracted. 631 00:25:24,820 --> 00:25:26,330 There's this one. 632 00:25:26,330 --> 00:25:29,590 And then this one was amazing. 633 00:25:29,590 --> 00:25:35,190 Okay, so think of that kitten late at night when making 634 00:25:35,190 --> 00:25:36,040 those decisions. 635 00:25:36,040 --> 00:25:40,110 All right, so back to more fun and less serious stuff, like 636 00:25:40,110 --> 00:25:40,780 conditions. 637 00:25:40,780 --> 00:25:43,900 >> All right, so we talked briefly about these. 638 00:25:43,900 --> 00:25:46,080 This is something that's probably quite familiar from 639 00:25:46,080 --> 00:25:47,260 the world of Scratch. 640 00:25:47,260 --> 00:25:49,860 And in the world of Scratch, we have this need sometimes to 641 00:25:49,860 --> 00:25:51,110 go make forks in the road. 642 00:25:51,110 --> 00:25:54,840 Either do this or that or this other thing here. 643 00:25:54,840 --> 00:25:58,990 And when we want to do this, we can use, in C now, this if 644 00:25:58,990 --> 00:26:00,860 else construct. 645 00:26:00,860 --> 00:26:06,420 And then here we have Boolean expressions. 646 00:26:06,420 --> 00:26:09,260 For instance, Boolean expressions here, we can OR 647 00:26:09,260 --> 00:26:12,260 them together, in the sense that we have this condition OR 648 00:26:12,260 --> 00:26:13,200 that condition. 649 00:26:13,200 --> 00:26:15,100 We can AND them together, in the sense that we want to 650 00:26:15,100 --> 00:26:17,710 check this condition AND that condition. 651 00:26:17,710 --> 00:26:22,440 And here we have a switch statement now, which is not so 652 00:26:22,440 --> 00:26:26,040 similar syntactically to those kinds of conditions, but it 653 00:26:26,040 --> 00:26:30,160 allows us to do the equivalent of if, else if, else if, else 654 00:26:30,160 --> 00:26:34,990 if, and the like by simply enumerating them case by case 655 00:26:34,990 --> 00:26:36,670 by case by case. 656 00:26:36,670 --> 00:26:38,370 So we saw those last time. 657 00:26:38,370 --> 00:26:40,430 And then we started touching upon things like loops. 658 00:26:40,430 --> 00:26:42,070 We saw one of these just a moment ago. 659 00:26:42,070 --> 00:26:44,180 But there are these other looping constructs. 660 00:26:44,180 --> 00:26:46,370 >> For instance, this one here. 661 00:26:46,370 --> 00:26:50,140 So while (condition), do this thing again and again. 662 00:26:50,140 --> 00:26:53,070 So fundamentally, what seems to be different between this 663 00:26:53,070 --> 00:26:55,760 for loop and this while loop here? 664 00:27:00,810 --> 00:27:05,045 This for loop and this while loop. 665 00:27:05,045 --> 00:27:07,840 Yeah? 666 00:27:07,840 --> 00:27:08,800 What's that? 667 00:27:08,800 --> 00:27:10,050 AUDIENCE: [INAUDIBLE]. 668 00:27:14,632 --> 00:27:15,120 DAVID J. MALAN: Good. 669 00:27:15,120 --> 00:27:17,130 So whereas in the for loop condition, there's clearly 670 00:27:17,130 --> 00:27:17,940 more syntax. 671 00:27:17,940 --> 00:27:20,560 There's this initialization, there's this update. 672 00:27:20,560 --> 00:27:23,820 In a while loop, there's just this condition. 673 00:27:23,820 --> 00:27:26,630 So it seems that it's a little pared down versus the for 674 00:27:26,630 --> 00:27:28,770 loop, which means if we want to have variables and we want 675 00:27:28,770 --> 00:27:30,800 to have incrementation, we actually have to 676 00:27:30,800 --> 00:27:32,500 do this thing ourselves. 677 00:27:32,500 --> 00:27:34,420 >> So let me go ahead and open up gedit. 678 00:27:34,420 --> 00:27:36,320 Let me switch over to the appliance. 679 00:27:36,320 --> 00:27:38,110 And let's just do a quick little example that 680 00:27:38,110 --> 00:27:40,550 distinguishes one of these from the other. 681 00:27:40,550 --> 00:27:42,490 And in the back of my mind here, I should say one thing. 682 00:27:42,490 --> 00:27:44,120 I specifically mentioned the name Tim. 683 00:27:44,120 --> 00:27:47,740 Tim was actually someone that a student tried to find to do 684 00:27:47,740 --> 00:27:48,680 their homework for them. 685 00:27:48,680 --> 00:27:51,280 We had no Tim in that particular section. 686 00:27:51,280 --> 00:27:53,690 So realize, lest I disclosed a student, it was not a student. 687 00:27:53,690 --> 00:27:55,720 It was a random person on the Internet doing things 688 00:27:55,720 --> 00:27:57,180 by proxy last year. 689 00:27:57,180 --> 00:27:58,670 So we find that, too. 690 00:27:58,670 --> 00:28:00,630 So in this case here, let me go ahead and 691 00:28:00,630 --> 00:28:02,810 open up a new file. 692 00:28:02,810 --> 00:28:04,800 File, New. 693 00:28:04,800 --> 00:28:06,050 This gives me a tab here. 694 00:28:06,050 --> 00:28:09,940 Let me go ahead and save it as loop.c. 695 00:28:09,940 --> 00:28:11,810 Let me go and click Save. 696 00:28:11,810 --> 00:28:15,340 And then down here, let's go ahead and start writing 697 00:28:15,340 --> 00:28:16,605 #include . 698 00:28:19,116 --> 00:28:20,520 Let me zoom in. 699 00:28:20,520 --> 00:28:23,410 Now we'll do int main(void). 700 00:28:23,410 --> 00:28:30,020 Now let me go ahead and do for (int i = 0; i < 701 00:28:30,020 --> 00:28:33,480 oh, 10; i++). 702 00:28:33,480 --> 00:28:36,620 And now I'm going to go ahead and do print the star that I 703 00:28:36,620 --> 00:28:37,890 did earlier. 704 00:28:37,890 --> 00:28:39,390 And then at the end of this program, we're just going to 705 00:28:39,390 --> 00:28:41,130 print a new line, just so that my prompt 706 00:28:41,130 --> 00:28:42,470 doesn't look all messy. 707 00:28:42,470 --> 00:28:45,170 return 0. 708 00:28:45,170 --> 00:28:47,610 Seem syntactically correct? 709 00:28:47,610 --> 00:28:48,040 So far. 710 00:28:48,040 --> 00:28:48,560 So let's see. 711 00:28:48,560 --> 00:28:51,290 >> So let me zoom out, go into my terminal window. 712 00:28:51,290 --> 00:28:54,570 And let me go ahead and run loop, because I called this 713 00:28:54,570 --> 00:28:55,690 thing loop.c. 714 00:28:55,690 --> 00:28:56,780 So make loop. 715 00:28:56,780 --> 00:28:57,840 Seems to compile OK. 716 00:28:57,840 --> 00:29:00,210 Let me run loop, and now Enter. 717 00:29:00,210 --> 00:29:01,820 And it seems to have printed 10 stars. 718 00:29:01,820 --> 00:29:03,780 So let's just convert this to a while loop and see what 719 00:29:03,780 --> 00:29:05,220 kinds of issues we trip over. 720 00:29:05,220 --> 00:29:11,290 So instead of this, let me go in here and say while i is 721 00:29:11,290 --> 00:29:12,760 less than 10-- 722 00:29:12,760 --> 00:29:14,910 let me get rid of the for loop. 723 00:29:14,910 --> 00:29:17,170 OK, so we have a couple of problems already. 724 00:29:17,170 --> 00:29:21,110 So the condition is the same, but I'm obviously missing the 725 00:29:21,110 --> 00:29:21,680 initialization. 726 00:29:21,680 --> 00:29:23,840 I am missing the incrementation. 727 00:29:23,840 --> 00:29:28,020 So what should the compiler likely tell me when I try to 728 00:29:28,020 --> 00:29:29,170 compile this program? 729 00:29:29,170 --> 00:29:29,666 Yeah? 730 00:29:29,666 --> 00:29:31,154 AUDIENCE: [INAUDIBLE]. 731 00:29:31,154 --> 00:29:31,650 >> DAVID J. MALAN: Good. 732 00:29:31,650 --> 00:29:34,180 So it's going to say something like undeclared--in this 733 00:29:34,180 --> 00:29:35,280 case, variable i. 734 00:29:35,280 --> 00:29:37,980 And indeed, use of undeclared identifier i. 735 00:29:37,980 --> 00:29:40,960 And so this is in contrast with languages like PHP and 736 00:29:40,960 --> 00:29:43,120 Python and Ruby, with which some of you might be familiar, 737 00:29:43,120 --> 00:29:44,820 where you can just kind of start using variables 738 00:29:44,820 --> 00:29:47,420 willy-nilly and not have to worry about declaring them 739 00:29:47,420 --> 00:29:48,560 explicitly always. 740 00:29:48,560 --> 00:29:51,770 In C and in languages like Java and C++, you have to be 741 00:29:51,770 --> 00:29:53,020 super explicit. 742 00:29:53,020 --> 00:29:55,760 And if you want a variable called i, you have to tell me 743 00:29:55,760 --> 00:29:57,360 what kind of variable it is. 744 00:29:57,360 --> 00:29:59,360 So we're going to have to fix this as follows. 745 00:29:59,360 --> 00:30:05,510 I'm going to have to go up here and type int i; therefore, 746 00:30:05,510 --> 00:30:07,860 I have declared a variable called i. 747 00:30:07,860 --> 00:30:09,180 Now, I've skipped one step. 748 00:30:09,180 --> 00:30:11,340 I've obviously not initialized it, but let's see if that at 749 00:30:11,340 --> 00:30:13,650 least makes Clang stop complaining. 750 00:30:13,650 --> 00:30:15,770 So let me remake this program. 751 00:30:15,770 --> 00:30:16,770 >> All right, now it's just complaining 752 00:30:16,770 --> 00:30:17,870 for a different reason. 753 00:30:17,870 --> 00:30:21,130 "Variable 'i' is uninitialized when used here." All right, so 754 00:30:21,130 --> 00:30:22,340 that's pretty explicit. 755 00:30:22,340 --> 00:30:25,510 Initialized just means setting it equal to a value. 756 00:30:25,510 --> 00:30:30,820 And we've not done that, so let me try equals 0. 757 00:30:30,820 --> 00:30:35,030 Now let's try this again and re-run Clang. 758 00:30:35,030 --> 00:30:36,140 Compiled this time. 759 00:30:36,140 --> 00:30:37,210 And I'm about to run it. 760 00:30:37,210 --> 00:30:43,120 But big old infinite loop, because I've done the 761 00:30:43,120 --> 00:30:45,530 initialization, I've done the condition, but I've never done 762 00:30:45,530 --> 00:30:47,030 any kind of incrementation. 763 00:30:47,030 --> 00:30:48,780 So how can I do the incrementation? 764 00:30:48,780 --> 00:30:51,170 Well, in a while loop, it feels like I'm going to have 765 00:30:51,170 --> 00:30:54,180 to do it inside of the loop, because much like the first 766 00:30:54,180 --> 00:30:56,570 week's examples of doing looping constructs, like with 767 00:30:56,570 --> 00:30:59,040 the socks and with the self-counting, we had to do 768 00:30:59,040 --> 00:31:01,550 something at the very end, like go back to the next line. 769 00:31:01,550 --> 00:31:05,040 What if I go ahead and do this i++ here? 770 00:31:05,040 --> 00:31:06,030 Let's not even compile this. 771 00:31:06,030 --> 00:31:06,890 Catch me already. 772 00:31:06,890 --> 00:31:09,704 What's wrong here? 773 00:31:09,704 --> 00:31:10,690 AUDIENCE: [INAUDIBLE]. 774 00:31:10,690 --> 00:31:11,770 >> DAVID J. MALAN: So it's definitely not int. 775 00:31:11,770 --> 00:31:13,080 It's i. 776 00:31:13,080 --> 00:31:15,110 And the curly braces, like before, 777 00:31:15,110 --> 00:31:16,800 indentation is not enough. 778 00:31:16,800 --> 00:31:18,410 So now I have this construct. 779 00:31:18,410 --> 00:31:21,780 So while i is less than 10, print a star, 780 00:31:21,780 --> 00:31:23,220 then increment i. 781 00:31:23,220 --> 00:31:25,680 And the way a while loop works is that as soon as you hit the 782 00:31:25,680 --> 00:31:29,630 bottom of the loop, which in this case looks like line 10, 783 00:31:29,630 --> 00:31:32,880 it's going to go back to line 6, at which point the 784 00:31:32,880 --> 00:31:34,400 condition will be checked again. 785 00:31:34,400 --> 00:31:37,500 And if i is still less than 10, we'll do lines 8 and 786 00:31:37,500 --> 00:31:41,250 then 9, then we'll hit 10, and go back to 6, again and 787 00:31:41,250 --> 00:31:45,580 again and again and again, so long as i is less than 10. 788 00:31:45,580 --> 00:31:47,860 So let's re-run make here. 789 00:31:47,860 --> 00:31:48,940 >> Okay, we've compiled okay. 790 00:31:48,940 --> 00:31:50,300 Let me re-run loop. 791 00:31:50,300 --> 00:31:52,620 And now it actually seems to work. 792 00:31:52,620 --> 00:31:55,100 So pluses and minuses here? 793 00:31:55,100 --> 00:31:58,910 Well, so far there's actually not a whole of plo-- 794 00:31:58,910 --> 00:31:59,420 so cute. 795 00:31:59,420 --> 00:32:01,870 All right, that was an--ah, that was an accident. 796 00:32:01,870 --> 00:32:05,200 All right, so let's go back to the for loop. 797 00:32:05,200 --> 00:32:07,530 So for loops are nice because they're super explicit. 798 00:32:07,530 --> 00:32:09,720 And even though they're a little clunky to write, it's 799 00:32:09,720 --> 00:32:11,500 very powerful and it allows you to do 800 00:32:11,500 --> 00:32:12,980 multiple things at once. 801 00:32:12,980 --> 00:32:16,240 While loops don't seem to have a huge amount of value just 802 00:32:16,240 --> 00:32:18,500 yet, because it feels like we just have to do more work. 803 00:32:18,500 --> 00:32:20,670 We have to put the initialization up here, the 804 00:32:20,670 --> 00:32:23,480 update down here, and we have to remember to do all that. 805 00:32:23,480 --> 00:32:26,260 So we'll see in time that while loops actually lend 806 00:32:26,260 --> 00:32:29,380 themselves to just different contexts, different data 807 00:32:29,380 --> 00:32:33,900 structures like lists and hash tables, things we'll get to 808 00:32:33,900 --> 00:32:34,970 mid-semester. 809 00:32:34,970 --> 00:32:37,900 But for now, know that there's this third type known as a do- 810 00:32:37,900 --> 00:32:38,480 while loop. 811 00:32:38,480 --> 00:32:39,540 And we've seen this briefly. 812 00:32:39,540 --> 00:32:41,830 And this might be super helpful with pset 1. 813 00:32:41,830 --> 00:32:45,570 Any time you want to do something and then check if 814 00:32:45,570 --> 00:32:48,940 the user cooperated, and if they didn't, do it again, a do- 815 00:32:48,940 --> 00:32:51,460 while loop lends itself to that kind of logic. 816 00:32:51,460 --> 00:32:55,640 Because as the ordering from top to bottom here suggests, 817 00:32:55,640 --> 00:32:57,750 do literally means do this. 818 00:32:57,750 --> 00:32:59,830 And do this again and again, what might that be? 819 00:32:59,830 --> 00:33:03,000 Maybe it means calling GetInt or GetString and then 820 00:33:03,000 --> 00:33:05,830 checking the value of GetInt or GetString and then yelling 821 00:33:05,830 --> 00:33:08,260 at the user if they haven't cooperated by asking them 822 00:33:08,260 --> 00:33:10,100 again and again and again. 823 00:33:10,100 --> 00:33:11,730 Where you want to do something once, 824 00:33:11,730 --> 00:33:13,210 then check some condition. 825 00:33:13,210 --> 00:33:14,110 >> So let's try this. 826 00:33:14,110 --> 00:33:17,130 Let me actually change this now to a do-while loop. 827 00:33:17,130 --> 00:33:18,830 And I'm going to go ahead and do the following. 828 00:33:18,830 --> 00:33:21,830 So do the following. 829 00:33:21,830 --> 00:33:26,870 Let's do int i = GetInt(); but let's first tell the user 830 00:33:26,870 --> 00:33:27,410 what to do. 831 00:33:27,410 --> 00:33:29,050 So a little different this time. 832 00:33:29,050 --> 00:33:31,270 "Give me an int". 833 00:33:31,270 --> 00:33:32,910 So I'll use printf for that. 834 00:33:32,910 --> 00:33:35,740 And now I'm going to go down here, and I'm going to do this 835 00:33:35,740 --> 00:33:41,520 while i is, let's say, greater than-- 836 00:33:41,520 --> 00:33:47,540 let's see, i is, let's say, less than 0, or i is 837 00:33:47,540 --> 00:33:48,730 greater than 10. 838 00:33:48,730 --> 00:33:51,810 In other words, I want a number from 1 to 9, just 839 00:33:51,810 --> 00:33:52,720 arbitrarily. 840 00:33:52,720 --> 00:33:55,290 So I'm using a combined Boolean expression here to 841 00:33:55,290 --> 00:33:59,930 make sure that i is less than 0 or greater than 10, in which 842 00:33:59,930 --> 00:34:02,530 case I will do this loop here again. 843 00:34:02,530 --> 00:34:04,400 So again, do this-- 844 00:34:04,400 --> 00:34:08,480 while i is less than 0 or i is greater than 10. 845 00:34:08,480 --> 00:34:11,440 >> So now let's go ahead and do this once we've done that. 846 00:34:11,440 --> 00:34:13,270 Let's just do a quick sanity check. 847 00:34:13,270 --> 00:34:18,929 printf("Thanks, i is %d", i). 848 00:34:18,929 --> 00:34:21,350 So this simple program asks the user for an int, 849 00:34:21,350 --> 00:34:24,000 makes sure it's within some range, 1 to 9 inclusive, 850 00:34:24,000 --> 00:34:26,280 and then thanks the user by reminding them what they just 851 00:34:26,280 --> 00:34:27,940 typed in, just as a little sanity check. 852 00:34:27,940 --> 00:34:30,659 But let's see if this works as intended. 853 00:34:30,659 --> 00:34:34,533 Let me go head down here and re-run make loop. 854 00:34:34,533 --> 00:34:35,350 Hmm. 855 00:34:35,350 --> 00:34:38,600 "Use of undeclared identifier 'i'". That's strange. 856 00:34:38,600 --> 00:34:41,509 I thought we resolved that. 857 00:34:45,489 --> 00:34:47,560 Same symptom but different code. 858 00:34:47,560 --> 00:34:47,899 Yeah? 859 00:34:47,899 --> 00:34:50,191 AUDIENCE: [INAUDIBLE] inside the two, we have to 860 00:34:50,191 --> 00:34:52,639 [INAUDIBLE]. 861 00:34:52,639 --> 00:34:53,260 >> DAVID J. MALAN: Exactly. 862 00:34:53,260 --> 00:34:55,989 So this actually leads us to a topic known as scope. 863 00:34:55,989 --> 00:34:59,350 It turns out that C, again, it really takes you literally. 864 00:34:59,350 --> 00:35:02,970 And if you do something like this where you declare an int 865 00:35:02,970 --> 00:35:06,120 and then assign it some value, but you do that inside of a 866 00:35:06,120 --> 00:35:09,840 pair of curly braces, what C does is it assumes that you 867 00:35:09,840 --> 00:35:14,800 only want those 32 bits known as i to exist within the 868 00:35:14,800 --> 00:35:18,200 context of those curly braces, within the context of lines 869 00:35:18,200 --> 00:35:22,420 6 through 9. So i is declared, and it is assigned a 870 00:35:22,420 --> 00:35:26,530 value in line 8, but as soon as you get outside of 871 00:35:26,530 --> 00:35:30,270 line 9 below the curly brace, i is no longer in 872 00:35:30,270 --> 00:35:31,910 scope, so to speak. 873 00:35:31,910 --> 00:35:35,030 S-C-O-P-E. It's no longer in the right context. 874 00:35:35,030 --> 00:35:37,940 So now there is no i, so it's as though we hadn't even 875 00:35:37,940 --> 00:35:38,770 declared it at all. 876 00:35:38,770 --> 00:35:41,520 >> So what's a fix then for something like this, if the 877 00:35:41,520 --> 00:35:44,300 reason is that i is declared within the curly braces, which 878 00:35:44,300 --> 00:35:45,120 is apparently bad? 879 00:35:45,120 --> 00:35:45,410 Here? 880 00:35:45,410 --> 00:35:46,820 AUDIENCE: [INAUDIBLE]. 881 00:35:46,820 --> 00:35:47,150 DAVID J. MALAN: Yeah. 882 00:35:47,150 --> 00:35:48,710 So we can initialize it outside. 883 00:35:48,710 --> 00:35:53,530 So let me go ahead and delete the declaration parts whereby 884 00:35:53,530 --> 00:35:55,820 I specify the type, and let me do it up here. 885 00:35:55,820 --> 00:36:00,220 So in line 5, it now says "Give me an int." Call it i. 886 00:36:00,220 --> 00:36:03,400 Notice in line 9, I do not want to do this, because I 887 00:36:03,400 --> 00:36:04,830 already have the 32 bits. 888 00:36:04,830 --> 00:36:06,140 I don't want to ask the computer for a 889 00:36:06,140 --> 00:36:07,630 different 32 bits. 890 00:36:07,630 --> 00:36:09,850 I want to use those same 32 bits. 891 00:36:09,850 --> 00:36:13,190 And now because i is declared in line 5, it's still legit 892 00:36:13,190 --> 00:36:16,550 to use it in line 11 and line 12. 893 00:36:16,550 --> 00:36:19,310 >> So let me try to recompile this and see 894 00:36:19,310 --> 00:36:20,490 if Clang stops yelling. 895 00:36:20,490 --> 00:36:22,380 make loop. 896 00:36:22,380 --> 00:36:25,470 So now it is "implicit declaration of function 897 00:36:25,470 --> 00:36:29,880 'GetInt' is invalid in C99." What is that? 898 00:36:29,880 --> 00:36:30,400 Yeah? 899 00:36:30,400 --> 00:36:32,330 AUDIENCE: [INAUDIBLE]. 900 00:36:32,330 --> 00:36:32,690 DAVID J. MALAN: Yeah. 901 00:36:32,690 --> 00:36:35,520 So now that I'm actually using GetInt, this is not something 902 00:36:35,520 --> 00:36:38,190 that just comes with C. This comes from CS50. 903 00:36:38,190 --> 00:36:39,890 So we need this here. 904 00:36:39,890 --> 00:36:41,450 And let me go back to the prompt down 905 00:36:41,450 --> 00:36:43,500 here and re-run make. 906 00:36:43,500 --> 00:36:44,160 Okay, finally. 907 00:36:44,160 --> 00:36:46,270 Now we've resolved that and the other error. 908 00:36:46,270 --> 00:36:48,930 Let me now run loop and see what happens. 909 00:36:48,930 --> 00:36:51,740 "Give me an int." I'll give it 11. 910 00:36:51,740 --> 00:36:53,100 I'll give it -1. 911 00:36:53,100 --> 00:36:54,470 I'll give it foo. 912 00:36:54,470 --> 00:36:56,080 I'll give it 5. 913 00:36:56,080 --> 00:36:57,450 And now it indeed works. 914 00:36:57,450 --> 00:36:59,410 But the prompt changed for a reason here. 915 00:36:59,410 --> 00:37:02,800 Why did it say retry one of these times but give me an 916 00:37:02,800 --> 00:37:03,920 int the other three times? 917 00:37:03,920 --> 00:37:05,500 Why is that behavior different? 918 00:37:05,500 --> 00:37:06,980 AUDIENCE: Gave it a string. 919 00:37:06,980 --> 00:37:07,830 DAVID J. MALAN: Sorry? 920 00:37:07,830 --> 00:37:08,570 AUDIENCE: You gave it a string. 921 00:37:08,570 --> 00:37:08,990 DAVID J. MALAN: Yeah. 922 00:37:08,990 --> 00:37:11,450 So we gave it a string in this third attempt, 923 00:37:11,450 --> 00:37:12,490 when I typed foo. 924 00:37:12,490 --> 00:37:13,200 Foo is a string. 925 00:37:13,200 --> 00:37:14,340 It's obviously not an int. 926 00:37:14,340 --> 00:37:17,500 And the way that CS50 has implemented GetInt is that we 927 00:37:17,500 --> 00:37:20,330 don't check if something's less than 0 or greater than 10 928 00:37:20,330 --> 00:37:22,260 for you, because how do we know in advance what kind of 929 00:37:22,260 --> 00:37:23,130 int you want? 930 00:37:23,130 --> 00:37:25,880 But we can minimally check for you, did the user at least 931 00:37:25,880 --> 00:37:26,730 type an integer? 932 00:37:26,730 --> 00:37:30,500 And if they didn't, we yell at the user by typing "retry" on 933 00:37:30,500 --> 00:37:31,440 the screen. 934 00:37:31,440 --> 00:37:34,210 >> So now we have a program that's looping. Okay. 935 00:37:34,210 --> 00:37:37,070 Now, which of these is sort of the better construct? 936 00:37:37,070 --> 00:37:39,060 So this is where things start to get a little messy, the 937 00:37:39,060 --> 00:37:42,360 fact that you have to remember to declare a variable up here 938 00:37:42,360 --> 00:37:44,630 if you want to use it inside of some 939 00:37:44,630 --> 00:37:46,460 curly braces and outside. 940 00:37:46,460 --> 00:37:48,490 But even if this looks a little cryptic at first 941 00:37:48,490 --> 00:37:50,750 glance, just again, remember the simple logic. 942 00:37:50,750 --> 00:37:54,630 In order to use anything in C, whether it's a function or 943 00:37:54,630 --> 00:37:57,680 it's a variable, you have to include it if it's a function 944 00:37:57,680 --> 00:37:59,770 in some library, or you need to declare it. 945 00:37:59,770 --> 00:38:02,405 But now you need to be extra mindful of the fact that 946 00:38:02,405 --> 00:38:04,940 you're declaring it in the right scope. 947 00:38:04,940 --> 00:38:08,150 You're not putting it too tightly inside of parentheses. 948 00:38:08,150 --> 00:38:09,410 >> So let me actually roll back. 949 00:38:09,410 --> 00:38:12,660 If we go back to our for example from earlier, and I go 950 00:38:12,660 --> 00:38:19,245 back to for int, int i = 0; i < 10; i++, and I 951 00:38:19,245 --> 00:38:26,370 do printf stars, like this, and then close paren, and now 952 00:38:26,370 --> 00:38:30,410 printf i is now-- 953 00:38:30,410 --> 00:38:33,500 according to the same logic, what will happen when I try to 954 00:38:33,500 --> 00:38:35,500 compile this program? 955 00:38:35,500 --> 00:38:36,790 AUDIENCE: Invalid identifier. 956 00:38:36,790 --> 00:38:38,560 DAVID J. MALAN: So it's another invalid identifier, 957 00:38:38,560 --> 00:38:39,470 undeclared identifier. 958 00:38:39,470 --> 00:38:41,810 Now, the reason's a little different. 959 00:38:41,810 --> 00:38:44,370 There's obviously no curly braces here, but the same 960 00:38:44,370 --> 00:38:46,790 idea, the same story of scope applies. 961 00:38:46,790 --> 00:38:50,340 If you have declared a variable like i inside of a 962 00:38:50,340 --> 00:38:53,960 for loop, even if you have not explicitly written the curly 963 00:38:53,960 --> 00:38:56,980 braces, think of them mentally as still being there, in which 964 00:38:56,980 --> 00:39:00,310 case i is only valid inside of the for loop. 965 00:39:00,310 --> 00:39:03,080 It is not valid once you get to the next line, which in 966 00:39:03,080 --> 00:39:05,090 this case is now 10. 967 00:39:05,090 --> 00:39:09,060 So just a few issues of scope and the like. 968 00:39:09,060 --> 00:39:12,620 All right, any questions? 969 00:39:12,620 --> 00:39:15,310 >> All right, so this is kind of a trivial little program, 970 00:39:15,310 --> 00:39:17,450 printing just little stars. 971 00:39:17,450 --> 00:39:20,400 But let's see if you remember this song here. 972 00:39:20,400 --> 00:39:22,530 This is an incredibly annoying song the kids would sing on 973 00:39:22,530 --> 00:39:23,550 the school bus and the like. 974 00:39:23,550 --> 00:39:25,990 But what's nice about it is that it has this cyclicity, 975 00:39:25,990 --> 00:39:27,910 whereby it's "99 bottles of beer on the wall, 976 00:39:27,910 --> 00:39:28,520 99 bottles of beer. 977 00:39:28,520 --> 00:39:31,030 Take one down, pass it around, 98 bottles of beer on the 978 00:39:31,030 --> 00:39:34,330 wall." And then the song repeats the 97, then 96, then 979 00:39:34,330 --> 00:39:38,040 95, then 94, all the way down to 0 if you actually got that 980 00:39:38,040 --> 00:39:38,920 far on the bus. 981 00:39:38,920 --> 00:39:41,960 So this is a nice program to sort of implement, because my 982 00:39:41,960 --> 00:39:43,650 God, if you could just implement this with a few 983 00:39:43,650 --> 00:39:46,660 lines of code, you could spit out the entire lyrics to this 984 00:39:46,660 --> 00:39:48,240 song quite quickly. 985 00:39:48,240 --> 00:39:50,420 But along the way, we can start to now tease apart some 986 00:39:50,420 --> 00:39:52,460 of these basic looping constructs and now also 987 00:39:52,460 --> 00:39:55,830 introduce functions that we write ourselves, return values 988 00:39:55,830 --> 00:39:57,020 that we pass around. 989 00:39:57,020 --> 00:39:58,910 But first, why don't we go ahead and take our five-minute 990 00:39:58,910 --> 00:39:59,320 break here? 991 00:39:59,320 --> 00:40:01,480 And when we get back, we will sing this song. 992 00:40:05,680 --> 00:40:08,760 >> All right, so we are back. 993 00:40:08,760 --> 00:40:11,850 And when I say we will now sing this song, I mean 994 00:40:11,850 --> 00:40:13,250 programmatically, not verbally. 995 00:40:13,250 --> 00:40:19,370 So here we have beer1.c, which is one implementation of this 996 00:40:19,370 --> 00:40:20,580 particular song. 997 00:40:20,580 --> 00:40:23,110 And just to be clear, for those unfamiliar with what 998 00:40:23,110 --> 00:40:24,460 this thing looks like, let me go ahead 999 00:40:24,460 --> 00:40:27,070 and make beer1, Enter. 1000 00:40:27,070 --> 00:40:30,400 Now let me run beer1, and what we'll see--how many bottles 1001 00:40:30,400 --> 00:40:31,140 of beer will there be? 1002 00:40:31,140 --> 00:40:33,240 I'll type in 99, like the song says. 1003 00:40:33,240 --> 00:40:34,040 Enter. 1004 00:40:34,040 --> 00:40:35,650 And now if we scroll through-- 1005 00:40:35,650 --> 00:40:38,280 oops--if we scroll through all of this, we'll see that 1006 00:40:38,280 --> 00:40:41,350 this did indeed sing the whole song. 1007 00:40:44,050 --> 00:40:44,540 Wait a minute. 1008 00:40:44,540 --> 00:40:46,240 My scroll bar's a little messed up. 1009 00:40:46,240 --> 00:40:47,940 Let's use the bigger window. 1010 00:40:47,940 --> 00:40:53,500 So beer1, 99, there we go. 1011 00:40:53,500 --> 00:40:56,420 So here we have the whole song, sung much faster by the 1012 00:40:56,420 --> 00:40:58,450 computer than it could have been by us. 1013 00:40:58,450 --> 00:41:00,340 So notice, though, the cyclical nature here. 1014 00:41:00,340 --> 00:41:03,380 It says 99, then 99, then "take one down, pass it 1015 00:41:03,380 --> 00:41:04,740 around," then 98. 1016 00:41:04,740 --> 00:41:06,640 And now it repeats again and again. 1017 00:41:06,640 --> 00:41:08,840 >> So this is actually a perfect opportunity for some kind of 1018 00:41:08,840 --> 00:41:10,400 looping construct. 1019 00:41:10,400 --> 00:41:12,950 Notice that I'm kind of cutting a corner here. 1020 00:41:12,950 --> 00:41:15,960 Notice that I'm saying "98 bottles of beer on the wall, 1021 00:41:15,960 --> 00:41:19,010 97 bottles of beer on the wall," and that was just so 1022 00:41:19,010 --> 00:41:21,640 that when we get to one bottles of beer, I don't have 1023 00:41:21,640 --> 00:41:23,300 to worry about the English grammar. 1024 00:41:23,300 --> 00:41:25,790 But we can also fix this with a little bit of an if 1025 00:41:25,790 --> 00:41:26,910 condition, perhaps. 1026 00:41:26,910 --> 00:41:30,110 If this number is singular, go ahead and say "bottle", 1027 00:41:30,110 --> 00:41:31,840 otherwise if it's plural, say "bottles". 1028 00:41:31,840 --> 00:41:34,150 But for now, I'm completely cutting that corner. 1029 00:41:34,150 --> 00:41:35,520 So let's see what we've got here. 1030 00:41:35,520 --> 00:41:37,150 So we've got some comments at the top. 1031 00:41:37,150 --> 00:41:39,450 I'm including these two libraries, as 1032 00:41:39,450 --> 00:41:41,140 we've commonly been. 1033 00:41:41,140 --> 00:41:43,610 And now let me scroll down to the first 1034 00:41:43,610 --> 00:41:44,990 actual lines of code. 1035 00:41:44,990 --> 00:41:47,020 Line 17 kicks off main. 1036 00:41:47,020 --> 00:41:50,610 Line 21 and 20 has how many bottles of beer will there be? 1037 00:41:50,610 --> 00:41:52,060 And then I call GetInt. 1038 00:41:52,060 --> 00:41:53,800 And now I have a bit of a sanity check. 1039 00:41:53,800 --> 00:41:57,030 >> So this is a convention that we'll now start adopting to 1040 00:41:57,030 --> 00:41:59,620 more rigorously check the user's input. 1041 00:41:59,620 --> 00:42:01,710 Sometimes you just don't want to prompt them again 1042 00:42:01,710 --> 00:42:02,630 and again and again. 1043 00:42:02,630 --> 00:42:05,620 If the user screws up and doesn't cooperate, fine. 1044 00:42:05,620 --> 00:42:07,430 Quit and just don't deal with them. 1045 00:42:07,430 --> 00:42:08,990 And so that's what I'm doing here. 1046 00:42:08,990 --> 00:42:12,520 If n is less than 1, I'm just going to yell at the user, 1047 00:42:12,520 --> 00:42:14,330 "Sorry, that makes no sense." And then I'm going to 1048 00:42:14,330 --> 00:42:16,650 arbitrarily return 1. 1049 00:42:16,650 --> 00:42:18,550 So again, this is just a convention to get used to. 1050 00:42:18,550 --> 00:42:19,850 For now, take it on faith. 1051 00:42:19,850 --> 00:42:22,700 But up until now, we've always been returning 0, because 1052 00:42:22,700 --> 00:42:25,204 we've said returning 0 denotes what? 1053 00:42:25,204 --> 00:42:26,000 AUDIENCE: Success. 1054 00:42:26,000 --> 00:42:27,320 DAVID J. MALAN: Success, that's all. 1055 00:42:27,320 --> 00:42:29,740 So now that we're finally starting to think about 1056 00:42:29,740 --> 00:42:31,330 non-successes-- 1057 00:42:31,330 --> 00:42:33,760 in other words, corner cases, error conditions-- 1058 00:42:33,760 --> 00:42:37,520 now I have an infinite supply, or at least four billion 1059 00:42:37,520 --> 00:42:39,790 possible things that can go wrong in my programs. 1060 00:42:39,790 --> 00:42:42,300 And I can start assigning them individual numbers. 1061 00:42:42,300 --> 00:42:44,340 Now, generally it suffices to just return 1062 00:42:44,340 --> 00:42:45,730 something other than 0. 1063 00:42:45,730 --> 00:42:48,040 So we're going to simply return 1 for now. 1064 00:42:48,040 --> 00:42:51,440 But the reason for returning 1 is that as soon as you return 1065 00:42:51,440 --> 00:42:55,110 1, guess what happens to the rest of the program? 1066 00:42:55,110 --> 00:42:55,720 It stops. 1067 00:42:55,720 --> 00:42:56,560 That's it. 1068 00:42:56,560 --> 00:42:59,150 So the fact that I'm returning 1 is effectively 1069 00:42:59,150 --> 00:43:02,950 short-circuiting this program's execution so that 1070 00:43:02,950 --> 00:43:06,780 nothing below line 27 will continue executing. 1071 00:43:06,780 --> 00:43:09,210 As soon as main returns, that is it. 1072 00:43:09,210 --> 00:43:13,160 >> All right, so if the user does cooperate and we reach line 30 1073 00:43:13,160 --> 00:43:15,680 because they typed in a legitimate number, here is my 1074 00:43:15,680 --> 00:43:16,990 implementation of this song. 1075 00:43:16,990 --> 00:43:19,050 So I first print out a newline character, just for 1076 00:43:19,050 --> 00:43:19,880 aesthetics. 1077 00:43:19,880 --> 00:43:21,500 I now have a for loop. 1078 00:43:21,500 --> 00:43:22,930 And notice I'm doing things in a bit 1079 00:43:22,930 --> 00:43:23,880 of a different direction. 1080 00:43:23,880 --> 00:43:26,210 I don't have to do less than, I don't have to do ++. 1081 00:43:26,210 --> 00:43:30,660 I can instead say initialize a variable i, set it equal to 1082 00:43:30,660 --> 00:43:35,080 n, the number the user typed in, then do the following, so 1083 00:43:35,080 --> 00:43:39,590 long as i is greater than 0, then i-- 1084 00:43:39,590 --> 00:43:42,070 once you've finished one iteration of this loop. 1085 00:43:42,070 --> 00:43:44,310 So we can count down using a for loop as well. 1086 00:43:44,310 --> 00:43:47,520 Now, this is pretty much week one stuff now, with printf. 1087 00:43:47,520 --> 00:43:51,770 So print "%d bottles of beer on the wall." Print "%d 1088 00:43:51,770 --> 00:43:54,990 bottles of beer." "Take one down, pass it around." Print 1089 00:43:54,990 --> 00:43:58,880 "%d bottles of beer on the wall." So it's still %d, but 1090 00:43:58,880 --> 00:44:02,770 notice that the argument to printf is changing. 1091 00:44:02,770 --> 00:44:05,840 After the comma, I have i, because I want to say 99. 1092 00:44:05,840 --> 00:44:08,590 After this comma, I have i, because I want to say 99. 1093 00:44:08,590 --> 00:44:14,030 After this comma, I have i - 1, because I want to say 98 in 1094 00:44:14,030 --> 00:44:16,260 this first iteration, and so forth. 1095 00:44:16,260 --> 00:44:18,520 And now down here, I just have some stupid little remark. 1096 00:44:18,520 --> 00:44:22,270 And then line 42, I return 0 by convention, signifying that 1097 00:44:22,270 --> 00:44:23,650 everything is okay. 1098 00:44:23,650 --> 00:44:24,490 >> So what if I goofed? 1099 00:44:24,490 --> 00:44:26,350 What might a common mistake here be? 1100 00:44:26,350 --> 00:44:29,200 Well, what if I accidentally said well, I do want to count 1101 00:44:29,200 --> 00:44:31,640 down to 0, I want 0 bottles of beer on the wall? 1102 00:44:31,640 --> 00:44:34,620 So I say, i is greater than or equal to 0. 1103 00:44:34,620 --> 00:44:38,920 What's going to be the symptom that I now see if I recompile 1104 00:44:38,920 --> 00:44:41,173 beer1 and run it? 1105 00:44:41,173 --> 00:44:42,120 AUDIENCE: Negative. 1106 00:44:42,120 --> 00:44:43,590 DAVID J. MALAN: Yeah, it's gonna go negative. 1107 00:44:43,590 --> 00:44:45,950 This is an off-by-one error, an incredibly 1108 00:44:45,950 --> 00:44:47,270 common mistake to make. 1109 00:44:47,270 --> 00:44:48,960 Let's actually go back to the terminal window and do it 1110 00:44:48,960 --> 00:44:50,620 here, so we can see more at a time. 1111 00:44:50,620 --> 00:44:53,280 Enter, 99 bottles of beer. 1112 00:44:53,280 --> 00:44:56,580 Close, but we went ever so slightly too far. 1113 00:44:56,580 --> 00:45:00,500 We sang the song too far down, such that we now hit the 1114 00:45:00,500 --> 00:45:01,510 negative number. 1115 00:45:01,510 --> 00:45:03,680 So it doesn't quite work. 1116 00:45:03,680 --> 00:45:06,450 >> All right, so we can easily fix that by going back to the 1117 00:45:06,450 --> 00:45:07,650 way it once was. 1118 00:45:07,650 --> 00:45:10,360 But what are some opportunities now for 1119 00:45:10,360 --> 00:45:11,190 improvement? 1120 00:45:11,190 --> 00:45:17,200 Well, let me open beer2.c and scroll down here and take a 1121 00:45:17,200 --> 00:45:19,310 look at this version. 1122 00:45:19,310 --> 00:45:21,370 What's the first thing that jumps out at you as different 1123 00:45:21,370 --> 00:45:23,715 in this version here? 1124 00:45:23,715 --> 00:45:24,190 AUDIENCE: [INAUDIBLE]. 1125 00:45:24,190 --> 00:45:26,510 DAVID J. MALAN: Yeah, so no more i, because it occurred to 1126 00:45:26,510 --> 00:45:29,350 me you know what, I'm asking the user for n, and then I'm 1127 00:45:29,350 --> 00:45:33,580 setting i equal to n, and then I'm changing i, but I'm never 1128 00:45:33,580 --> 00:45:34,590 touching n again. 1129 00:45:34,590 --> 00:45:37,390 So what the heck was the point of you allocating another 32 1130 00:45:37,390 --> 00:45:45,210 bits called i just so that I can have a different variable? 1131 00:45:45,210 --> 00:45:47,960 So in this case, I sort of recognized that unnecessary 1132 00:45:47,960 --> 00:45:49,190 design feature. 1133 00:45:49,190 --> 00:45:52,730 And I'm now going to say while n is greater than 0, go 1134 00:45:52,730 --> 00:45:56,180 ahead and print the same song, passing an n to printf as the 1135 00:45:56,180 --> 00:46:00,210 second argument, and n - 1 as the second argument down here. 1136 00:46:00,210 --> 00:46:02,930 And then on each iteration of this loop, go ahead and just 1137 00:46:02,930 --> 00:46:05,080 decrement n itself. 1138 00:46:05,080 --> 00:46:06,960 Now, functionally, this program 1139 00:46:06,960 --> 00:46:08,010 is going to be identical. 1140 00:46:08,010 --> 00:46:10,730 If I type in 99, n starts at 99. 1141 00:46:10,730 --> 00:46:12,890 I decrement, decrement, decrement, decrement. 1142 00:46:12,890 --> 00:46:15,875 I'm going to get all the way down to "One bottle of beer on 1143 00:46:15,875 --> 00:46:16,740 the wall, one bottle of beer. 1144 00:46:16,740 --> 00:46:18,020 Take one down, pass it around. 1145 00:46:18,020 --> 00:46:21,480 0 bottles of beer on the wall." The end, because I did 1146 00:46:21,480 --> 00:46:23,200 get the condition correct. 1147 00:46:23,200 --> 00:46:24,280 It's greater than 0. 1148 00:46:24,280 --> 00:46:26,220 I didn't make this mistake. 1149 00:46:26,220 --> 00:46:28,470 >> So which is better, version one or version two? 1150 00:46:31,380 --> 00:46:33,480 So I heard a bunch of murmurings for two. 1151 00:46:33,480 --> 00:46:34,730 Why two? 1152 00:46:37,210 --> 00:46:38,225 What's that? 1153 00:46:38,225 --> 00:46:39,215 AUDIENCE: [INAUDIBLE]. 1154 00:46:39,215 --> 00:46:40,070 DAVID J. MALAN: Oh, okay. 1155 00:46:40,070 --> 00:46:42,870 So it won't go below 0, but remember, in version one, the 1156 00:46:42,870 --> 00:46:45,870 original correct version didn't go below 0 either. 1157 00:46:45,870 --> 00:46:48,340 So remember that this is the correct version. 1158 00:46:48,340 --> 00:46:51,630 So let's at least compare the two correct versions. 1159 00:46:51,630 --> 00:46:53,300 What's an argument in favor of version 1160 00:46:53,300 --> 00:46:55,146 two being, mmm, better? 1161 00:46:55,146 --> 00:46:55,642 Yeah? 1162 00:46:55,642 --> 00:46:57,630 AUDIENCE: It uses less space. 1163 00:46:57,630 --> 00:46:59,530 DAVID J. MALAN: Okay, so it uses less space, right? 1164 00:46:59,530 --> 00:47:02,900 Whereas version one used 32 bits for n, and then another 1165 00:47:02,900 --> 00:47:07,680 32 bits for i. 1166 00:47:07,680 --> 00:47:10,060 Version two only uses 32 bits for n, so that 1167 00:47:10,060 --> 00:47:11,700 seems to be a plus. 1168 00:47:11,700 --> 00:47:12,950 Other thoughts? 1169 00:47:18,070 --> 00:47:21,520 Does anyone want to argue in favor of one? 1170 00:47:21,520 --> 00:47:22,070 Yeah? 1171 00:47:22,070 --> 00:47:25,240 AUDIENCE: You have to use extra line of code for n--. 1172 00:47:25,240 --> 00:47:26,090 >> DAVID J. MALAN: Okay, sure. 1173 00:47:26,090 --> 00:47:26,960 So that's fair. 1174 00:47:26,960 --> 00:47:29,040 So this just, at least to me-- 1175 00:47:29,040 --> 00:47:31,940 I mean, this actually feels a little messier, the fact that 1176 00:47:31,940 --> 00:47:35,120 I can't sort of encapsulate all of my logic in one 1177 00:47:35,120 --> 00:47:38,030 beautiful line, the for loop, as the for loop can. 1178 00:47:38,030 --> 00:47:40,240 Here, I kind of have to tack on this n-- 1179 00:47:40,240 --> 00:47:41,120 at the end of the loop, because 1180 00:47:41,120 --> 00:47:42,550 it's logically necessary. 1181 00:47:42,550 --> 00:47:45,190 But it kind of rubs me the wrong way, just because it 1182 00:47:45,190 --> 00:47:48,260 seems separate from the logic of up here, even though, 1183 00:47:48,260 --> 00:47:49,430 again, it's necessary. 1184 00:47:49,430 --> 00:47:50,990 Other thoughts? 1185 00:47:50,990 --> 00:47:51,490 Yeah? 1186 00:47:51,490 --> 00:47:52,740 AUDIENCE: [INAUDIBLE]. 1187 00:47:57,990 --> 00:47:58,350 >> DAVID J. MALAN: Yeah. 1188 00:47:58,350 --> 00:48:00,730 So what if you instead, at the end of the song, wanted to 1189 00:48:00,730 --> 00:48:02,950 print out again the name of the song? 1190 00:48:02,950 --> 00:48:05,660 Like "Thanks for playing 99 bottles of beer", or something 1191 00:48:05,660 --> 00:48:06,690 silly like that? 1192 00:48:06,690 --> 00:48:09,750 But the point is, you wanted access to the original value. 1193 00:48:09,750 --> 00:48:13,180 The fact that you've mutated or changed n on every 1194 00:48:13,180 --> 00:48:16,330 iteration and therefore have destroyed its original value 1195 00:48:16,330 --> 00:48:18,650 means you just can't do that at the end. 1196 00:48:18,650 --> 00:48:20,660 Now, arguably, we clearly don't want to do 1197 00:48:20,660 --> 00:48:21,450 that in this program. 1198 00:48:21,450 --> 00:48:22,350 So who cares? 1199 00:48:22,350 --> 00:48:23,630 But that's a very valid point. 1200 00:48:23,630 --> 00:48:25,520 And to be honest, there's really no one 1201 00:48:25,520 --> 00:48:26,630 right answer here. 1202 00:48:26,630 --> 00:48:28,740 They're both equally correct. 1203 00:48:28,740 --> 00:48:30,210 I could be convinced either way. 1204 00:48:30,210 --> 00:48:33,310 I will say that, in general, it's a good principle if you 1205 00:48:33,310 --> 00:48:36,030 asked the user for some value and you stored in a variable 1206 00:48:36,030 --> 00:48:38,730 like n, just sort of on principle, it's probably good 1207 00:48:38,730 --> 00:48:40,160 to keep that around. 1208 00:48:40,160 --> 00:48:43,400 And any data you want to mutate again and again, just 1209 00:48:43,400 --> 00:48:46,030 give yourself a copy of that variable, just so that you 1210 00:48:46,030 --> 00:48:47,830 have access to the original. 1211 00:48:47,830 --> 00:48:51,040 You are spending 32 more bits, but the reality is this 1212 00:48:51,040 --> 00:48:53,490 computer has, like, two gigabytes of RAM these days, 1213 00:48:53,490 --> 00:48:55,310 and we're quibbling over 32 bits? 1214 00:48:55,310 --> 00:48:56,320 Really not such a big deal. 1215 00:48:56,320 --> 00:48:58,550 And even on this device here, with a half a gig or a 1216 00:48:58,550 --> 00:49:01,700 gigabyte of RAM, 32 bits versus 64 bits, 1217 00:49:01,700 --> 00:49:02,920 not such a big deal. 1218 00:49:02,920 --> 00:49:05,890 Certainly today, it's going to be way overwhelmed by the size 1219 00:49:05,890 --> 00:49:08,400 of the program itself, which is going to be several hundred 1220 00:49:08,400 --> 00:49:10,890 kilobytes, if not a few megabytes, these days. 1221 00:49:10,890 --> 00:49:13,550 >> So reasonable concerns, no one right answer. 1222 00:49:13,550 --> 00:49:15,490 But at least those are the thoughts that should start to 1223 00:49:15,490 --> 00:49:16,790 go through your mind? 1224 00:49:16,790 --> 00:49:19,600 Because in pset 0, even though we really only expected 1225 00:49:19,600 --> 00:49:22,340 correctness, or at least disclaiming various bugs that 1226 00:49:22,340 --> 00:49:25,440 you might have encountered, as we move forward, design is 1227 00:49:25,440 --> 00:49:27,910 going to be another key aspect, both of writing code 1228 00:49:27,910 --> 00:49:29,770 and also our evaluating code. 1229 00:49:29,770 --> 00:49:32,310 And so at least give thought to things like this. 1230 00:49:32,310 --> 00:49:35,590 And just because something works doesn't mean it's good, 1231 00:49:35,590 --> 00:49:37,130 doesn't mean it's well-designed. 1232 00:49:37,130 --> 00:49:38,820 And that's one of the things the teaching fellows and 1233 00:49:38,820 --> 00:49:41,990 problem sets will help us tease part over time. 1234 00:49:41,990 --> 00:49:45,020 >> Well, what about, let's say, this version here? 1235 00:49:45,020 --> 00:49:49,090 Let me do something a little sexy here in a moment. 1236 00:49:49,090 --> 00:49:50,740 First let me get rid of this. 1237 00:49:50,740 --> 00:49:54,120 And now let's fix this grammatical issue. 1238 00:49:54,120 --> 00:49:58,780 So in this version, I want to fix the grammar so that, 1239 00:49:58,780 --> 00:50:02,460 rather than just say parenthetical s, like "bottle" 1240 00:50:02,460 --> 00:50:03,360 or "bottles"-- 1241 00:50:03,360 --> 00:50:04,900 I don't want to cut that corner-- 1242 00:50:04,900 --> 00:50:08,350 I also want to dynamically print out the word "bottles" 1243 00:50:08,350 --> 00:50:12,820 or "bottle", thereby using these %s placeholders today. 1244 00:50:12,820 --> 00:50:16,550 So I need to conditionally check what is the value of i. 1245 00:50:16,550 --> 00:50:19,590 And if it's 1, I want to say "bottle", and if it's anything 1246 00:50:19,590 --> 00:50:23,115 else, I want to say "bottles". So let's try to do this. 1247 00:50:23,115 --> 00:50:31,340 So if i == 1, then let me go ahead and declare-- 1248 00:50:31,340 --> 00:50:34,080 I need a string, so let me do string s1, because it's the 1249 00:50:34,080 --> 00:50:36,070 first string I care about right now. 1250 00:50:36,070 --> 00:50:40,980 I'm going to say "bottle". And then, let's see, string 1251 00:50:40,980 --> 00:50:43,110 s2--and I'll explain where I'm going in a moment-- 1252 00:50:43,110 --> 00:50:47,650 "bottles." So recall that, in this song, we need to be able 1253 00:50:47,650 --> 00:50:50,580 to print things, two different words potentially. 1254 00:50:50,580 --> 00:50:53,590 So if we look back here, notice that when we get to 1255 00:50:53,590 --> 00:50:56,440 this example here, "two bottles of beer on the wall, 1256 00:50:56,440 --> 00:50:59,490 two bottles of beer, take one down, pass it around", I want 1257 00:50:59,490 --> 00:51:02,380 this fourth line to now say "one bottle of beer on the 1258 00:51:02,380 --> 00:51:04,900 wall". So I need to decide, do I want to say "bottles" or 1259 00:51:04,900 --> 00:51:07,780 "bottle"? So I'm going to arbitrarily say, all right, 1260 00:51:07,780 --> 00:51:10,530 I'm going to now declare a variable called s1, string 1261 00:51:10,530 --> 00:51:13,830 one, that's going to get plugged in here and also here, 1262 00:51:13,830 --> 00:51:16,070 because those words are always identical, just because of the 1263 00:51:16,070 --> 00:51:17,290 nature of the song. 1264 00:51:17,290 --> 00:51:20,100 And I'm going to call s2 whatever word I want to 1265 00:51:20,100 --> 00:51:21,560 eventually appear down here. 1266 00:51:21,560 --> 00:51:25,530 Now, literally, 99 times out of 100, it's going to be the 1267 00:51:25,530 --> 00:51:28,820 same in both of those cases, because 3 is plural, 2 is 1268 00:51:28,820 --> 00:51:30,200 plural, 4 is plural. 1269 00:51:30,200 --> 00:51:34,640 But in this corner case, where we get to 2 and then 1, or 1270 00:51:34,640 --> 00:51:37,250 even 1 and then 0, I need this logic. 1271 00:51:37,250 --> 00:51:41,020 So I have to spend some time in my code getting that right. 1272 00:51:41,020 --> 00:51:47,530 So if I do this, if i == 1, then set s1 equal to "bottle" 1273 00:51:47,530 --> 00:51:52,010 and s2 equal to "bottles", because this will be for 1 1274 00:51:52,010 --> 00:51:56,340 bottle, and this will be for 0 bottles. 1275 00:51:56,340 --> 00:51:58,250 And this here, what does this represent? 1276 00:51:58,250 --> 00:51:59,780 Just to be clear. 1277 00:51:59,780 --> 00:52:00,620 This is just a comment. 1278 00:52:00,620 --> 00:52:03,730 So the fact that you can have single-line comments means you 1279 00:52:03,730 --> 00:52:06,110 can comment your code like this, but another common 1280 00:52:06,110 --> 00:52:09,050 paradigm, too, is that if you have a super-short phrase that 1281 00:52:09,050 --> 00:52:11,410 you want to put yourself and it's just more readable to put 1282 00:52:11,410 --> 00:52:13,270 it right at the end of the line of code, you can 1283 00:52:13,270 --> 00:52:15,230 absolutely do something like this. 1284 00:52:15,230 --> 00:52:20,150 >> So now what if I do this? Else if i is not equal to 1. 1285 00:52:20,150 --> 00:52:21,620 So bang equals-- 1286 00:52:21,620 --> 00:52:23,150 exclamation point is known as "bang". 1287 00:52:23,150 --> 00:52:25,080 So bang = 1. 1288 00:52:25,080 --> 00:52:28,530 So if i is not equal to 1, what do I instead want to do? 1289 00:52:28,530 --> 00:52:31,700 Well, the first word I want to be what? 1290 00:52:34,620 --> 00:52:40,030 So string 1 should be "bottles" for plural bottles, 1291 00:52:40,030 --> 00:52:42,440 and then this will be plural "bottles" as well, for now. 1292 00:52:42,440 --> 00:52:43,800 And we'll see if this actually gets us to 1293 00:52:43,800 --> 00:52:44,870 where we want to go. 1294 00:52:44,870 --> 00:52:47,680 So now if I scroll down here, notice that I'm plugging in 1295 00:52:47,680 --> 00:52:50,170 not only i, but s1. 1296 00:52:50,170 --> 00:52:51,860 I'm plugging in i and s1. 1297 00:52:51,860 --> 00:52:54,440 And then down here, I'm minus 1, which is the same as 1298 00:52:54,440 --> 00:52:55,920 before, but s2. 1299 00:52:55,920 --> 00:52:58,730 In other words, I want the English word to change based 1300 00:52:58,730 --> 00:52:59,930 on this logic. 1301 00:52:59,930 --> 00:53:03,310 Now, there's already some problems in this code. 1302 00:53:03,310 --> 00:53:08,460 What is broken already out of the gate here? 1303 00:53:08,460 --> 00:53:10,796 Yeah? 1304 00:53:10,796 --> 00:53:13,210 AUDIENCE: [INAUDIBLE]. 1305 00:53:13,210 --> 00:53:13,800 >> DAVID J. MALAN: Exactly. 1306 00:53:13,800 --> 00:53:16,030 So I've already violated the lesson of scope. 1307 00:53:16,030 --> 00:53:19,610 So I've declared s1 and s2, but I've done it inside of 1308 00:53:19,610 --> 00:53:22,980 curly braces, which means yeah, this code will work up 1309 00:53:22,980 --> 00:53:27,430 until line 42, but as soon as I hit line 43, guess what no 1310 00:53:27,430 --> 00:53:28,900 longer exists? 1311 00:53:28,900 --> 00:53:32,600 Well, guess what's no longer in scope--neither s1 or s2. 1312 00:53:32,600 --> 00:53:33,780 So we have to fix this. 1313 00:53:33,780 --> 00:53:36,180 So let me delete the declarations. 1314 00:53:36,180 --> 00:53:39,320 And I'll leave the variable names and delete this here 1315 00:53:39,320 --> 00:53:40,120 and delete this here. 1316 00:53:40,120 --> 00:53:43,557 And in what lines should I really declare these things? 1317 00:53:43,557 --> 00:53:44,960 AUDIENCE: [INAUDIBLE]. 1318 00:53:44,960 --> 00:53:45,410 DAVID J. MALAN: Yeah, so probably 1319 00:53:45,410 --> 00:53:46,850 right up here, 33-ish. 1320 00:53:46,850 --> 00:53:50,670 So string s1 and then string s2. 1321 00:53:50,670 --> 00:53:51,950 And it turns out, I can do this. 1322 00:53:51,950 --> 00:53:54,260 If you're declaring two variables of the same type, 1323 00:53:54,260 --> 00:53:57,420 you can actually just use a comma and do that in C. All 1324 00:53:57,420 --> 00:53:58,970 right, so now I have two variables-- 1325 00:53:58,970 --> 00:53:59,860 s1 and s2. 1326 00:53:59,860 --> 00:54:02,000 I'm assigning them values in these 1327 00:54:02,000 --> 00:54:04,210 conditions here, or in here. 1328 00:54:04,210 --> 00:54:06,690 And then I'm using them down below. 1329 00:54:06,690 --> 00:54:10,960 How well is this now going to work? 1330 00:54:10,960 --> 00:54:12,740 >> Well, it's still a little buggy, but let's at least see 1331 00:54:12,740 --> 00:54:13,730 how far we've gotten. 1332 00:54:13,730 --> 00:54:16,500 So let me go ahead and make beer3. 1333 00:54:16,500 --> 00:54:17,695 Is this beer3? 1334 00:54:17,695 --> 00:54:19,410 Yep, this is beer3. 1335 00:54:19,410 --> 00:54:21,510 And now let me go ahead and run beer3. 1336 00:54:21,510 --> 00:54:23,820 399 99. 1337 00:54:23,820 --> 00:54:25,840 We can probably skip most of them. 1338 00:54:25,840 --> 00:54:29,100 And down here, look at that. 1339 00:54:29,100 --> 00:54:31,110 "One bottle of beer on the wall, one bottle of beer, take 1340 00:54:31,110 --> 00:54:34,306 one down, pass it around, 0 bottles of beer on the wall." 1341 00:54:34,306 --> 00:54:37,570 But I'm drawing your attention to only half of the solution. 1342 00:54:37,570 --> 00:54:39,620 Kind of screwed up here. 1343 00:54:39,620 --> 00:54:43,030 So it seems that the corner cases arise when i equals what 1344 00:54:43,030 --> 00:54:44,030 two values? 1345 00:54:44,030 --> 00:54:45,020 AUDIENCE: 2, 1. 1346 00:54:45,020 --> 00:54:46,190 DAVID J. MALAN: 2 and 1. 1347 00:54:46,190 --> 00:54:48,180 It's not 1 and not 1. 1348 00:54:48,180 --> 00:54:51,890 It's really just these last two stanzas of this song. 1349 00:54:51,890 --> 00:54:53,890 So what do I instead want to do? 1350 00:54:53,890 --> 00:54:58,890 So I seem to have caught the case where if i is == to 1, 1351 00:54:58,890 --> 00:55:02,240 then the first word is "bottle", but the second word 1352 00:55:02,240 --> 00:55:07,230 is "bottles". But here, I want to change this to be == 2. 1353 00:55:07,230 --> 00:55:08,570 And if this is the case, what do I want the 1354 00:55:08,570 --> 00:55:09,620 first word to be? 1355 00:55:09,620 --> 00:55:10,430 AUDIENCE: "Bottles". 1356 00:55:10,430 --> 00:55:12,890 DAVID J. MALAN: "Bottles", so for two bottles. 1357 00:55:12,890 --> 00:55:14,690 And then this word here should be-- 1358 00:55:14,690 --> 00:55:15,340 AUDIENCE: "Bottle". 1359 00:55:15,340 --> 00:55:17,316 DAVID J. MALAN: "Bottle", singular. 1360 00:55:20,430 --> 00:55:25,160 >> All right, let's zoom out, go back over here, re-run make, 1361 00:55:25,160 --> 00:55:28,590 re-run beer3, type 99 again. 1362 00:55:28,590 --> 00:55:30,710 Okay, "Segmentation fault (core dumped)." 1363 00:55:30,710 --> 00:55:32,780 What have I done wrong? 1364 00:55:36,050 --> 00:55:38,722 AUDIENCE: You don't have a value [INAUDIBLE]. 1365 00:55:38,722 --> 00:55:40,480 DAVID J. MALAN: Ah, excellent point. 1366 00:55:40,480 --> 00:55:43,310 All right, so what's wrong here? 1367 00:55:43,310 --> 00:55:45,450 So segmentation fault, and we're actually going to see 1368 00:55:45,450 --> 00:55:49,020 this quite a few times in the future, deliberately. 1369 00:55:49,020 --> 00:55:51,030 But for now, what does this actually mean? 1370 00:55:51,030 --> 00:55:53,620 A segmentation fault almost always means that you have 1371 00:55:53,620 --> 00:55:56,760 somehow tried to access memory, RAM in your computer, 1372 00:55:56,760 --> 00:56:00,600 that you don't own, that you have not actually asked the 1373 00:56:00,600 --> 00:56:02,050 operating system for. 1374 00:56:02,050 --> 00:56:04,440 So in this case, notice what I've done, which is 1375 00:56:04,440 --> 00:56:05,870 flawed in my logic. 1376 00:56:05,870 --> 00:56:09,500 I have assigned s1 and s2 a value if i equals 1. 1377 00:56:09,500 --> 00:56:11,590 I've also done that if i equals 2. 1378 00:56:11,590 --> 00:56:13,710 But I haven't done it in the infinite number of other 1379 00:56:13,710 --> 00:56:14,690 possibilities-- 1380 00:56:14,690 --> 00:56:17,940 in particular, 3 or 4 or dot, dot, dot, 99. 1381 00:56:17,940 --> 00:56:20,100 So one fix for this could just be let's 1382 00:56:20,100 --> 00:56:22,190 have an else condition. 1383 00:56:22,190 --> 00:56:26,780 And let me go in here and say s1 equals-- 1384 00:56:26,780 --> 00:56:28,180 what should it be here? 1385 00:56:28,180 --> 00:56:28,750 AUDIENCE: [INAUDIBLE]. 1386 00:56:28,750 --> 00:56:30,460 >> DAVID J. MALAN: "Bottles", because in the common case, 1387 00:56:30,460 --> 00:56:32,020 it's just the same thing. 1388 00:56:32,020 --> 00:56:35,580 So equals quote, unquote, "bottles." So for plural 1389 00:56:35,580 --> 00:56:41,010 bottles, and then up here, for plural bottles. 1390 00:56:41,010 --> 00:56:44,580 Okay, so now let me go back to my terminal window, 1391 00:56:44,580 --> 00:56:47,200 recompile, re-run it. 1392 00:56:47,200 --> 00:56:48,440 99. 1393 00:56:48,440 --> 00:56:49,150 Whew. 1394 00:56:49,150 --> 00:56:50,610 And let's do a quick sanity check. 1395 00:56:50,610 --> 00:56:52,400 Technically, we'd want to read all of these to make sure 1396 00:56:52,400 --> 00:56:53,370 they're correct, but let's look at 1397 00:56:53,370 --> 00:56:54,640 least the known culprits. 1398 00:56:54,640 --> 00:56:57,370 3 bottles, 2 bottles, 2 bottles, 1 1399 00:56:57,370 --> 00:57:00,380 bottle, 1 bottle, 0 bottles. 1400 00:57:00,380 --> 00:57:03,080 We seem to have at least fixed it for now. 1401 00:57:03,080 --> 00:57:06,010 But the catch here is that what a god awful mess this is 1402 00:57:06,010 --> 00:57:07,470 just to solve a stupid 1403 00:57:07,470 --> 00:57:09,540 one-character grammatical detail. 1404 00:57:09,540 --> 00:57:11,150 So there's kind of a reason that I cut this corner 1405 00:57:11,150 --> 00:57:14,090 earlier, because it's just completely annoying to have to 1406 00:57:14,090 --> 00:57:15,020 write this much code. 1407 00:57:15,020 --> 00:57:17,530 But it turns out that there's slightly more elegant ways of 1408 00:57:17,530 --> 00:57:20,110 expressing the exact same thing. 1409 00:57:20,110 --> 00:57:22,040 And we can do this as follows. 1410 00:57:22,040 --> 00:57:23,890 >> Let me leave this on the screen for a moment and 1411 00:57:23,890 --> 00:57:27,320 introduce something known as a ternary operator. 1412 00:57:27,320 --> 00:57:29,600 This is kind of a one-liner that's just meant to make our 1413 00:57:29,600 --> 00:57:31,880 lives a little sexier, as promised. 1414 00:57:31,880 --> 00:57:33,130 And I'm going to do this as follows. 1415 00:57:33,130 --> 00:57:35,810 Give me a string called s1, and let me 1416 00:57:35,810 --> 00:57:37,200 assign it as follows. 1417 00:57:37,200 --> 00:57:39,900 (i == 1) ? 1418 00:57:39,900 --> 00:57:47,820 "bottle", otherwise "bottles". String s2 gets (i == 2) ? 1419 00:57:47,820 --> 00:57:52,670 "bottle", otherwise "bottles". 1420 00:57:52,670 --> 00:57:57,050 So what then is the difference here? 1421 00:57:57,050 --> 00:57:59,370 These two lines of code, I argue, can 1422 00:57:59,370 --> 00:58:02,200 replace this whole mess. 1423 00:58:02,200 --> 00:58:04,280 So I call it a mess, just because it kind of rubs me the 1424 00:58:04,280 --> 00:58:05,940 wrong way that it's so many lines of code. 1425 00:58:05,940 --> 00:58:06,650 Not wrong. 1426 00:58:06,650 --> 00:58:07,700 It's not bad design. 1427 00:58:07,700 --> 00:58:10,140 Like, this is perfectly correct and perfectly fine. 1428 00:58:10,140 --> 00:58:12,970 But coding gets tedious if you have to express yourself so 1429 00:58:12,970 --> 00:58:15,530 damn specifically again and again and again with a simple 1430 00:58:15,530 --> 00:58:16,620 scenario like this. 1431 00:58:16,620 --> 00:58:19,470 So C has some shortcuts, like this. 1432 00:58:19,470 --> 00:58:24,270 So this essentially is saying declare a string called s1 and 1433 00:58:24,270 --> 00:58:32,610 assign it either this value or this value if i is ==-- 1434 00:58:32,610 --> 00:58:35,290 sorry, I should say this more clearly. 1435 00:58:35,290 --> 00:58:41,680 Declare a variable s1, assign it this value if this is true. 1436 00:58:41,680 --> 00:58:44,280 Otherwise, assign it this value. 1437 00:58:44,280 --> 00:58:47,220 So in other words, this is sort of a one-line way of 1438 00:58:47,220 --> 00:58:51,490 saying if else but doing an assignment along the way. 1439 00:58:51,490 --> 00:58:55,540 So if i is 1, then go ahead and call this "bottle". And 1440 00:58:55,540 --> 00:58:59,830 then this else, call it "bottles". Meanwhile, s2, the 1441 00:58:59,830 --> 00:59:04,060 second word that we need to define, if i equals 2, we'll 1442 00:59:04,060 --> 00:59:08,350 set s2 to "bottle". Otherwise, set it to "bottles". And what 1443 00:59:08,350 --> 00:59:11,460 this means now is I can go through this and delete all of 1444 00:59:11,460 --> 00:59:12,860 those lines of code. 1445 00:59:12,860 --> 00:59:17,220 And when I say, somewhat ridiculously, that this is now 1446 00:59:17,220 --> 00:59:20,060 sexier, it's sexier in the sort of stylistic sense. 1447 00:59:20,060 --> 00:59:22,660 The fact that functionally, this code is actually going to 1448 00:59:22,660 --> 00:59:24,610 do the exact same thing. 1449 00:59:24,610 --> 00:59:26,890 And even though it might look a little cryptic at first 1450 00:59:26,890 --> 00:59:29,250 glance, because we've not seen this construct before, I'd 1451 00:59:29,250 --> 00:59:31,850 argue that it's ultimately going to be so much more 1452 00:59:31,850 --> 00:59:34,820 readable and so much easier for we humans to sort of 1453 00:59:34,820 --> 00:59:36,830 understand, because now you can just read the 1454 00:59:36,830 --> 00:59:38,830 code all on one line. 1455 00:59:38,830 --> 00:59:41,550 It's still similar in spirit to an if, where this is the 1456 00:59:41,550 --> 00:59:44,920 condition and then this is what's inside the if and this 1457 00:59:44,920 --> 00:59:46,480 is what's inside the else. 1458 00:59:46,480 --> 00:59:49,450 But we can do this just much more elegantly. 1459 00:59:49,450 --> 00:59:52,650 >> And if I now go back to my terminal, having deleted all 1460 00:59:52,650 --> 00:59:55,530 of those lines and replaced them with just those two, 1461 00:59:55,530 --> 01:00:00,150 recompile, re-run bottles of beer with 99, notice that my 1462 01:00:00,150 --> 01:00:03,350 grammar is, in fact, still correct. 1463 01:00:03,350 --> 01:00:06,160 So again, something to start. 1464 01:00:06,160 --> 01:00:08,840 2 bottles of beer, 1 bottle of beer. 1465 01:00:08,840 --> 01:00:09,370 Looks right. 1466 01:00:09,370 --> 01:00:10,100 Yeah. 1467 01:00:10,100 --> 01:00:13,900 So there we have a much more succinct solution. 1468 01:00:13,900 --> 01:00:16,020 So this, too, as you get more comfortable with C, not 1469 01:00:16,020 --> 01:00:18,630 necessarily with the first pset or even second, but 1470 01:00:18,630 --> 01:00:21,170 realize that these constructs can allow us to do things ever 1471 01:00:21,170 --> 01:00:22,810 more elegantly. 1472 01:00:22,810 --> 01:00:25,200 Now let's do one other thing here. 1473 01:00:25,200 --> 01:00:31,460 Let me go ahead and open up return1.c. 1474 01:00:31,460 --> 01:00:34,340 Now let's start to solve another problem in a way that 1475 01:00:34,340 --> 01:00:37,140 allows us to write more sophisticated code. 1476 01:00:37,140 --> 01:00:39,960 >> So here's a simple little program whose purpose in life 1477 01:00:39,960 --> 01:00:41,870 is to increment values. 1478 01:00:41,870 --> 01:00:43,100 And actually, let's take a step back. 1479 01:00:43,100 --> 01:00:44,400 Let me do this manually. 1480 01:00:44,400 --> 01:00:52,200 Let me do include and int main(void). 1481 01:00:52,200 --> 01:00:53,450 And let me call this increment.c. 1482 01:00:57,150 --> 01:00:58,570 And what do I want to do? 1483 01:00:58,570 --> 01:01:02,240 I'm going to go ahead and say something like-- 1484 01:01:02,240 --> 01:01:04,280 will we call the numbers the same-- 1485 01:01:04,280 --> 01:01:04,980 int x. 1486 01:01:04,980 --> 01:01:13,670 So int x gets 2; printf x is %d, new line, x. 1487 01:01:13,670 --> 01:01:16,780 So I'm typing fast, but sort of familiar stuff now. 1488 01:01:16,780 --> 01:01:18,830 Then I'm going to do x++. 1489 01:01:18,830 --> 01:01:21,710 Then I'm going to print that same sentence again. 1490 01:01:21,710 --> 01:01:24,550 And then I'm going to return 0 just to quit the program. 1491 01:01:24,550 --> 01:01:25,960 All right, so this is a program that 1492 01:01:25,960 --> 01:01:26,960 increments a number. 1493 01:01:26,960 --> 01:01:29,830 It's first going to initialize something to 2, and then it's 1494 01:01:29,830 --> 01:01:33,470 going to increment it and print it again. 1495 01:01:33,470 --> 01:01:36,930 >> So let's run increment, incredibly simple program. 1496 01:01:36,930 --> 01:01:40,940 But suppose now that I want to cube the value, so do 1497 01:01:40,940 --> 01:01:42,490 something somewhat arbitrary. 1498 01:01:42,490 --> 01:01:45,140 And I actually want to do x gets the cube of it. 1499 01:01:45,140 --> 01:01:47,570 So I could use what's called the pow function, but I don't 1500 01:01:47,570 --> 01:01:48,650 really know where that is yet. 1501 01:01:48,650 --> 01:01:50,580 So I'm going to do this the old-fashioned way. 1502 01:01:50,580 --> 01:01:54,550 x times this equals x times x times x. 1503 01:01:54,550 --> 01:01:56,880 So I'm cubing the value, multiplying it by itself again 1504 01:01:56,880 --> 01:02:00,440 and again and again, so that we get the power 1505 01:02:00,440 --> 01:02:02,050 of 3 in this case. 1506 01:02:02,050 --> 01:02:06,000 So now the numbers I should print should be, as we'll see 1507 01:02:06,000 --> 01:02:08,450 here--make increment, so it's actually not really increment 1508 01:02:08,450 --> 01:02:10,260 anymore, but we'll leave the name alone-- 1509 01:02:10,260 --> 01:02:11,590 2 and then 8. 1510 01:02:11,590 --> 01:02:17,670 Now, we have the beginnings of an opportunity for refinement 1511 01:02:17,670 --> 01:02:21,570 here, whereby this cubing thing of multiplying a number 1512 01:02:21,570 --> 01:02:24,680 by itself by itself by itself feels like this might just be 1513 01:02:24,680 --> 01:02:27,920 useful to have as a function, much like someone decided 1514 01:02:27,920 --> 01:02:30,430 years ago--you know, kind of useful if one of us sits down 1515 01:02:30,430 --> 01:02:33,120 and writes printf so that the rest of the world can use it, 1516 01:02:33,120 --> 01:02:36,160 why don't we sit down and write a function called cube 1517 01:02:36,160 --> 01:02:39,250 that does this cubing for us so we don't have to manually 1518 01:02:39,250 --> 01:02:41,500 implement the notion of cubing values here? 1519 01:02:41,500 --> 01:02:44,040 >> So a simple example, but let's go ahead and use this is as an 1520 01:02:44,040 --> 01:02:46,280 opportunity to write our own function. 1521 01:02:46,280 --> 01:02:49,110 So thus far, we've only used main, and we've used other 1522 01:02:49,110 --> 01:02:51,780 people's functions, but we haven't written our own. 1523 01:02:51,780 --> 01:02:52,650 So here we go. 1524 01:02:52,650 --> 01:02:56,330 I'm going to go ahead and write a function called cube. 1525 01:02:56,330 --> 01:02:58,490 And I'm going to have it take an input. 1526 01:02:58,490 --> 01:03:02,070 So its input is going to be an integer. 1527 01:03:02,070 --> 01:03:03,570 And what is it going to do? 1528 01:03:03,570 --> 01:03:08,500 It's going to declare int output = input times input 1529 01:03:08,500 --> 01:03:09,880 times input. 1530 01:03:09,880 --> 01:03:12,190 And then it's going to return that output. 1531 01:03:12,190 --> 01:03:14,500 And then I have to be specific now. 1532 01:03:14,500 --> 01:03:16,820 This function is going to return an int. 1533 01:03:16,820 --> 01:03:19,130 So here then is how you'd write your own functions. 1534 01:03:19,130 --> 01:03:20,850 You first decide what's the name of your 1535 01:03:20,850 --> 01:03:21,720 function going to be. 1536 01:03:21,720 --> 01:03:23,964 And generally, something explanatory is good, so I'll 1537 01:03:23,964 --> 01:03:25,060 call it cube. 1538 01:03:25,060 --> 01:03:27,180 Then you have to specify what it's going to return, what's 1539 01:03:27,180 --> 01:03:28,240 its output going to be. 1540 01:03:28,240 --> 01:03:29,595 And we don't have that many options yet. 1541 01:03:29,595 --> 01:03:32,260 Int, char, float, bool, string. 1542 01:03:32,260 --> 01:03:34,260 For now, I'm going to stick with an int, because I want it 1543 01:03:34,260 --> 01:03:35,880 to return an integer. 1544 01:03:35,880 --> 01:03:38,770 Then you have to specify what its inputs, if any, are. 1545 01:03:38,770 --> 01:03:41,570 And if cube takes an argument, takes something between 1546 01:03:41,570 --> 01:03:44,970 parentheses, you have to give that argument a name so that 1547 01:03:44,970 --> 01:03:47,860 you can call it something as you're implementing or writing 1548 01:03:47,860 --> 01:03:50,550 this function, and you have to give it a type, which in this 1549 01:03:50,550 --> 01:03:51,810 case is going to be int. 1550 01:03:51,810 --> 01:03:54,690 So in short, cube is a function that takes an integer 1551 01:03:54,690 --> 01:03:57,560 as input and returns an integer as output. 1552 01:03:57,560 --> 01:03:59,240 >> So what does it do with that input? 1553 01:03:59,240 --> 01:04:03,710 Well, in line 14, I declare a variable called output, and I 1554 01:04:03,710 --> 01:04:07,410 assign it the value, input times input times input. 1555 01:04:07,410 --> 01:04:11,490 And then I return output. 1556 01:04:11,490 --> 01:04:14,890 So how do I use this then? 1557 01:04:14,890 --> 01:04:19,210 What do I change these highlighted characters on line 1558 01:04:19,210 --> 01:04:21,006 7 to be, do you think? 1559 01:04:21,006 --> 01:04:21,800 AUDIENCE: [INAUDIBLE]. 1560 01:04:21,800 --> 01:04:25,570 DAVID J. MALAN: Yeah, so cube of x. 1561 01:04:25,570 --> 01:04:28,290 So x is a variable, which means it holds some value. 1562 01:04:28,290 --> 01:04:30,190 Fortunately, it's of type integer. 1563 01:04:30,190 --> 01:04:34,280 And because x is an int, that means I can pass it into cube. 1564 01:04:34,280 --> 01:04:39,500 And even though I'm overriding the value of x with the value 1565 01:04:39,500 --> 01:04:42,780 of cube x, as has been the case thus far, any time you 1566 01:04:42,780 --> 01:04:46,150 have equal sign and a line of code, the stuff on the right 1567 01:04:46,150 --> 01:04:49,090 gets executed and then gets assigned to the 1568 01:04:49,090 --> 01:04:50,150 value on the left. 1569 01:04:50,150 --> 01:04:52,950 So the order of operations is as we would hope. 1570 01:04:52,950 --> 01:04:56,620 So does this work? 1571 01:04:56,620 --> 01:04:58,410 Well, let me go down here. 1572 01:04:58,410 --> 01:04:59,970 Let me open up my terminal window. 1573 01:04:59,970 --> 01:05:03,610 Let me do make increment, Enter. 1574 01:05:03,610 --> 01:05:07,140 "Implicit declaration of function 'cube' is invalid in 1575 01:05:07,140 --> 01:05:13,700 C99." As an aside, C99 refers to the language C as it was 1576 01:05:13,700 --> 01:05:16,790 defined in 1999, which was an update over the version from 1577 01:05:16,790 --> 01:05:19,360 1989, which is an update over the original. 1578 01:05:19,360 --> 01:05:21,740 So that's all that means. 1579 01:05:21,740 --> 01:05:24,250 >> So what does it mean that "implicit declaration of 1580 01:05:24,250 --> 01:05:26,790 function 'cube' is invalid?" It's right here. 1581 01:05:26,790 --> 01:05:28,430 It's right there in line 12. 1582 01:05:28,430 --> 01:05:30,460 AUDIENCE: [INAUDIBLE]. 1583 01:05:30,460 --> 01:05:30,730 DAVID J. MALAN: What's that? 1584 01:05:30,730 --> 01:05:32,470 AUDIENCE: It's not before. 1585 01:05:32,470 --> 01:05:33,540 DAVID J. MALAN: It's not before. 1586 01:05:33,540 --> 01:05:34,740 So this is the thing. 1587 01:05:34,740 --> 01:05:38,190 C is kind of stupid, or C compilers are kind of stupid. 1588 01:05:38,190 --> 01:05:41,060 They really only do what you tell them to do. 1589 01:05:41,060 --> 01:05:44,770 And they, in particular, only read your code top to bottom, 1590 01:05:44,770 --> 01:05:45,620 left to right. 1591 01:05:45,620 --> 01:05:49,140 So if the compiler, Clang, is reading your code, line 1, it 1592 01:05:49,140 --> 01:05:50,120 figures out how to do this. 1593 01:05:50,120 --> 01:05:50,940 Oh, here comes main. 1594 01:05:50,940 --> 01:05:53,000 Okay, let me go ahead and declare a variable x. 1595 01:05:53,000 --> 01:05:54,160 Let me print something. 1596 01:05:54,160 --> 01:05:55,890 Line 7, what the heck is cube? 1597 01:05:55,890 --> 01:05:58,230 It's not declared in stdio.h. 1598 01:05:58,230 --> 01:06:00,950 It doesn't come with C. I have no idea what to do. 1599 01:06:00,950 --> 01:06:03,960 And so Clang just bails and quits with that error message. 1600 01:06:03,960 --> 01:06:05,850 So we can fix this in a couple of ways. 1601 01:06:05,850 --> 01:06:10,530 We can teach Clang what cube is by just moving where the 1602 01:06:10,530 --> 01:06:11,820 declaration is. 1603 01:06:11,820 --> 01:06:14,640 So I cut and pasted it atop main. 1604 01:06:14,640 --> 01:06:17,770 Now realize that just because main is no longer first, it's 1605 01:06:17,770 --> 01:06:19,150 still executed by default. 1606 01:06:19,150 --> 01:06:20,060 Main is main. 1607 01:06:20,060 --> 01:06:21,022 It's the default function name. 1608 01:06:21,022 --> 01:06:22,930 It doesn't matter where it is in a file. 1609 01:06:22,930 --> 01:06:26,910 But at least now Clang has seen cube before I use it. 1610 01:06:26,910 --> 01:06:28,500 So let's see if Clang is happier now. 1611 01:06:28,500 --> 01:06:31,410 Make increment, it did compile this time. 1612 01:06:31,410 --> 01:06:33,060 >> Let me run increment. 1613 01:06:33,060 --> 01:06:34,810 And indeed, it seems to be working. 1614 01:06:34,810 --> 01:06:36,810 Now, you can come up with scenarios eventually where 1615 01:06:36,810 --> 01:06:38,650 it's not feasible to put every function 1616 01:06:38,650 --> 01:06:39,740 above every other function. 1617 01:06:39,740 --> 01:06:42,140 You'll get stuck in this infinite loop in reality, 1618 01:06:42,140 --> 01:06:43,480 where this guy wants to be here but this 1619 01:06:43,480 --> 01:06:44,390 guy needs to be there. 1620 01:06:44,390 --> 01:06:45,830 So that doesn't always work. 1621 01:06:45,830 --> 01:06:49,020 So thankfully, C has a more elegant solution. 1622 01:06:49,020 --> 01:06:50,790 I'm going to put this back where it was, just because I 1623 01:06:50,790 --> 01:06:53,390 prefer, as a matter of principle, that main always be 1624 01:06:53,390 --> 01:06:55,550 at the top, because it's just nice to see what this program 1625 01:06:55,550 --> 01:06:56,920 does by default. 1626 01:06:56,920 --> 01:06:58,950 And what I'm going to do up here is declare what's called 1627 01:06:58,950 --> 01:07:00,250 a prototype. 1628 01:07:00,250 --> 01:07:05,730 I'm going to re-declare my cube function by literally 1629 01:07:05,730 --> 01:07:07,180 copying and pasting. 1630 01:07:07,180 --> 01:07:08,290 Actually, that's not literally. 1631 01:07:08,290 --> 01:07:13,060 So literally copying and pasting line 15 1632 01:07:13,060 --> 01:07:15,160 up above line 6. 1633 01:07:15,160 --> 01:07:17,010 It doesn't matter what line this ends up on. 1634 01:07:17,010 --> 01:07:18,380 It happens to be on line 4. 1635 01:07:18,380 --> 01:07:19,950 But it does have to be before main. 1636 01:07:19,950 --> 01:07:21,150 But notice the difference. 1637 01:07:21,150 --> 01:07:24,100 Line 4 ends with a semicolon, which means hey, 1638 01:07:24,100 --> 01:07:27,510 Clang, take my word for it that there exists a function 1639 01:07:27,510 --> 01:07:31,350 called cube that takes an int and returns an int. 1640 01:07:31,350 --> 01:07:33,020 But I'm not gonna tell you what it is yet. 1641 01:07:33,020 --> 01:07:35,180 Just know that I promise to tell you eventually. 1642 01:07:35,180 --> 01:07:38,490 And indeed, now it's okay that this is down below. 1643 01:07:38,490 --> 01:07:41,275 >> So this is generally better, because then at the top of 1644 01:07:41,275 --> 01:07:44,240 your file, you can just rattle off, rapid-fire, one line 1645 01:07:44,240 --> 01:07:46,470 each, what the names of your functions are, what their 1646 01:07:46,470 --> 01:07:49,120 inputs are, what their outputs are. 1647 01:07:49,120 --> 01:07:52,210 And to be more clear, input generally means argument or 1648 01:07:52,210 --> 01:07:54,110 parameter, synonymous. 1649 01:07:54,110 --> 01:07:56,890 Output means return value, what does it 1650 01:07:56,890 --> 01:07:58,700 hand back to me. 1651 01:07:58,700 --> 01:08:03,420 So in this case here, cube has been declared at the top, but 1652 01:08:03,420 --> 01:08:06,940 defined, otherwise known as implemented, at the bottom. 1653 01:08:06,940 --> 01:08:09,620 So now let's go back here and re-run this. 1654 01:08:09,620 --> 01:08:13,430 So now let me go ahead and re-run make, re-run increment. 1655 01:08:13,430 --> 01:08:16,500 And it now seems to be working just fine. 1656 01:08:16,500 --> 01:08:19,450 So now we can go ahead and factor out something like the 1657 01:08:19,450 --> 01:08:23,720 beer example into this fourth version. 1658 01:08:23,720 --> 01:08:25,590 So let me scroll down here. 1659 01:08:25,590 --> 01:08:28,149 And notice that I kind of took this lesson to heart just now. 1660 01:08:28,149 --> 01:08:31,140 The fact that I was singing the same stanza again and 1661 01:08:31,140 --> 01:08:34,130 again and again, the same chorus line in the song, felt 1662 01:08:34,130 --> 01:08:36,439 like why don't I factor that out into a function? 1663 01:08:36,439 --> 01:08:38,470 And indeed, this should be one of the motivations. 1664 01:08:38,470 --> 01:08:40,960 Besides the fact that someone else in the world might want 1665 01:08:40,960 --> 01:08:42,390 to use a cube function-- 1666 01:08:42,390 --> 01:08:44,560 that's a good reason to factor something out and write your 1667 01:08:44,560 --> 01:08:45,720 own custom function-- 1668 01:08:45,720 --> 01:08:48,720 if there's a chunk of code in your program that just makes 1669 01:08:48,720 --> 01:08:51,370 conceptual sense, that you kind of want to give it a 1670 01:08:51,370 --> 01:08:53,740 name-- like in this case, chorus-- 1671 01:08:53,740 --> 01:08:57,380 then you can similarly write that as a separate function. 1672 01:08:57,380 --> 01:08:59,560 You don't have to write everything in main if it just 1673 01:08:59,560 --> 01:09:02,609 feels cleaner to separate it out and give it a name. 1674 01:09:02,609 --> 01:09:05,529 >> So in this case here, notice that I have a comment atop 1675 01:09:05,529 --> 01:09:06,859 this function that just sings about the 1676 01:09:06,859 --> 01:09:08,630 specified numbers of bottles. 1677 01:09:08,630 --> 01:09:10,609 Notice here that I don't need to call these 1678 01:09:10,609 --> 01:09:12,520 things input and output. 1679 01:09:12,520 --> 01:09:16,090 In fact, this time I just called my input b for bottle. 1680 01:09:16,090 --> 01:09:19,960 And notice here, void suggests what? 1681 01:09:19,960 --> 01:09:21,309 That chorus-- 1682 01:09:21,309 --> 01:09:22,660 AUDIENCE: Doesn't return it. 1683 01:09:22,660 --> 01:09:23,870 DAVID J. MALAN: Doesn't return a value. 1684 01:09:23,870 --> 01:09:26,800 And indeed, functions don't have to return values. 1685 01:09:26,800 --> 01:09:28,060 They can just do something. 1686 01:09:28,060 --> 01:09:30,270 They can have what are called side effects, which in this 1687 01:09:30,270 --> 01:09:33,109 case is just a whole bunch of printing on the screen. 1688 01:09:33,109 --> 01:09:36,580 So notice that this code here, I literally just stole from 1689 01:09:36,580 --> 01:09:37,680 the previous example. 1690 01:09:37,680 --> 01:09:39,930 The only difference is instead of using i as my 1691 01:09:39,930 --> 01:09:42,890 variable, I'm now using b as my variable. 1692 01:09:42,890 --> 01:09:45,880 So I have b down here, I have b down here, I have b 1693 01:09:45,880 --> 01:09:47,109 minus 1 down here. 1694 01:09:47,109 --> 01:09:49,279 But the code is exactly the same. 1695 01:09:49,279 --> 01:09:52,529 But just to show you now how we can use this, let me go 1696 01:09:52,529 --> 01:09:56,780 ahead and actually change this to be a for loop. 1697 01:09:56,780 --> 01:10:03,850 for (int i = n; i > n; i--). 1698 01:10:03,850 --> 01:10:06,230 >> So I've stolen that from our previous example. 1699 01:10:06,230 --> 01:10:08,970 Previously, it's in line 37 that I would have started 1700 01:10:08,970 --> 01:10:10,640 singing this annoying song. 1701 01:10:10,640 --> 01:10:15,810 But instead, I'm just going to now call chorus of i. 1702 01:10:15,810 --> 01:10:16,870 Done. 1703 01:10:16,870 --> 01:10:20,260 So now in every iteration of this loop, I call this other 1704 01:10:20,260 --> 01:10:22,220 function, chorus, that I happened to write. 1705 01:10:22,220 --> 01:10:24,110 It wasn't written by someone else years ago. 1706 01:10:24,110 --> 01:10:27,930 But chorus, meanwhile, uses printf to print 1707 01:10:27,930 --> 01:10:29,840 out these four lines. 1708 01:10:29,840 --> 01:10:32,720 But the fact that I'm calling chorus again and again in a 1709 01:10:32,720 --> 01:10:35,900 loop means that I'm going to get, at the very end, the 1710 01:10:35,900 --> 01:10:39,310 exact same song as I have thus far. 1711 01:10:39,310 --> 01:10:42,130 So in short, now if I look back at my code, even though 1712 01:10:42,130 --> 01:10:44,240 functionally this is equivalent, notice that it's 1713 01:10:44,240 --> 01:10:46,020 starting to get even more readable. 1714 01:10:46,020 --> 01:10:48,410 I don't exactly know how GetInt 1715 01:10:48,410 --> 01:10:49,250 is implemented. 1716 01:10:49,250 --> 01:10:52,050 Frankly, I don't know how chorus is implemented. 1717 01:10:52,050 --> 01:10:52,970 But it doesn't matter to me. 1718 01:10:52,970 --> 01:10:55,620 I don't care, because now I can sort of, as a human, read 1719 01:10:55,620 --> 01:10:57,050 this from top to bottom. 1720 01:10:57,050 --> 01:10:59,950 And because the functions are named according to what they 1721 01:10:59,950 --> 01:11:02,910 do, my code is increasingly readable. 1722 01:11:02,910 --> 01:11:05,190 And as our programs get much more complex-- 1723 01:11:05,190 --> 01:11:07,220 by the semester's end, you'll be writing hundreds of lines 1724 01:11:07,220 --> 01:11:10,970 of code in languages like PHP and JavaScript and the like-- 1725 01:11:10,970 --> 01:11:13,550 you'll find that it's so much easier than to keep track of 1726 01:11:13,550 --> 01:11:14,080 what you've done. 1727 01:11:14,080 --> 01:11:15,810 And when you start collaborating with friends or 1728 01:11:15,810 --> 01:11:19,010 partners or colleagues, you'll be able to write much more 1729 01:11:19,010 --> 01:11:22,910 massive programs by starting to exercise these basic 1730 01:11:22,910 --> 01:11:23,990 building blocks. 1731 01:11:23,990 --> 01:11:25,550 >> So with that said, why don't we call it a day? 1732 01:11:25,550 --> 01:11:27,190 And we will see you on Wednesday. 1733 01:11:27,190 --> 01:11:33,611 [APPLAUSE]