1 00:00:00,506 --> 00:00:08,516 [ Silence ] 2 00:00:09,016 --> 00:00:09,083 [ Inaudible Discussions ] 3 00:00:10,176 --> 00:00:13,436 >> Alright, welcome back, this is CS50 4 00:00:13,436 --> 00:00:16,106 and this is the start of week 3. 5 00:00:16,106 --> 00:00:18,766 So in addition to this bit of geek humor today, 6 00:00:19,016 --> 00:00:20,316 I thought I'd share an e-mail 7 00:00:20,356 --> 00:00:22,516 that someone not even taking CS50 8 00:00:22,516 --> 00:00:25,456 but nonetheless an undergrad sent to me the other day 9 00:00:25,456 --> 00:00:26,366 that I thought you'd enjoy. 10 00:00:27,516 --> 00:00:29,916 [ Noise ] 11 00:00:30,416 --> 00:00:32,816 [ Laughter ] 12 00:00:33,316 --> 00:00:37,536 >> Okay. Anyhow, I don't normally share your e-mails 13 00:00:37,536 --> 00:00:39,936 publicly in senders but this one was good. 14 00:00:39,936 --> 00:00:41,986 So just a quad full rapid fire announcements, so one, 15 00:00:41,986 --> 00:00:46,046 if you still have a Scratch 4 from hacker, the Hacker Edition 16 00:00:46,046 --> 00:00:48,056 of problem set 0, please sometime this week, 17 00:00:48,096 --> 00:00:49,656 drop it off with one of the teaching fellows 18 00:00:49,656 --> 00:00:50,896 or CAs off to the corner. 19 00:00:51,486 --> 00:00:53,786 Sections were announced this weekend and are already 20 00:00:53,786 --> 00:00:55,216 in progress as of yesterday, 21 00:00:55,216 --> 00:00:56,646 realize that if you have a conflict 22 00:00:56,646 --> 00:00:58,506 and this always happens 'cause things get shuffled 23 00:00:58,506 --> 00:00:59,106 around on you. 24 00:00:59,356 --> 00:01:02,576 Just go to this URL, submit a request if you haven't already 25 00:01:02,576 --> 00:01:05,126 and if for some reason we seem to have forgotten about you, 26 00:01:05,366 --> 00:01:07,926 just e-mail sectioning at CS50.net and Matt 27 00:01:08,026 --> 00:01:11,566 and Rob will be sure to follow up. 28 00:01:11,566 --> 00:01:14,186 So another lunch, it actually went well last Friday. 29 00:01:14,186 --> 00:01:15,106 We thought we'd do it again. 30 00:01:15,106 --> 00:01:18,276 So if you would like to join me in some of the TFs and CAs, 31 00:01:18,276 --> 00:01:23,106 CS50.net/RSVP that's this Friday at 1:15 p.m. And again, 32 00:01:23,106 --> 00:01:26,296 we'll vary the times and days over time, 33 00:01:26,436 --> 00:01:28,366 and then office hours. 34 00:01:28,366 --> 00:01:29,546 So Wednesday office hours 35 00:01:29,546 --> 00:01:31,366 in particular have proved to be quite popular. 36 00:01:31,366 --> 00:01:33,556 So we thought we would expand the program 37 00:01:33,556 --> 00:01:35,936 to include our friends from Quincy House. 38 00:01:36,016 --> 00:01:39,216 So on Wednesdays now, office hours will be in Quincy House 39 00:01:39,496 --> 00:01:42,076 and then as usual [inaudible] tonight, Leverett tomorrow, 40 00:01:42,076 --> 00:01:44,386 Lowell House on Thursday. 41 00:01:44,386 --> 00:01:46,176 The schedule's always on the course's website. 42 00:01:46,666 --> 00:01:50,236 Also to satiate the appetites of those 10 percent of you 43 00:01:50,236 --> 00:01:51,486 who are among those more comfortable, 44 00:01:51,486 --> 00:01:53,346 what we thought we would do is try 45 00:01:53,346 --> 00:01:56,626 and experiment whereby we fork off some hacker-specific office 46 00:01:56,626 --> 00:01:58,916 hours that will offer somewhere on campus. 47 00:01:58,916 --> 00:01:59,926 We're still sorting out the details. 48 00:01:59,926 --> 00:02:02,256 But for those of you who are diving into the Hacker Edition 49 00:02:02,256 --> 00:02:04,416 of this week's P-set and next and so forth, 50 00:02:04,726 --> 00:02:06,626 realize that this will be an opportunity 51 00:02:06,626 --> 00:02:09,436 in a more intimate setting to just sit back and sit 52 00:02:09,536 --> 00:02:11,346 across the table from some 53 00:02:11,346 --> 00:02:14,926 of our hacker-type teaching fellows, and ask any 54 00:02:14,926 --> 00:02:17,256 and all questions that might arise during the evening. 55 00:02:17,256 --> 00:02:18,916 But we'll focus on the standard edition 56 00:02:18,916 --> 00:02:21,116 at regularly scheduled office hours. 57 00:02:21,656 --> 00:02:24,886 So great, P-set 0 is now on progress, 58 00:02:24,886 --> 00:02:28,306 now that we've assigned TFs and P-set 1 will also be returned. 59 00:02:28,546 --> 00:02:30,796 You'll hear about this from your teaching fellows via e-mail 60 00:02:30,796 --> 00:02:32,726 over the next few days and thereafter. 61 00:02:32,726 --> 00:02:34,986 Now that we have sections assigned, we'll be on track 62 00:02:34,986 --> 00:02:37,086 to return feedback typically within just 1 week. 63 00:02:37,086 --> 00:02:39,346 It's just start of term where we insert this delay 64 00:02:39,346 --> 00:02:40,546 because of lack of sectioning. 65 00:02:41,046 --> 00:02:41,806 And now a request, 66 00:02:42,236 --> 00:02:45,946 so help.CS50.net has proved hopefully actually helpful 67 00:02:45,986 --> 00:02:50,176 for you, but realize that we can do best by you if you provide us 68 00:02:50,176 --> 00:02:52,436 with more detail than is sometimes there. 69 00:02:52,436 --> 00:02:55,736 So writing us notes, however sweet that pretty much boil 70 00:02:55,736 --> 00:02:59,326 down to it doesn't work isn't enough for us to go on, 71 00:02:59,326 --> 00:03:01,376 so honestly, please, do get in to the habit. 72 00:03:01,376 --> 00:03:03,326 Anytime you pose a question of us, 73 00:03:03,616 --> 00:03:05,296 state exactly what the problem is, 74 00:03:05,296 --> 00:03:06,566 like what are symptoms you're seeing, 75 00:03:06,566 --> 00:03:08,106 what is the specific error message? 76 00:03:08,106 --> 00:03:10,716 Don't just say I'm seeing an error message 'cause it's 77 00:03:10,956 --> 00:03:13,476 enormously useful for us to know what error message. 78 00:03:13,716 --> 00:03:16,866 And then also, what have you tried, what has not worked, 79 00:03:16,866 --> 00:03:19,276 what operating system are you using, if it's germane 80 00:03:19,276 --> 00:03:20,256 to the appliance itself? 81 00:03:20,386 --> 00:03:23,136 In short, just try to provide us with as much detail so that 82 00:03:23,136 --> 00:03:25,276 when we reply to you, we don't have a questions mark, 83 00:03:25,276 --> 00:03:28,016 we actually have an answer in the insurance of efficiency. 84 00:03:28,506 --> 00:03:31,816 With that said, our goal is indeed to return e-mails 85 00:03:31,816 --> 00:03:34,686 within 24 hours as best we can and we're doing okay. 86 00:03:34,806 --> 00:03:37,226 These are the statistics from last week whereby 87 00:03:37,226 --> 00:03:41,476 over 200 questions were answered between 0 and 1 hour is there. 88 00:03:41,476 --> 00:03:43,916 The gray bars are last week, the green bars are this week. 89 00:03:43,956 --> 00:03:45,486 So the number of questions is increasing. 90 00:03:45,826 --> 00:03:48,276 Some questions took us 1 to 4 hours as denoted 91 00:03:48,276 --> 00:03:49,356 by the second green bar. 92 00:03:49,686 --> 00:03:51,756 Four to 8, 8 to 12 dot, dot, 93 00:03:51,906 --> 00:03:54,026 dot and then we accidentally left one person hanging 94 00:03:54,026 --> 00:03:55,176 for like 2 days by accident. 95 00:03:55,386 --> 00:03:59,536 But that wasn't anomaly, so realize our goal is to respond 96 00:03:59,846 --> 00:04:01,926 as quickly as possible. 97 00:04:02,416 --> 00:04:07,366 So today, is of again about security in this domain 98 00:04:07,366 --> 00:04:09,976 and then also about C and what I thought I'd do is draw our 99 00:04:09,976 --> 00:04:11,136 attention to a file. 100 00:04:11,136 --> 00:04:13,166 We actually included in last week's source code, 101 00:04:13,166 --> 00:04:14,516 really just to peak curiosity. 102 00:04:14,516 --> 00:04:17,736 It's way more sophisticated that the point at which we're at now. 103 00:04:18,036 --> 00:04:21,996 But back in 2007, it was the day or so before CS50 lecture 104 00:04:21,996 --> 00:04:25,406 when the first jailbreak code was released for the iPhone. 105 00:04:25,406 --> 00:04:28,476 Jailbreaking generally means to hack an iPhone is such a way 106 00:04:28,476 --> 00:04:30,586 that you don't have to use it on AT&T 107 00:04:30,586 --> 00:04:32,926 or you can install unauthorized software on it. 108 00:04:33,066 --> 00:04:34,996 Or just generally reclaim control 109 00:04:34,996 --> 00:04:37,176 of the phone that's otherwise pretty locked down by Apple. 110 00:04:37,386 --> 00:04:39,526 And what was fun at the time and fast forward to today, 111 00:04:39,736 --> 00:04:41,176 is that it was actually implemented 112 00:04:41,176 --> 00:04:42,806 that first hack in C-code. 113 00:04:42,806 --> 00:04:45,076 And so if you're just curious to see how something 114 00:04:45,076 --> 00:04:46,916 like this might work, I've just opened 115 00:04:46,916 --> 00:04:50,996 in G edit a file called iunlock.c and scrolling 116 00:04:50,996 --> 00:04:52,056 down through this file, 117 00:04:52,056 --> 00:04:54,726 you'll see that even though there's a lot of new stuff, 118 00:04:54,876 --> 00:04:56,386 you'll see some familiar syntax, 119 00:04:56,386 --> 00:04:59,396 sharp include apparently not just standard I/O though, 120 00:04:59,396 --> 00:05:01,166 but some other files in there as well. 121 00:05:01,166 --> 00:05:03,306 And if you scroll down you'll see some things we'll get 122 00:05:03,306 --> 00:05:05,666 to in a few weeks, strucs and so forth. 123 00:05:05,926 --> 00:05:08,696 But here we have void, here we have the name of some function 124 00:05:08,696 --> 00:05:11,496 "int i" and so, some of this should certainly be 125 00:05:11,496 --> 00:05:12,646 readable already. 126 00:05:12,646 --> 00:05:15,076 And it's probably not something worth understanding its 127 00:05:15,076 --> 00:05:18,426 entirety, but perhaps it does relate the real world media 128 00:05:18,426 --> 00:05:21,636 and things you hear about like jailbreaking to the kinds 129 00:05:21,636 --> 00:05:23,656 of things that we are actually doing. 130 00:05:23,946 --> 00:05:25,666 I'm also speaking of security. 131 00:05:25,946 --> 00:05:28,146 I went through my spam folder which is always fun 132 00:05:28,146 --> 00:05:29,506 and I thought I would try 133 00:05:29,626 --> 00:05:32,006 to share not just our own student's e-mail 134 00:05:32,276 --> 00:05:33,296 but this one here. 135 00:05:33,936 --> 00:05:35,906 So it's not particularly helpful 136 00:05:35,906 --> 00:05:37,166 to read the entirety of this thing. 137 00:05:37,476 --> 00:05:39,066 But the immediate takeaway should be do not click 138 00:05:39,256 --> 00:05:40,956 on any links in an e-mail like this. 139 00:05:41,546 --> 00:05:44,056 As you will see towards semester's end, it is trivial 140 00:05:44,056 --> 00:05:46,566 to write a program that actually sends e-mail. 141 00:05:46,996 --> 00:05:49,176 It's trivial to write a program that sends e-mail 142 00:05:49,176 --> 00:05:50,516 as though it's from your roommates. 143 00:05:50,916 --> 00:05:52,746 And so you see a lot of spam 144 00:05:52,746 --> 00:05:55,386 on the internet that's also customized in such a way 145 00:05:55,386 --> 00:05:58,616 that it seems to be from your own mail server's domain. 146 00:05:58,616 --> 00:06:00,386 This piece of spam here specifically 147 00:06:00,386 --> 00:06:02,306 mentions college.harvard.edu. 148 00:06:02,306 --> 00:06:06,106 Well, it's really not hard to spam every possible username 149 00:06:06,106 --> 00:06:09,106 within college.harvard.edu with something like this. 150 00:06:09,106 --> 00:06:12,456 Generally known as a phising attack, the idea being trying 151 00:06:12,456 --> 00:06:15,896 to hook unsuspecting users into clicking a link that, 152 00:06:15,896 --> 00:06:18,336 Click Here, and what generally happens once you've 153 00:06:18,516 --> 00:06:21,196 clicked there. 154 00:06:21,446 --> 00:06:23,686 So a virus, some kind of file gets downloaded 155 00:06:23,686 --> 00:06:24,916 on to your computer, especially 156 00:06:24,916 --> 00:06:28,266 if it's a PC it could be some form that says, 157 00:06:28,336 --> 00:06:31,126 please provide your username and password, that website 158 00:06:31,126 --> 00:06:33,576 that you end up at, might even look identical 159 00:06:33,576 --> 00:06:35,346 to college.harvard.edu. 160 00:06:35,346 --> 00:06:38,086 But as we'll see in a few weeks, it's really not that hard to go 161 00:06:38,086 --> 00:06:39,926 to college.harvard.edu. 162 00:06:40,186 --> 00:06:43,116 Look at its HTML source code, the language 163 00:06:43,116 --> 00:06:45,406 in which webpages are written and copy and paste it 164 00:06:45,406 --> 00:06:47,466 into your own bad guys website in voila, 165 00:06:47,786 --> 00:06:50,336 you now have your own copy of college.harvard.edu. 166 00:06:50,336 --> 00:06:52,406 So a lot of fun stuff there on the horizon. 167 00:06:52,736 --> 00:06:55,976 As an aside, I'm reminded of my own freshman year, 168 00:06:55,976 --> 00:06:57,266 when I first discovered this trick 169 00:06:57,266 --> 00:06:59,366 where you can send an e-mail as anyone on the internet. 170 00:06:59,366 --> 00:07:01,576 It doesn't have to be your own actual e-mail account. 171 00:07:01,986 --> 00:07:04,786 And so of course, my proctor mates and I were engaged 172 00:07:04,786 --> 00:07:07,696 in some stupid argument over e-mail within math use 173 00:07:07,696 --> 00:07:11,306 and I decided to be the ever so witty one and send a reply 174 00:07:11,686 --> 00:07:14,446 from the opposing argument side essentially conceding 175 00:07:14,446 --> 00:07:16,206 to what ever stupid argument we were having. 176 00:07:16,636 --> 00:07:18,536 Unfortunately, I wasn't so good with computers 177 00:07:18,696 --> 00:07:21,566 and I accidentally left my signature enabled 178 00:07:22,146 --> 00:07:25,896 in the e-mail client so there was this dear proctor mates, 179 00:07:25,896 --> 00:07:27,706 dot, dot, dot, I now agree with such 180 00:07:27,706 --> 00:07:29,736 and such signed proctor mates, DJM. 181 00:07:30,686 --> 00:07:32,576 So, kind of an idiot. 182 00:07:32,576 --> 00:07:35,306 So in any case, we'll see how to do this and has-- 183 00:07:35,476 --> 00:07:37,996 actually how to do it well so that it serves you 184 00:07:37,996 --> 00:07:39,636 for good purposes and not that. 185 00:07:40,226 --> 00:07:41,656 This stuff too, and this should-- 186 00:07:41,656 --> 00:07:42,936 this is really just a silly one. 187 00:07:42,936 --> 00:07:46,196 Anytime you see domain name ending in 0LX.net, 188 00:07:46,236 --> 00:07:47,896 this too should be a tell. 189 00:07:47,896 --> 00:07:48,726 And later in this semester, 190 00:07:48,726 --> 00:07:51,036 we'll talk about other signs frankly 191 00:07:51,036 --> 00:07:54,496 of security potential breaches, but realize too, 192 00:07:54,496 --> 00:07:56,356 this is a fascinating numbers game, right. 193 00:07:56,356 --> 00:07:58,616 Even though most of you, all of you in this room might laugh 194 00:07:58,616 --> 00:08:00,796 and think I'm not-- I'm never gonna click on a link like that, 195 00:08:01,126 --> 00:08:03,236 that may be true, but if you send out an e-mail 196 00:08:03,236 --> 00:08:06,736 to a million people, and only 1 percent of people are not 197 00:08:06,736 --> 00:08:10,066 like you and they do actually click, that's 10,000 victims 198 00:08:10,266 --> 00:08:11,946 for whatever attack this actually is. 199 00:08:11,946 --> 00:08:14,676 So this, there is this notion of order of magnitude 200 00:08:14,676 --> 00:08:17,376 in computer science and in data analysis that we'll get 201 00:08:17,376 --> 00:08:19,696 to before long that just really speaks to the power 202 00:08:19,696 --> 00:08:22,016 of statistics frankly and even something stupid like this, 203 00:08:22,316 --> 00:08:24,406 right, all you need is 1 percent of those people clicking 204 00:08:24,406 --> 00:08:26,996 on an e-mail which is practically free to send 205 00:08:26,996 --> 00:08:30,126 and voila, you've done something either particularly lucrative 206 00:08:30,126 --> 00:08:31,326 or malicious. 207 00:08:31,326 --> 00:08:34,826 This one too, this is a little and this is the last one. 208 00:08:35,486 --> 00:08:37,866 This one I received as an attachment, right. 209 00:08:37,866 --> 00:08:40,216 I get all sorts of ads for Viagra and such, 210 00:08:40,246 --> 00:08:43,206 but this one came in as in-- okay, wait a minute, 211 00:08:43,946 --> 00:08:48,176 this one came in as an advertisement in my spam folder, 212 00:08:48,406 --> 00:08:50,616 as an attachment in my spam folder. 213 00:08:50,916 --> 00:08:52,326 So what's going in here, right? 214 00:08:52,786 --> 00:08:55,396 Why is first of all this attachment all wavy? 215 00:08:55,396 --> 00:09:00,406 Why is it an image in the first place and not text? 216 00:09:00,406 --> 00:09:01,486 [ Inaudible Remark ] 217 00:09:01,486 --> 00:09:05,636 >> Yeah, so part of it is spam filters hopefully won't actually 218 00:09:05,796 --> 00:09:08,716 catch this because what most spam filters do are looking 219 00:09:08,716 --> 00:09:09,746 for pattern matching. 220 00:09:09,746 --> 00:09:11,536 Something else we'll talk about later in this semester. 221 00:09:11,736 --> 00:09:14,976 Looking for keywords like Viagra and words that, you know, 222 00:09:14,976 --> 00:09:16,416 people might use in an e-mail 223 00:09:16,416 --> 00:09:17,896 but statistically you're more likely 224 00:09:17,896 --> 00:09:19,246 to use it in some kind of spam. 225 00:09:19,526 --> 00:09:20,726 And so they've used an image 226 00:09:20,846 --> 00:09:22,986 because you can't really do text analysis on this, 227 00:09:23,146 --> 00:09:24,736 at least not as easily. 228 00:09:24,766 --> 00:09:26,306 But you can do text analysis. 229 00:09:26,306 --> 00:09:29,256 You can do what's called OCR, optical character recognition. 230 00:09:29,616 --> 00:09:32,196 But by kind of making the image wavy in this way, 231 00:09:32,196 --> 00:09:33,996 which they probably did with Photoshop or something 232 00:09:33,996 --> 00:09:36,766 like that, just makes it harder for applications like that 233 00:09:36,796 --> 00:09:40,576 to actually interpret what this image is. 234 00:09:40,816 --> 00:09:43,526 Now as for fun and also just to make I wasn't taking me 235 00:09:43,526 --> 00:09:47,636 to someplace sketchy, I did go to dot-- ed5.ru this morning, 236 00:09:47,936 --> 00:09:49,796 but it does seem to have been taken down. 237 00:09:49,796 --> 00:09:51,356 So it's now a dead end. 238 00:09:51,966 --> 00:09:54,456 So now a more serious note, we're at the point 239 00:09:54,456 --> 00:09:56,356 in this semester where folks need to make a decision 240 00:09:56,356 --> 00:09:59,706 between staying or leaving and we always see comments 241 00:10:00,126 --> 00:10:01,786 like this screen shot here. 242 00:10:02,266 --> 00:10:03,586 So this is from a website 243 00:10:03,586 --> 00:10:06,796 with which you're probably very familiar. 244 00:10:07,436 --> 00:10:10,836 We see though comments that are a little more explicit. 245 00:10:11,876 --> 00:10:14,606 And this is not to make light of comments like these. 246 00:10:15,826 --> 00:10:19,106 This happens every semester to some subset 247 00:10:19,106 --> 00:10:24,096 of students here at 1-2. 248 00:10:24,096 --> 00:10:25,796 So, right, this is not meant to like-- 249 00:10:25,796 --> 00:10:27,726 elicit that emotion frankly but really-- 250 00:10:27,726 --> 00:10:29,046 [ Laughter ] 251 00:10:29,046 --> 00:10:31,836 >> Really to emphasize, first of all, these FMLs are 252 00:10:31,836 --> 00:10:33,636 from last year, so 12 months ago. 253 00:10:33,636 --> 00:10:34,496 So if a number of you are 254 00:10:34,496 --> 00:10:36,986 in the audience particularly among those less comfortable, 255 00:10:36,986 --> 00:10:38,986 the 55 percent demographic this semester, 256 00:10:39,336 --> 00:10:42,316 do realize that this is certainly early on for a lot 257 00:10:42,316 --> 00:10:44,336 of students for whom this is a very new world, 258 00:10:44,566 --> 00:10:46,956 these are very sort of normal and sort 259 00:10:46,956 --> 00:10:48,836 of cyclical emotions that you feel. 260 00:10:48,836 --> 00:10:50,366 But it really is the sort of thing 261 00:10:50,566 --> 00:10:52,526 where once you get more acclimated to this, 262 00:10:52,526 --> 00:10:55,136 once you stop making what you will eventually call stupid 263 00:10:55,136 --> 00:10:57,056 mistakes, leaving off semi colons 264 00:10:57,056 --> 00:10:58,986 and forgetting parentheses and this little things 265 00:10:59,226 --> 00:11:01,876 that you just become all tied to you before long, 266 00:11:02,256 --> 00:11:05,116 realize that the material, the ideas, 267 00:11:05,116 --> 00:11:07,346 your own programs will get more exciting. 268 00:11:07,346 --> 00:11:11,106 I mean, if you think back to the excessive use of videography 269 00:11:11,106 --> 00:11:12,906 and photography that we've shown you thus far, 270 00:11:13,076 --> 00:11:15,566 you didn't really see anyone crying at the CS50 fair. 271 00:11:15,566 --> 00:11:17,746 You saw some people asleep, maybe at this CS50 hackathon 272 00:11:17,776 --> 00:11:19,356 but there is no one in tears. 273 00:11:19,356 --> 00:11:20,706 It was really mostly smiles. 274 00:11:20,706 --> 00:11:24,116 And I can promise you this, as can our 40 some odd TFs 275 00:11:24,116 --> 00:11:27,086 and 40 some odd CAs that that is precisely the emotion you 276 00:11:27,086 --> 00:11:27,696 will feel. 277 00:11:27,896 --> 00:11:31,086 And so if you're really at this point right now, honestly, 278 00:11:31,086 --> 00:11:33,576 I dare say this is more a function of strategy 279 00:11:33,576 --> 00:11:36,256 and your current work habits as they relate to 50, 280 00:11:36,446 --> 00:11:38,856 and not something fundamental to the material itself. 281 00:11:39,126 --> 00:11:41,646 As I said a week or so ago, honestly, if you feel that sort 282 00:11:41,646 --> 00:11:44,136 of stress, sort of building up in you, if you're working 283 00:11:44,136 --> 00:11:47,026 on some P-set, it's already 3 a.m., 4 a.m., well, 284 00:11:47,026 --> 00:11:49,226 just honestly call it a night, take it a break. 285 00:11:49,226 --> 00:11:51,866 Because even I can't sort of code under pressure, 286 00:11:52,106 --> 00:11:54,246 and much better than to cash in that late day 287 00:11:54,246 --> 00:11:56,736 that you might have or simply to take a break and come back 288 00:11:56,866 --> 00:11:59,816 to it rather than waste some 3, 4 hours staring 289 00:11:59,816 --> 00:12:03,106 at a frustratingly blinking prompt to only to get nowhere. 290 00:12:03,106 --> 00:12:06,296 Honestly, this happens to me to this day, it's just no fun 291 00:12:06,296 --> 00:12:07,996 and it's not easy to code under stress. 292 00:12:08,126 --> 00:12:10,556 And if anything, reach out to me Rob, Matt, 293 00:12:10,786 --> 00:12:12,686 or any of your now assigned teaching fellows, 294 00:12:13,086 --> 00:12:14,626 if you have any questions or concerns, 295 00:12:14,626 --> 00:12:18,056 but realize there have been many, many others before you. 296 00:12:18,636 --> 00:12:20,476 Not in tears, just before you. 297 00:12:20,476 --> 00:12:21,336 [ Laughter ] 298 00:12:21,336 --> 00:12:24,356 >> So, where are we going this week? 299 00:12:24,356 --> 00:12:26,076 Let's set the stage and let's dive back 300 00:12:26,076 --> 00:12:27,116 in to some of that code. 301 00:12:27,116 --> 00:12:29,666 So in P-set 2, the problem domain is security 302 00:12:29,666 --> 00:12:31,186 and more specifically cryptography, 303 00:12:31,186 --> 00:12:32,716 the art of encrypting information. 304 00:12:32,876 --> 00:12:34,856 And most anytime you encrypt information, 305 00:12:35,206 --> 00:12:38,266 you need some secret between you, say Alice, 306 00:12:38,346 --> 00:12:41,206 and the other person Bob, because otherwise, 307 00:12:41,266 --> 00:12:44,116 there's no way for the two of you to know how 308 00:12:44,116 --> 00:12:46,456 to interpret what might look like nonsense 309 00:12:46,506 --> 00:12:48,366 that you're sending across the internet 310 00:12:48,366 --> 00:12:50,686 or across a room on a piece of paper. 311 00:12:50,976 --> 00:12:53,346 So in cryptography there's this notion of plain text, 312 00:12:53,346 --> 00:12:55,496 the original message depicted there at left, 313 00:12:55,766 --> 00:12:56,406 then there's the notion 314 00:12:56,406 --> 00:12:58,626 of cypher text depicted there in the middle. 315 00:12:58,816 --> 00:13:00,566 And the cypher text is the scrambled stuff, 316 00:13:00,566 --> 00:13:03,526 it looks like nonsense, it looks like random letters 317 00:13:03,756 --> 00:13:06,116 but there's some algorithm, there's some process 318 00:13:06,116 --> 00:13:09,166 for reversing that pro-- reversing that scrambled text 319 00:13:09,396 --> 00:13:11,176 and that's of course known as decryption 320 00:13:11,386 --> 00:13:13,636 and that yields back the plain text. 321 00:13:13,636 --> 00:13:16,036 And so you need some secret, and the simplest kind 322 00:13:16,036 --> 00:13:18,376 of secret might be well, if I wanna write the letter A, 323 00:13:18,376 --> 00:13:21,456 let me actually write to my significant other 324 00:13:21,456 --> 00:13:24,456 in the class the letter B. And if I want a B, I write a C 325 00:13:24,456 --> 00:13:25,686 and the C in a D, and so forth. 326 00:13:25,686 --> 00:13:28,056 You rotate perhaps the letters by one place 327 00:13:28,286 --> 00:13:30,546 or you can be fancier, rotate them by 2 places. 328 00:13:30,746 --> 00:13:33,666 Or 3 places or 13 places, 329 00:13:33,666 --> 00:13:37,096 though hopefully not 26 places, okay, alright. 330 00:13:37,126 --> 00:13:38,706 So otherwise it's not all that effective. 331 00:13:38,706 --> 00:13:39,846 And so this is generally known 332 00:13:39,846 --> 00:13:42,946 as secret key cryptography whereby you need 333 00:13:42,946 --> 00:13:45,646 to know some secret, Alice and Bob, and that secret 334 00:13:45,646 --> 00:13:48,196 in this scenario is just a number, like the number 1 335 00:13:48,246 --> 00:13:50,696 if you're gonna rotate all of those characters by 1 place. 336 00:13:50,976 --> 00:13:54,756 There's a well-known rotation called rot13, R-O-T 13, 337 00:13:55,026 --> 00:13:57,046 which was historically used on the internet 338 00:13:57,616 --> 00:14:01,006 to encrypt information but in a very simplistic way. 339 00:14:01,006 --> 00:14:03,506 It was often used back in the day on message boards. 340 00:14:03,506 --> 00:14:05,726 If you wanted to talk about movies and spoilers, 341 00:14:05,726 --> 00:14:07,996 but you didn't wanna be the jerk who spoils it for everyone, 342 00:14:08,276 --> 00:14:09,566 so this way you had to click a button 343 00:14:09,566 --> 00:14:12,736 and it would unrotate the scramble text by 13 places. 344 00:14:12,996 --> 00:14:17,156 Now just thinking about this rotation from 1-- 345 00:14:17,156 --> 00:14:20,466 0 to 26 places, how secure would you say this is? 346 00:14:22,016 --> 00:14:24,256 Alright, it's not all that secure, alright. 347 00:14:24,256 --> 00:14:26,686 It might be tedious and time consuming to figure 348 00:14:26,686 --> 00:14:28,696 out what a handwritten notes says 'cause you'd have 349 00:14:28,696 --> 00:14:30,486 to redo it all by hand and you could guess, 350 00:14:30,636 --> 00:14:33,046 maybe A as B, B as C and so forth. 351 00:14:33,046 --> 00:14:37,136 If you screw up maybe A as C, B as D so you might have 352 00:14:37,136 --> 00:14:40,046 to do this some 25 times to actually figure 353 00:14:40,046 --> 00:14:41,416 out what the secret was. 354 00:14:41,416 --> 00:14:43,276 And then voila, the secret is cracked. 355 00:14:43,486 --> 00:14:46,686 Well, what you're gonna do in P-set 2 is actually automate all 356 00:14:46,686 --> 00:14:48,926 of that, so that all you have to do is run a command and bam, 357 00:14:49,326 --> 00:14:51,286 decrypted, or bam, encrypted. 358 00:14:51,286 --> 00:14:53,686 And certainly, a computer can do this much faster. 359 00:14:53,926 --> 00:14:56,166 But you can actually do better than this 360 00:14:56,206 --> 00:14:57,746 so called Caesar cypher. 361 00:14:57,746 --> 00:15:00,076 So the Caesar cypher is the name given to any 362 00:15:00,076 --> 00:15:01,526 of these rotational cyphers. 363 00:15:01,746 --> 00:15:02,876 Whereby you take an alphabet, 364 00:15:02,876 --> 00:15:05,206 and you kinda rotate it conceptually this way 365 00:15:05,206 --> 00:15:07,406 so that A lines up with some different letter 366 00:15:07,616 --> 00:15:09,366 and this is what little Ralphie was referring 367 00:15:09,366 --> 00:15:13,136 to in A Christmas Story when he actually was using 368 00:15:13,136 --> 00:15:16,036 that secret decoder ring to crack the be sure 369 00:15:16,036 --> 00:15:18,046 to drink your Ovaltine advertisement. 370 00:15:18,346 --> 00:15:21,686 So this is again named after Caesar, but then years later, 371 00:15:21,686 --> 00:15:24,336 there came along another fellow, named Vigenere, 372 00:15:24,336 --> 00:15:27,256 who've actually built upon this idea of a rotational cypher 373 00:15:27,566 --> 00:15:29,606 but didn't just used one secret, right. 374 00:15:29,606 --> 00:15:32,096 A recurring theme you'll see even in computer science is 375 00:15:32,276 --> 00:15:33,956 if well, the first attempt 376 00:15:33,956 --> 00:15:35,586 at doing something isn't quite good enough 377 00:15:35,586 --> 00:15:38,856 or quite secure enough, maybe do it again, or do it again and try 378 00:15:38,856 --> 00:15:41,636 to increase the computational complexity of something. 379 00:15:41,636 --> 00:15:43,016 And so what this fellow proposed, 380 00:15:43,196 --> 00:15:45,646 the so called Vigenere cypher, is simply a cypher 381 00:15:45,646 --> 00:15:49,326 where you don't use one key, you use maybe 2 keys or 3 keys 382 00:15:49,326 --> 00:15:52,036 or even 4 and then you'll use the first key 383 00:15:52,036 --> 00:15:54,476 on the first letter, the second key on the second letter, 384 00:15:54,566 --> 00:15:57,176 third on the third, fourth or fourth ant then if your input, 385 00:15:57,176 --> 00:16:00,256 your plain text has 5 letters, then you just repeat back 386 00:16:00,256 --> 00:16:02,106 to the first letter in your key. 387 00:16:02,326 --> 00:16:05,596 Now it's a little tedious to remember multiple numbers 388 00:16:05,596 --> 00:16:08,526 like the number 2 and 3 and 13 and 14. 389 00:16:08,526 --> 00:16:10,576 And so what Vigenere proposed is that rather 390 00:16:10,576 --> 00:16:12,226 than just remember a number, like you might 391 00:16:12,226 --> 00:16:15,716 for the Caesar cypher, you instead remember a word. 392 00:16:15,756 --> 00:16:21,166 Like my keyword might be ABC and then you simply decide sort 393 00:16:21,166 --> 00:16:24,566 of as a society that anytime a keyword has the letter A, 394 00:16:24,886 --> 00:16:27,266 this is going to represent the number 0, 395 00:16:27,436 --> 00:16:29,326 the letter B is gonna represent the number 1, 396 00:16:29,326 --> 00:16:32,216 the letter C is gonna represent the number 2, and so forth. 397 00:16:32,376 --> 00:16:37,256 So if your secret, not key, but secret keyword is ABC, 398 00:16:37,496 --> 00:16:40,946 that's really like saying, we have 3 keys and they are 0, 1, 399 00:16:40,946 --> 00:16:44,806 2 and so, if wanna encrypt something like hello, 400 00:16:45,266 --> 00:16:48,586 you can do, if this is plain text, H-E-L-L-O, 401 00:16:48,586 --> 00:16:53,036 and I wanna encrypt it with A, B, C. Well, it's 5 letters 402 00:16:53,036 --> 00:16:55,646 so I actually have to repeat my keyword, so I just do this. 403 00:16:56,036 --> 00:16:58,856 And now, H plus A well A is 0, 404 00:16:58,856 --> 00:17:05,026 so H plus 0 is H. E plus B is actually E plus 1 so that goes 405 00:17:05,026 --> 00:17:10,816 to F, L plus 2, so L M N, so that's N, N and then I'm back 406 00:17:10,986 --> 00:17:15,836 to B here, so O, rotated by 1 place is P, 407 00:17:15,926 --> 00:17:20,346 and so-- well, did I mess up? 408 00:17:20,346 --> 00:17:20,726 [ Inaudible Remark ] 409 00:17:20,726 --> 00:17:22,626 >> O, L, oh yes-- yes, yes, thank you. 410 00:17:22,746 --> 00:17:23,946 This is plus 0, thank you. 411 00:17:24,996 --> 00:17:28,086 Plug in the code, alright, so that's L, 412 00:17:28,546 --> 00:17:32,116 L-- no, no, no-- hang on. 413 00:17:32,316 --> 00:17:36,146 You don't have 300 people staring at you. 414 00:17:36,146 --> 00:17:36,213 [ Laughter ] 415 00:17:36,213 --> 00:17:41,586 >> Okay. So plus 2 L, M, N. Okay, okay, thank you. 416 00:17:42,086 --> 00:17:45,996 [ Applause ] 417 00:17:46,496 --> 00:17:48,346 >> Really set the bar high here in 50, okay. 418 00:17:48,996 --> 00:17:51,436 So that would now be the cypher text, right. 419 00:17:51,436 --> 00:17:55,346 And now this is actually harder to decrypt or to crack 420 00:17:55,866 --> 00:17:58,896 in the sense of trying to brute force your way through it. 421 00:17:58,896 --> 00:18:01,446 When we say brute force, it means try all possible keys 422 00:18:01,476 --> 00:18:02,466 to figure out what it is. 423 00:18:02,646 --> 00:18:05,156 But now this is getting increasingly computational 424 00:18:05,156 --> 00:18:07,926 complex whereas the complexity of the Caesar cypher, 425 00:18:07,926 --> 00:18:10,326 if you're just rotating by a letter of the English alphabet, 426 00:18:10,626 --> 00:18:13,686 you have 26 possible keys, release one-- 427 00:18:13,976 --> 00:18:16,526 0 through 25 or 1 through 26 depending 428 00:18:16,526 --> 00:18:17,716 on where you wanna start counting. 429 00:18:18,006 --> 00:18:20,176 How many do you actually have in the Vigenere cypher? 430 00:18:20,596 --> 00:18:22,206 Well, for your first keyword, you have what? 431 00:18:22,306 --> 00:18:23,626 26 possibilities. 432 00:18:23,956 --> 00:18:28,196 Your second letter in the keyword you have another 26, 433 00:18:28,446 --> 00:18:31,106 and then another 26 possibilities and then another. 434 00:18:31,306 --> 00:18:34,146 So in general, the complexity of C-- 435 00:18:34,146 --> 00:18:37,806 of the Vigenere cypher is gonna be 26 raised to some power 436 00:18:37,976 --> 00:18:39,776 where that power, let's call it K, 437 00:18:39,776 --> 00:18:42,316 or whatever is simply the length of that key. 438 00:18:42,316 --> 00:18:46,826 So 26 times 26 times 26 times 26, now this is starting 439 00:18:46,826 --> 00:18:48,016 to actually get pretty big. 440 00:18:48,016 --> 00:18:52,536 If we use a let's say 5-letter keyword alone, let me just pull 441 00:18:52,536 --> 00:18:54,256 up a little text based calculator here. 442 00:18:54,526 --> 00:18:58,296 And if I do 26 raised to the 5 power, and hit Enter, 443 00:18:58,646 --> 00:19:04,606 so that's already some 11 million possible keywords 444 00:19:04,636 --> 00:19:08,006 that the bad guy might actually have to try in order to figure 445 00:19:08,006 --> 00:19:09,656 out what keyword was actually used. 446 00:19:09,876 --> 00:19:12,766 Now here too, we have computers, and computers can churn 447 00:19:12,766 --> 00:19:15,736 through 11 million possible keywords, pretty darn fast. 448 00:19:16,676 --> 00:19:19,116 Thankfully though, there exist some more sophisticated 449 00:19:19,116 --> 00:19:21,736 algorithms out there, but that's something we'll revisit 450 00:19:22,236 --> 00:19:23,346 before long. 451 00:19:23,626 --> 00:19:26,826 Now, just as a teaser for those of you who might be a little shy 452 00:19:26,826 --> 00:19:28,156 of tackling the Hacker Edition, 453 00:19:28,156 --> 00:19:30,666 realize that this week is actually pretty open ended. 454 00:19:30,666 --> 00:19:32,046 What we've given you, if you choose 455 00:19:32,046 --> 00:19:34,996 to elect this edition, is a password file. 456 00:19:34,996 --> 00:19:36,926 So, on most any Unix or Linux 457 00:19:36,926 --> 00:19:39,816 or Mac OS system there's a text file historically 458 00:19:40,016 --> 00:19:42,266 that contains all the user names who are authorized to use 459 00:19:42,266 --> 00:19:43,486 that computer and then all 460 00:19:43,486 --> 00:19:46,006 of their passwords separated by a colon. 461 00:19:46,006 --> 00:19:49,756 So for instance, Caesar, colon, and then his encrypted password, 462 00:19:50,006 --> 00:19:54,116 [inaudible] colon, and then his encrypted password and so forth. 463 00:19:54,366 --> 00:19:56,976 So these are not in plain text, these are the cypher texts. 464 00:19:56,976 --> 00:19:59,026 And so the challenge of the Hacker Edition this week, 465 00:19:59,026 --> 00:20:02,576 if you'd not yet dived in, is to take this as input and figure it 466 00:20:02,986 --> 00:20:05,166 out what are each of these people's passwords, 467 00:20:05,166 --> 00:20:09,216 and you will find that they are varying levels of difficulties. 468 00:20:09,556 --> 00:20:10,846 Rob's is not so difficult, 469 00:20:10,926 --> 00:20:13,006 Mailyn's [phonetic] is actually pretty difficult. 470 00:20:13,146 --> 00:20:16,816 And so you'll see that various heuristics are actually 471 00:20:16,816 --> 00:20:18,056 applicable here, right. 472 00:20:18,056 --> 00:20:20,786 If you were implementing a password cracking program, 473 00:20:20,996 --> 00:20:23,536 even if at first time you have no idea how to do this in C, 474 00:20:23,746 --> 00:20:27,146 what kinds of words or what kinds of passwords might you try 475 00:20:27,396 --> 00:20:29,886 if the goal is to brute force figure 476 00:20:29,886 --> 00:20:32,226 out whose password is what. 477 00:20:32,876 --> 00:20:35,016 So you can use what's called the dictionary attack. 478 00:20:35,016 --> 00:20:36,866 So this is actually pretty sophisticated approach, 479 00:20:37,026 --> 00:20:38,466 but it turns out in the appliance, 480 00:20:38,466 --> 00:20:41,176 as in most computers these days, there's a huge text file 481 00:20:41,176 --> 00:20:43,676 with like 150,000 English words. 482 00:20:43,906 --> 00:20:46,076 Well, that's actually not all that much to a computer. 483 00:20:46,076 --> 00:20:48,986 What you could try doing is open that dictionary file, 484 00:20:49,236 --> 00:20:51,226 read through it, top to bottom, left to right 485 00:20:51,226 --> 00:20:54,456 and try encrypting every one of those English dictionary words 486 00:20:54,456 --> 00:20:57,816 and if you see a match in this file, as we discussed last week, 487 00:20:57,816 --> 00:21:00,266 voila, you'd figured out what Rob's password is. 488 00:21:00,266 --> 00:21:02,796 So in other words, you can't really decrypt these things, 489 00:21:02,796 --> 00:21:05,176 'cause they're what we called one-way hashes. 490 00:21:05,466 --> 00:21:08,446 But you can encrypt a guess and see 491 00:21:08,446 --> 00:21:11,086 if it matches what's actually in this file. 492 00:21:11,376 --> 00:21:12,946 Now, other things you might try, honestly, 493 00:21:12,946 --> 00:21:14,026 you could try some easy ones. 494 00:21:14,026 --> 00:21:16,586 Maybe it's all numbers, maybe it's the word password, 495 00:21:16,586 --> 00:21:18,836 maybe it's the number 1, 2, 3, 4, 5. 496 00:21:19,116 --> 00:21:21,096 So one of the challenges of the Hacker Edition is that, 497 00:21:21,396 --> 00:21:25,176 because there's actually a whole lot of possible passwords 498 00:21:25,176 --> 00:21:26,756 that any one of these people's could be, 499 00:21:27,046 --> 00:21:29,226 turns out that your program could take days, 500 00:21:29,306 --> 00:21:30,716 weeks to actually run. 501 00:21:30,716 --> 00:21:32,726 So you're never actually gonna see certainly before the 502 00:21:32,726 --> 00:21:33,726 deadline if you're right. 503 00:21:33,726 --> 00:21:35,396 And so one of the challenges is going 504 00:21:35,396 --> 00:21:39,166 to be write a password-cracking program that optimizes 505 00:21:39,166 --> 00:21:41,886 for what hopefully normal people might use as passwords. 506 00:21:42,096 --> 00:21:43,546 And then only eventually resorts 507 00:21:43,546 --> 00:21:45,566 to just trying all possible letters 508 00:21:46,106 --> 00:21:49,666 in the ASCII character set, all 256 possibilities. 509 00:21:49,946 --> 00:21:52,566 So do feel free to dive in and even if you decide, 510 00:21:52,906 --> 00:21:55,066 I have to abort this particular edition, that's fine, 511 00:21:55,066 --> 00:21:56,816 you can then dive into the standard edition. 512 00:21:56,816 --> 00:21:59,006 You can chose week to week which one to do. 513 00:21:59,766 --> 00:22:03,176 Alright. Any questions on P-sets or otherwise? 514 00:22:03,906 --> 00:22:05,776 No, alright. 515 00:22:05,956 --> 00:22:10,256 So let's go ahead and open up a blank file here. 516 00:22:10,406 --> 00:22:11,816 So let me close iUnlock. 517 00:22:12,076 --> 00:22:13,806 And recall that we spent some time 518 00:22:13,806 --> 00:22:18,506 with this fellow here last week. 519 00:22:18,746 --> 00:22:21,046 This notion of 100 bottles a beer on the wall 520 00:22:21,046 --> 00:22:22,826 and singing something very familiar to him, 521 00:22:22,826 --> 00:22:24,886 had I actually planned ahead it wouldn't have been a donut, 522 00:22:24,886 --> 00:22:27,086 it would have been a bottle of beer, but that's the first thing 523 00:22:27,086 --> 00:22:27,896 that came up on Google. 524 00:22:28,316 --> 00:22:31,166 So the connection here is to 100 bottles of beer on the wall, 525 00:22:31,436 --> 00:22:33,906 and recall that we implemented this with a lot of printf's 526 00:22:34,346 --> 00:22:35,516 and with a main function. 527 00:22:35,516 --> 00:22:38,376 But then we started factoring this thing out, 528 00:22:38,376 --> 00:22:39,506 some of that code out. 529 00:22:39,816 --> 00:22:42,016 So if I recall, we started with something like this, 530 00:22:42,016 --> 00:22:47,586 let me zoom in and do include standard io.h and that gives me, 531 00:22:47,586 --> 00:22:49,336 quick sanity check, what function? 532 00:22:50,586 --> 00:22:53,346 Printf, that's all, and now another quick sanity check, 533 00:22:53,346 --> 00:22:54,276 why is it black and white? 534 00:22:54,276 --> 00:22:54,956 Where is my color? 535 00:22:56,286 --> 00:22:57,326 Okay, alright, so. 536 00:22:57,886 --> 00:22:59,566 Well, we'll notch things up a bit now. 537 00:22:59,566 --> 00:23:00,566 That was too easy, alright. 538 00:23:00,646 --> 00:23:02,286 So let me go ahead and save this 539 00:23:02,326 --> 00:23:06,196 as let's call it what we did before, beer1.c, 540 00:23:06,356 --> 00:23:09,666 now that G edit knows that this is a C file it starts a syntax 541 00:23:09,846 --> 00:23:10,906 highlighting it for us. 542 00:23:10,906 --> 00:23:12,766 And then recall how began this thing. 543 00:23:12,766 --> 00:23:14,496 We had int main, I didn't take any 544 00:23:14,496 --> 00:23:16,146 so called command line arguments, 545 00:23:16,486 --> 00:23:21,656 instead I simply asked the user how many bottles 546 00:23:21,656 --> 00:23:25,246 of beer will there be, and then a question mark. 547 00:23:25,246 --> 00:23:28,486 And then I'll put a new line character, semicolon 548 00:23:28,646 --> 00:23:30,836 and now I actually need to get the input from the user, 549 00:23:30,836 --> 00:23:33,236 so the function we keep using for this is-- 550 00:23:34,516 --> 00:23:36,796 okay, so let's call it get int. 551 00:23:37,176 --> 00:23:38,956 Okay, feel free to yell at me if I'm making mistakes. 552 00:23:40,566 --> 00:23:41,856 This time that was unintentional. 553 00:23:43,406 --> 00:23:45,366 Okay, so couple mistakes already, right. 554 00:23:45,366 --> 00:23:48,226 So first, I do need the CS50 library so at 555 00:23:48,226 --> 00:23:51,436 that I even have access to get int, and there's still a bug 556 00:23:51,436 --> 00:23:52,746 in here already, this won't compile. 557 00:23:52,836 --> 00:23:52,956 Yeah. 558 00:23:52,956 --> 00:23:53,916 [ Inaudible Remark ] 559 00:23:53,916 --> 00:23:54,766 >> I'm sorry? 560 00:23:54,956 --> 00:24:00,636 On the third line here, we need to actually do int, right. 561 00:24:00,636 --> 00:24:03,306 So we actually need to declare this variable and let me see 562 00:24:03,306 --> 00:24:09,256 if I can-- let's see, turn on, that's okay. 563 00:24:09,486 --> 00:24:11,986 I was gonna turn on line numbers but we'll leave it off for now. 564 00:24:12,226 --> 00:24:15,006 Alright, so int and get int so that's good. 565 00:24:15,006 --> 00:24:17,316 And now let's go ahead and forge ahead. 566 00:24:17,316 --> 00:24:22,186 So I'm gonna go ahead now and say for int I gets, 567 00:24:22,186 --> 00:24:29,396 let's say N. I is greater than equal to 0 and then I minus, 568 00:24:29,396 --> 00:24:31,556 minus, so in other words, I want some kind of loop that just 569 00:24:31,556 --> 00:24:33,816 like the song is gonna count down from however number 570 00:24:33,816 --> 00:24:34,916 of bottles I start with. 571 00:24:35,156 --> 00:24:37,366 And then on each iteration it's gonna decrement, decrement, 572 00:24:37,366 --> 00:24:39,956 decrement and it's gonna stop, once we actually hit 0, 573 00:24:39,956 --> 00:24:42,566 and then recall that the song was something along the lines 574 00:24:42,566 --> 00:24:46,666 of-- I don't know what this is gonna be yet, bottles of beer 575 00:24:46,666 --> 00:24:48,906 on the wall, and then I'll do a new line in this 576 00:24:48,906 --> 00:24:51,926 and let me just do some quick copy paste so that we don't have 577 00:24:51,926 --> 00:24:54,306 to type out all of these lines and now let's just change this. 578 00:24:54,706 --> 00:24:56,946 100 bottles of beer, take 1 down, 579 00:24:56,946 --> 00:24:58,596 pass it around, so that comes next. 580 00:24:59,426 --> 00:25:05,026 So take 1 down, pass it around, that's pretty easy. 581 00:25:05,026 --> 00:25:07,456 And then something, something bottles of beer on the wall. 582 00:25:07,456 --> 00:25:08,336 So we're almost there. 583 00:25:08,536 --> 00:25:10,206 These question marks are illegitimate, 584 00:25:10,266 --> 00:25:14,396 so I should probably plug in a-- okay, so percent D, 585 00:25:14,396 --> 00:25:16,266 'cause we're talking about a decimal integer, 586 00:25:16,266 --> 00:25:18,046 like 99, 98 and so forth. 587 00:25:18,446 --> 00:25:21,066 So let me go ahead and plug that in now, and now, 588 00:25:21,066 --> 00:25:23,036 what value do I actually want to plug in here? 589 00:25:23,036 --> 00:25:25,136 'Cause right now, printf can't just take one argument, 590 00:25:25,136 --> 00:25:25,986 it has to take two. 591 00:25:27,386 --> 00:25:29,806 Yeah, so we wanna just plug in I, not N? 592 00:25:30,636 --> 00:25:33,876 If I plugged in N, what would the song sing? 593 00:25:35,016 --> 00:25:36,486 The same number again and again. 594 00:25:36,486 --> 00:25:39,126 It would just say 99, 99, 99, so we do want I, 595 00:25:39,126 --> 00:25:40,886 'cause I is the number that's being decremented 596 00:25:40,886 --> 00:25:43,316 on each iteration so now I want I here, 597 00:25:44,416 --> 00:25:47,966 now I want I here, okay good. 598 00:25:48,086 --> 00:25:50,016 Right, there is no actual placeholder there 599 00:25:50,326 --> 00:25:52,436 but down here, I want I as well. 600 00:25:53,466 --> 00:25:54,286 Okay, exactly. 601 00:25:54,286 --> 00:25:56,866 So we don't even though on each iteration, 602 00:25:56,866 --> 00:25:59,936 we are decrementing I, realize that within one stanza 603 00:25:59,936 --> 00:26:03,046 of this song, we have to say verbally 2 numbers both 604 00:26:03,046 --> 00:26:05,296 where we started and where we're gonna end up. 605 00:26:05,596 --> 00:26:07,346 So, according to that song we're supposed to end 606 00:26:07,346 --> 00:26:09,396 with 98 bottles of beer on the wall. 607 00:26:09,396 --> 00:26:10,936 So I minus 1 will do that. 608 00:26:11,686 --> 00:26:16,956 Any objections now to how we're doing this? 609 00:26:17,146 --> 00:26:18,536 Some tweaks. 610 00:26:18,536 --> 00:26:19,616 [ Inaudible Remarks ] 611 00:26:19,616 --> 00:26:20,526 >> I'm sorry? 612 00:26:20,526 --> 00:26:20,726 [ Inaudible Remarks ] 613 00:26:20,726 --> 00:26:23,896 >> Ah yeah, so thus far, we're not really enforcing any kind 614 00:26:23,896 --> 00:26:27,556 of boundaries on N. In fact if I don't notice that quite yet, 615 00:26:27,556 --> 00:26:30,426 let me go ahead and zoom out, let me go ahead and open 616 00:26:30,426 --> 00:26:34,206 up my terminal window here, and let me go ahead and make beer 1, 617 00:26:34,586 --> 00:26:36,716 that's good, so it did compile okay. 618 00:26:36,716 --> 00:26:37,676 So that's promising. 619 00:26:37,806 --> 00:26:40,306 As an aside, we were asked the other day how I keep clearing 620 00:26:40,306 --> 00:26:42,546 the screen, if you wanna do that, it's just control L, 621 00:26:42,606 --> 00:26:44,286 it just flashes what you see on the screen. 622 00:26:44,626 --> 00:26:46,576 So let me go ahead now and run beer 1. 623 00:26:46,806 --> 00:26:48,246 How many bottles of beer will there be? 624 00:26:48,246 --> 00:26:53,276 Let's say 99, and unfortunately, this seems to air 625 00:26:54,226 --> 00:26:56,996 at least once we-- oh, now it's just not scrolling far-- 626 00:26:56,996 --> 00:26:58,776 back far and out, but that's okay. 627 00:26:58,776 --> 00:27:01,676 This is a bottle, right, minus 1 bottles of beer on the wall? 628 00:27:02,156 --> 00:27:03,176 Let's fix that one first, 629 00:27:03,176 --> 00:27:04,356 'cause that's the first one that jumps out. 630 00:27:04,356 --> 00:27:05,236 What's the easy fix here? 631 00:27:05,236 --> 00:27:05,886 [ Inaudible Remarks ] 632 00:27:05,886 --> 00:27:09,916 >> Yeah. So it should really be greater than 0, 633 00:27:09,916 --> 00:27:12,166 or you could say greater than or equal to 1, 634 00:27:12,336 --> 00:27:13,896 either way would be perfectly legitimate. 635 00:27:13,896 --> 00:27:17,406 Whatever seems most logical to you, so that should fix that bug 636 00:27:17,486 --> 00:27:18,566 but there's this other one. 637 00:27:18,566 --> 00:27:21,886 Let me zoom in again, let me go ahead and run beer 1 638 00:27:22,476 --> 00:27:26,046 and now let's just be difficult, negative 3, okay, 639 00:27:26,166 --> 00:27:27,296 so didn't sing anything. 640 00:27:27,296 --> 00:27:29,096 So that actually worked okay, but why? 641 00:27:29,456 --> 00:27:32,676 What caught that error? 642 00:27:32,676 --> 00:27:33,536 [ Inaudible Remarks ] 643 00:27:33,536 --> 00:27:37,626 >> Yeah. So right, because we're initializing I to negative 3 644 00:27:37,866 --> 00:27:40,366 and then we're checking that condition only do the following. 645 00:27:40,366 --> 00:27:43,846 So long as I is greater than or equal to 1, well, 646 00:27:43,846 --> 00:27:46,766 we're detecting this and effectively not executing any 647 00:27:46,766 --> 00:27:49,406 of those 4 print f lines, so we simply quit. 648 00:27:49,716 --> 00:27:52,326 However, it's not really clear to the user what's going on, 649 00:27:52,326 --> 00:27:54,816 so it would not be unreasonable to say something like, well, 650 00:27:55,056 --> 00:27:58,796 if N is less than let's say 1, then let's go ahead 651 00:27:58,796 --> 00:28:03,916 and say something like print F, please input a positive number 652 00:28:04,596 --> 00:28:07,796 and then that alone could be enough. 653 00:28:07,946 --> 00:28:09,716 But generally as a matter of good practice, 654 00:28:09,716 --> 00:28:11,196 what should I do after this printf? 655 00:28:12,806 --> 00:28:15,276 You probably wanna return something other than 0. 656 00:28:15,276 --> 00:28:17,476 Again, this is something you sort of should take on faith 657 00:28:17,476 --> 00:28:20,036 for now, you don't really see these numbers just yet, 658 00:28:20,036 --> 00:28:20,946 but we soon will. 659 00:28:21,056 --> 00:28:22,236 But you wanna return something other 660 00:28:22,236 --> 00:28:25,546 than 0 'cause 0 generally denotes good 661 00:28:25,546 --> 00:28:27,116 and anything else denotes bad. 662 00:28:27,326 --> 00:28:28,106 Now what about this? 663 00:28:28,106 --> 00:28:29,366 I seem to be missing return. 664 00:28:29,366 --> 00:28:33,036 So I do, I strictly need something at the bottom. 665 00:28:33,086 --> 00:28:35,436 You don't really, but once your program start getting more 666 00:28:35,436 --> 00:28:37,426 sophisticated, it's not a bad habit 667 00:28:37,426 --> 00:28:40,116 to just explicitly return 0 but what C does 668 00:28:40,116 --> 00:28:43,096 for you these days is you will need for main specifically, 669 00:28:43,346 --> 00:28:44,766 0 gets returned automatically. 670 00:28:44,866 --> 00:28:47,216 So that's why we've done that thus far. 671 00:28:48,086 --> 00:28:49,716 Alright, so not bad. 672 00:28:49,716 --> 00:28:53,766 Any questions on this thus far? 673 00:28:53,766 --> 00:28:54,786 [ Inaudible Remark ] 674 00:28:54,786 --> 00:28:56,196 >> Why can't you use percent I? 675 00:28:56,646 --> 00:28:59,326 Oh, so you actually can, I think, 676 00:28:59,326 --> 00:29:00,946 I actually never really use percent I, 677 00:29:01,006 --> 00:29:02,656 I think they're synonymous. 678 00:29:03,246 --> 00:29:04,006 But I'll double check. 679 00:29:05,346 --> 00:29:05,996 Other questions? 680 00:29:07,556 --> 00:29:10,346 Alright, so let's now rather than jump in to code 681 00:29:10,346 --> 00:29:13,356 that was prefab just last time, let me rip this apart 682 00:29:13,356 --> 00:29:15,096 in a manner that's a little more clear. 683 00:29:15,096 --> 00:29:17,696 I feel like last week did not quite do. 684 00:29:17,766 --> 00:29:19,986 Some of these ideas just is and were a bit confusing. 685 00:29:19,986 --> 00:29:20,836 So let me now fix. 686 00:29:21,256 --> 00:29:22,816 So it feels like something like this. 687 00:29:23,226 --> 00:29:24,506 This printing of something 688 00:29:24,506 --> 00:29:27,006 in a loop that's taking us input some number 689 00:29:27,006 --> 00:29:28,966 like N can kind of be factored out. 690 00:29:29,306 --> 00:29:31,006 So that conceptually, I could have 691 00:29:31,006 --> 00:29:33,486 as we did last week a chorus function whose purpose 692 00:29:33,486 --> 00:29:35,686 in life is to just sing this song. 693 00:29:35,686 --> 00:29:37,906 This again is an example of the fancier terms, 694 00:29:37,906 --> 00:29:41,276 hierarchal decomposition where you simply take some chunk 695 00:29:41,276 --> 00:29:44,416 of code that conceptually does something and that's it. 696 00:29:44,416 --> 00:29:45,966 It's very well defined what it does, 697 00:29:45,966 --> 00:29:49,186 factored out into a function just to kind of clean 698 00:29:49,186 --> 00:29:51,466 up what's going on in your main function. 699 00:29:51,656 --> 00:29:53,466 And so by that, I mean this, let me go ahead 700 00:29:53,466 --> 00:29:57,386 and copy this code temporarily, let me go down here now, 701 00:29:57,386 --> 00:29:58,456 and define a new function, 702 00:29:58,456 --> 00:30:00,486 it's gonna return void 'cause it's just gonna print. 703 00:30:00,486 --> 00:30:01,976 It's not gonna return any values or numbers. 704 00:30:02,016 --> 00:30:02,083 . 705 00:30:02,083 --> 00:30:04,596 >> I'm gonna call it like last week chorus. 706 00:30:04,926 --> 00:30:07,526 Just to be clear, I'm going to go ahead 707 00:30:07,526 --> 00:30:10,096 and call this int bottles, 708 00:30:10,246 --> 00:30:13,106 I'm not gonna call it N this time, alright. 709 00:30:13,106 --> 00:30:15,876 And then I'm gonna go ahead and paste in that same code. 710 00:30:16,136 --> 00:30:18,156 And I just need to tweak it a little bit. 711 00:30:18,156 --> 00:30:19,836 I need to change this to bottles 712 00:30:20,356 --> 00:30:22,856 and everything else looks pretty good. 713 00:30:23,036 --> 00:30:24,886 So let me now scroll back up. 714 00:30:24,886 --> 00:30:26,576 I definitely don't need this anymore, 715 00:30:26,576 --> 00:30:28,966 but what do I wanna put here instead? 716 00:30:29,946 --> 00:30:31,956 How do I call a function that I've written? 717 00:30:32,916 --> 00:30:35,646 Yeah, it's just a word, just like printf, chorus, 718 00:30:35,646 --> 00:30:39,306 and then I need to pass in the value N, so why do this? 719 00:30:39,306 --> 00:30:41,956 Well now, if you kind of scroll back up, and this is one 720 00:30:42,346 --> 00:30:46,196 of the aims of good design, it's actually now really super simple 721 00:30:46,196 --> 00:30:49,626 to read this program as for the first time and realize, oh, 722 00:30:49,626 --> 00:30:51,656 I can totally wrap my mind around this quickly. 723 00:30:51,656 --> 00:30:54,316 First is prompting for some input, it's getting that input, 724 00:30:54,476 --> 00:30:56,256 it's doing a sanity check on the-- 725 00:30:56,256 --> 00:30:58,896 what value the user types in, and then it's printing a chorus. 726 00:30:58,966 --> 00:31:00,826 And what's nice now, is you reach the end 727 00:31:00,826 --> 00:31:04,026 of this function main, the program is done, and so now, 728 00:31:04,126 --> 00:31:06,406 if you are curious and once you wrapped your mind 729 00:31:06,406 --> 00:31:09,526 around this program, now you can dive in deeper and say okay, 730 00:31:09,746 --> 00:31:12,496 what is chorus, and sure enough, if you scroll down, 731 00:31:12,546 --> 00:31:15,386 now you can focus on this more bite size program. 732 00:31:15,386 --> 00:31:18,906 So this notion of decomposition is partly for this reason here 733 00:31:19,086 --> 00:31:21,546 so that frankly your programs don't become this and this 734 00:31:21,546 --> 00:31:24,186 and this long, whereby the time you get to the halfway down 735 00:31:24,186 --> 00:31:25,176 or the bottom of the function, 736 00:31:25,176 --> 00:31:26,886 you forget what you even did before, 737 00:31:27,136 --> 00:31:29,976 rather much like an English story or an outline 738 00:31:29,976 --> 00:31:31,646 for an essay, you can get a sense 739 00:31:31,646 --> 00:31:35,316 from main alone what's going on and only if you care, 740 00:31:35,316 --> 00:31:37,666 as to how course works do you need to look 741 00:31:37,666 --> 00:31:39,166 down lower in the file. 742 00:31:39,756 --> 00:31:41,726 Now, we can do this slightly differently 743 00:31:41,726 --> 00:31:42,996 but there's a bug first. 744 00:31:43,246 --> 00:31:46,156 This code will not compile, why? 745 00:31:46,746 --> 00:31:46,846 Yeah. 746 00:31:46,846 --> 00:31:48,436 [ Inaudible Remark ] 747 00:31:48,436 --> 00:31:50,616 >> Yeah, so I need this thing called the function prototype 748 00:31:50,616 --> 00:31:52,686 because again, C is pretty primitive in that 749 00:31:52,846 --> 00:31:54,276 if you don't tell it that something 750 00:31:54,276 --> 00:31:56,726 like a function exists, it's gonna assume it doesn't 751 00:31:56,996 --> 00:31:59,326 if it encounters it earlier in the file. 752 00:31:59,536 --> 00:32:02,746 So even though chorus absolutely exists down here, 753 00:32:02,876 --> 00:32:06,076 I need to provide a little clue at the very top of my file, 754 00:32:06,176 --> 00:32:08,256 and I don't strictly need to hit Enter here. 755 00:32:08,256 --> 00:32:10,616 It's typically more common just to put a line like that. 756 00:32:10,946 --> 00:32:14,026 I just need to copy and paste literally the 757 00:32:14,026 --> 00:32:15,006 function's prototype. 758 00:32:15,086 --> 00:32:17,626 It's return type, so the word like void but more on those 759 00:32:17,666 --> 00:32:19,746 to come, the name of the function chorus, 760 00:32:19,986 --> 00:32:22,356 it's type of integer, type of argument, 761 00:32:22,586 --> 00:32:23,816 and in this case, its name. 762 00:32:23,816 --> 00:32:26,776 Though as an aside, its name is not strictly necessary, 763 00:32:26,776 --> 00:32:27,816 you might see in textbooks 764 00:32:27,846 --> 00:32:30,226 that people just do this, that's fine too. 765 00:32:30,466 --> 00:32:33,656 But it's somewhat simpler and more readable, I would say, 766 00:32:33,656 --> 00:32:35,366 to include the name of the argument. 767 00:32:35,676 --> 00:32:38,096 So now this should compile, let's take a look. 768 00:32:38,096 --> 00:32:40,866 Let me zoom in, let me go ahead and make beer 1, 769 00:32:41,346 --> 00:32:42,616 it did indeed compile. 770 00:32:42,616 --> 00:32:44,026 Let me go ahead and run beer 1, 771 00:32:44,386 --> 00:32:47,616 we'll do let's just say 99 bottles of beer, zooms by, 772 00:32:47,926 --> 00:32:49,376 0 bottles of beer on the wall. 773 00:32:49,846 --> 00:32:52,656 But there's still a bug, not so much a logical bug now 774 00:32:52,656 --> 00:32:55,046 but really a grammatical one, which is what obviously? 775 00:32:55,046 --> 00:32:56,466 [ Inaudible Remarks ] 776 00:32:56,466 --> 00:32:57,916 >> Yeah, so now I'm kinda mispronouncing. 777 00:32:57,916 --> 00:33:00,466 This one bottles of beer on the wall feels 778 00:33:00,466 --> 00:33:01,496 like we can do better, right. 779 00:33:01,496 --> 00:33:03,396 And this might seem like a trivial little thing, 780 00:33:03,656 --> 00:33:05,956 but all of us kind of, you know, if you notice these things 781 00:33:05,956 --> 00:33:08,706 in Windows or Mac programs, and you kind of-- 782 00:33:08,706 --> 00:33:09,776 you know, eyebrows go up. 783 00:33:09,776 --> 00:33:12,426 If you see something stupid like this in a program that you paid 784 00:33:12,426 --> 00:33:16,326 for or downloaded and it's just got grammatical mistakes in it. 785 00:33:16,326 --> 00:33:18,526 But this is actually really easy to fix, right. 786 00:33:18,526 --> 00:33:22,016 Conceptually, we just need to do what, inside of this loop? 787 00:33:22,396 --> 00:33:27,796 We just need to conditionally say bottle or bottle, 788 00:33:27,796 --> 00:33:29,736 so we can do this in any number of ways. 789 00:33:29,976 --> 00:33:32,336 In fact, the simplest might be to do this. 790 00:33:32,756 --> 00:33:40,616 So if I equals, equals, 1, let me go ahead and indent this. 791 00:33:40,616 --> 00:33:43,266 Let me go ahead and do a little copy-paste 792 00:33:43,266 --> 00:33:44,956 but that should be your first warning sign. 793 00:33:44,956 --> 00:33:47,836 If you find that you're doing a lot of copy-paste, odds are, 794 00:33:47,886 --> 00:33:49,826 you can something a little differently. 795 00:33:50,236 --> 00:33:53,296 So let me do this here so if that [inaudible], 796 00:33:53,296 --> 00:33:55,886 I'm gonna do this, let me scroll down. 797 00:33:55,886 --> 00:33:58,476 Let me print this over here. 798 00:33:59,246 --> 00:34:02,216 So now I just need to change the grammar, so if 1 bottle 799 00:34:02,216 --> 00:34:03,546 of beer, 1 bottle of beer. 800 00:34:03,796 --> 00:34:05,976 Technically, this is a little redundant now. 801 00:34:05,976 --> 00:34:07,416 Do I need to be doing the placeholder? 802 00:34:07,876 --> 00:34:10,386 No, you can leave it, but-- so in short, there's a number 803 00:34:10,386 --> 00:34:11,306 of ways we can do this, right. 804 00:34:11,306 --> 00:34:13,456 I could hard code the number of 1 int at this point, 805 00:34:13,676 --> 00:34:16,306 get rid of I and then also do the same in the second line. 806 00:34:16,606 --> 00:34:18,846 Or I can keep it the same but feels 807 00:34:18,846 --> 00:34:20,996 like we're doing a little too much work here, right. 808 00:34:20,996 --> 00:34:23,526 We're kind of copying and pasting 2 pretty ugly lines 809 00:34:23,526 --> 00:34:26,026 of code, making them almost identical except 810 00:34:26,026 --> 00:34:27,556 for the omission of 1 letter. 811 00:34:27,996 --> 00:34:30,066 So what could we do instead? 812 00:34:30,566 --> 00:34:32,836 [ Inaudible Remarks ] 813 00:34:33,336 --> 00:34:35,066 >> So use the conditional or okay. 814 00:34:35,066 --> 00:34:36,896 So we saw one clever approach 815 00:34:36,896 --> 00:34:40,496 with like a one liner whereby we just factored out-- 816 00:34:41,086 --> 00:34:42,516 whereby we factored out this condition. 817 00:34:42,516 --> 00:34:44,076 Let's actually not go there just yet. 818 00:34:44,076 --> 00:34:47,426 Let's see if we can't simplify at least what we're asking for. 819 00:34:47,426 --> 00:34:48,466 What if I instead I do this? 820 00:34:48,556 --> 00:34:50,726 Where if I equals, equals 1, 821 00:34:51,086 --> 00:34:53,246 really the whole sentence doesn't have to change, 822 00:34:53,246 --> 00:34:56,566 rather it's simply what aspect of it, it's the word. 823 00:34:56,726 --> 00:35:02,426 So what if I said something like S gets bottle, otherwise, 824 00:35:03,636 --> 00:35:07,736 S gets bottles and now I don't need these curly braces 'cause 825 00:35:07,736 --> 00:35:08,886 it's just one line of code. 826 00:35:09,116 --> 00:35:10,356 This isn't quite right yet, 827 00:35:10,386 --> 00:35:11,916 but notice where I could go with this. 828 00:35:11,996 --> 00:35:13,956 So let me actually rip out this, 'cause I've decided, 829 00:35:14,166 --> 00:35:15,476 I don't really like this approach. 830 00:35:15,476 --> 00:35:18,996 Let me move this over here, get rid of this, so now we're back 831 00:35:19,056 --> 00:35:22,016 to the original version except for this part up top here. 832 00:35:22,446 --> 00:35:26,016 So this isn't gonna compile yet, and it's not even useful yet, 833 00:35:26,016 --> 00:35:27,886 because what do I need to change here? 834 00:35:28,806 --> 00:35:30,826 That could be percent S, that could be percent S, 835 00:35:31,206 --> 00:35:33,366 then I'm gonna have to plug in S here, then I'm gonna have 836 00:35:33,366 --> 00:35:34,636 to plug in S here, but, 837 00:35:34,746 --> 00:35:37,416 what else am I still gonna have to do? 838 00:35:37,416 --> 00:35:37,483 [ Inaudible Remarks ] 839 00:35:37,483 --> 00:35:40,956 >> Yeah. So I still need to declare S. So let me do this, 840 00:35:40,956 --> 00:35:43,576 string S, but okay, wait a minute, I kinda need 841 00:35:43,576 --> 00:35:44,756 to do it here then right. 842 00:35:44,756 --> 00:35:46,876 'Cause only one of those branches is gonna execute. 843 00:35:47,606 --> 00:35:49,656 But still broken, why? 844 00:35:49,656 --> 00:35:49,723 [ Inaudible Remarks ] 845 00:35:49,723 --> 00:35:51,766 >> Yeah, scope. 846 00:35:52,086 --> 00:35:55,116 So again, this issue with scope and even though in this case, 847 00:35:55,226 --> 00:35:57,976 we have just single lines of code and so we're allowed 848 00:35:57,976 --> 00:36:00,296 to cut a corner we don't strictly need these 849 00:36:00,296 --> 00:36:01,126 curly braces. 850 00:36:01,356 --> 00:36:05,306 Remember that rule of thumb that if there are curly braces 851 00:36:05,306 --> 00:36:08,096 or effectively there are, except in this special case 852 00:36:08,096 --> 00:36:09,026 where you can omit them, 853 00:36:09,356 --> 00:36:14,406 really that means S will exist here or S will exist here. 854 00:36:14,586 --> 00:36:18,226 But as soon as you get here, later in the program, S is gone. 855 00:36:18,226 --> 00:36:20,236 That memory is no longer accessible to you. 856 00:36:20,376 --> 00:36:23,836 So you can't save the word S. So I need a better solution, 857 00:36:23,836 --> 00:36:26,966 so I can't declare the variable inside the curly braces 858 00:36:27,206 --> 00:36:28,146 or inside the condition 859 00:36:28,146 --> 00:36:31,036 but I can declare it, for instance, here. 860 00:36:31,356 --> 00:36:33,546 So on occasion, you will encounter scenarios 861 00:36:33,656 --> 00:36:36,776 where you have to declare variables a little sooner 862 00:36:36,776 --> 00:36:38,186 than you actually wanna use them. 863 00:36:38,396 --> 00:36:41,966 But you need to declare then somewhere within the scope 864 00:36:41,966 --> 00:36:44,026 of the chunk of code that you wanna use them in. 865 00:36:44,566 --> 00:36:46,636 Now recall last week, we had what we called, 866 00:36:46,636 --> 00:36:48,036 it's called the ternary operator. 867 00:36:48,036 --> 00:36:50,596 It was that funky thing with parentheses and so forth. 868 00:36:50,986 --> 00:36:54,626 It turns out, that if this kind of strikes you as kind of ugly 869 00:36:54,626 --> 00:36:57,126 and my God, I just doubled the size of this function just 870 00:36:57,126 --> 00:37:00,046 to do something stupid like print out bottle or bottles. 871 00:37:00,396 --> 00:37:04,586 Well, realize that there's syntactic sugar in languages 872 00:37:04,586 --> 00:37:06,646 like C where you could actually say this. 873 00:37:06,646 --> 00:37:11,866 String S gets either the value bottle or bottles based 874 00:37:11,866 --> 00:37:15,446 on whether I equals, equals 1, and if I does equal 1, 875 00:37:15,506 --> 00:37:17,466 I wanted to get the word bottle. 876 00:37:17,466 --> 00:37:19,856 Otherwise I wanted to get the word bottles. 877 00:37:20,066 --> 00:37:23,816 And so what's nice is all this kind of ugly code, not wrong, 878 00:37:23,816 --> 00:37:26,276 wouldn't be penalized for this certainly, 'cause it is correct 879 00:37:26,276 --> 00:37:27,906 and it's nicely indented and so forth, 880 00:37:28,246 --> 00:37:30,176 but you can actually simplify this 881 00:37:30,216 --> 00:37:31,276 to something much more elegant. 882 00:37:31,476 --> 00:37:34,736 And so this is the so called ternary operator and opposed 883 00:37:34,736 --> 00:37:39,896 to binary or unary in the sense that it actually takes 3 values, 884 00:37:39,896 --> 00:37:42,846 one to the right, one to the middle, and then 1 to the left. 885 00:37:43,046 --> 00:37:45,026 But that's just unnecessary jargon. 886 00:37:45,486 --> 00:37:47,856 So with this work, is S now in scope? 887 00:37:48,066 --> 00:37:50,316 So it actually is. 888 00:37:50,316 --> 00:37:51,016 So this is nice-- 889 00:37:51,086 --> 00:37:52,816 a nice one-liner for fixing the grammar. 890 00:37:52,816 --> 00:37:54,556 We haven't fixed everything, right. 891 00:37:55,086 --> 00:37:58,456 This is still broken and I can't quite use the same word there 892 00:37:58,456 --> 00:38:01,766 necessarily, but let me wave my hand at that final detail, 893 00:38:02,126 --> 00:38:05,296 but the idea hopefully is how we can fix the grammar is hopefully 894 00:38:05,296 --> 00:38:08,626 more clear now. 895 00:38:10,716 --> 00:38:10,806 Yeah. 896 00:38:10,806 --> 00:38:11,026 [ Inaudible Remark ] 897 00:38:11,026 --> 00:38:14,356 >> If else-- if-- and if else if, else if? 898 00:38:15,326 --> 00:38:17,516 So you could absolutely do that. 899 00:38:19,016 --> 00:38:24,226 To contrive a scenario here, if I equals, equals, 0 I could say, 900 00:38:24,226 --> 00:38:29,886 S gets no bottles and yell, for instance, else if I equals, 901 00:38:29,886 --> 00:38:33,896 equals 1, then I can do S gets 1 bottle for instance, 902 00:38:33,966 --> 00:38:38,606 else I can do S gets bottles. 903 00:38:39,646 --> 00:38:41,876 So in other words, I can have as many branches as I like 904 00:38:41,876 --> 00:38:43,626 and as before, I don't need those curly braces. 905 00:38:43,626 --> 00:38:45,556 [ Inaudible Remarks ] 906 00:38:45,556 --> 00:38:47,366 >> Oh, oh I'm sorry. 907 00:38:47,366 --> 00:38:48,526 I misinterpreted your question. 908 00:38:48,646 --> 00:38:52,336 No. So, that was the shorter answer. 909 00:38:52,336 --> 00:38:54,246 No, you can have-- well actually, that's-- 910 00:38:54,246 --> 00:38:55,886 that-- okay, no, I'm wrong. 911 00:38:56,256 --> 00:39:00,066 So you can, it just starts to get less clear. 912 00:39:00,066 --> 00:39:02,646 You can actually put another set of parentheses here, 913 00:39:02,846 --> 00:39:05,136 and another question mark and colon, and another set 914 00:39:05,136 --> 00:39:06,096 of parentheses and so forth. 915 00:39:06,266 --> 00:39:09,146 But I would argue against doing that, because honestly, 916 00:39:09,146 --> 00:39:11,286 it becomes much less readable if you're not sure 917 00:39:11,286 --> 00:39:13,256 which one lines up with which idea. 918 00:39:13,696 --> 00:39:24,216 So I reduce it just to this degree. 919 00:39:24,416 --> 00:39:24,946 Yeah. 920 00:39:25,446 --> 00:39:28,426 [ Inaudible Remarks ] 921 00:39:28,926 --> 00:39:30,556 >> Uh-huh. 922 00:39:30,556 --> 00:39:30,623 [ Inaudible Remarks ] 923 00:39:30,623 --> 00:39:31,756 >> Really good question. 924 00:39:31,756 --> 00:39:34,996 So if you declare a function in this way, with the prototype 925 00:39:34,996 --> 00:39:36,256 at the very top of your function. 926 00:39:36,706 --> 00:39:39,256 That seems to run the risk of colliding 927 00:39:39,306 --> 00:39:41,596 with other functions you wrote and might still be using, 928 00:39:41,896 --> 00:39:43,386 that might run the risk of colliding 929 00:39:43,386 --> 00:39:45,326 with functions other people wrote, right. 930 00:39:45,326 --> 00:39:46,846 For instance, what if the person 931 00:39:46,846 --> 00:39:49,666 who wrote the standard I/O library whose header file is 932 00:39:49,666 --> 00:39:51,196 called standard io.h? 933 00:39:51,466 --> 00:39:54,266 What if that file contains a function called chorus? 934 00:39:54,806 --> 00:39:56,796 Well, in C, you're kind of out of luck. 935 00:39:56,796 --> 00:39:57,846 Like that happens. 936 00:39:57,936 --> 00:40:00,456 There's no notion of what's called name spaces or packages 937 00:40:00,456 --> 00:40:03,436 in C. So this is a problem that is solved 938 00:40:03,436 --> 00:40:05,626 by more modern languages which will get to you later 939 00:40:05,626 --> 00:40:09,286 in this semester among them PHP, JavaScript and the like. 940 00:40:09,396 --> 00:40:12,026 C plus, plus handles this as those Java but in C, 941 00:40:12,126 --> 00:40:15,196 you cannot for instance, steal the name of a function 942 00:40:15,196 --> 00:40:19,456 that someone else wrote that you are using by way of including it 943 00:40:19,456 --> 00:40:19,976 with something like this. 944 00:40:20,046 --> 00:40:21,846 >> So you could not implement get int, 945 00:40:21,846 --> 00:40:25,106 you could not implement printf unless, you were willing 946 00:40:25,106 --> 00:40:27,306 to sacrifice that other person's version of it. 947 00:40:27,896 --> 00:40:28,966 Good question, yeah. 948 00:40:29,516 --> 00:40:34,336 [ Inaudible Remarks ] 949 00:40:34,836 --> 00:40:35,706 >> Ah, good question. 950 00:40:35,706 --> 00:40:40,906 Would you want to declare the string S outside of the 4 loop? 951 00:40:40,906 --> 00:40:43,716 You could in theory declare it outside of the loop 952 00:40:43,716 --> 00:40:45,556 and you would then still have access to it. 953 00:40:45,766 --> 00:40:48,266 Because it would still be in scope, but the problem is 954 00:40:48,296 --> 00:40:51,916 that the words are changing as this loop iterates. 955 00:40:52,316 --> 00:40:54,936 It might go from 3 to 2 to 1 to 0. 956 00:40:55,166 --> 00:40:57,036 It might go from 2 to 1 to 0. 957 00:40:57,316 --> 00:40:59,486 So, in other words, you need to make the decision 958 00:41:00,356 --> 00:41:02,666 at some point conditionally in the loop 959 00:41:02,666 --> 00:41:04,136 as to what word you're gonna spit out. 960 00:41:04,296 --> 00:41:06,336 You can't do it based on N alone, right. 961 00:41:06,336 --> 00:41:09,696 Because it's not N's bottles, it's the I equals 1. 962 00:41:09,696 --> 00:41:09,966 [ Inaudible Remarks ] 963 00:41:09,966 --> 00:41:14,976 >> Oh I see, absolutely. 964 00:41:14,976 --> 00:41:18,876 So if you want it, you could do this here. 965 00:41:19,176 --> 00:41:21,716 However, I would argue as a matter of style. 966 00:41:21,926 --> 00:41:22,916 This gains you nothing. 967 00:41:23,126 --> 00:41:24,996 Oh, and I see what you're saying, in terms of efficiency. 968 00:41:24,996 --> 00:41:28,086 So this is-- this would be recommended against these days. 969 00:41:28,086 --> 00:41:30,266 The version of C that we are using allows you 970 00:41:30,266 --> 00:41:33,326 to do exactly what I did the first time and the compiler, 971 00:41:33,326 --> 00:41:36,906 namely GCC is smart enough to realize that it doesn't need 972 00:41:36,906 --> 00:41:41,226 to reallocate a new 32 bits, 32 bits, 32 bits or whatever it is 973 00:41:41,226 --> 00:41:42,446 for that particular string. 974 00:41:42,696 --> 00:41:44,426 All it will do is update the assignment. 975 00:41:44,546 --> 00:41:45,926 So for that kind of detail, 976 00:41:46,396 --> 00:41:48,596 generally the compiler is smarter than us, 977 00:41:48,596 --> 00:41:49,726 so you don't have worry about that. 978 00:41:50,836 --> 00:41:51,776 Good question, yeah. 979 00:41:52,516 --> 00:42:00,776 [ Inaudible Remarks ] 980 00:42:01,276 --> 00:42:02,006 >> If you had the same-- 981 00:42:02,006 --> 00:42:04,396 if you had 2 libraries with the same function name in them, 982 00:42:04,396 --> 00:42:05,586 you could not use them together. 983 00:42:05,586 --> 00:42:06,116 It would break. 984 00:42:06,116 --> 00:42:07,776 The compiler would yell that previously-- 985 00:42:07,976 --> 00:42:09,896 it would yell that the function is previously declared. 986 00:42:10,546 --> 00:42:11,146 Good question. 987 00:42:11,816 --> 00:42:14,096 Alright, so that was bottles. 988 00:42:14,096 --> 00:42:16,936 Let's take a look now at 2 buggy programs just 989 00:42:16,936 --> 00:42:22,116 to see whether this starts to pop out a little more. 990 00:42:22,116 --> 00:42:27,456 This is buggy4.c. So this is a program that's supposed 991 00:42:27,456 --> 00:42:29,896 to increment a variable but I claim does not. 992 00:42:29,896 --> 00:42:31,836 All that made it at top is the comments. 993 00:42:32,196 --> 00:42:33,306 So let's look at the top. 994 00:42:33,306 --> 00:42:34,836 At the top, we have a function prototype 995 00:42:34,926 --> 00:42:36,976 for a function that's apparently called increment 996 00:42:37,176 --> 00:42:40,776 that takes no arguments and returns nothing, main does what? 997 00:42:41,096 --> 00:42:45,396 Alright. So X gets 1, it prints out the value, just says, dot, 998 00:42:45,526 --> 00:42:49,126 dot, dot, calls increment, then prints out the value of X again. 999 00:42:49,606 --> 00:42:52,276 So the que-- this is buggy, this is not in fact going 1000 00:42:52,276 --> 00:42:54,216 to increment X, but why? 1001 00:42:54,216 --> 00:42:55,526 Let's look at the increment function. 1002 00:42:57,076 --> 00:43:00,506 This is broken, and in fact won't even compile, why? 1003 00:43:01,126 --> 00:43:01,246 Yeah. 1004 00:43:01,246 --> 00:43:02,096 [ Inaudible Remarks ] 1005 00:43:02,096 --> 00:43:07,546 >> Yeah, it doesn't declare the type of what? 1006 00:43:07,546 --> 00:43:08,506 [ Inaudible Remarks ] 1007 00:43:08,506 --> 00:43:10,216 >> Okay. So it hasn't declared a type 1008 00:43:10,216 --> 00:43:13,226 for the variable X, okay, I'll fix that. 1009 00:43:13,226 --> 00:43:15,856 Let me do in text. 1010 00:43:15,856 --> 00:43:18,026 Better? So not quite. 1011 00:43:18,066 --> 00:43:21,296 These two is now actually worse, you can't declare a variable 1012 00:43:21,296 --> 00:43:22,706 like this and then do plus, plus. 1013 00:43:22,706 --> 00:43:24,126 Frankly, it doesn't even have a value yet. 1014 00:43:24,156 --> 00:43:25,826 So that's not quite right, so it's a good thought 1015 00:43:25,826 --> 00:43:29,166 and it is related to this fundamental problem here, yeah? 1016 00:43:29,356 --> 00:43:31,356 [ Inaudible Remarks ] 1017 00:43:31,546 --> 00:43:35,306 >> Yeah, exactly, so X exists but it only exists up here. 1018 00:43:35,306 --> 00:43:38,726 So it only exists in the scope of main whose scope is defined 1019 00:43:38,726 --> 00:43:40,006 by its own curly braces. 1020 00:43:40,386 --> 00:43:43,406 So okay, alright, let me fix, then let me do this. 1021 00:43:43,406 --> 00:43:47,866 Now increment has its own X. Okay, yeah? 1022 00:43:48,516 --> 00:43:53,586 [ Inaudible Remarks ] 1023 00:43:54,086 --> 00:43:54,676 >> Okay. 1024 00:43:55,516 --> 00:44:10,576 [ Inaudible Remarks ] 1025 00:44:11,076 --> 00:44:11,316 >> Okay. 1026 00:44:11,316 --> 00:44:13,016 [ Inaudible Remarks ] 1027 00:44:13,016 --> 00:44:16,956 >> Okay, so we somehow need to pass from main the value of X 1028 00:44:17,116 --> 00:44:20,236 into this increment function it it's actually gonna do anything 1029 00:44:20,236 --> 00:44:21,166 if I can simplify. 1030 00:44:21,416 --> 00:44:24,386 And let me just before I erase the second mistake here 1031 00:44:24,686 --> 00:44:25,896 with this compile though. 1032 00:44:27,206 --> 00:44:28,986 So this would actually compile, right. 1033 00:44:28,986 --> 00:44:31,546 'Cause if you go back to basic definitions what is increment 1034 00:44:31,546 --> 00:44:32,156 now doing? 1035 00:44:32,296 --> 00:44:34,196 Well, it's not taking any input, but that's fine, 1036 00:44:34,396 --> 00:44:36,976 it is declaring a variable called X and it's 1037 00:44:36,976 --> 00:44:38,666 of type int and that means what? 1038 00:44:38,756 --> 00:44:42,816 32 bits are being set aside inside of increment's frame. 1039 00:44:42,816 --> 00:44:44,736 Remember when we drew RAM as a big rectangle, 1040 00:44:44,926 --> 00:44:47,116 so a sliver of RAM has now been allocated 1041 00:44:47,116 --> 00:44:48,036 to the increment function. 1042 00:44:48,036 --> 00:44:50,546 And in there is some 32 bits that are gonna be used 1043 00:44:50,546 --> 00:44:53,236 for this variable X, and then it's incrementing X. 1044 00:44:53,716 --> 00:44:54,716 But there is a problem here. 1045 00:44:54,866 --> 00:44:56,386 What is X at that point in the story? 1046 00:44:57,556 --> 00:45:00,256 Like we don't know, and in fact, if you think back now 1047 00:45:00,256 --> 00:45:03,246 to last week's picture when we drew RAM as a big rectangle. 1048 00:45:03,426 --> 00:45:07,056 The interesting thing about this design of memory use 1049 00:45:07,056 --> 00:45:09,566 in a computer is if this is main at the bottom. 1050 00:45:09,696 --> 00:45:12,316 Well, main is kind of lucky in that his memory always sticks 1051 00:45:12,316 --> 00:45:14,976 around until the program ends because his gets put 1052 00:45:15,186 --> 00:45:17,036 into the computer's memory first. 1053 00:45:17,316 --> 00:45:19,266 Well, what if you call a function foo, 1054 00:45:19,266 --> 00:45:21,246 it ends up there but then foo returns. 1055 00:45:21,246 --> 00:45:23,186 So what happens to it, this gets reclaimed. 1056 00:45:23,226 --> 00:45:26,066 What if you then call a function bar, well, it might go there 1057 00:45:26,066 --> 00:45:29,096 on top of main but then it return so its memory goes away. 1058 00:45:29,436 --> 00:45:31,366 But it doesn't really go away per se, 1059 00:45:31,366 --> 00:45:32,856 it's just that the computer forgets 1060 00:45:32,956 --> 00:45:35,836 that those bits were once used by a function foo 1061 00:45:35,836 --> 00:45:39,196 or those bits were once used by a function bar but all those 0s 1062 00:45:39,196 --> 00:45:40,266 and 1s are still there. 1063 00:45:40,446 --> 00:45:41,836 All the magnetic particles 1064 00:45:41,836 --> 00:45:43,896 or all the electrons are still there 1065 00:45:43,896 --> 00:45:46,006 in the same orientation you left them. 1066 00:45:46,296 --> 00:45:48,176 And so what might happen when a function 1067 00:45:48,176 --> 00:45:49,986 like increment is called, well, 1068 00:45:49,986 --> 00:45:52,236 increment is gonna get a sliver of memory. 1069 00:45:52,456 --> 00:45:57,256 But if you had 011, 011 whatever the 0s and 1s were 1070 00:45:57,646 --> 00:46:01,276 when a function called foo or bar was using that chunk 1071 00:46:01,276 --> 00:46:03,206 of memory, what value is gonna be an X 1072 00:46:03,416 --> 00:46:04,396 at this point in the story. 1073 00:46:05,386 --> 00:46:06,506 The answer before was this 1074 00:46:06,506 --> 00:46:09,396 but really it's whatever junk was left over there 1075 00:46:09,706 --> 00:46:13,176 by those previous function calls, foo or bar. 1076 00:46:13,486 --> 00:46:16,706 So these two is going to be for bad guys an opportunity 1077 00:46:16,966 --> 00:46:18,796 to do bad things, right? 1078 00:46:18,796 --> 00:46:21,616 If you can imagine a program whose purpose in life is not 1079 00:46:21,616 --> 00:46:24,176 to increment numbers but to ask you for your password, right, 1080 00:46:24,176 --> 00:46:26,306 and you guys have been doing this, to submit 50 program 1081 00:46:26,306 --> 00:46:28,736 for instance in the appliance asks you for a password. 1082 00:46:28,856 --> 00:46:32,436 Well, that password gets stored in the appliance's RAM inside 1083 00:46:32,436 --> 00:46:34,436 of some function, inside of some slice 1084 00:46:34,436 --> 00:46:36,146 of RAM allocated to some function. 1085 00:46:36,396 --> 00:46:39,246 But as soon as you're done running submit 50, okay, 1086 00:46:39,246 --> 00:46:41,266 that memory is given back to the operating system 1087 00:46:41,266 --> 00:46:42,606 and these slivers go away. 1088 00:46:42,606 --> 00:46:46,136 But what about the 0s and 1s, what about the ASCII characters 1089 00:46:46,136 --> 00:46:47,416 that were temporarily 1090 00:46:47,466 --> 00:46:51,596 in RAM storing your password, where are they? 1091 00:46:51,836 --> 00:46:54,526 They're still in RAM, right, the computer's forgotten 1092 00:46:54,526 --> 00:46:57,596 where they are but if a bad guy has physical access 1093 00:46:57,596 --> 00:46:59,246 to your computer or somehow hacks 1094 00:46:59,246 --> 00:47:01,956 in via some network connection and has the ability 1095 00:47:02,216 --> 00:47:05,156 and the savvy to poke around your computer's RAM, 1096 00:47:05,376 --> 00:47:07,316 you might see 1, 2, 3, 4, 1097 00:47:07,316 --> 00:47:10,506 5 or whatever your password is just lying around there 1098 00:47:10,746 --> 00:47:13,796 in memory and it's simply because, again, computer's use 1099 00:47:13,796 --> 00:47:15,356 of RAM is the simplistic. 1100 00:47:15,476 --> 00:47:18,306 So what's happening here, I'm saying give me 32 bits, 1101 00:47:18,306 --> 00:47:21,126 call it X. Increment that value but who knows what 1102 00:47:21,126 --> 00:47:23,316 that value is, maybe it is, 1, 2, 3, 4, 5. 1103 00:47:23,556 --> 00:47:26,476 So what did I just do, I plus plus it to 1, 2, 3, 4, 1104 00:47:26,476 --> 00:47:29,346 6 but then this function returns 1105 00:47:29,726 --> 00:47:31,566 and so what effect does this have ultimately 1106 00:47:31,566 --> 00:47:34,806 on this variable here X, absolutely none. 1107 00:47:34,806 --> 00:47:37,186 It's in a completely different sliver of RAM. 1108 00:47:38,506 --> 00:47:39,006 So that was a lot. 1109 00:47:39,006 --> 00:47:41,466 Why don't we go ahead and take our 5-minute break here. 1110 00:47:41,966 --> 00:47:44,186 [ Noise ] 1111 00:47:44,686 --> 00:47:49,276 >> Alright, we are back. 1112 00:47:50,626 --> 00:47:54,546 So recall that last week we scratched the surface 1113 00:47:54,546 --> 00:47:56,256 of this other topic known as an array, 1114 00:47:56,256 --> 00:47:58,686 in English as best you understand now, 1115 00:47:58,686 --> 00:48:01,186 what is an array with regard to C? 1116 00:48:02,846 --> 00:48:03,586 Anyone got something? 1117 00:48:04,696 --> 00:48:07,826 So it's a list, right, it's some kind of variable, 1118 00:48:07,826 --> 00:48:09,726 let's call it noun, that's not quite right but it's some kind 1119 00:48:09,726 --> 00:48:11,646 of variable that doesn't store one value 1120 00:48:11,646 --> 00:48:13,986 but it stores multiple values and we did see something just 1121 00:48:13,986 --> 00:48:16,486 like this in scratch and scratch called them list. 1122 00:48:16,486 --> 00:48:18,486 And in other word, that gets tossed 1123 00:48:18,486 --> 00:48:20,216 around for these things that's called vectors. 1124 00:48:20,486 --> 00:48:24,576 But an array in C can be likened conceptionally to like a bunch 1125 00:48:24,576 --> 00:48:27,486 of mailboxes, right, an array in C is a bunch 1126 00:48:27,486 --> 00:48:29,636 of contiguous chunks of memory. 1127 00:48:29,636 --> 00:48:31,986 Contiguous just means back to back to back in RAM. 1128 00:48:32,306 --> 00:48:34,806 And so in this case here, this might be an array 1129 00:48:34,806 --> 00:48:36,986 of mailboxes of size 5. 1130 00:48:37,276 --> 00:48:41,226 So I could store for instance one thing inside each 1131 00:48:41,226 --> 00:48:42,896 of these mailboxes and that's it. 1132 00:48:42,986 --> 00:48:44,466 Now, what thing can I put in there? 1133 00:48:44,466 --> 00:48:46,286 Well, it depends on how we declare the array. 1134 00:48:46,606 --> 00:48:50,036 If we say this is an array of int, I can fit 32 bits 1135 00:48:50,036 --> 00:48:51,586 in each of these mailboxes. 1136 00:48:51,906 --> 00:48:55,106 If I declare them, the array as a char array, 1137 00:48:55,316 --> 00:48:57,606 I can only fit how many bits in each. 1138 00:48:59,376 --> 00:49:02,246 So just H, right, remember that a char is a byte 1139 00:49:02,246 --> 00:49:05,646 and a byte is a bit so if this is an array of chars, 1140 00:49:05,646 --> 00:49:08,796 of characters, well I can only fit 8 bits in each, right? 1141 00:49:08,796 --> 00:49:10,936 So that's like having smaller or bigger mailboxes. 1142 00:49:11,276 --> 00:49:14,866 Now, if I wanted to store a word in these mailboxes, well, 1143 00:49:14,866 --> 00:49:17,096 what's the longest word I could store in here? 1144 00:49:17,726 --> 00:49:21,236 And so maximally 5 for sure, right, 1145 00:49:21,236 --> 00:49:22,696 if there's only 5 mailboxes. 1146 00:49:22,926 --> 00:49:25,066 But recall from last week, it's not quite 5. 1147 00:49:25,246 --> 00:49:29,846 In fact, the upper bound is 4 because we actually want to keep 1148 00:49:29,846 --> 00:49:32,406 around some kind of reminder 1149 00:49:32,406 --> 00:49:35,176 that that string, that word ends here. 1150 00:49:35,176 --> 00:49:38,426 And so that special character, recall, was the null character 1151 00:49:38,426 --> 00:49:39,766 or the backslash zero, 1152 00:49:39,766 --> 00:49:42,616 so all zero bits denotes the end of a string. 1153 00:49:42,616 --> 00:49:44,436 So we can generalize this now as an array, 1154 00:49:44,676 --> 00:49:48,386 it's just its placeholders, it's cubbies, it's a mailbox inside 1155 00:49:48,386 --> 00:49:51,346 of which you can put a whole bunch of values one 1156 00:49:51,546 --> 00:49:53,986 after the other but by the design they all have 1157 00:49:54,026 --> 00:49:55,536 to be of the same type. 1158 00:49:55,856 --> 00:49:57,426 So let's actually see this in action. 1159 00:49:57,426 --> 00:50:00,376 Let me go back to my G edit window here, 1160 00:50:00,376 --> 00:50:02,466 let me open a new file and I'm gonna go ahead 1161 00:50:02,466 --> 00:50:05,766 and create something that just lets me play with a string. 1162 00:50:06,046 --> 00:50:10,106 >> Let me go ahead and first declare this as let's say 1163 00:50:10,106 --> 00:50:15,076 in John Harvard's directory as string 1.c. Because it turns 1164 00:50:15,076 --> 00:50:17,056 out even though we just introduced this jargon last week 1165 00:50:17,056 --> 00:50:20,416 of an array, we've been using arrays actually since week 1 1166 00:50:20,416 --> 00:50:22,746 when we first introduced a string 'cause what's a string? 1167 00:50:22,966 --> 00:50:24,336 Well, it's a word, a phrase, sentence, 1168 00:50:24,336 --> 00:50:26,096 paragraph whatever, but what is that? 1169 00:50:26,306 --> 00:50:29,636 It's one character after another after another after another. 1170 00:50:29,636 --> 00:50:34,436 So this thing we've been calling string casually is actually an 1171 00:50:34,436 --> 00:50:35,276 array of character. 1172 00:50:35,276 --> 00:50:37,206 So we can now peel back that layer. 1173 00:50:37,206 --> 00:50:40,916 So let's go ahead and include, let's say the CS50 Library. 1174 00:50:41,236 --> 00:50:44,886 Let's go ahead and include standard io.h. Let's go ahead 1175 00:50:44,886 --> 00:50:46,626 and do int, main, void. 1176 00:50:46,626 --> 00:50:48,716 I don't want any command line arguments just yet. 1177 00:50:48,716 --> 00:50:52,636 And then in here let me go ahead and ask user for string. 1178 00:50:52,636 --> 00:50:55,766 So I'm gonna do string S, get string 1179 00:50:56,446 --> 00:50:58,356 and then what do I wanna do with this? 1180 00:50:58,356 --> 00:51:00,006 Well, first let me figure out the length. 1181 00:51:00,136 --> 00:51:05,506 Int, let's say N get strlen of S. So it turns 1182 00:51:05,506 --> 00:51:09,066 out that there is a function called string length or srtlen 1183 00:51:09,306 --> 00:51:11,966 and it happens to be declared in a file, 1184 00:51:12,126 --> 00:51:13,766 actually I don't remember. 1185 00:51:13,766 --> 00:51:15,096 So what are my solutions here? 1186 00:51:15,096 --> 00:51:17,246 So let me actually go and open a terminal window 1187 00:51:17,476 --> 00:51:18,406 and I can actually type. 1188 00:51:18,406 --> 00:51:21,126 If I know the function is called strlen I can say man 1189 00:51:21,126 --> 00:51:25,626 for manual strlen enter and you'll see a few things among 1190 00:51:25,626 --> 00:51:27,146 which at the very top is a reminder 1191 00:51:27,366 --> 00:51:28,866 as to what header file it's in. 1192 00:51:28,866 --> 00:51:31,796 So I apparently need that and now this is a little cryptic 1193 00:51:31,796 --> 00:51:34,006 at first glance but this will make sense before long, 1194 00:51:34,226 --> 00:51:36,166 the function is indeed called strlen. 1195 00:51:36,376 --> 00:51:39,326 It takes one argument but that argument is apparently not 1196 00:51:39,326 --> 00:51:39,736 a string. 1197 00:51:39,916 --> 00:51:41,836 What data type is it apparently? 1198 00:51:43,046 --> 00:51:46,046 Const char asterisk for some reason. 1199 00:51:46,286 --> 00:51:49,016 Well, as a teaser and a star here means a pointer. 1200 00:51:49,016 --> 00:51:50,306 A pointer is a memory address 1201 00:51:50,306 --> 00:51:51,626 and we'll actually come back to that. 1202 00:51:51,846 --> 00:51:53,886 But for now, just assume for simplicity 1203 00:51:53,986 --> 00:51:58,086 that everything highlighted here in white is just a "string." 1204 00:51:58,236 --> 00:52:02,566 The keyword const char star is what we have simplified 1205 00:52:02,566 --> 00:52:05,716 temporarily in the CS50 Library as "string." 1206 00:52:05,936 --> 00:52:07,016 Now as for this here, 1207 00:52:07,146 --> 00:52:09,476 size underscore T, this too is a teaser. 1208 00:52:09,476 --> 00:52:12,366 It turns out that in C you can declare your own data types 1209 00:52:12,366 --> 00:52:14,076 if you don't want to confine yourself 1210 00:52:14,076 --> 00:52:16,166 to just int or float or double. 1211 00:52:16,386 --> 00:52:19,056 You can actually create a student data structure. 1212 00:52:19,056 --> 00:52:22,356 You can create a human data structure inside 1213 00:52:22,356 --> 00:52:26,156 of which are multiple fields like a student's name, ID number 1214 00:52:26,156 --> 00:52:27,476 and phone number and the like. 1215 00:52:27,746 --> 00:52:30,056 But we'll get there too but for now just know 1216 00:52:30,056 --> 00:52:33,166 that size T happens to be synonymous with int. 1217 00:52:33,706 --> 00:52:35,746 So realize that when looking at man pages, 1218 00:52:35,746 --> 00:52:38,066 it's sometimes they actually won't make much sense 1219 00:52:38,066 --> 00:52:38,776 at first glance. 1220 00:52:38,776 --> 00:52:40,136 And in fact not until mid to late 1221 00:52:40,136 --> 00:52:41,646 in the semester will you look at this and be like, 1222 00:52:42,116 --> 00:52:43,576 I remember what that is. 1223 00:52:43,826 --> 00:52:46,016 For now, just kind of reason through as best you can 1224 00:52:46,016 --> 00:52:49,246 that okay, this at least means I need this header file 1225 00:52:49,246 --> 00:52:51,796 so let me go ahead and go up here and include, 1226 00:52:51,796 --> 00:52:56,886 include string.H and then recall this reference in particular. 1227 00:52:56,886 --> 00:53:00,546 On CS50's website we have 1228 00:53:01,046 --> 00:53:05,716 under resources the following link at the very top. 1229 00:53:05,986 --> 00:53:09,726 So to C reference, this is a relatively more user friendly 1230 00:53:09,726 --> 00:53:13,576 reference guide to all of C's functions and even though many 1231 00:53:13,576 --> 00:53:16,116 of them might seem new, in total there's not a huge number, 1232 00:53:16,116 --> 00:53:18,466 certainly not as many as Java for those with backgrounds. 1233 00:53:18,846 --> 00:53:21,246 But let's go to C string and character because it feels 1234 00:53:21,246 --> 00:53:22,636 like I'm doing something with strings. 1235 00:53:23,046 --> 00:53:28,286 And sure enough if I scroll down, strlen, there it is, 1236 00:53:28,406 --> 00:53:30,766 returns the length of a string, let me click that. 1237 00:53:30,946 --> 00:53:34,036 And now this isn't all that enlightening in this case 1238 00:53:34,036 --> 00:53:34,956 but you'll find that a lot 1239 00:53:34,956 --> 00:53:37,416 of this documentation includes examples, 1240 00:53:37,416 --> 00:53:39,196 includes links to related function. 1241 00:53:39,416 --> 00:53:41,716 So hopefully, it will at least answer some questions. 1242 00:53:41,756 --> 00:53:43,536 But honestly, when in doubt, just try it. 1243 00:53:43,816 --> 00:53:46,636 So let's see what happens if I pass strlen, an argument that's 1244 00:53:46,636 --> 00:53:49,146 of type string a.k.a. const char star 1245 00:53:49,556 --> 00:53:50,586 and store its value in ints. 1246 00:53:50,856 --> 00:53:52,916 I'm not gonna bother with this size T and all this. 1247 00:53:52,916 --> 00:53:55,146 I'm just gonna go with what feels simple to me. 1248 00:53:55,436 --> 00:53:57,606 So now I have in end the length of the string. 1249 00:53:57,796 --> 00:53:59,006 Let me go ahead and have a loop. 1250 00:53:59,006 --> 00:54:01,806 So for int I get zero. 1251 00:54:02,386 --> 00:54:05,486 Let me do I is less than N. Let me do I plus, 1252 00:54:05,616 --> 00:54:08,456 plus then let me open some curly braces and what do I wanna do? 1253 00:54:08,456 --> 00:54:10,666 Well, let me go ahead and treat this string 1254 00:54:10,726 --> 00:54:14,746 as though it is array of characters. 1255 00:54:14,746 --> 00:54:18,236 So let me go ahead and print F a single character. 1256 00:54:18,236 --> 00:54:21,746 So percent C one at a time and then I'm gonna put a new line. 1257 00:54:21,946 --> 00:54:24,846 So in short I wanna print 1 character per line 1258 00:54:25,156 --> 00:54:29,846 out of whatever is in S. But S, I think I need 1259 00:54:29,846 --> 00:54:31,076 to use I here somehow. 1260 00:54:31,306 --> 00:54:34,736 How do I get the Ith character of S, yeah. 1261 00:54:34,736 --> 00:54:36,676 So the next syntax we introduced was this, 1262 00:54:36,676 --> 00:54:40,696 S open bracket I close bracket and that says go 1263 00:54:40,696 --> 00:54:43,986 to the variable S then index into it, so to speak, 1264 00:54:44,106 --> 00:54:46,416 to the Ith location, 0, 1, 2, 1265 00:54:46,476 --> 00:54:48,926 3 and print out that particular letter. 1266 00:54:49,236 --> 00:54:50,756 So let's see what happens now. 1267 00:54:50,976 --> 00:54:54,086 So this feels like it should iterate from I to N 1268 00:54:54,086 --> 00:54:56,046 where N is the string length and then print 1269 00:54:56,046 --> 00:54:58,326 out whatever character is at that location. 1270 00:54:59,186 --> 00:55:00,956 Any syntax errors before I try to compile? 1271 00:55:02,326 --> 00:55:03,106 Alright, let's try. 1272 00:55:03,106 --> 00:55:07,086 So let me just go down here, this is make string 1, enter, 1273 00:55:07,086 --> 00:55:08,536 okay, good sign so far. 1274 00:55:08,536 --> 00:55:12,676 Let me go ahead and do string 1, enter, and now let me type 1275 00:55:12,676 --> 00:55:15,886 in hello world, enter, okay. 1276 00:55:16,166 --> 00:55:18,236 It feels like that actually did work. 1277 00:55:18,236 --> 00:55:20,996 If I scroll back up, we see H-E-L-L-O one per line. 1278 00:55:20,996 --> 00:55:23,356 We see the space bar character and then voila, 1279 00:55:23,356 --> 00:55:24,216 we're at the very end. 1280 00:55:24,426 --> 00:55:25,496 So what's the takeaway here? 1281 00:55:25,496 --> 00:55:27,986 Well, apparently all this time we've actually been using 1282 00:55:27,986 --> 00:55:29,876 arrays, we just didn't slap that label on it 1283 00:55:29,876 --> 00:55:32,656 but in a string is just an array of characters. 1284 00:55:32,916 --> 00:55:35,556 But here is where you need to be a little careful. 1285 00:55:35,656 --> 00:55:41,806 Suppose I kind of messed up here and suppose I did this, alright? 1286 00:55:41,806 --> 00:55:44,226 So you already know hopefully instinctively this is bad, 1287 00:55:44,226 --> 00:55:47,556 unclear what's gonna happen but going beyond the length 1288 00:55:47,556 --> 00:55:49,336 of something probably feels like it's 1289 00:55:49,336 --> 00:55:50,956 at least gonna make some aesthetic bug. 1290 00:55:50,956 --> 00:55:51,926 So let's see what happens. 1291 00:55:51,926 --> 00:55:55,166 I'm now iterating from 0 up through N which means 1292 00:55:55,166 --> 00:55:58,216 if the length of the string is N, this really means a total 1293 00:55:58,216 --> 00:56:01,206 of N plus 1 iterations 'cause if you started 0, 1294 00:56:01,206 --> 00:56:04,376 you get one extra 1 which is probably one too many. 1295 00:56:04,756 --> 00:56:05,486 So let's recompile. 1296 00:56:05,576 --> 00:56:12,986 So I'm gonna rerun make string 1, enter, rerun string 1 enter, 1297 00:56:13,426 --> 00:56:18,586 hello world, enter, it doesn't feel so bad. 1298 00:56:19,046 --> 00:56:20,866 So that doesn't seem to be too problematic. 1299 00:56:20,866 --> 00:56:22,056 Why did I get a space? 1300 00:56:22,346 --> 00:56:25,636 Well, that's how 0 in this case is being interpreted, 1301 00:56:25,636 --> 00:56:28,786 so backslash 0 is being automatically inserted 1302 00:56:28,786 --> 00:56:29,936 into S for me. 1303 00:56:30,196 --> 00:56:31,936 So we'll see this before long but for now, 1304 00:56:31,936 --> 00:56:34,456 know that what get string does is it actually reads one 1305 00:56:34,456 --> 00:56:35,746 character at a time another, another, 1306 00:56:35,746 --> 00:56:38,426 another from the keyboard and then when you are done hitting 1307 00:56:38,426 --> 00:56:40,246 that last key on the keyboard and you hit Enter, 1308 00:56:40,496 --> 00:56:43,756 when you are the user it then adds in a backslash 0 1309 00:56:43,756 --> 00:56:44,986 to the very end of the string. 1310 00:56:45,246 --> 00:56:48,726 But when you call string length, it does not in fact-- 1311 00:56:48,846 --> 00:56:53,126 does not in fact count that backslash 0. 1312 00:56:53,126 --> 00:56:54,766 So in other words, if I type in hello, 1313 00:56:54,866 --> 00:56:59,676 H-E-L-L-O string length is gonna return what value, 5. 1314 00:56:59,676 --> 00:57:02,706 It's not going to return 6 even though how many bytes are 1315 00:57:02,706 --> 00:57:03,646 being used? 1316 00:57:03,886 --> 00:57:07,156 Well, 6 'cause there actually is that 6, 1317 00:57:07,486 --> 00:57:11,176 0 character terminating it but we'll see this very long. 1318 00:57:11,396 --> 00:57:12,756 Now let's just do something crazy. 1319 00:57:13,046 --> 00:57:17,126 I would like to go 100 times the length of this string just 1320 00:57:17,126 --> 00:57:18,246 to see what's in memory, right? 1321 00:57:18,376 --> 00:57:22,656 If I argued before that inside of RAM are these leftovers 1322 00:57:22,656 --> 00:57:25,566 from previous function calls, let's see what's in there, 1323 00:57:25,566 --> 00:57:27,286 let's print them out 1 character at a time. 1324 00:57:27,546 --> 00:57:29,746 So just to keep things a little more readable, 1325 00:57:29,746 --> 00:57:31,846 let me not do the new lines 'cause I'd like to just see it 1326 00:57:31,846 --> 00:57:34,116 on one screen rather than scrolling so let's get rid 1327 00:57:34,116 --> 00:57:36,716 of the new line and now let me go ahead and scroll down. 1328 00:57:37,326 --> 00:57:39,526 Let me rerun string, make string 1. 1329 00:57:40,526 --> 00:57:45,896 String 1, enter, let's type in hello, enter, that's funky. 1330 00:57:46,466 --> 00:57:49,056 What is that, right? 1331 00:57:49,056 --> 00:57:50,016 So it turns out there's a lot 1332 00:57:50,016 --> 00:57:52,606 of unprintable characters in ASCII, right? 1333 00:57:52,606 --> 00:57:55,106 If you think back to Asciitable.com 1334 00:57:55,106 --> 00:57:58,126 or the chart we had a while ago, if you go to Asciitable.com, 1335 00:57:58,126 --> 00:58:00,026 I think Tommy mentioned this in the walkthrough last night. 1336 00:58:00,376 --> 00:58:02,796 This is frankly an unnecessarily complex looking chart. 1337 00:58:03,006 --> 00:58:05,036 But that's just maps letters to numbers. 1338 00:58:05,036 --> 00:58:08,016 If we scroll down to 65 over here in the top right, 1339 00:58:08,276 --> 00:58:11,786 it maps to A. But notice that over here there's crazy things 1340 00:58:11,786 --> 00:58:14,256 like form feed and shift out, shift in. 1341 00:58:14,306 --> 00:58:15,996 I don't even know what some of these characters are. 1342 00:58:16,296 --> 00:58:18,186 Well, neither does the terminal window. 1343 00:58:18,186 --> 00:58:20,936 And so it prints them as these funky garbage characters. 1344 00:58:21,136 --> 00:58:23,206 I mean frankly let's really mess 1345 00:58:23,206 --> 00:58:24,746 around here a thousand times the length. 1346 00:58:24,906 --> 00:58:26,126 Let's see what we can see. 1347 00:58:26,516 --> 00:58:29,666 Alright, go down here, zoom in, remake. 1348 00:58:30,176 --> 00:58:31,606 And again, remember this keyboard shortcut. 1349 00:58:31,606 --> 00:58:33,206 If you're tired of typing the same thing again 1350 00:58:33,206 --> 00:58:35,346 and again you can always hit up and down to scroll 1351 00:58:35,346 --> 00:58:37,986 through your history or you can type exclamation point 1352 00:58:37,986 --> 00:58:40,856 and then start matching whatever the last command was you typed 1353 00:58:40,856 --> 00:58:42,686 that started with M and hit enter 1354 00:58:42,916 --> 00:58:44,796 and your blinking prompt will figure out what it was. 1355 00:58:44,796 --> 00:58:47,436 So I'm gonna now go ahead and rerun string 1. 1356 00:58:47,676 --> 00:58:52,016 Type in hello enter, still not doing much. 1357 00:58:52,566 --> 00:58:54,416 What might it be doing though? 1358 00:58:55,436 --> 00:58:56,526 Can I go further? 1359 00:58:56,526 --> 00:58:58,316 It's getting a little crazy. 1360 00:58:58,656 --> 00:59:02,646 Make, rerun, hello, ah-huh. 1361 00:59:03,106 --> 00:59:05,226 So some of you have seen this already, yes. 1362 00:59:05,736 --> 00:59:07,986 If so, good job, very advance already. 1363 00:59:08,256 --> 00:59:09,476 So this is bad, right? 1364 00:59:09,476 --> 00:59:11,546 A segmentation fault just sounds bad 1365 00:59:11,546 --> 00:59:14,946 and we did induce this last week when we I did what? 1366 00:59:15,896 --> 00:59:16,996 Remember when I kept calling, 1367 00:59:16,996 --> 00:59:18,076 I forget what the function was called. 1368 00:59:18,076 --> 00:59:19,556 Maybe it was foo or something silly. 1369 00:59:19,696 --> 00:59:22,416 Remember, I just kept having foo call foo which called foo 1370 00:59:22,416 --> 00:59:24,156 which called foo, and what did that mean? 1371 00:59:24,326 --> 00:59:27,236 It meant that more and more RAM is getting allocated, allocated, 1372 00:59:27,286 --> 00:59:30,316 allocated, until finally it crossed over its segment 1373 00:59:30,316 --> 00:59:34,986 so you get a fault and core dump actually is silly terminology 1374 00:59:34,986 --> 00:59:36,976 which means you now literally have a file 1375 00:59:37,056 --> 00:59:39,476 in your current folder called core, 1376 00:59:39,476 --> 00:59:41,746 and what do you think is inside of that file? 1377 00:59:42,156 --> 00:59:44,126 It's actually useful. 1378 00:59:44,126 --> 00:59:44,906 It's a bad sign. 1379 00:59:44,906 --> 00:59:46,686 It means you screwed up or I screwed up 1380 00:59:46,686 --> 00:59:48,046 but what's inside of it? 1381 00:59:48,046 --> 00:59:49,666 It's kind of some forensic information, 1382 00:59:49,666 --> 00:59:52,966 inside of that core file is essentially the entire content 1383 00:59:52,966 --> 00:59:57,036 of the appliance's RAM at the moment your program crashed. 1384 00:59:57,036 --> 00:59:58,816 Now, it's not everything 'cause that would be huge. 1385 00:59:58,816 --> 01:00:00,236 It's only as much as you need to see. 1386 01:00:00,386 --> 01:00:03,036 But we'll see in future weeks a tool again called the Debugger 1387 01:00:03,216 --> 01:00:05,916 whereby we can do a little forensic analysis of this file 1388 01:00:05,916 --> 01:00:08,496 and figure out retroactively where 1389 01:00:08,496 --> 01:00:10,796 and hopefully why my program fails. 1390 01:00:10,796 --> 01:00:11,746 Now what happened here? 1391 01:00:11,906 --> 01:00:15,496 Well, I iterated like what, 100,000 times farther 1392 01:00:15,496 --> 01:00:17,166 than I was supposed to on this string. 1393 01:00:17,426 --> 01:00:18,326 So what does that mean? 1394 01:00:18,486 --> 01:00:19,196 Well, it doesn't mean 1395 01:00:19,196 --> 01:00:21,236 that I kept calling functions again and again. 1396 01:00:21,366 --> 01:00:24,806 It means I simply tried to touch or print memory 1397 01:00:24,806 --> 01:00:26,716 that was way out of my boundaries. 1398 01:00:26,886 --> 01:00:29,506 And so this is a bad thing. 1399 01:00:29,816 --> 01:00:32,056 So hopefully that issue makes a little more sense. 1400 01:00:32,536 --> 01:00:36,036 But it turns out we should be a little more careful still. 1401 01:00:36,216 --> 01:00:40,246 I can make this program crash in other ways because it turns 1402 01:00:40,246 --> 01:00:42,976 out that get string doesn't always return a string. 1403 01:00:43,276 --> 01:00:45,666 >> It's hard to simulate this but there are ways 1404 01:00:45,666 --> 01:00:47,326 where a bad guy or even we 1405 01:00:47,326 --> 01:00:52,526 if we were really crafty here could tell get string to return 1406 01:00:52,776 --> 01:00:55,376 without even giving it any characters whatsoever. 1407 01:00:55,656 --> 01:00:57,826 And so if we actually read the documentation 1408 01:00:57,826 --> 01:01:00,356 for the CS50 Library which we can do as follows. 1409 01:01:00,356 --> 01:01:01,706 I'm gonna open up G edit. 1410 01:01:01,706 --> 01:01:03,226 And in today's source code 1411 01:01:03,226 --> 01:01:06,926 in the source directory is a file called CS50.H. 1412 01:01:07,096 --> 01:01:09,226 So this has been in the appliance all this time. 1413 01:01:09,226 --> 01:01:12,306 You've not have to care about or see it in person but you'll 1414 01:01:12,416 --> 01:01:15,896 at the top some fancy stuff and some files we haven't seen. 1415 01:01:16,186 --> 01:01:19,436 But let me scroll down and point out just a couple of details. 1416 01:01:19,436 --> 01:01:21,916 So this again is CS50.H. Every time 1417 01:01:21,916 --> 01:01:24,556 for the past 2 weeks you've been saying include CS50.H, 1418 01:01:24,786 --> 01:01:26,506 what has GCC been doing for you? 1419 01:01:26,686 --> 01:01:29,416 It's been opening this file and effectively copying 1420 01:01:29,416 --> 01:01:32,466 and pasting its contents at the very top of your program 1421 01:01:32,946 --> 01:01:34,376 and then proceeding with your own code. 1422 01:01:34,566 --> 01:01:35,506 What is the point of that? 1423 01:01:35,806 --> 01:01:38,476 Well, it means that no matter where you call get int 1424 01:01:38,476 --> 01:01:41,816 or get string, the compiler already knows about it 1425 01:01:41,976 --> 01:01:43,986 because if we scroll down further in this file, 1426 01:01:44,176 --> 01:01:47,186 notice that we put all the function prototypes 1427 01:01:47,186 --> 01:01:50,126 for all the CS50 functions in here with a whole bunch 1428 01:01:50,126 --> 01:01:52,946 of comments explaining how they work for you the human 1429 01:01:53,226 --> 01:01:56,486 so that no matter where you call get int, get string, get long, 1430 01:01:56,486 --> 01:01:59,106 long, the function prototypes have already been declared 1431 01:01:59,106 --> 01:02:02,796 for you because again, when you do sharp sign include, 1432 01:02:02,946 --> 01:02:05,086 it's like copying and pasting this file at the top. 1433 01:02:05,416 --> 01:02:07,796 Now what about string, how have we been simplifying 1434 01:02:07,796 --> 01:02:08,646 that all this time? 1435 01:02:08,926 --> 01:02:11,936 Well, again you can declare, you can define your own types in C 1436 01:02:12,116 --> 01:02:13,226 and again we'll come back to this. 1437 01:02:13,506 --> 01:02:17,576 But that one line is what makes possible the data type we have 1438 01:02:17,576 --> 01:02:19,826 been calling string all of this time. 1439 01:02:20,196 --> 01:02:22,626 But let me scroll down as another teaser to come 1440 01:02:22,626 --> 01:02:23,736 with regard to pointers. 1441 01:02:23,736 --> 01:02:25,616 If I scroll down to the documentation here, 1442 01:02:25,916 --> 01:02:26,686 forget string. 1443 01:02:27,146 --> 01:02:28,226 Notice that it says this. 1444 01:02:28,326 --> 01:02:30,706 It reads a line of text from standard input, 1445 01:02:30,706 --> 01:02:32,576 that just means keyboard, and returns it 1446 01:02:32,576 --> 01:02:34,026 as a string otherwise known 1447 01:02:34,026 --> 01:02:37,116 as char star sands trailing new line character. 1448 01:02:37,116 --> 01:02:38,936 So, in other words, even though you've been hitting enter 1449 01:02:38,936 --> 01:02:41,646 at the keyboard, we do not hand you as part of the string 1450 01:02:41,856 --> 01:02:44,446 that backslash N. Otherwise every time you printed strings 1451 01:02:44,446 --> 01:02:46,316 they would move the cursor to the next line. 1452 01:02:46,316 --> 01:02:47,926 So we get rid of that. 1453 01:02:47,926 --> 01:02:49,896 Returns, this is what's interesting. 1454 01:02:50,236 --> 01:02:54,566 Returns null upon error or no input whatsoever. 1455 01:02:54,896 --> 01:02:56,506 So it turns out there's a few scenarios 1456 01:02:56,506 --> 01:02:58,816 in which get string cannot give you a string. 1457 01:02:59,056 --> 01:03:02,106 Either somehow the bad guy has avoided hitting enter at all 1458 01:03:02,306 --> 01:03:05,426 but he has nonetheless said I'm done executing get string. 1459 01:03:05,806 --> 01:03:08,476 Or what's another situation in which a function 1460 01:03:08,476 --> 01:03:11,386 like get string could fathomably fail. 1461 01:03:11,456 --> 01:03:14,016 Like what could a bad guy do that's just really annoying 1462 01:03:14,016 --> 01:03:17,056 and breaks a function like get string whose purpose in life is 1463 01:03:17,056 --> 01:03:18,176 to get a string from the keyboard 1464 01:03:18,176 --> 01:03:20,066 and hand you back a chunk of memory with that string. 1465 01:03:21,706 --> 01:03:24,516 Yeah, what if it's a super, super, super long string, right, 1466 01:03:24,516 --> 01:03:28,186 the appliance recall only has by default like 768 megabytes 1467 01:03:28,286 --> 01:03:30,976 of memory and some of you with netbooks and the like have had 1468 01:03:30,976 --> 01:03:33,796 to crank that memory down to only like 256. 1469 01:03:33,996 --> 01:03:36,346 So what if the bad guy, you know, it's a little tedious 1470 01:03:36,456 --> 01:03:39,226 but typed in billions of characters on the keyboard 1471 01:03:39,226 --> 01:03:41,616 or really just did a whole lot of copy paste to paste 1472 01:03:41,616 --> 01:03:44,646 in a huge string or the whole King James Bible 1473 01:03:44,676 --> 01:03:46,476 which you can just copy and paste from the web page 1474 01:03:46,476 --> 01:03:47,756 and then paste at the prompt. 1475 01:03:47,916 --> 01:03:50,286 What might happen, well get string might not be able 1476 01:03:50,286 --> 01:03:53,036 to allocate enough memory from the operating system 1477 01:03:53,236 --> 01:03:54,606 and so what is get string gonna do? 1478 01:03:54,606 --> 01:03:55,236 Well, according 1479 01:03:55,236 --> 01:03:58,186 to its documentation it's not gonna return that string, 1480 01:03:58,576 --> 01:04:01,146 it's gonna return a special character called null 1481 01:04:01,146 --> 01:04:01,606 in all caps. 1482 01:04:02,256 --> 01:04:05,776 And this is the absence of any actual memory, 1483 01:04:05,776 --> 01:04:07,036 the absence of any string. 1484 01:04:07,036 --> 01:04:08,656 But we'll come back to that. 1485 01:04:08,996 --> 01:04:12,146 For now, know that this program is actually a little buggy 1486 01:04:12,366 --> 01:04:16,696 because we're not checking if S is actually a legitimate value. 1487 01:04:16,696 --> 01:04:17,926 We'll see in future weeks 1488 01:04:17,976 --> 01:04:21,026 that in fact it could be itself flawed, 1489 01:04:21,826 --> 01:04:23,336 rather it could be nonexistent. 1490 01:04:23,336 --> 01:04:25,756 And so we could get a segmentation just 1491 01:04:25,756 --> 01:04:27,046 by trying to traverse it. 1492 01:04:27,646 --> 01:04:29,716 So let me try another version here. 1493 01:04:29,716 --> 01:04:33,956 Let me go ahead and open up a prefabbed file this time, 1494 01:04:34,106 --> 01:04:38,916 string2.c 'cause it turns out there's an inefficiency in this. 1495 01:04:39,086 --> 01:04:40,696 So what I'll start to do now in lecture 1496 01:04:40,696 --> 01:04:42,296 so that all the answers are not always 1497 01:04:42,296 --> 01:04:45,326 on the screen is even though in the printout on the PDFs online 1498 01:04:45,326 --> 01:04:47,316 and the source code which you're welcome to download in advance 1499 01:04:47,316 --> 01:04:49,376 or bring to class on a laptop, I go ahead 1500 01:04:49,376 --> 01:04:50,306 and with a little program. 1501 01:04:50,306 --> 01:04:53,106 I strip out all of the comments, all of the one line comments 1502 01:04:53,106 --> 01:04:54,986 so that it doesn't just tell you what's going on here. 1503 01:04:55,326 --> 01:04:57,016 So that's why there are some empty lines here. 1504 01:04:57,296 --> 01:05:00,356 And now let me actually point out this. 1505 01:05:00,476 --> 01:05:04,096 This is the key to solving the problem I just alluded to, 1506 01:05:04,096 --> 01:05:07,966 checking if S actually does not equal null, but again more 1507 01:05:07,966 --> 01:05:08,766 on that in the future. 1508 01:05:08,766 --> 01:05:12,176 Let's focus instead on just this part here 1509 01:05:12,206 --> 01:05:14,806 which is almost identical to the thing I just implemented 1510 01:05:14,806 --> 01:05:16,016 but with one difference. 1511 01:05:16,486 --> 01:05:18,386 I would argue that this implementation 1512 01:05:18,386 --> 01:05:20,966 of string is worse than what we just did on the fly. 1513 01:05:21,636 --> 01:05:22,836 This is more inefficient. 1514 01:05:22,836 --> 01:05:25,196 This is bad design so to speak. 1515 01:05:26,336 --> 01:05:31,506 What's-- damn it, I have to spoil the answer now. 1516 01:05:31,976 --> 01:05:33,536 This is really good design. 1517 01:05:34,046 --> 01:05:39,936 So what if-- damn it-- I opened the wrong version. 1518 01:05:39,936 --> 01:05:40,606 Okay, here we go. 1519 01:05:40,606 --> 01:05:44,916 Let's put this over here, okay. 1520 01:05:46,546 --> 01:05:50,816 This is bad design, what should we do instead. 1521 01:05:50,816 --> 01:05:55,286 Well, let's try-- that question is clearly out of the bag now, 1522 01:05:55,506 --> 01:06:03,126 why is this bad design, why don't you like this? 1523 01:06:03,126 --> 01:06:03,266 [ Inaudible Remark ] 1524 01:06:03,266 --> 01:06:03,966 >> Okay, good. 1525 01:06:04,056 --> 01:06:05,486 So remember how the for loop works. 1526 01:06:05,486 --> 01:06:07,826 You got the initialization of some variables and that's 1527 01:06:07,826 --> 01:06:09,626 over here to the left of the semicolon. 1528 01:06:09,896 --> 01:06:11,666 You've got the increment over here on the right 1529 01:06:11,666 --> 01:06:14,106 of the semicolon that happens every time the loop 1530 01:06:14,106 --> 01:06:14,696 goes through. 1531 01:06:14,906 --> 01:06:16,576 And then remember this part, the condition, 1532 01:06:16,726 --> 01:06:18,016 how many times does this thing check. 1533 01:06:19,336 --> 01:06:21,306 So every time you go through the loop. 1534 01:06:21,416 --> 01:06:24,096 So what's the stupid design decision here even though this 1535 01:06:24,096 --> 01:06:25,576 is nice and clean and readable, right? 1536 01:06:25,576 --> 01:06:28,216 This is very succinct, it's one liner, it's not ugly 1537 01:06:28,516 --> 01:06:31,286 but how many times am I calling strlen on S? 1538 01:06:32,736 --> 01:06:35,136 Well, every time this loop goes around. 1539 01:06:35,136 --> 01:06:39,956 So if I type in H-E-L-L-O, what is strlen of H-E-L-L-O gonna be 1540 01:06:39,956 --> 01:06:40,826 on the first iteration? 1541 01:06:42,476 --> 01:06:44,416 5, what about the second iteration, 1542 01:06:44,416 --> 01:06:45,896 what's this length of hello. 1543 01:06:46,526 --> 01:06:49,956 5 and then 5 and then 5, right, the fact that I'm doing this 1544 01:06:49,956 --> 01:06:52,876 like an idiot just means that we are doing the same exact thing 1545 01:06:52,876 --> 01:06:55,566 again and again and again and that's a waste. 1546 01:06:55,676 --> 01:06:58,106 So we can do better than that in a couple of ways. 1547 01:06:58,196 --> 01:07:01,456 One, we could do it in the manner I first did where I said, 1548 01:07:01,456 --> 01:07:04,456 you know what, give me a variable N and pass, 1549 01:07:04,456 --> 01:07:07,866 give it the value of strlen of S and then go ahead 1550 01:07:07,866 --> 01:07:10,666 and do I is less than N here. 1551 01:07:10,896 --> 01:07:11,766 So that fixes it. 1552 01:07:11,976 --> 01:07:14,596 But if you don't like that syntax you can actually do it 1553 01:07:14,596 --> 01:07:18,706 in line and this was that spoiler, N get strlen of S. 1554 01:07:19,576 --> 01:07:22,326 So notice now I have 2 initializations to the left. 1555 01:07:22,786 --> 01:07:25,196 I can do a condition now based on that variable 1556 01:07:25,376 --> 01:07:27,746 and so this is just a marginally cleaner way 1557 01:07:27,996 --> 01:07:31,346 of actually checking the length of S but only once 1558 01:07:31,686 --> 01:07:34,296 because even though I is being incremented we're not actually 1559 01:07:34,346 --> 01:07:36,656 changing the length of that thing itself. 1560 01:07:37,206 --> 01:07:40,366 So this is good design. 1561 01:07:40,566 --> 01:07:41,866 The bad version that I changed 1562 01:07:41,866 --> 01:07:44,086 in to a moment ago we're calling strlen, strlen again, 1563 01:07:44,276 --> 01:07:46,236 that's what we mean in the PDFs of the problem sets 1564 01:07:46,316 --> 01:07:49,296 that when we say grading with respect to design, 1565 01:07:49,646 --> 01:07:51,336 look for those kinds of inefficiencies. 1566 01:07:51,336 --> 01:07:52,686 That might not be glaringly obvious 1567 01:07:52,686 --> 01:07:55,976 and they're not incorrect, they are just bad design. 1568 01:07:56,356 --> 01:07:58,966 So let me go ahead and open up just one 1569 01:07:58,966 --> 01:08:00,466 or so other things here. 1570 01:08:00,906 --> 01:08:02,586 Let's take a look at this one. 1571 01:08:02,946 --> 01:08:06,426 So this is a program and this is actually so lightly useful. 1572 01:08:06,426 --> 01:08:08,696 It's kind of a calculator but just for quiz averages. 1573 01:08:08,996 --> 01:08:11,056 This is a program whose purpose in life is 1574 01:08:11,056 --> 01:08:14,726 to ask the user further quiz scores then it computes the 1575 01:08:14,726 --> 01:08:17,306 average of those quiz scores and tells you what your average is. 1576 01:08:17,306 --> 01:08:20,386 So marginally useful but it introduces a few new features 1577 01:08:20,386 --> 01:08:22,546 that are now gonna be increasingly useful. 1578 01:08:22,546 --> 01:08:23,706 So let's start at the top. 1579 01:08:23,886 --> 01:08:26,946 In English, what would you wager this line is doing? 1580 01:08:27,666 --> 01:08:32,396 So the verb, at least one verb 1581 01:08:32,396 --> 01:08:34,256 and the answer should be it's declaring something, 1582 01:08:34,256 --> 01:08:34,996 what's it declaring? 1583 01:08:35,986 --> 01:08:37,446 So it's declaring an array and I say 1584 01:08:37,446 --> 01:08:38,656 that the verb should be declare 1585 01:08:38,816 --> 01:08:41,836 because any time you see a variable data type like floats 1586 01:08:41,836 --> 01:08:43,956 or int or string, you're declaring something. 1587 01:08:43,956 --> 01:08:45,056 So you're declaring an array. 1588 01:08:45,056 --> 01:08:45,956 How do you know it's an array? 1589 01:08:46,316 --> 01:08:48,586 Well, the clue today is just these square braces. 1590 01:08:48,846 --> 01:08:50,196 Now, what is quizzes in all caps, 1591 01:08:50,386 --> 01:08:51,496 we've not seen that before. 1592 01:08:51,726 --> 01:08:55,326 Well it turns out that a very good practice, also good design 1593 01:08:55,326 --> 01:08:58,956 in a program is if you need to use some constant value 1594 01:08:59,046 --> 01:09:01,086 like the number 2, 2 quizzes per semester. 1595 01:09:01,366 --> 01:09:04,186 It's best not to hard code the number 2 all throughout your 1596 01:09:04,186 --> 01:09:06,536 program but rather to factor that out, 1597 01:09:06,786 --> 01:09:10,296 use what's called sharp define, so similar to sharp include 1598 01:09:10,296 --> 01:09:11,796 but the word is different, sharp define. 1599 01:09:12,046 --> 01:09:14,096 You then give the constant a name 1600 01:09:14,266 --> 01:09:17,376 and by convention it is all capital letters though it's not 1601 01:09:17,376 --> 01:09:19,336 required but that's what programmers do. 1602 01:09:19,496 --> 01:09:21,116 And then the number that you want 1603 01:09:21,116 --> 01:09:24,226 to make quizzes synonymous with. 1604 01:09:24,226 --> 01:09:26,046 So it creates like an alias so that 1605 01:09:26,046 --> 01:09:28,346 when your programs compile anywhere the word 1606 01:09:28,346 --> 01:09:31,546 "quizzes" appears, the number 2 is gonna be substituted. 1607 01:09:33,636 --> 01:09:35,256 Does it matter if it's an int or a double? 1608 01:09:35,256 --> 01:09:38,386 No, we could actually do this but you wanna make sure-- 1609 01:09:38,846 --> 01:09:41,836 sorry, when you define a constant you can make it almost 1610 01:09:41,836 --> 01:09:42,556 any data type. 1611 01:09:42,866 --> 01:09:44,476 This though would be bad here 1612 01:09:44,706 --> 01:09:47,986 because when you declare an array with square braces, 1613 01:09:47,986 --> 01:09:50,316 you must pass it in ints, you cannot pass at a floats. 1614 01:09:50,746 --> 01:09:51,936 So what is going on here? 1615 01:09:52,016 --> 01:09:54,286 We've not seen this syntax in a program yet 1616 01:09:54,286 --> 01:09:56,736 but this variable is gonna be called grades. 1617 01:09:57,276 --> 01:09:58,966 How big is this array gonna be? 1618 01:09:59,066 --> 01:10:00,226 >> Well, when you wanna specify 1619 01:10:00,226 --> 01:10:03,416 in advance how big an array should be, you just specify 1620 01:10:03,416 --> 01:10:05,056 in square braces that number. 1621 01:10:05,056 --> 01:10:07,016 So I could do this and in fact 1622 01:10:07,016 --> 01:10:08,866 that is synonymous with what I just did. 1623 01:10:09,136 --> 01:10:12,066 But again, the goal of a constant is to factor that out 1624 01:10:12,066 --> 01:10:14,266 because look just ahead, we don't know what this is doing 1625 01:10:14,266 --> 01:10:16,596 yet but notice I've already used quizzes 3 times. 1626 01:10:16,836 --> 01:10:19,306 Just if you fast forward if we ever had 3 quizzes 1627 01:10:19,306 --> 01:10:22,456 or God forbid 4 or 5 during the semester, you would then have 1628 01:10:22,456 --> 01:10:24,726 to go change that number all over the place 1629 01:10:24,726 --> 01:10:26,456 and it's just too easy to make a mistake. 1630 01:10:26,456 --> 01:10:28,206 Leave a 2 up here or a 3 down here 1631 01:10:28,406 --> 01:10:29,706 and now the program is broken. 1632 01:10:29,706 --> 01:10:32,766 So we can standardize the number at the very top of the program. 1633 01:10:33,196 --> 01:10:36,396 So in short, this gives me an array of size 2, 1634 01:10:36,536 --> 01:10:38,156 2 mailboxes side by side, 1635 01:10:38,396 --> 01:10:41,136 each of which can store a float as a value. 1636 01:10:41,366 --> 01:10:44,026 Alright. What were your quiz scores, then we iterate 1637 01:10:44,146 --> 01:10:45,766 from I as 0 up to quizzes. 1638 01:10:46,196 --> 01:10:47,626 This is sort of old school now. 1639 01:10:47,686 --> 01:10:53,206 So quiz number 1 of 2 so I'm just doing 0 plus 1 is 1, 1640 01:10:53,206 --> 01:10:55,246 so this will literally say quiz 1 of 2. 1641 01:10:55,546 --> 01:10:57,646 So I'm trying to make it more human friendly by counting 1642 01:10:57,646 --> 01:10:59,176 from 1 not rather than zero. 1643 01:10:59,176 --> 01:11:00,486 And then what's this doing? 1644 01:11:00,666 --> 01:11:02,186 Well, this is now the syntax. 1645 01:11:02,416 --> 01:11:05,236 If you already have an array and it's a big enough size, 1646 01:11:05,596 --> 01:11:06,796 if you wanna put something 1647 01:11:06,996 --> 01:11:12,116 in the Ith location you just specify grades, bracket I, get, 1648 01:11:12,116 --> 01:11:14,736 in other words the assignment operator whatever it is you 1649 01:11:14,736 --> 01:11:15,446 wanna put there. 1650 01:11:15,846 --> 01:11:17,736 So in short, what do these lines of code do? 1651 01:11:17,736 --> 01:11:21,226 It declares an array of size 2, a mailbox with 2 slots. 1652 01:11:21,596 --> 01:11:23,756 It then asks the user for their quiz scores 1653 01:11:23,756 --> 01:11:26,126 and then it stores those 2 floating point values 1654 01:11:26,126 --> 01:11:30,566 in grades bracket 0 and grades bracket 1, that's all. 1655 01:11:30,566 --> 01:11:32,436 So one number here, one number here. 1656 01:11:32,726 --> 01:11:34,166 Let's go ahead and scroll down now 1657 01:11:35,176 --> 01:11:37,496 and now I'm computing the average and this is it. 1658 01:11:37,796 --> 01:11:39,676 So how do you compute the average of numbers? 1659 01:11:39,676 --> 01:11:42,126 Frankly, this is very easy with 2 but we wanna keep it general. 1660 01:11:42,356 --> 01:11:43,276 You compute your average 1661 01:11:43,276 --> 01:11:44,836 by adding all your quiz scores together 1662 01:11:44,836 --> 01:11:46,076 and dividing by the total. 1663 01:11:46,286 --> 01:11:46,956 So let's do that. 1664 01:11:47,186 --> 01:11:49,416 I have a sum initially that's equal to zero. 1665 01:11:49,826 --> 01:11:52,576 I then iterate from 0 up to quizzes, 1666 01:11:52,576 --> 01:11:53,906 so however many quizzes I have. 1667 01:11:54,166 --> 01:11:56,866 Then I can use this fancy syntax plus equal adds 1668 01:11:56,916 --> 01:11:58,876 to some the Ith grade. 1669 01:11:59,546 --> 01:12:02,046 So once I get to this line here what have I just done? 1670 01:12:02,176 --> 01:12:05,906 I've stored in a variable called sum, the sum of my 2 quizzes. 1671 01:12:05,906 --> 01:12:08,886 So something plus something, now I have a total but now I need 1672 01:12:08,886 --> 01:12:11,656 to get the average so I need to divide by quizzes. 1673 01:12:11,946 --> 01:12:15,296 And just so that I don't kind of screw you out of the A instead 1674 01:12:15,296 --> 01:12:17,846 of the A minus, we wanna make sure we round up or round 1675 01:12:17,846 --> 01:12:20,146 down because otherwise we would be truncating. 1676 01:12:20,146 --> 01:12:23,816 Remember what happens when you divide something 1677 01:12:23,816 --> 01:12:26,606 by an integer potentially, so let's go ahead and round 1678 01:12:26,606 --> 01:12:27,856 so we round up or down. 1679 01:12:28,136 --> 01:12:32,306 The round function is in, turns out the math dot H header, 1680 01:12:32,816 --> 01:12:35,626 so more about that online under cs50.net.resources 1681 01:12:36,076 --> 01:12:40,176 but these now stores an average in integer that's the result 1682 01:12:40,176 --> 01:12:42,906 of rounding the sum divided by quizzes. 1683 01:12:43,096 --> 01:12:45,166 So at the end of the day, this is just basic arithmetic 1684 01:12:45,166 --> 01:12:47,236 that you could do paper pencil on or a calculator 1685 01:12:47,236 --> 01:12:50,286 on your head even, but what we've introduced now is the 1686 01:12:50,286 --> 01:12:53,446 ability to store multiple grades in an array. 1687 01:12:53,656 --> 01:12:58,836 Why didn't I just use 2 variable for grade 1 and for grade 2? 1688 01:12:59,086 --> 01:13:03,106 Right, float, grade 1, comma and-- semicolon, float grade 2, 1689 01:13:03,106 --> 01:13:06,106 semicolon, why is that bad arguably? 1690 01:13:06,106 --> 01:13:06,646 [ Inaudible Question ] 1691 01:13:06,646 --> 01:13:08,436 >> Yeah, exactly. 1692 01:13:09,116 --> 01:13:11,336 What if I have a third quiz, a fourth quiz, 1693 01:13:11,336 --> 01:13:12,586 do you really wanna start copying 1694 01:13:12,586 --> 01:13:15,186 and pasting your variables and have grade 1, grade 2, grade 3, 1695 01:13:15,186 --> 01:13:17,236 grade 4, grade 5, grade 10. 1696 01:13:17,496 --> 01:13:19,026 No, rather you can put them all 1697 01:13:19,026 --> 01:13:21,926 in the same variable called grades and then just index 1698 01:13:21,926 --> 01:13:23,866 into it in this Ith location. 1699 01:13:23,866 --> 01:13:26,626 And so it's with these primitives, modelling strings 1700 01:13:26,626 --> 01:13:29,266 as arrays and being able to reverse strings, 1701 01:13:29,266 --> 01:13:32,636 our arrays with 4 loops that you'll be able to take something 1702 01:13:32,636 --> 01:13:35,756 like hello and encrypt it whether you're doing the Hacker 1703 01:13:35,756 --> 01:13:37,596 Edition this week or the standard edition. 1704 01:13:37,796 --> 01:13:42,176 So with that, we will see you on Wednesday.