YouTube2Text

Harvard CS50 – Full Computer Science University Course — Transcript

by freeCodeCamp.org · 256,684 words · 28,480 segments · language en · Watch on YouTube

Full transcript

  1. 0:00If you want to learn about computer science and the art of programming, this course is where to start.
  2. 0:04CS50 is considered by many to be one of the best computer science courses in the world.
  3. 0:09This is a Harvard University course taught by Dr. David Malan
  4. 0:13and we are proud to bring it to the freeCodeCamp YouTube channel.
  5. 0:17Throughout a series of lectures, Dr. Malan will teach you how to think algorithmically and solve problems efficiently.
  6. 0:23And make sure to check the description for a lot of extra resources that go along with the course.
  7. 0:27[MUSIC PLAYING]
  8. 1:45DAVID MALAN: All right, this is CS50, Harvard University's introduction
  9. 1:50to the intellectual enterprises of computer science
  10. 1:52and the art of programming, back here on campus in beautiful Sanders Theatre
  11. 1:56for the first time in quite a while.
  12. 1:58So welcome to the class.
  13. 2:01My name is David--
  14. 2:02OK.
  15. 2:03[CHEERING AND APPLAUSE]
  16. 2:11So my name is David Malan.
  17. 2:13And I took this class myself some time ago, but almost didn't.
  18. 2:16It was sophomore fall and I was sitting in on the class.
  19. 2:20And I was a little curious but, eh, it didn't really
  20. 2:22feel like the field for me.
  21. 2:24I was definitely a computer person, but computer science
  22. 2:26felt like something altogether.
  23. 2:28And I only got up the nerve to take the class,
  24. 2:30ultimately, because the professor at the time, Brian Kernighan,
  25. 2:32allowed me to take the class pass/fail, initially.
  26. 2:35And that is what made all the difference.
  27. 2:37I quickly found that computer science is not just
  28. 2:39about programming and working in isolation on your computer.
  29. 2:42It's really about problem solving more generally.
  30. 2:45And there was something about homework, frankly,
  31. 2:48that was, like, actually fun for perhaps the first time in, what, 19 years.
  32. 2:51And there was something about this ability
  33. 2:54that I discovered, along with all of my classmates,
  34. 2:56to actually create something and bring a computer to life to solve a problem,
  35. 3:00and sort of bring to bear something that I'd been using every day
  36. 3:03but didn't really know how to harness, that's been gratifying ever since,
  37. 3:06and definitely challenging and frustrating.
  38. 3:08Like, to this day, all these years later,
  39. 3:10you're going to run up against mistakes, otherwise known as bugs,
  40. 3:13in programming, that just drive you nuts.
  41. 3:15And you feel like you've hit a wall.
  42. 3:16But the trick really is to give it enough time,
  43. 3:18to take a step back, take a break when you need to.
  44. 3:21And there's nothing better, I daresay, than that sense of gratification
  45. 3:24and pride, really, when you get something
  46. 3:26to work, and in a class like this, present, ultimately,
  47. 3:28at term's end, something like your very own final project.
  48. 3:32Now, this isn't to say that I took to it 100% perfectly.
  49. 3:35In fact, just this past week, I looked in my old CS50 binder, which I still
  50. 3:40have from some 25 years ago, and took a photo
  51. 3:43of what was apparently the very first program that I wrote and submitted,
  52. 3:47and quickly received minus 2 points on.
  53. 3:50But this is a program that we'll soon see in the coming days that
  54. 3:53does something quite simply like print "Hello, CS50," in this case,
  55. 3:57to the screen.
  56. 3:58And to be fair, I technically hadn't really
  57. 4:00followed the directions, which is why I lost those couple of points.
  58. 4:02But if you just look at this, especially if you've never programmed before,
  59. 4:05you might have heard about programming language
  60. 4:07but you've never typed something like this out,
  61. 4:09undoubtedly it's going to look cryptic.
  62. 4:11But unlike human languages, frankly, which
  63. 4:13were a lot more sophisticated, a lot more vocabulary, a lot more
  64. 4:17grammatical rules, programming, once you start to wrap your mind around what
  65. 4:21it is and how it works and what these various languages are, it's so easy,
  66. 4:24you'll see, after a few months of a class like this,
  67. 4:26to start teaching yourself, subsequently,
  68. 4:29other languages, as they may come, in the coming years as well.
  69. 4:32So what ultimately matters in this particular course
  70. 4:36is not so much where you end up relative to your classmates
  71. 4:38but where you end up relative to yourself when you began.
  72. 4:41And indeed, you'll begin today.
  73. 4:43And the only experience that matters ultimately in this class is your own.
  74. 4:46And so, consider where you are today.
  75. 4:49Consider, perhaps, just how cryptic something like that
  76. 4:51looked a few seconds ago.
  77. 4:52And take comfort in knowing just some months from now all of that
  78. 4:56will be within your own grasp.
  79. 4:58And if you're thinking that, OK, surely the person in front of me, to the left,
  80. 5:01to the right, behind me, knows more than me, that's statistically not the case.
  81. 5:052/3 of CS50 students have never taken a CS course before, which is to say,
  82. 5:10you're in very good company throughout this whole term.
  83. 5:14So then, what is computer science?
  84. 5:16I claim that it's problem solving.
  85. 5:18And the upside of that is that problem solving is
  86. 5:20something we sort of do all the time.
  87. 5:23But a computer science class, learning to program,
  88. 5:25I think kind of cleans up your thoughts.
  89. 5:27It helps you learn how to think more methodically, more carefully, more
  90. 5:31correctly, more precisely.
  91. 5:32Because, honestly, the computer is not going
  92. 5:34to do what you want unless you are correct and precise and methodical.
  93. 5:37And so, as such, there's these fringe benefits
  94. 5:39of just learning to think like a computer scientist and a programmer.
  95. 5:42And it doesn't take all that much to start doing so.
  96. 5:45This, for instance, is perhaps the simplest picture of computer science,
  97. 5:49sure, but really problem solving in general.
  98. 5:51Problems are all about taking input, like the problem you want to solve.
  99. 5:54You want to get the solution, a.k.a.
  100. 5:56output.
  101. 5:57And so, something interesting has got to be happening in here,
  102. 5:59in here, when you're trying to get from those inputs to outputs.
  103. 6:03Now, in the world of computers specifically,
  104. 6:05we need to decide in advance how we represent these inputs and outputs.
  105. 6:09We all just need to decide, whether it's Macs or PCs or phones or something
  106. 6:13else, that we're all going to speak some common language, irrespective
  107. 6:16of our human languages as well.
  108. 6:18And you may very well know that computers tend to speak only
  109. 6:22what language, so to speak?
  110. 6:26Assembly, one, but binary, two, might be your go-to.
  111. 6:29And binary, by implying two, means that the world of computers
  112. 6:32has just two digits at its disposal, 0 and 1.
  113. 6:35And indeed, we humans have many more than that, certainly not just zeros
  114. 6:40and ones alone.
  115. 6:40But a computer indeed only has zeros and ones.
  116. 6:43And yet, somehow they can do so much.
  117. 6:45They can crunch numbers in Excel, send text messages,
  118. 6:47create images and artwork and movies and more.
  119. 6:51And so, how do you get from something as simple as a few zeros, a few ones,
  120. 6:54to all of the stuff that we're doing today
  121. 6:56in our pockets and laptops and desktops?
  122. 6:58Well, it turns out that we can start quite simply.
  123. 7:01If a computer were to want to do something as simple as count, well,
  124. 7:05what could it do?
  125. 7:06Well, in our human world, we might count doing this,
  126. 7:09like 1, 2, 3, 4, 5, using so-called unitary notation, literally the digits
  127. 7:13on your fingers where one finger represents one person in the room,
  128. 7:16if I'm, for instance, taking attendance.
  129. 7:18Now, we humans would typically actually count 1, 2, 3, 4, 5, 6.
  130. 7:22And we'd go past just those five digits and count much higher,
  131. 7:25using zeros through nines.
  132. 7:26But computers, somehow, only have these zeros and ones.
  133. 7:29So if a computer only somehow speaks binary, zeros and ones,
  134. 7:33how does it even count past the number 1?
  135. 7:36Well, here are 3 zeros, of course.
  136. 7:38And if you translate this number in binary, 000,
  137. 7:42to a more familiar number in decimal, we would just call this zero.
  138. 7:46Enough said.
  139. 7:47If we were to represent, with a computer, the number 1,
  140. 7:49it would actually be 001, which, not surprisingly,
  141. 7:52is exactly the same as we might do in our human world,
  142. 7:55but we might not bother writing out the two zeros at the beginning.
  143. 7:59But a computer, now, if it wants to count as high as two,
  144. 8:02it doesn't have the digit 2.
  145. 8:03And so it has to use a different pattern of zeros and ones.
  146. 8:06And that happens to be 010.
  147. 8:08So this is not 10 with a zero in front of it.
  148. 8:10It's indeed zero one zero in the context of binary.
  149. 8:13And if we want to count higher now than two,
  150. 8:15we're going to have to tweak these zeros and ones further to get 3.
  151. 8:19And then if we want 4 or 5 or 6 or 7, we're
  152. 8:24just kind of toggling these zeros and ones, a.k.a.
  153. 8:26bits, for binary digits that represent, via these different patterns,
  154. 8:31different numbers that you and I, as humans, know,
  155. 8:33of course, as the so-called decimal system, 0 through 9,
  156. 8:36dec implying 10, 10 digits, those zeros through nine.
  157. 8:40So why that particular pattern?
  158. 8:42And why these particular zeros and ones?
  159. 8:44Well, it turns out that representing one thing or the other
  160. 8:48is just really simple for a computer.
  161. 8:50Why?
  162. 8:50At the end of the day, they're powered by electricity.
  163. 8:53And it's a really simple thing to just either store some electricity
  164. 8:56or don't store some electricity.
  165. 8:57Like, that's as simple as the world can get, on or off.
  166. 9:001 or 0, so to speak.
  167. 9:03So, in fact, inside of a computer, a phone, anything
  168. 9:05these days that's electronic, pretty much,
  169. 9:07is some number of switches, otherwise known as transistors.
  170. 9:10And they're tiny.
  171. 9:11You've got thousands, millions of them in your Mac or PC or phone these days.
  172. 9:14And these are just tiny little switches that can get turned on and off.
  173. 9:17And by turning those things on and off in patterns,
  174. 9:20a computer can count from 0 on up to 7, and even higher than that.
  175. 9:24And so these switches, really, you can think of being as like switches
  176. 9:27like this.
  177. 9:27Let me just borrow one of our little stage lights here.
  178. 9:29Here's a light bulb.
  179. 9:30It's currently off.
  180. 9:32And so, I could just think of this as representing,
  181. 9:34in my laptop, a transistor, a switch, representing 0.
  182. 9:38But if I allow some electricity to flow, now I, in fact, have a 1.
  183. 9:43Well, how do I count higher than 1?
  184. 9:44I, of course, need another light bulb.
  185. 9:46So let me grab another one here.
  186. 9:48And if I put it in that same kind of pattern, I don't want to just do this.
  187. 9:53That's sort of the old finger counting way of unary, just 1, 2.
  188. 9:57I want to actually take into account the pattern
  189. 9:59of these things being on and off.
  190. 10:00So if this was one a moment ago, what I think I did earlier was I turned it off
  191. 10:06and let the next one over be on, a.k.a.
  192. 10:10010.
  193. 10:12And let me get us a third bit, if you will.
  194. 10:15And that feels like enough.
  195. 10:16Here is that same pattern now, starting at the beginning with 3.
  196. 10:20So here is 000.
  197. 10:22Here is 001.
  198. 10:25Here is 010, a.k.a., in our human world of decimal, 2.
  199. 10:32And then we could, of course, keep counting further.
  200. 10:35This now would be 3 and dot dot dot.
  201. 10:37If this other bulb now goes on, and that switch is turned
  202. 10:40and all three stay on-- this, again, was what number?
  203. 10:43AUDIENCE: Seven.
  204. 10:44DAVID MALAN: OK, so, seven.
  205. 10:45So it's just as simple, relatively, as that, if you will.
  206. 10:49But how is it that these patterns came to be?
  207. 10:53Well, these patterns actually follow something very familiar.
  208. 10:56You and I don't really think about it at this level
  209. 10:58anymore because we've probably been doing math and numbers since grade
  210. 11:02school or whatnot.
  211. 11:04But if we consider something in decimal, like the number 123,
  212. 11:09I immediately jump to that.
  213. 11:10This looks like 123 in decimal.
  214. 11:12But why?
  215. 11:13It's really just three symbols, a 1, a 2 with a bit of curve, a 3
  216. 11:17with a couple of curves, that you and I now instinctively
  217. 11:20just assign meaning to.
  218. 11:22But if we do rewind a few years, that is one hundred twenty-three
  219. 11:27because you're assigning meaning to each of these columns.
  220. 11:30The 3 is in the so-called ones place.
  221. 11:33The 2 is in the so-called tens place.
  222. 11:36And the 1 is in the so-called hundreds place.
  223. 11:39And then the math ensues quickly in your head.
  224. 11:41This is technically 100 times 1, plus 10 times 2, plus 1 times 3, a.k.a.
  225. 11:47100 plus 20 plus 3.
  226. 11:48And there we get the sort of mathematical notion we know as 123.
  227. 11:54Well, nicely enough, in binary, it's actually the same thing.
  228. 11:58It's just these columns mean a little something different.
  229. 12:01If you use three digits in decimal, and you have the ones place,
  230. 12:05the tens place, and the hundreds place, well, why was that 1, 10, and 100?
  231. 12:09They're technically just powers of 10.
  232. 12:11So 10 to the 0, 10 to the 1, 10 to the 2.
  233. 12:13Why 10?
  234. 12:14Decimal system, "dec" meaning 10.
  235. 12:16You have 8 and 10 digits, 0 through 9.
  236. 12:18In the binary system, if you're going to use three digits,
  237. 12:21just change the bases if you're using only zeros and ones.
  238. 12:24So now it's powers of 2, 2 to the 0, 2 to the 1, 2 to the 2, a.k.a.
  239. 12:291 and 2 and 4, respectively.
  240. 12:31And if you keep going, it's going to be 8s column, 16s column, 32, 64,
  241. 12:36and so forth.
  242. 12:37So, why did we get these patterns that we did?
  243. 12:40Here's your 000 because it's 4 times 0, 2 times 0, 1 times 0, obviously 0.
  244. 12:46This is why we got the decimal number 1 in binary.
  245. 12:49This is why we got the number 2 in binary, because it's 4 times
  246. 12:530, plus 2 times 1, plus 1 times 0, and now 3, and now 4, and now 5, and now 6,
  247. 13:01and now 7.
  248. 13:01And, of course, if you wanted to count as high as 8, to be clear,
  249. 13:05what do you have to do?
  250. 13:06What does a computer need to do to count even higher than 7?
  251. 13:08AUDIENCE: Add a bit.
  252. 13:09DAVID MALAN: Add a bit.
  253. 13:10Add another light bulb, another switch.
  254. 13:12And, indeed, computers have standardized just how
  255. 13:14many zeros and ones, or bits or switches,
  256. 13:17they throw at these kinds of problems.
  257. 13:19And, in fact, most computers would typically use at least eight at a time.
  258. 13:23And even if you're only counting as high as three or seven,
  259. 13:25you would still use eight and have a whole bunch of zeros.
  260. 13:28But that's OK, because the computers these days certainly
  261. 13:31have so many more, thousands, millions of transistors and switches
  262. 13:35that that's quite OK.
  263. 13:37All right, so, with that said, if we can now count as high as seven
  264. 13:41or, frankly, as high as we want, that only
  265. 13:44seems to make computers useful for things like Excel,
  266. 13:46like number crunching.
  267. 13:48But computers, of course, let you send text messages,
  268. 13:50write documents, and so much more.
  269. 13:52So how would a computer represent something like a letter,
  270. 13:55like the letter A of the English alphabet, if, at the end of the day,
  271. 13:59all they have is switches?
  272. 14:02Any thoughts?
  273. 14:03Yeah.
  274. 14:03AUDIENCE: You can represent letters in numbers.
  275. 14:05DAVID MALAN: OK, so we could represent letters using numbers.
  276. 14:08OK, so what's a proposal?
  277. 14:10What number should represent what?
  278. 14:11AUDIENCE: Say if you were starting at the beginning of the alphabet,
  279. 14:15you could say 1 is A, 2 is B, 3 is C.
  280. 14:18DAVID MALAN: Perfect.
  281. 14:19Yeah, we just all have to agree somehow that one number is
  282. 14:22going to represent one letter.
  283. 14:23So 1 is A, 2 is B, 3 is C, Z is 26, and so forth.
  284. 14:28Maybe we can even take into account uppercase and lowercase.
  285. 14:30We just have to agree and sort of write it down in some global standard.
  286. 14:34And humans, indeed, did just that.
  287. 14:36They didn't use 1, 2, 3.
  288. 14:38It turns out they started a little higher up.
  289. 14:40Capital A has been standardized as the number 65.
  290. 14:44And capital B has been standardized as the number 66.
  291. 14:47And you can kind of imagine how it goes up from there.
  292. 14:50And that's because whatever you're representing,
  293. 14:53ultimately, can only be stored, at the end of the day, as zeros and ones.
  294. 14:57And so, some humans in a room before, decided that capital A shall be 65,
  295. 15:01or, really, this pattern of zeros and ones inside of every computer
  296. 15:05in the world, 01000001.
  297. 15:08So if that pattern of zeros and ones ever appears in a computer,
  298. 15:12it might be interpreted then as indeed a capital letter A, eight of those bits
  299. 15:17at a time.
  300. 15:18But I worry, just to be clear, we might have now created a problem.
  301. 15:23It might seem, if I play this naively, that, OK,
  302. 15:25how do I now actually do math with the number 65?
  303. 15:28If now Excel displays 65 is an A, let alone Bs and Cs.
  304. 15:33So how might a computer do as you've proposed,
  305. 15:37have this mapping from numbers to letters, but still support numbers?
  306. 15:41It feels like we've given something up.
  307. 15:43Yeah?
  308. 15:44AUDIENCE: By having a prefix for letters?
  309. 15:46DAVID MALAN: By having a prefix?
  310. 15:47AUDIENCE: You could have prefixes and suffixes.
  311. 15:48DAVID MALAN: OK, so we could perhaps have some kind of prefix,
  312. 15:51like some pattern of zeros and ones--
  313. 15:53I like this-- that indicates to the computer
  314. 15:56here comes another pattern that represents a letter.
  315. 15:58Here comes another pattern that represents a number or a letter.
  316. 16:02So, not bad.
  317. 16:03I like that.
  318. 16:04Other thoughts?
  319. 16:05How might a computer distinguish these two?
  320. 16:08Yeah.
  321. 16:08AUDIENCE: Have a different file format, so,
  322. 16:11like, odd text or just check the graphic or--
  323. 16:16DAVID MALAN: Indeed, and that's spot-on.
  324. 16:17Nothing wrong with what you suggested, but the world generally does just that.
  325. 16:20The reason we have all of these different file formats in the world,
  326. 16:23like JPEG and GIF and PNGs and Word documents, .docx,
  327. 16:28and Excel files and so forth, is because a bunch of humans got in a room
  328. 16:32and decided, well, in the context of this type of file, or really,
  329. 16:35more specifically, in the context of this type of program,
  330. 16:38Excel versus Photoshop versus Google Docs or the like,
  331. 16:42we shall interpret any patterns of zeros and ones as being maybe numbers
  332. 16:46for Excel, maybe letters in, like, a text messaging program or Google Docs,
  333. 16:51or maybe even colors of the rainbow in something like Photoshop and more.
  334. 16:54So it's context dependent.
  335. 16:55And we'll see, when we ourselves start programming,
  336. 16:58you the programmer will ultimately provide
  337. 17:00some hints to the computer that tells the computer, interpret it as follows.
  338. 17:05So, similar in spirit to that, but not quite a standardized with these
  339. 17:08prefixes.
  340. 17:09So this system here actually has a name ASCII, the American Standard
  341. 17:12Code for Information Interchange.
  342. 17:14And indeed, it began here in the US, and that's
  343. 17:16why it's actually a little biased toward A's through Z's
  344. 17:19and a bit of punctuation as well.
  345. 17:21And that quickly became a problem.
  346. 17:22But if we start simply now, in English, the mapping
  347. 17:26itself is fairly straightforward.
  348. 17:28So if A is 65, B it 66, and dot dot dot, suppose
  349. 17:33that you received a text message, an email, from a friend,
  350. 17:36and underneath the hood, so to speak, if you kind of
  351. 17:39looked inside the computer, what you technically received in this text
  352. 17:42or this email happened to be the numbers 72, 73, 33,
  353. 17:48or, really, the underlying pattern of zeros and ones.
  354. 17:50What might your friend have sent you as a message, if it's 72, 73, 33?
  355. 17:56AUDIENCE: Hey.
  356. 17:58DAVID MALAN: Hey?
  357. 17:58Close.
  358. 17:59AUDIENCE: Hi.
  359. 17:59DAVID MALAN: Hi.
  360. 18:00It's, indeed, hi.
  361. 18:01Why?
  362. 18:02Well, apparently, according to this little cheat sheet, H is 72, I is 73.
  363. 18:06It's not obvious from this chart what the 33 is,
  364. 18:09but indeed, this pattern represents "hi."
  365. 18:11And anyone want to guess, or if you know, what 33 is?
  366. 18:13AUDIENCE: Exclamation point.
  367. 18:14DAVID MALAN: Exclamation point.
  368. 18:16And this is, frankly, not the kind of thing most people know.
  369. 18:18But it's easily accessible by a nice user-friendly chart like this.
  370. 18:22So this is an ASCII chart.
  371. 18:23When I said that we just need to write down this mapping earlier,
  372. 18:26this is what people did.
  373. 18:27They wrote it down in a book or in a chart.
  374. 18:29And, for instance, here is our 72 for H, here is our 73 for I,
  375. 18:33and here is our 33 for exclamation point.
  376. 18:37And computers, Macs, PCs, iPhones, Android devices,
  377. 18:41just know this mapping by heart, if you will.
  378. 18:43They've been designed to understand those letters.
  379. 18:46So here, I might have received "hi."
  380. 18:48Technically, what I've received is these patterns of zeros and ones.
  381. 18:51But it's important to note that when you get these patterns of zeros and ones
  382. 18:54in any format, be it email or text or a file,
  383. 18:58they do tend to come in standard lengths,
  384. 19:00with a certain number of zeros and ones altogether.
  385. 19:04And this happens to be 8 plus 8, plus 8.
  386. 19:07So just to get the message "hi, exclamation point,"
  387. 19:10you would have received at least, it would seem, some 24 bits.
  388. 19:15But frankly, bits are so tiny, literally and mathematically,
  389. 19:18that we don't tend to think or talk, generally, in terms of bits.
  390. 19:21You're probably more familiar with bytes.
  391. 19:23B-Y-T-E-S is a byte, is a byte, is a byte.
  392. 19:27A byte is just 8 bits.
  393. 19:29And even those, frankly, aren't that useful if we do out the math.
  394. 19:32How high can you count if you have eight bits?
  395. 19:34Anyone know?
  396. 19:35Say it again?
  397. 19:38Higher than that.
  398. 19:39Unless you want to go negative, that's fine.
  399. 19:42256, technically 255.
  400. 19:45Long story short, if we actually got into the weeds of all of these zeros
  401. 19:48and ones, and we figured out what 11111111 mathematically adds up
  402. 19:54to in decimal, it would indeed be 255, or less
  403. 19:57if you want to represent negative numbers as well.
  404. 20:00So this is useful because now we can speak, not just in terms of bytes
  405. 20:04but, if the files are bigger, kilobytes is thousands of bytes,
  406. 20:06megabytes is millions of bytes, gigabytes is billions of bytes,
  407. 20:10terabytes are trillions of bytes, and so forth.
  408. 20:14We have a vocabulary for these increasingly large quantities of data.
  409. 20:20The problem is that, if you're using ASCII and, therefore, eight bits or one
  410. 20:24byte per character, and originally, only seven, you
  411. 20:27can only represent 255 characters.
  412. 20:30And that's actually 256 total characters, including zero.
  413. 20:33And that's fine if you're using literally English, in this case,
  414. 20:37plus a bunch of punctuation.
  415. 20:39But there's many human languages in the world
  416. 20:42that need many more symbols and, therefore, many more bits.
  417. 20:45So, thankfully, the world decided that we'll indeed
  418. 20:48support not just the US English keyboard, but all
  419. 20:51of the accented characters that you might want for some languages.
  420. 20:54And heck, if we use enough bits, zeros and ones,
  421. 20:57not only can we represent all human languages in written form,
  422. 21:01as well as some emotions along the way, we
  423. 21:03can capture the latter with these things called emojis.
  424. 21:06And indeed, these are very much in vogue these days.
  425. 21:09You probably send and/or receive many of these things any given day.
  426. 21:12These are just characters, like letters of an alphabet, patterns
  427. 21:16of zeros and ones that you're receiving, that the world has also standardized.
  428. 21:20For instance, there are certain emojis that
  429. 21:22are represented with certain patterns of bits.
  430. 21:24And when you receive them, your phone, your laptop, your desktop,
  431. 21:28displays them as such.
  432. 21:30And this newer standard is called Unicode.
  433. 21:32So it's a superset of what we called ASCII.
  434. 21:35And Unicode is just a mapping of many more numbers to many more letters
  435. 21:39or characters, more generally, that might
  436. 21:42use eight bits for backwards compatibility
  437. 21:45with the old way of doing things with ASCII, but they might also use 16 bits.
  438. 21:49And if you have 16 bits, you can actually
  439. 21:51represent more than 65,000 possible letters.
  440. 21:54And that's getting up there.
  441. 21:55And heck, Unicode might even use 32 bits to represent letters and numbers
  442. 22:01and punctuation symbols and emojis.
  443. 22:03And that would give you up to 4 billion possibilities.
  444. 22:06And, I daresay, one of the reasons we see so many emojis these days is we
  445. 22:09have so much room.
  446. 22:11I mean, we've got room for billions more, literally.
  447. 22:14So, in fact, just as a little bit of trivia,
  448. 22:16has anyone ever received this decimal number, or if you prefer binary now,
  449. 22:21has anyone ever received this pattern of zeros and ones on your phone,
  450. 22:25in a text or an email, perhaps this past year?
  451. 22:29Well, if you actually look this up, this esoteric sequence of zeros and ones
  452. 22:33happens to represent face with medical mask.
  453. 22:37And notice that if you've got an iPhone or an Android device,
  454. 22:40you might be seeing different things.
  455. 22:43In fact, this is the Android version of this, most recently.
  456. 22:46This is the iOS version of it, most recently.
  457. 22:49And there's bunches of other interpretations by other companies
  458. 22:51as well.
  459. 22:53So Unicode, as a consortium, if you will,
  460. 22:55has standardized the descriptions of what these things are.
  461. 22:58But the companies themselves, manufacturers out there,
  462. 23:02have generally interpreted it as you see fit.
  463. 23:05And this can lead to some human miscommunications.
  464. 23:08In fact, for like, literally, embarrassingly, like a year or two,
  465. 23:11I started being in the habit of using the emoji that kind of looks
  466. 23:14like this because I thought it was like woo, happy face, or whatever.
  467. 23:17I didn't realize this is the emoji for hug
  468. 23:19because whatever device I was using sort of looks like this, not like this.
  469. 23:24And that's because of their interpretation of the data.
  470. 23:27This has happened too when what was a gun became a water
  471. 23:31pistol in some manufacturers' eyes.
  472. 23:33And so it's an interesting dichotomy between what information we all
  473. 23:37want to represent and how we choose, ultimately, to represent it.
  474. 23:42Questions, then, on these representations of formats,
  475. 23:45be it numbers or letters, or soon more.
  476. 23:49Yeah?
  477. 23:49AUDIENCE: Why is decimal popular for a computer
  478. 23:52if binary is the basis for everything?
  479. 23:54DAVID MALAN: Sorry, why is what so popular?
  480. 23:56AUDIENCE: Why is the decimal popular if binary is the fundamental--
  481. 23:59DAVID MALAN: Yeah, so we'll come back to this in a few weeks, in fact.
  482. 24:01There are other ways to represent numbers.
  483. 24:03Binary is one.
  484. 24:04Decimal is another.
  485. 24:06Unary is another.
  486. 24:07And hexadecimal is yet a fourth that uses 16 total digits, literally 0
  487. 24:12through 9 plus A, B, C, D, E, F. And somehow,
  488. 24:15you can similarly count even higher with those.
  489. 24:18We'll see in a few weeks why this is compelling.
  490. 24:21But hexadecimal, long story short, uses four bits per digit.
  491. 24:24And so, four bits, if you have two digits in hex, that gives you eight.
  492. 24:28And it's just a very convenient unit of measure.
  493. 24:30And it's also human convention in the world of files and other things.
  494. 24:34But we'll come back to that soon.
  495. 24:35Other questions?
  496. 24:36AUDIENCE: Do the lights on the stage supposedly say that--
  497. 24:39DAVID MALAN: Do the lights on the stage supposedly say anything?
  498. 24:42Well, if we had thought in advance to use maybe 64 light bulbs,
  499. 24:46that would seem to give us 8 total bytes on stage, 8 times 8,
  500. 24:51giving us just that.
  501. 24:52Maybe.
  502. 24:54Good question.
  503. 24:55Other questions on 0's and 1's?
  504. 24:58It's a little bright in here.
  505. 25:01No?
  506. 25:02Oh, yes?
  507. 25:04Where everyone's pointing somewhere specific.
  508. 25:08There we go.
  509. 25:09Sorry.
  510. 25:10Very bright in this corner.
  511. 25:11AUDIENCE: I was just going to ask about the 255 bits,
  512. 25:14like with the maximum characters.
  513. 25:16[INAUDIBLE]
  514. 25:16DAVID MALAN: Ah, sure, and we'll come back to this, in some form,
  515. 25:19in the coming days too, at a slower pace too,
  516. 25:22we have, with eight bits, two possible values for the first
  517. 25:26and then two for the next, two for the next, and so forth.
  518. 25:28So that's 2 times 2 times 2.
  519. 25:30That's 2 to the eighth power total, which
  520. 25:32means you can have 256 total possible patterns of zeros and ones.
  521. 25:36But as we'll see soon computer scientists, programmers,
  522. 25:40software often starts counting at 0 by convention and if you use one of those
  523. 25:45patterns, 00000000 to represent the decimal number we know is zero,
  524. 25:50you only have 255 other patterns left to count as high as therefore 255.
  525. 25:56That's all.
  526. 25:57Good question.
  527. 25:59All right, so what then might we have besides these emojis and letters
  528. 26:04and numbers?
  529. 26:04Well, we of course have things like colors and programs
  530. 26:07like Photoshop and pictures and photos.
  531. 26:09Well let me ask the question again.
  532. 26:11How might a computer, do you think, knowing what you know now, represents
  533. 26:14something like a color?
  534. 26:16Like what are our options if all we've got are zeros and ones and switches?
  535. 26:19Yeah?
  536. 26:20AUDIENCE: RGB
  537. 26:21DAVID MALAN: RGB.
  538. 26:23RGB indeed is this acronym that represents some amount of red
  539. 26:27and some amount of green and blue and indeed computers
  540. 26:29can represent colors by just doing that.
  541. 26:32Remembering, for instance, this dot.
  542. 26:33This yellow dot on the screen that might be part of any of those emojis
  543. 26:36these days, well that's some amount of red, some amount of green,
  544. 26:39some amount of blue.
  545. 26:40And if you sort of mix those colors together,
  546. 26:42you can indeed get a very specific one.
  547. 26:44And we'll see you in just a moment just that.
  548. 26:46So indeed earlier on, humans only used seven bits total.
  549. 26:51And it was only once they decided, well, let's add an eighth bit that they
  550. 26:54got extended ASCII and that was initially in part
  551. 26:57a solution to the same problem of not having enough room, if you will,
  552. 27:00in those patterns of zeros and ones to represent all of the characters
  553. 27:05that you might want.
  554. 27:06But even that wasn't enough and that's why we've now gone up to 16 and 32
  555. 27:10and long past 7.
  556. 27:11So if we come back now to this one particular color.
  557. 27:16RGB was proposed as a scheme, but how might this work?
  558. 27:19Well, consider for instance this.
  559. 27:21If we do indeed decide as a group to represent any color of the rainbow
  560. 27:25with some mixture of some red, some green, and some blue,
  561. 27:28we have to decide how to represent the amount of red and green and blue.
  562. 27:33Well, it turns out if all we have are zeros and ones, ergo numbers,
  563. 27:37let's do just that.
  564. 27:38For instance, suppose a computer we're using, these three numbers 72, 73, 33,
  565. 27:44no longer in the context of an email or a text message,
  566. 27:47but now in the context of something like Photoshop, a program for editing
  567. 27:51and creating graphical files, maybe this first number
  568. 27:55could be interpreted as representing some amount of red, green, and blue,
  569. 28:00respectively.
  570. 28:00And that's exactly what happens.
  571. 28:02You can think of the first digit as red, second as green, third as blue.
  572. 28:05And so ultimately when you combine that amount of red, that amount of green,
  573. 28:10that amount of blue, it turns out it's going to resemble the shade of yellow.
  574. 28:14And indeed, you can come up with a numbers between 0 and 255
  575. 28:18for each of those colors to mix any other color that you might want.
  576. 28:21And you can actually see this in practice.
  577. 28:23Even though our screens, admittedly, are getting really good
  578. 28:26on our phones and laptops such that you barely see the dots, they are there.
  579. 28:30You might have heard the term pixel before.
  580. 28:32Pixel's just a dot on the screen and you've
  581. 28:34got thousands, millions of them these days horizontally and vertically.
  582. 28:38If I take even this emoji, which again happens
  583. 28:41to be one company's interpretation of a face with medical mask
  584. 28:46and zoom in a bit, maybe zoom in a bit more,
  585. 28:48you can actually start to see these pixels.
  586. 28:50Things get pixelated because what you're seeing
  587. 28:53is each of the individual dots that compose this particular image.
  588. 28:57And apparently each of these individual dots
  589. 28:59are probably using 24 bits, eight bits for red, eight bits for green, eight
  590. 29:04bits for blue, in some pattern.
  591. 29:07This program or some other like Photoshop is interpreting one pattern
  592. 29:11and it's white or yellow or black or some brown in between.
  593. 29:16So if you look sort of awkwardly, but up close to your phone or your laptop
  594. 29:19or maybe your TV, you can see exactly this, too.
  595. 29:23All right, well, what about things that we also
  596. 29:25watch every day on YouTube or the like?
  597. 29:27Things like videos.
  598. 29:28How would a computer, knowing what we know now,
  599. 29:30represent something like a video?
  600. 29:35How might you represent a video using only zeros and ones?
  601. 29:37Yeah?
  602. 29:38AUDIENCE: As we can see here, they represent images, right?
  603. 29:43[INAUDIBLE] sounds of the 0 and 1s as well.
  604. 29:47[INAUDIBLE]
  605. 29:50DAVID MALAN: Yeah, exactly.
  606. 29:52To summarize, what video really adds is just some notion of time.
  607. 29:55It's not just one image, it's not just one letter or a number,
  608. 29:58it's presumably some kind of sequence because time is passing.
  609. 30:01So with a whole bunch of images, maybe 24 maybe 30 per second,
  610. 30:05if you fly them by the human's eyes, we can
  611. 30:08interpret them using our eyes and brain that there is now
  612. 30:11movement and therefore video.
  613. 30:13Similarly with audio or music.
  614. 30:16If we just came up with some convention for representing those same notes
  615. 30:20on a musical instrument, could we have the computer synthesize them, too?
  616. 30:23And this might be actually pretty familiar.
  617. 30:25Let me pull up a quick video here, which happens to be an old school
  618. 30:29version of the same idea.
  619. 30:31You might remember from childhood.
  620. 30:32[MUSIC PLAYING]
  621. 30:40[CLICKING]
  622. 30:54So granted that particular video is an actual video
  623. 30:58of a paper-based animation, but indeed, that's really all you need,
  624. 31:02is some sequence of these images, which themselves of course
  625. 31:06are just zeros and ones because they're just this grid of these pixels or dots.
  626. 31:10Now something like musical notes like these, those of you who are musicians
  627. 31:14might just naturally play these on physical devices,
  628. 31:16but computers can certainly represent those sounds, too.
  629. 31:19For instance, a popular format for audio is
  630. 31:22called MIDI and MIDI might just represent
  631. 31:24each note that you saw a moment ago essentially as a sequence of numbers.
  632. 31:29But more generally, you might think about music as having notes,
  633. 31:32for instance, A through G, maybe some flats and some sharps,
  634. 31:35you might have the duration like how long is the note being heard or played
  635. 31:39on a piano or some other device, and then
  636. 31:41just the volume like how hard does a human in the real world
  637. 31:43press down on that key and therefore how loud is that sound?
  638. 31:46It would seem that just remembering little details like that quantitatively
  639. 31:51we can then represent really all of these otherwise analog human realities.
  640. 31:57So that then is really a laundry list of ways
  641. 32:00that we can just represent information.
  642. 32:02Again, computers or digital have all of these different formats,
  643. 32:05but at the end of the day and as fancy as those devices in years
  644. 32:07are, it's just zeros and ones, tiny little switches or light bulbs,
  645. 32:11if you will, represented in some way and it's up to the software
  646. 32:14that you and I and others write to use those zeros
  647. 32:17and ones in ways we want to get the computers to do something
  648. 32:21more powerfully.
  649. 32:22Questions, then, on this representation of information, which I daresay
  650. 32:27is ultimately what problem solving is all about, taking in information
  651. 32:30and producing new via some process in between.
  652. 32:35Any questions there?
  653. 32:38Yeah, in back.
  654. 32:40AUDIENCE: Yeah, so we talked about how different file formats kind of allow
  655. 32:44you to interpret information.
  656. 32:45How does a file format like .mp4 discriminate between audio and video
  657. 32:50within itself as a value?
  658. 32:52DAVID MALAN: So a really good question.
  659. 32:53There are many other file formats out there.
  660. 32:55You allude to MP4 for video and more generally the use
  661. 32:58are these things called codecs and containers.
  662. 33:01It's not quite as simple when using larger files, for instance,
  663. 33:04in more modern formats that a video is just a sequence of images,
  664. 33:08for instance.
  665. 33:08Why?
  666. 33:09If you stored that many images for like a Hollywood movie,
  667. 33:13like 24 or 30 of them per second, that's a huge number of images.
  668. 33:17And if you've ever taken photos on your phone,
  669. 33:19you might know how many megabytes or larger even individual photographs
  670. 33:23might be.
  671. 33:24So humans have developed over the years a fancier software
  672. 33:27that uses much more math to represent the same information more minimally
  673. 33:32just using somehow shorter patterns of zeros and ones
  674. 33:35than are most simplistic representation here.
  675. 33:37And they use what might be called compression.
  676. 33:40If you've ever used a zip file or something else,
  677. 33:42somehow your computer is using fewer zeros and ones
  678. 33:45to represent the same amount of information,
  679. 33:47ideally without losing any information.
  680. 33:49In the world of multimedia, which we'll touch on a little bit in a few weeks,
  681. 33:52there are both lossy and lossless formats out there.
  682. 33:56Lossless means you lose no information whatsoever.
  683. 33:59But more commonly as you're alluding to one is lossy compression, L-O-S-S-Y,
  684. 34:05where you're actually throwing away some amount of quality.
  685. 34:08You're getting some amount of pixelation that might not
  686. 34:10look perfect to the human, but heck it's a lot cheaper and a lot easier
  687. 34:13to distribute.
  688. 34:14And in the world of multimedia, you have containers like QuickTime
  689. 34:17and other MPEG containers that can combine
  690. 34:20different formats of video, different formats of audio in one file,
  691. 34:24but there, too, do designers have discretion.
  692. 34:26So more in a few weeks, too.
  693. 34:28Other questions, then, on information here as well?
  694. 34:32Yeah?
  695. 34:32AUDIENCE: So I know computers used to be very big
  696. 34:35and taking up like a whole room and stuff.
  697. 34:37Is the reason they've gotten smaller because we can store
  698. 34:41this information piecemeal or what?
  699. 34:43DAVID MALAN: Exactly.
  700. 34:44I mean, back in the day you might have heard of the expression a vacuum
  701. 34:47tube, which is like some physically large device that
  702. 34:50might have only stored some 0 or 1.
  703. 34:53Yes, it is the miniaturization of hardware these days
  704. 34:55that has allowed us to store as many and many more zeros and ones much more
  705. 35:00closely together.
  706. 35:01And as we've built more fancy machines that
  707. 35:03can sort of design this hardware at an even smaller scale,
  708. 35:06we're just packing more and more into these devices.
  709. 35:08But there, too, is a trade off.
  710. 35:09For instance, you might know by using your phone or your laptop
  711. 35:13for quite a while, maybe on your lap, starts to get warm.
  712. 35:15So there are these literal physical side effects
  713. 35:17of this where now some of our devices run hot.
  714. 35:20This is why like a data center in the real world
  715. 35:23might need more air conditioning than a typical place,
  716. 35:25because there are these physical artifacts as well.
  717. 35:28In fact, if you'd like to see one of the earliest computers from decades ago,
  718. 35:31across the river here in now Allston in the new engineering building
  719. 35:35is the Harvard Mark 1 computer that will give you a much better mental model
  720. 35:40of just that.
  721. 35:41Well if we come back now to this first picture
  722. 35:44being computer science or really problem solving,
  723. 35:47I daresay we have more than enough ways now
  724. 35:49to represent information, input and output, so long as we all just agree
  725. 35:53on something and thankfully all of those before us have given us
  726. 35:56things like ASCII and Unicode.
  727. 35:57Not to mention MP4s, word documents, and the like.
  728. 36:01But what's inside of this proverbial black box into which these inputs are
  729. 36:05going in the outputs are coming?
  730. 36:07Well that's where we get this term you might have heard, too.
  731. 36:09An algorithm, which is just step-by-step instructions for solving some problem
  732. 36:14incarnated in the world of computers by software.
  733. 36:17When you write software aka programs, you
  734. 36:20are implementing one or more algorithms, one or more sets of instructions
  735. 36:26for solving some problem, and maybe you're using this language or that,
  736. 36:29but at the end of the day, no matter the language
  737. 36:31you use the computer is going to represent what you type
  738. 36:34using just zeros and ones.
  739. 36:37So what might be a representative algorithm?
  740. 36:40Nowadays you might use your phone quite a bit
  741. 36:42to make calls or send texts or emails and therefore you
  742. 36:45have a whole bunch of contacts in your address book.
  743. 36:48Nowadays, of course, this is very digital,
  744. 36:50but whether on iOS or Android or the like,
  745. 36:53you might have a whole bunch of names, first name
  746. 36:56and/or last, as well as numbers and emails and the like.
  747. 36:58You might be in the habit of like scrolling through on your phone
  748. 37:01all of those names to find the person you want to call.
  749. 37:05It's probably sorted alphabetically by first name or last name, A through Z,
  750. 37:09or some other symbol.
  751. 37:11This is frankly quite the same as we used to do back in my day, CS50,
  752. 37:16when we just used a physical book.
  753. 37:18In this physical book might be a whole bunch
  754. 37:20of names alphabetically sorted from left to right
  755. 37:22corresponding to a whole bunch of numbers.
  756. 37:24So suppose that in this old Harvard phone book
  757. 37:27we want to search for John Harvard.
  758. 37:29We might of course start quite simply at the beginning
  759. 37:31here, looking at one page at a time, and this is an algorithm.
  760. 37:36This is like literally step-by-step looking for the solution
  761. 37:40to this problem.
  762. 37:41In that sense, if John Harvard's in the phone book,
  763. 37:43is this algorithm page-by-page correct, would you say?
  764. 37:47AUDIENCE: Yes.
  765. 37:48DAVID MALAN: Yes.
  766. 37:49Like if John Harvard's in the phone book,
  767. 37:51obviously I'm eventually going to get to him, so that's what we mean by correct.
  768. 37:54Is it efficient?
  769. 37:56Is it well designed, would you say?
  770. 37:58No.
  771. 37:58I mean this is going to take forever even just to get to the Js or the Hs,
  772. 38:01depending how this thing's sorted.
  773. 38:03All right, well let me go a little faster.
  774. 38:04I'll start like two pages at a time.
  775. 38:062, 4, 6, 8, 10, 12, and so forth.
  776. 38:11Sounds faster, is faster, is it correct?
  777. 38:13AUDIENCE: No.
  778. 38:14DAVID MALAN: OK, why is it not correct?
  779. 38:16Yeah?
  780. 38:17AUDIENCE: So if you're starting on page 1,
  781. 38:19you're only going odd number of pages, so if it's on an even number page,
  782. 38:22you'll miss it.
  783. 38:22DAVID MALAN: Exactly.
  784. 38:23If I start on an odd number of pages and I'm going two at a time
  785. 38:26I might miss pages in between.
  786. 38:28And if I therefore conclude when I get to the back
  787. 38:30of the book there was no John Harvard, I might have just errored.
  788. 38:33This would be again one of these bugs.
  789. 38:35But if I try a little harder, I feel like there's a solution.
  790. 38:39We don't have to completely throw out this algorithm.
  791. 38:41I think we can probably go roughly twice as fast still.
  792. 38:44But what should we do instead to fix this?
  793. 38:47Yeah, in back.
  794. 38:48AUDIENCE: [INAUDIBLE]
  795. 38:58DAVID MALAN: Nice.
  796. 38:59So I think what many of us, most of us, if we even use this technology any more
  797. 39:02these days, we might go roughly to the middle of the phone book
  798. 39:05just to kind of get us started.
  799. 39:06And now I'm looking down, I'm looking for J, assuming first name, J Harvard,
  800. 39:10and it looks like I'm in the M section.
  801. 39:13So just to be clear, what should I do next?
  802. 39:15AUDIENCE: [INAUDIBLE]
  803. 39:21DAVID MALAN: OK, and presumably it is John Harvard
  804. 39:23would be to the left of this.
  805. 39:24So here's an opportunity to figuratively and literally tear
  806. 39:27this particular problem in half, throw half of the problem away.
  807. 39:32It's actually pretty easy if you just do it that way.
  808. 39:34The hard way is this way.
  809. 39:36But I've now just decreased the size of this problem really in half.
  810. 39:41So if I started with 1,000 pages of phone numbers and names, now
  811. 39:45I'm down to 500.
  812. 39:46And already we haven't found John Harvard,
  813. 39:48but that's a big bite out of this problem.
  814. 39:50I do think it's correct because if J is to the left of M, of course,
  815. 39:54he's definitely not going to be over there.
  816. 39:56I think if I repeat this again dividing and conquering, if you will,
  817. 40:00here I might have gone a little too far.
  818. 40:02Now I'm in like the E section.
  819. 40:03So let me tear the problem in half again, throw another 250 pages away,
  820. 40:08and again repeat, dividing and dividing and conquering
  821. 40:11until finally, presumably, I end up with just one page of a phone
  822. 40:14book on which John Harvard's name either is or is not,
  823. 40:18but because of the algorithm you proposed, step by step,
  824. 40:21I know that he's not in anything I discarded.
  825. 40:24So traumatic is that might have been made out
  826. 40:28to be, it's actually just harnessing pretty good human intuition.
  827. 40:31Indeed, this is what programming is all about, too.
  828. 40:33It's not about learning a completely new world,
  829. 40:36but really just how to harness intuition and ideas that you might already
  830. 40:40have and take naturally but learning how to express
  831. 40:43them now more succinctly, more precisely,
  832. 40:45using things called programming languages.
  833. 40:49Why is an algorithm like that if I found John Harvard better than, ultimately,
  834. 40:54just doing the first one or even the second
  835. 40:56and maybe doubling back to check those even pages?
  836. 40:59Well let's just look at little charts here.
  837. 41:01Again, we don't have to get into the nuances of numbers,
  838. 41:04but if we've got like a chart here, xy plot, on the x-axis
  839. 41:07here I claim as the size of the problem.
  840. 41:09So measured in the numbers of pages in the phone book.
  841. 41:12So the farther you go out here, the more pages are in the phone book.
  842. 41:16And here we have time to solve on the y-axis.
  843. 41:18So the higher you go up, the more time it's
  844. 41:21going to be taking to solve that particular problem.
  845. 41:24So let's just arbitrarily say that the first algorithm, involving
  846. 41:27like n pages, might be represented graphically like this.
  847. 41:31No matter the slope, it's a straight line
  848. 41:33because there's presumably a one to one relationship
  849. 41:36between numbers of pages and number of seconds or number of page turns.
  850. 41:40Why?
  851. 41:40If the phone company adds another page next year
  852. 41:43because some new people move to town, that's
  853. 41:45going to require one additional page for me.
  854. 41:47One to one.
  855. 41:49If, though, we use the second algorithm, flawed though it was,
  856. 41:52unless we double back a little bit to fix someone being in between,
  857. 41:56that's too going to be a straight line, but it's
  858. 41:59going to be a different slope because now there's a 2 to 1 or a 1 to 2
  859. 42:02relationship because I'm going to pages at a time.
  860. 42:06So if the phone company adds another page or another two pages,
  861. 42:10that still only just one more step.
  862. 42:13You can see the difference if I kind of draw this.
  863. 42:15If this is the phone book in question, this number of pages,
  864. 42:18it might take this many seconds on the yellow line
  865. 42:20to represent or to find someone like John Harvard.
  866. 42:24But of course on the first algorithm, the red line,
  867. 42:27it's literally going to take twice as many steps.
  868. 42:29And what do the n here mean? n is the go-to variable
  869. 42:32for computer scientist or programmer just generically representing a number.
  870. 42:36So if the number of pages in the phone book is n,
  871. 42:38the number of steps the second algorithm would have taken
  872. 42:41would be in the worst case n over 2.
  873. 42:44Half as many because you're going twice as fast.
  874. 42:46But the third algorithm, actually if you recall your logarithms,
  875. 42:50looks a little something like this.
  876. 42:52There's a fundamentally different relationship
  877. 42:54between the size of the problem and the amount of time required to solve it
  878. 42:58that technically is log-based, too, again,
  879. 43:00but it's really the shape that's different.
  880. 43:02The implication there is that if, for instance, Cambridge and Allston,
  881. 43:06two different towns here in Massachusetts, merge next year
  882. 43:08and there's just one phone book that's twice as big,
  883. 43:11no big deal for that third and final algorithm.
  884. 43:14Why?
  885. 43:15You just tear the problem one more time in half,
  886. 43:17taking one more byte, that's it, not another 1,000
  887. 43:21bytes just to get to the solution.
  888. 43:23Put another way, you can walk it way, way,
  889. 43:26way out here to a much bigger phone book and ultimately
  890. 43:29that green line is barely going to have budged.
  891. 43:32So this then is just a way of now formalizing and thinking
  892. 43:35about what the performance or quality of these algorithms might be.
  893. 43:42Before we now make one more formalization of the algorithm itself,
  894. 43:46any questions then on this notion of efficiency or now performance of ideas?
  895. 43:52Yeah.
  896. 43:52AUDIENCE: How many phone books have you got?
  897. 43:56DAVID MALAN: (LAUGHING) A lot of phone books over the years
  898. 43:58and if you or your parents have any more still somewhere we could definitely
  899. 44:02use them because they're hard to find.
  900. 44:04Other questions?
  901. 44:05But thanks.
  902. 44:07Other questions here, too?
  903. 44:09No.
  904. 44:10Oh, was that a murmur?
  905. 44:11Yes, over here.
  906. 44:13AUDIENCE: You could get Harry Potter as a guest speaker.
  907. 44:15DAVID MALAN: Sorry, say again.
  908. 44:16AUDIENCE: You could get Harry Potter as a guest speaker.
  909. 44:18DAVID MALAN: (LAUGHING) Oh, yeah.
  910. 44:19Hopefully.
  911. 44:20Then we'd have a little something more to use here.
  912. 44:23So now if we want to formalize further what it is we just did,
  913. 44:28we can go ahead and introduce this.
  914. 44:30A form of code aka pseudocode.
  915. 44:33Pseudocode is not a specific language, it's not like something
  916. 44:35we're about to start coding in, it's just a way of expressing yourself
  917. 44:38in English or any human language succinctly
  918. 44:41correctly toward an end of getting your idea for an algorithm across.
  919. 44:45So for instance, here might be how we could
  920. 44:47formalize the code, the pseudocode for that same algorithm.
  921. 44:51Step one was pick up the phone book, as I did.
  922. 44:54Step two might be open to the middle of the phone book,
  923. 44:56as you proposed that we do first.
  924. 44:58Step three was probably to look down at the pages, I did.
  925. 45:01And step four gets a little more interesting
  926. 45:04because I had to quickly make a decision and ask myself a question.
  927. 45:07If person is on page, then I should probably just
  928. 45:11go ahead and call that person.
  929. 45:13But that probably wasn't the case at least for John Harvard,
  930. 45:15and I opened the M section.
  931. 45:17So there's this other question I should now
  932. 45:19ask else if the person is earlier in the book,
  933. 45:22then I should tear the problem in half as I did but go left, so
  934. 45:26to speak, and then not just open to the middle of the left half of the book,
  935. 45:30but really just go back to step three, repeat myself.
  936. 45:33Why?
  937. 45:33Because I can just repeat what I just did, but with a smaller problem
  938. 45:37having taken this big bite.
  939. 45:39But, if the person was later in the book,
  940. 45:41as might have happened with a different person than John Harvard,
  941. 45:44then I should open to the middle of the right half of the book,
  942. 45:47again go back to line three, but again, I'm
  943. 45:49not going to get sucked doing something forever like this
  944. 45:51because I keep shrinking the size of the problem.
  945. 45:54Lastly, the only possible scenario that's
  946. 45:56left, if John Harvard is not on the page and he's not to the left
  947. 45:59and he's not to the right, what should our conclusion be?
  948. 46:02AUDIENCE: He's not there.
  949. 46:03DAVID MALAN: He's not there.
  950. 46:04He's not listed.
  951. 46:05So we need to quit in some other form.
  952. 46:08Now as an aside, it's kind of deliberate that I buried that last question
  953. 46:11at the end because this is what happens all too often in programming,
  954. 46:16whether you're new at it or professional,
  955. 46:17just not considering all possible cases, corner cases if you will,
  956. 46:22that might not happen that often, but if you don't anticipate them
  957. 46:25in your own code, pseudocode or otherwise,
  958. 46:28this is when and why programs might crash
  959. 46:31or you might say stupid little spinning beach balls or hourglasses
  960. 46:34or your computer might reboot.
  961. 46:35Why?
  962. 46:35It's doing something sort of unpredictable
  963. 46:38if a human, maybe myself, didn't anticipate this.
  964. 46:42Like what does this program do if John Harvard is not in the phone book
  965. 46:45if I had omitted lines 12 and 13?
  966. 46:48I don't know.
  967. 46:48Maybe it would behave differently on a Mac or PC
  968. 46:50because it's sort of undefined behavior.
  969. 46:53These are the kinds of omissions that frankly you're invariably
  970. 46:56going to make, bugs you're going to introduce,
  971. 46:58mistakes you're going to make early on, and me, too, 25 years later.
  972. 47:02But you'll get better at thinking about those corner cases
  973. 47:06and handling anything that can possibly go wrong and as a result,
  974. 47:09your code will be all the better for it.
  975. 47:11Now the problem ultimately with learning how to program,
  976. 47:15especially if you've never had experience
  977. 47:16or even if you do but you learned one language only,
  978. 47:21is that they all look a little cryptic at first glance.
  979. 47:25But they do share certain commonalities.
  980. 47:27In fact, we'll use this pseudocode to define those first.
  981. 47:30Highlighted in yellow here are what henceforth
  982. 47:32we're going to start calling functions.
  983. 47:34Lots of different programming languages exist, but most of them
  984. 47:37have what we might call functions, which are actions
  985. 47:40or verbs that solve some smaller problem.
  986. 47:43That is to say, you might use a whole bunch of functions
  987. 47:46to solve a bigger problem because each function tends to do
  988. 47:50something very specific or precise.
  989. 47:52These then in English might be translated in code, actual computer
  990. 47:57code, to these things called functions.
  991. 47:59Highlighted in yellow now are what we might call conditionals.
  992. 48:02Conditionals are things that you do conditionally
  993. 48:05based on the answer to some question.
  994. 48:07You can think of them kind of like forks in the road.
  995. 48:09Do you go left or go right or some other direction
  996. 48:12based on the answer to some question?
  997. 48:14Well, what are those questions?
  998. 48:16Highlighted now in yellow or what we would call Boolean expressions, named
  999. 48:20after a mathematician last name Bool, that simply have yes no answers.
  1000. 48:25Or, if you prefer, true or false answers or, heck, if you prefer 1 or 0 answers.
  1001. 48:31We just need to distinguish one scenario from another.
  1002. 48:34The last thing manifests in this pseudocode
  1003. 48:37is what I might highlight now and call loops.
  1004. 48:39Some kind of cycle, some kind of directive that tells us to do something
  1005. 48:43again and again so that I don't need a 1,000-line program to search
  1006. 48:48a 1,000-page phone book, I can get away with a 13-line program but sort
  1007. 48:53of repeat myself inherently in order to solve some problem until I get to that
  1008. 48:58last step.
  1009. 48:59So this then is what we might call pseudocode
  1010. 49:01and indeed there are other characteristics
  1011. 49:05of programs that we'll touch on before long, things like arguments and return
  1012. 49:08values, variables, and more, but unfortunately in most languages,
  1013. 49:13including some we will very deliberately use in this class
  1014. 49:16and that everyone in the real world these days still uses,
  1015. 49:19its programs tend to look like this.
  1016. 49:22This for instance, is a distillation of that very first program
  1017. 49:24I wrote in 1996 in CS50 itself just to print something on the screen.
  1018. 49:29In fact, this version here just tries to print quote unquote, "Hello, world."
  1019. 49:34Which is, dare say, the most canonical first thing that most
  1020. 49:37any programmer ever gets a computer to say just because,
  1021. 49:41but look at this mess.
  1022. 49:42I mean, there's a hash symbol, these angled brackets, parentheses,
  1023. 49:45words like int, curly braces, quotes, parentheses, semicolons, and back
  1024. 49:49slashes.
  1025. 49:50I mean there's more overhead and more syntax and clutter
  1026. 49:54than there is an actual idea.
  1027. 49:55Now that's not to say that you won't be able to understand this before long,
  1028. 50:00because honestly there's not that many patterns, indeed programming languages
  1029. 50:03have typically a much smaller vocabulary than any actual human language,
  1030. 50:07but at first it might indeed look quite cryptic.
  1031. 50:10But you can perhaps infer I have no idea what these other lines do yet,
  1032. 50:14but "Hello, world." is presumably quote unquote what
  1033. 50:18will be printed on the screen.
  1034. 50:19But what we'll do today, after a short break,
  1035. 50:22and set the stage for next week is introduce
  1036. 50:24these exact same ideas in just a bit using Scratch,
  1037. 50:27something that you yourselves might have used
  1038. 50:29when you're quite younger but without the same vocabulary applied
  1039. 50:32to those ideas.
  1040. 50:34The upside of what we'll soon do using Scratch, this graphical programming
  1041. 50:38language from our friends down the road at MIT, it'll let us today
  1042. 50:41start to drag and drop things that look like puzzle pieces that interlock
  1043. 50:46together if it makes logical sense to do so,
  1044. 50:48but without the distraction of hashes, parentheses,
  1045. 50:51curly braces, angle brackets, semicolons, and things
  1046. 50:54that are quite beside the point.
  1047. 50:56But for now, let's go ahead and take a 10 minute break here
  1048. 50:58and when we resume, we will start programming.
  1049. 51:01So this on the screen is a language called
  1050. 51:04C something that will dive into next week and thankfully
  1051. 51:07this now on the screen is another language called Python
  1052. 51:10that we'll also take a look at in a few weeks before long along
  1053. 51:13with other languages along the way.
  1054. 51:15Today though, and for this first week, week zero, so to speak,
  1055. 51:19we use Scratch because again it will allow
  1056. 51:21us to explore some of those programming fundamentals
  1057. 51:23that will be in C and in Python and in JavaScript and other languages, too,
  1058. 51:28but in a way where we don't have to worry about the distractions of syntax.
  1059. 51:32So the world of Scratch looks like this.
  1060. 51:35It's a web-based or downloadable programming environment
  1061. 51:38that has this layout here by default. On the left here
  1062. 51:40we'll soon see is a palette of puzzle pieces, programming blocks that
  1063. 51:45represent all of those ideas we just discussed.
  1064. 51:47And by dragging and dropping these puzzle pieces
  1065. 51:50or blocks over this big area and connecting them together,
  1066. 51:54if it makes logical sense to do so, we'll
  1067. 51:56start programming in this environment.
  1068. 51:58The environment allows you to have multiple sprites, so to speak.
  1069. 52:01Multiple characters, things like a cat or anything
  1070. 52:04else, and those sprites exist in this rectangular world
  1071. 52:08up here that you can full screen to make bigger and this here by default
  1072. 52:11is Scratch, who can move up, down, left, right and do many more things, too.
  1073. 52:16Within its Scratch's world you can think of it
  1074. 52:19as perhaps a familiar coordinate system with Xs and Ys
  1075. 52:23which is helpful only when it comes time to position things on the screen.
  1076. 52:27Right now Scratch is at the default, 0,0, where x equals 0 and y equals 0.
  1077. 52:32If you were to move the cat way up to the top, x would stay zero,
  1078. 52:36y would be positive 180.
  1079. 52:37If you move the cat all the way to the bottom, x would stay zero,
  1080. 52:40but y would now be negative 180.
  1081. 52:42And if you went left, x would become negative 240 but y would stay 0,
  1082. 52:47or to the right x would be 240 and y would stay zero.
  1083. 52:51So those numbers generally don't so much matter because you can just
  1084. 52:55move relatively in this world up, down, left, right,
  1085. 52:58but when it comes time to precisely position
  1086. 53:01some of these sprites or other imagery, it'll
  1087. 53:03be helpful just to have that mental model off up, down, left, and right.
  1088. 53:07Well let's go ahead and make perhaps the simplest of programs here.
  1089. 53:10I'm going to switch over to the same programming environment
  1090. 53:13now for a tour of the left hand side.
  1091. 53:15So by default selected here are the category in blue motion,
  1092. 53:20which has a whole bunch of puzzle pieces or blocks that relate to motion.
  1093. 53:24And whereas Scratch as a graphical language
  1094. 53:27categorizes things by the type of things that these pieces do,
  1095. 53:30we'll see that throughout this whole palette
  1096. 53:32we'll have functions and variables and conditionals
  1097. 53:35and Boolean expressions and more each in a different color and shape.
  1098. 53:38So for instance, moving 10 steps or turning one way or the other
  1099. 53:42would be functions categorized here as things like motion.
  1100. 53:45Under looks in purple, you might have speech bubbles
  1101. 53:49that you can create by dragging and dropping
  1102. 53:51these that might say "hello" or whatever for some number of seconds.
  1103. 53:54Or you could switch costumes, change the cat to look like a dog or a bird
  1104. 53:58or anything else in between.
  1105. 54:00Sounds, too.
  1106. 54:01You can play sounds like "meow" or anything you might import or record,
  1107. 54:05yourself.
  1108. 54:06Then there's these things Scratch calls events and the most important of these
  1109. 54:09is the first, when green flag clicked.
  1110. 54:11Because if we look over to the right of Scratch's world here,
  1111. 54:14this rectangular region has this green flag and red stop
  1112. 54:17sign up above, one of which is for Play one of which is for Stop
  1113. 54:20and so that's going to allow us to start and stop our actual programs
  1114. 54:24when that green flag is initially clicked.
  1115. 54:27But you can listen for other types of events when the spacebar is pressed
  1116. 54:31or something else, when this sprite is clicked or something else.
  1117. 54:35Here you already see like a programmer's incarnation of things
  1118. 54:39you and I take for granted like every day now on our phones.
  1119. 54:42Any time you tap an icon or drag your finger or hit a button on the side.
  1120. 54:46These are what a programmer would call events,
  1121. 54:48things that happen and are often triggered by us
  1122. 54:51humans and things that a program be it in Scratch or Python
  1123. 54:55or C or anything else can listen for and respond to.
  1124. 54:59Indeed, that's why when you tap the phone icon on your phone,
  1125. 55:01the phone application starts up because someone
  1126. 55:04wrote software that's listening for a finger press on that particular icon.
  1127. 55:08So Scratch has these same things, too.
  1128. 55:10Under Control in orange, you can see that we
  1129. 55:13can wait for one second or repeat something
  1130. 55:15some number of times, 10 by default, but we
  1131. 55:17can change anything in these white circles to anything else.
  1132. 55:20There's another puzzle piece here forever,
  1133. 55:22which implies some kind of loop where we can do something again and again.
  1134. 55:25Even though it seems a little tight, there's
  1135. 55:27not much room to fit something there, Scratch
  1136. 55:29is going to have these things grow and shrink
  1137. 55:31however we want to fill similarly shaped pieces.
  1138. 55:33Here are those conditionals.
  1139. 55:35If something is true or false, then do this next thing.
  1140. 55:40And that's how we can put in this little trapezoid-like shape.
  1141. 55:42Some form of Boolean expression, a question with a yes/no, true/false,
  1142. 55:46or one/zero answer and decide whether to do something or not.
  1143. 55:50You can combine these things, too.
  1144. 55:52If something is true, do this, else do this other thing.
  1145. 55:55And you can even tuck one inside of the other
  1146. 55:57if you want to ask three or four or more questions.
  1147. 56:01Sensing, too, is going to be a thing.
  1148. 56:03You can ask questions aka Boolean expressions like is the sprite touching
  1149. 56:07the mouse pointer, the arrow on the screen?
  1150. 56:10So that you can start to interact with these programs.
  1151. 56:12What is the distance between a sprite and a mouse pointer?
  1152. 56:15You can do simple calculations just to figure out maybe
  1153. 56:17if the enemy is getting close to the cat.
  1154. 56:20Under Operator some lower level stuff like math, but also the ability
  1155. 56:23to pick random numbers, which for a game is great
  1156. 56:25because then you can kind of vary the difficulty
  1157. 56:27or what's happening in a game without the same game playing
  1158. 56:30the same way every time.
  1159. 56:31And you can combine ideas.
  1160. 56:33Something and something must be true in order to make that kind of decision
  1161. 56:37before.
  1162. 56:38Or we can even join two words together.
  1163. 56:40Says apple and banana by default, but you can type in or drag and drop
  1164. 56:43whatever you want there to combine multiple words into full,
  1165. 56:46larger sentences.
  1166. 56:48Then lastly down here, there's in orange things called variables.
  1167. 56:52In math we've obviously got x and y and whatnot.
  1168. 56:54In programming we'll have the same ability
  1169. 56:56to store in these named symbols, x or y, values that we care about.
  1170. 57:03Numbers or letters or words or colors or anything, ultimately.
  1171. 57:06But in programming you'll see that it's much more conventional not to just
  1172. 57:09use simple letters like x and y and z, but to actually
  1173. 57:13give variables full singular or plural words to describe what they are.
  1174. 57:20Then lastly, if this isn't enough color blocks for you,
  1175. 57:24you can create your own blocks.
  1176. 57:25Indeed, this is going to be a programming principle we'll apply today
  1177. 57:29and with the first problem set whereby once you start to assemble these puzzle
  1178. 57:32pieces and you realize, oh, would have been nice if those several pieces could
  1179. 57:37have just been replaced by one had MIT thought to give me that
  1180. 57:40one puzzle piece, you yourself can make your own blocks
  1181. 57:44by connecting these all together, giving them a name, and boom,
  1182. 57:47a new puzzle piece will exist.
  1183. 57:49So let's do the simplest, most canonical programs
  1184. 57:51here, starting up with control, and I'm going
  1185. 57:53to click and drag and drop this thing here when green flag clicked.
  1186. 57:57Then I'm going to grab one more, for instance under Looks,
  1187. 58:01and under Looks I'm going to go ahead and just say
  1188. 58:03something like initially not just Hello but the more canonical
  1189. 58:07Hello comma world.
  1190. 58:09Now you might guess that in this programming environment,
  1191. 58:12I can go over here now and click the green flag and voila,
  1192. 58:15Hello comma world.
  1193. 58:17So that's my first program and obviously much
  1194. 58:19more user friendly than typing out the much more cryptic text that we
  1195. 58:21saw on the screen that you, too, will type out next week.
  1196. 58:25But for now, we'll just focus on these ideas, in this case, a function.
  1197. 58:28So what it is that just happened?
  1198. 58:29This purple block here is Say, that's the function,
  1199. 58:32and it seems to take some form of input in the white oval, specifically Hello
  1200. 58:37comma world.
  1201. 58:38Well this actually fits the paradigm that we looked
  1202. 58:40at earlier of just inputs and outputs.
  1203. 58:42So if I may, if you consider what this puzzle piece is doing,
  1204. 58:45it actually fits this model.
  1205. 58:47The input in this case is going to be Hello comma world in white.
  1206. 58:51The algorithm is going to be implemented as a function by MIT called Say
  1207. 58:55and the output of that is going to be some kind of side effect,
  1208. 58:57like the cat and the speech bubble are saying Hello, world.
  1209. 59:01So already even that simple drag and drop
  1210. 59:03mimics exactly this relatively simple mental model.
  1211. 59:07So let's take things further.
  1212. 59:08Let's go ahead now and make the program a little more interactive so
  1213. 59:11that it says something like Hello, David, or Hello, Carter,
  1214. 59:14or Hello to you specifically.
  1215. 59:16And for this, I'm going to go under Sensing.
  1216. 59:18And you might have to poke around to find these things the first time
  1217. 59:21around, but I've done this a few times so I kind of know where things are
  1218. 59:24and what color.
  1219. 59:25There's this function here.
  1220. 59:26Ask what's your name, but that's in white,
  1221. 59:28so we can change the question to anything
  1222. 59:30we want, and it's going to wait for the human to type in their answer.
  1223. 59:34This function called Ask is a little different
  1224. 59:37from the Say block, which just had this side effect of printing a speech
  1225. 59:41bubble to the screen.
  1226. 59:42The ask function is even more powerful in that after it asks the human to type
  1227. 59:47something in.
  1228. 59:47This function is going to hand you back what
  1229. 59:50they typed in in the form of what's called a return value, which
  1230. 59:55is stored ultimately and by default this thing called Answer.
  1231. 59:57This little blue oval here called Answer is again
  1232. 1:00:00one of these variables that in math would
  1233. 1:00:02be called just x or y but in programming we're saying what it does.
  1234. 1:00:05So I'm going to go ahead and do this.
  1235. 1:00:07Let me go ahead and drag and drop this block
  1236. 1:00:09and I want to ask the question before saying anything,
  1237. 1:00:11but you'll notice that Scratch is smart and it's
  1238. 1:00:13going to realize I want to insert something in between
  1239. 1:00:15and it's just going to move things up and down.
  1240. 1:00:17I'm going to let go and ask the default question, what's your name?
  1241. 1:00:20And now if I want to go ahead and say hello, David or Carter,
  1242. 1:00:23let's just do Hello comma, because I obviously
  1243. 1:00:26don't know when I'm writing the program who's going to use it.
  1244. 1:00:28So let me now grab another looks block up here, say something again, and now
  1245. 1:00:35let me go back to Sensing and now grab the return value, represented
  1246. 1:00:39by this other puzzle piece, and let me just drag and drop it here.
  1247. 1:00:42Notice it's the same shape, even if it's not quite the same size.
  1248. 1:00:45Things will grow or shrink as needed.
  1249. 1:00:47All right, so let's now zoom out.
  1250. 1:00:49Let me go and stop the old version because I don't want to say Hello,
  1251. 1:00:52world anymore.
  1252. 1:00:53Let me hit the green flag and what's my name?
  1253. 1:00:55All right, David.
  1254. 1:00:56Enter.
  1255. 1:00:58Huh.
  1256. 1:00:59All right, maybe I just wasn't paying close enough attention.
  1257. 1:01:01Let me try it again.
  1258. 1:01:03Green flag, D-A-V-I-D, Enter.
  1259. 1:01:06This seems like a bug.
  1260. 1:01:09What's the bug or mistake might you think?
  1261. 1:01:13Yeah?
  1262. 1:01:14AUDIENCE: Do you need to somehow add them together in the same text box?
  1263. 1:01:17DAVID MALAN: Yeah, we kind of want to combine them in the same text box.
  1264. 1:01:20And it's technically a bug because this just looks kind of stupid.
  1265. 1:01:23It's just saying David after I asked for my name.
  1266. 1:01:26I'd like it to say maybe Hello then David,
  1267. 1:01:29but it's just blowing past the Hello and printing David.
  1268. 1:01:32But let's put our finger on why this is happening.
  1269. 1:01:34You're right for the solution, but what's the actual fundamental problem?
  1270. 1:01:38In back.
  1271. 1:01:39AUDIENCE: So it says hello, but it gets to that last step
  1272. 1:01:42so quickly you can't see it.
  1273. 1:01:43DAVID MALAN: Perfect.
  1274. 1:01:44I mean, computers are really darn fast these days.
  1275. 1:01:47It is saying Hello, all of us are just too slow in this room
  1276. 1:01:50to even see it because it's then saying David on the screen so fast as well.
  1277. 1:01:54So there's a couple of solutions here, and yours is spot on,
  1278. 1:01:57but just to poke around, you'll see the first example
  1279. 1:01:59of how many ways in programming be it Scratch or C or Python or anything
  1280. 1:02:03else, that there are going to be to solve problems?
  1281. 1:02:05We'll teach you over the course of these weeks,
  1282. 1:02:07sometimes some ways are better relatively than others,
  1283. 1:02:10but rarely is there a best way necessarily,
  1284. 1:02:13because again reasonable people will disagree.
  1285. 1:02:15And what we'll try to teach you over the coming weeks
  1286. 1:02:17is how to kind of think through those nuances.
  1287. 1:02:20And it's not going to be obvious at first glance,
  1288. 1:02:22but the more programs you write, the more feedback
  1289. 1:02:24you get, the more bugs that you introduce,
  1290. 1:02:26the more you'll get your footing with exactly this kind of problem solving.
  1291. 1:02:30So let me try this in a couple of ways.
  1292. 1:02:33Up here would be one solution to the problem.
  1293. 1:02:35MIT anticipated this kind of issue, especially with first-time programmers,
  1294. 1:02:40and I could just use a puzzle piece that says
  1295. 1:02:42say the following for two seconds or one second
  1296. 1:02:44or whatever, then do the same with the next word
  1297. 1:02:47and it might be kind of a bit of a pause,
  1298. 1:02:50Hello, one second, two seconds, David, one second, two seconds, but at least
  1299. 1:02:54it would look a little more grammatically correct.
  1300. 1:02:56But I can do it a little more elegantly, as you've proposed.
  1301. 1:02:59Let me go ahead and throw away one of these blocks,
  1302. 1:03:01and you can just drag and let go and it'll delete itself.
  1303. 1:03:04Let me go down to Operators because this Join block here is the right shape.
  1304. 1:03:10So even if you're not sure what goes where, just focus on the shapes first.
  1305. 1:03:13Let me drag this over here.
  1306. 1:03:15It grew to fill that.
  1307. 1:03:17Let me go ahead and say hello comma space.
  1308. 1:03:20Now it could just say by default Hello, banana,
  1309. 1:03:22but let me go back to Sensing, Drag answer,
  1310. 1:03:27and that's going to drag and drop there.
  1311. 1:03:29So now notice we're sort of stacking or nesting one block on another
  1312. 1:03:34so that the output of one becomes the input to another, but that's OK here.
  1313. 1:03:38Let me go ahead and zoom out, hit Stop, and hit Play.
  1314. 1:03:42All right, what's your name?
  1315. 1:03:43D-A-V-I-D, Enter, and voila.
  1316. 1:03:45Now it's presumably as we first intended.
  1317. 1:03:48[APPLAUSE]
  1318. 1:03:49(LAUGHING) Oh, thank you.
  1319. 1:03:55Thank you.
  1320. 1:03:56No minus 2 this time.
  1321. 1:03:57So consider that even with this additional example,
  1322. 1:04:02it still fits the same mental model, but in a little more interesting way.
  1323. 1:04:05Here's that new function Ask something and wait.
  1324. 1:04:08And notice that in this case too there's an input, otherwise known
  1325. 1:04:12henceforth as an argument or a parameter, programming
  1326. 1:04:15speak for just an input in the context of a function.
  1327. 1:04:18If we use our drawing as before to represent this thing here,
  1328. 1:04:21we'll see that the input now is going to be quote unquote "What's your name?"
  1329. 1:04:26The algorithm is going to be implemented by way of this new puzzle piece,
  1330. 1:04:30the function called Ask, and the output of that thing this time
  1331. 1:04:33is not going to be the cat saying anything yet,
  1332. 1:04:36but rather it's going to be the actual answer.
  1333. 1:04:39So instead of the visual side effect of the speech bubble appearing,
  1334. 1:04:43now nothing visible is happening yet.
  1335. 1:04:45Thanks to this function it's sort of handing me back like a scrap of paper
  1336. 1:04:49with whatever I typed in written on it so I can reuse D-A-V-I-D one or more
  1337. 1:04:55times even like I did.
  1338. 1:04:57Now what did I then do with that value?
  1339. 1:05:00Well consider that with the subsequent function
  1340. 1:05:04we had this Say block, too, combined with a join.
  1341. 1:05:08So we have this variable called Answer, we're joining it
  1342. 1:05:11with that first argument, Hello.
  1343. 1:05:14So already we see that some functions like Join
  1344. 1:05:16can take not one but two arguments, or inputs, and that's fine.
  1345. 1:05:20The output of Join is presumably going to be Hello, David or Hello, Carter
  1346. 1:05:24or whatever the human typed in.
  1347. 1:05:27That output notice is essentially becoming the input to another function,
  1348. 1:05:31Say, just because we've kind of stacked things
  1349. 1:05:33or nested them on top of one another.
  1350. 1:05:35But methodically, it's really the same idea.
  1351. 1:05:40The input now are two things, Hello comma and the return value
  1352. 1:05:44from the previous Ask function.
  1353. 1:05:47The function now is going to be Join, the output is going to be Hello, David.
  1354. 1:05:51But that Hello, David output is now going
  1355. 1:05:53to become the input to another function, namely that first block called Say,
  1356. 1:05:57and that's then going to have the side effect of printing out Hello, David
  1357. 1:06:01on the screen.
  1358. 1:06:02So again as sort of sophisticated as ours as yours as others programs
  1359. 1:06:06are going to get, they really do fit this very simple mental model
  1360. 1:06:09of inputs and outputs and you just have to learn to recognize the vocabulary
  1361. 1:06:12and to know what kinds of puzzle pieces or concepts ultimately to apply.
  1362. 1:06:17But you can ultimately really kind of spice these things up.
  1363. 1:06:19Let me go back to my program here that just is
  1364. 1:06:21using the speech bubble at the moment.
  1365. 1:06:22Scratch's inside has some pretty fancy interactive features, too.
  1366. 1:06:26I click the Extensions button in the bottom left corner.
  1367. 1:06:28And let me go ahead and choose the Text to Speech extension.
  1368. 1:06:33This is using a Cloud service, so if you have an internet connection
  1369. 1:06:36it can actually talk to the Cloud or a third party service,
  1370. 1:06:39and this one is going to give me a few new green puzzle pieces, namely
  1371. 1:06:42the ability to speak something from my speakers
  1372. 1:06:45instead of just saying it textually.
  1373. 1:06:47So let me go ahead and drag this.
  1374. 1:06:48Now notice I don't have to interlock them if I'm just kind of playing around
  1375. 1:06:51and I want to move some things around.
  1376. 1:06:52I just want to use this as like a canvas temporarily.
  1377. 1:06:55Let me go ahead and steal the Join from here,
  1378. 1:06:58put it there, let me throw away the Say block by just moving it
  1379. 1:07:01left and letting go, and now let me join this in
  1380. 1:07:04so I've now changed my program to be a little more interesting.
  1381. 1:07:08So now let me stop the old version.
  1382. 1:07:10Let me start the new.
  1383. 1:07:11What's your name?
  1384. 1:07:12Type in David.
  1385. 1:07:13And voila:
  1386. 1:07:14PROGRAM: Hello, banana.
  1387. 1:07:18DAVID MALAN: (LAUGHING) OK, minus 2 for real.
  1388. 1:07:20All right, so what I accidentally threw away there, intentionally
  1389. 1:07:27for instructional purposes, was the actual answer
  1390. 1:07:30that came back from the ask block.
  1391. 1:07:32That's embarrassing.
  1392. 1:07:33So now if I play this again, let's click the green icon.
  1393. 1:07:37What's your name?
  1394. 1:07:38David.
  1395. 1:07:38And now:
  1396. 1:07:40PROGRAM: Hello, David.
  1397. 1:07:41DAVID MALAN: There we go.
  1398. 1:07:42Hello, David.
  1399. 1:07:43All right, thank you.
  1400. 1:07:45[APPLAUSE]
  1401. 1:07:50OK, so we have these functions then in place, but what more can we do?
  1402. 1:07:54Well what about those conditionals and loops and other constructs?
  1403. 1:07:57How can we bring these programs to life so it's not just
  1404. 1:07:59clicking a button and voila, something's happening?
  1405. 1:08:01Let's go ahead and make this now even more interactive.
  1406. 1:08:04Let me go ahead and throw away most of these pieces
  1407. 1:08:06and let me just spice things up with some more audio under Sound.
  1408. 1:08:09I'm going to go to Play Sound Meow until done.
  1409. 1:08:12Here we go, green flag.
  1410. 1:08:13[MEOW]
  1411. 1:08:15OK, it's a little loud, but it did exactly do what it said.
  1412. 1:08:18Let's hear it again.
  1413. 1:08:19[QUIETER MEOW]
  1414. 1:08:21OK.
  1415. 1:08:21It's kind of an underwhelming program eventually
  1416. 1:08:23since you'd like to think that the cat would just meow on its own, but.
  1417. 1:08:26[MEOW]
  1418. 1:08:26I have to keep hitting the button.
  1419. 1:08:28Well this seems like an opportunity for doing something again and again.
  1420. 1:08:31So all right, well if I wanted to meow, meow, meow,
  1421. 1:08:33let me just grab a few of these, or you can even right click or Control click
  1422. 1:08:37and you can Copy Paste even in code here.
  1423. 1:08:39Let me play this now.
  1424. 1:08:41[THREE MEOWS]
  1425. 1:08:43All right, so now like it's not really emoting
  1426. 1:08:45happiness in quite the same way.
  1427. 1:08:46It might be hungry or upset.
  1428. 1:08:47So let's slow it down.
  1429. 1:08:49Let me go to Control, wait one second in between,
  1430. 1:08:52which might be a little less worrisome.
  1431. 1:08:55Here we go, Play.
  1432. 1:08:56[THREE SLOWER MEOWS]
  1433. 1:09:01OK, so if my goal was to make the cat meow three times,
  1434. 1:09:06I dare say this code or algorithm is correct.
  1435. 1:09:10But let's now critique its design.
  1436. 1:09:12Is this well-designed?
  1437. 1:09:14And if not, why not?
  1438. 1:09:17What are your thoughts here?
  1439. 1:09:19Yeah?
  1440. 1:09:21AUDIENCE: You could use the forever or a repeat to make it more--
  1441. 1:09:27DAVID MALAN: Yeah, so yeah, agreed.
  1442. 1:09:28I could use forever or repeat, but let me push a little harder.
  1443. 1:09:31But why?
  1444. 1:09:31Like this works, I'm kind of done with the assignments, what's bad about it?
  1445. 1:09:36AUDIENCE: There's too much repetition.
  1446. 1:09:37DAVID MALAN: Yeah, there's too much repetition, right?
  1447. 1:09:40If I wanted to change the sound that the cat is making
  1448. 1:09:42to a different variant of meow or have it bark instead like a dog,
  1449. 1:09:46I could change it from the dropdown here apparently,
  1450. 1:09:48but then I'd have to change it here and then I'd have to change it here,
  1451. 1:09:51and God, if this were even longer that just gets tedious quickly
  1452. 1:09:54and you're probably increasing the probability
  1453. 1:09:56that you're going to screw up and you're going
  1454. 1:09:57to miss one of the dropdowns or something stupid and introduce a bug.
  1455. 1:10:00Or, if you wanted to change the number of seconds you're waiting,
  1456. 1:10:02you've got to change it in two, maybe even more places.
  1457. 1:10:05Again, you're just creating risk for yourself
  1458. 1:10:07and potential bugs in the program.
  1459. 1:10:09So I do like the repeat or the forever idea so that I don't repeat myself.
  1460. 1:10:13And indeed, what I alluded to being possible,
  1461. 1:10:15copy pasting earlier, doesn't mean it's a good thing.
  1462. 1:10:18And in code, generally speaking, when you
  1463. 1:10:20start to copy and paste puzzle pieces or text next week,
  1464. 1:10:23you're probably not doing something quite well.
  1465. 1:10:26So let me go ahead and throw away most of these to get rid of the duplication,
  1466. 1:10:30keeping just two of the blocks that I care about.
  1467. 1:10:33Let me grab the Repeat block for now, let me move this inside of the Repeat
  1468. 1:10:37block, it's going to grow to fit it, let me reconnect all this
  1469. 1:10:40and change the 10 just to a 3, and now, Play.
  1470. 1:10:44[THREE SLOW MEOWS]
  1471. 1:10:49So, better.
  1472. 1:10:50It's the same thing.
  1473. 1:10:51It's still correct, but now I've set the stage
  1474. 1:10:53to let the cat meow, for instance, four times by changing one thing,
  1475. 1:10:5740 times by changing one thing, or it could just use the Forever block
  1476. 1:11:00and just walk away and it will meow forever instead.
  1477. 1:11:03If that's your goal, that would be better.
  1478. 1:11:05A better design but still correct.
  1479. 1:11:07But you know what?
  1480. 1:11:08Now that I have a program that's designed
  1481. 1:11:10to have a cat meow, wow like why?
  1482. 1:11:13I mean, MIT invented Scratch, Scratch as a cat,
  1483. 1:11:16why is there no puzzle piece called Meow?
  1484. 1:11:18This feels like a missed opportunity.
  1485. 1:11:20Now to be fair, they gave us all the building blocks
  1486. 1:11:22with which we could implement that idea, but a principle of programming
  1487. 1:11:26and really computer science is to leverage what we're
  1488. 1:11:28going to now start calling Abstraction.
  1489. 1:11:30We have step-by-step instructions here, the Repeat, the Play,
  1490. 1:11:34and the Wait that collectively implements this idea
  1491. 1:11:37that we humans would call meowing.
  1492. 1:11:38Wouldn't it be nice to abstract away those several puzzle
  1493. 1:11:41pieces into just one that literally just says what it does, meow?
  1494. 1:11:45Well here's where we can make our own blocks.
  1495. 1:11:48Let me go over here to Scratch under the pink block category
  1496. 1:11:52here and let me click Make a Block.
  1497. 1:11:55Here I see a slightly different interface
  1498. 1:11:57where I can choose a name for it and I'm going to call it Meow.
  1499. 1:12:00I'm going to keep it simple.
  1500. 1:12:01That's it.
  1501. 1:12:01No inputs to meow yet.
  1502. 1:12:03I'm just going to click OK.
  1503. 1:12:05Now I'm just going to clean this up a bit here.
  1504. 1:12:08Let me drag and drop Play Sound and Wait over here.
  1505. 1:12:12And you know what?
  1506. 1:12:13I'm just going to drag this way down here, way down
  1507. 1:12:15here because now that I'm done implementing Meow,
  1508. 1:12:18I'm going to literally abstract it away, sort of out of sight,
  1509. 1:12:21out of mind, because now notice at top left there is a new pink puzzle
  1510. 1:12:25piece called Meow.
  1511. 1:12:26So at this point, I'd argue it doesn't really matter how Meow is implemented.
  1512. 1:12:31Frankly, I don't know how Ask or Say was implemented by MIT.
  1513. 1:12:35They abstracted those things away for us.
  1514. 1:12:37Now I have a brand new puzzle piece that just says what it is.
  1515. 1:12:40And this is now still correct, but arguably better design.
  1516. 1:12:44Why?
  1517. 1:12:45Because it's just more readable to me, to you,
  1518. 1:12:47it's more maintainable when you look at your code
  1519. 1:12:49a year from now for the first time because you're sort of finally looking
  1520. 1:12:52back at the very first program you wrote.
  1521. 1:12:53It says what it does.
  1522. 1:12:55The function itself has semantics, which conveys what's going on.
  1523. 1:12:59If you really care about how Meow is implemented,
  1524. 1:13:01you could scroll down and start to tinker with the underlying
  1525. 1:13:04implementation details, but otherwise you don't need to care anymore.
  1526. 1:13:09Now I feel like there's an even additional opportunity
  1527. 1:13:13here for abstraction and to factor out some of this functionality.
  1528. 1:13:17It's kind of lame that I have this Repeat block that
  1529. 1:13:21lets me call the Meow function, so to speak, use the Meow function
  1530. 1:13:24three times.
  1531. 1:13:25Wouldn't it be nice if I could just call them Meow function,
  1532. 1:13:28aka use the Meow function, and pass it in input that tells the puzzle
  1533. 1:13:32piece how many times I want it to meow?
  1534. 1:13:35Well let me go ahead and zoom out and scroll down.
  1535. 1:13:37Let me right click or Control click on the pink piece here and choose Edit,
  1536. 1:13:41or I could just start from scratch, no pun intended, with a new one.
  1537. 1:13:44Now here, rather than just give this thing a name Meow, let me go ahead
  1538. 1:13:48and add an input here.
  1539. 1:13:50I'm going to go ahead and type in, for instance, n,
  1540. 1:13:53for number of times to meow, and just to make
  1541. 1:13:56this even more user friendly and self descriptive,
  1542. 1:13:58I'm going to add a label, which has no functional impact,
  1543. 1:14:00it's just an aesthetic, and I'm just going
  1544. 1:14:03to say Times, just to make it read more like English
  1545. 1:14:05in this case that tells me what the puzzle piece does.
  1546. 1:14:08Now I'm going to click OK.
  1547. 1:14:09And now I need to refine this a little bit.
  1548. 1:14:12Let me go ahead and grab under Control a repeat block,
  1549. 1:14:18let me move the Play, Sound, and Wait, into the repeat block.
  1550. 1:14:22I don't want 10 and I also don't want 3 here.
  1551. 1:14:24What I want now is this n that is my actual variable that Scratch
  1552. 1:14:29is creating for me that represents whatever input the human programmer
  1553. 1:14:33provides.
  1554. 1:14:34Notice that snaps right in place.
  1555. 1:14:35Let me connect this and now voila, I have an even fancier version of Meow
  1556. 1:14:39that is parameterized.
  1557. 1:14:40It takes input that affects its behavior accordingly.
  1558. 1:14:44Now I'm going to scroll back up, because out of sight, out of mind,
  1559. 1:14:47I just care that Meow exists.
  1560. 1:14:49Now I can tighten up my code, so to speak, use even fewer lines
  1561. 1:14:52to do the same thing by throwing away the Repeat block,
  1562. 1:14:55reconnecting this new puzzle piece here that takes an input like 3 and voila,
  1563. 1:15:00now we're really programming, right?
  1564. 1:15:02We've not made any forward progress functionally.
  1565. 1:15:04The thing just mouse three times.
  1566. 1:15:06But it's a better design.
  1567. 1:15:09As you program more and more, these are the kinds
  1568. 1:15:11of instincts still start to acquire so that one,
  1569. 1:15:13you can start to take a big assignment, a big problem set, something
  1570. 1:15:16for homework even, that feels kind of overwhelming at first, like, oh my God
  1571. 1:15:20where do I even begin?
  1572. 1:15:21But if you start to identify what are the subproblems of a bigger problem?
  1573. 1:15:25Then you can start making progress.
  1574. 1:15:27I do this to this day where if I have to tackle some programming-related project
  1575. 1:15:32it's so easy to drag my feet and ugh, it's going to take forever to start,
  1576. 1:15:36until I just start writing down like a to do list
  1577. 1:15:38and I start to modularize the program and say, all right, well
  1578. 1:15:41what do I want this thing to do?
  1579. 1:15:42Meowing.
  1580. 1:15:43What's that mean?
  1581. 1:15:43I've got to have it say something on the screen.
  1582. 1:15:45All right, I need to have it say something on the screen
  1583. 1:15:48some number of times.
  1584. 1:15:49Like literally a mental or written checklist, or pseudocode code,
  1585. 1:15:52if you will, in English on a piece of paper or text file,
  1586. 1:15:55and then you can decide, OK, the first thing I
  1587. 1:15:57need to do for homework to solve this real world problem,
  1588. 1:16:00I just need a Meow function.
  1589. 1:16:02I need to use a bunch of other code, too,
  1590. 1:16:04but I need to create a Meow function and boom,
  1591. 1:16:06now you have a piece of the problem solved not unlike we did with the phone
  1592. 1:16:10book there, but in this case, we'll have presumably other problems to solve.
  1593. 1:16:14All right, so what more can we do?
  1594. 1:16:16Let's add a few more pieces to the puzzle here.
  1595. 1:16:18Let's actually interact with the cat now.
  1596. 1:16:20Let me go ahead and now when the green flag is clicked, let me go ahead
  1597. 1:16:24and ask a question using an event here.
  1598. 1:16:26Let me go ahead and say, let's see, I want
  1599. 1:16:31to do something like implement the notion of petting the cat.
  1600. 1:16:34So if the cursor is touching the cat like here, something like this,
  1601. 1:16:39it'd be cute if the cat meows like you're petting a cat.
  1602. 1:16:42So I'm going to ask the question, when the green flag is clicked,
  1603. 1:16:45if let's see I think I need Sensing.
  1604. 1:16:48So if touching mouse pointer, this is way too big
  1605. 1:16:50but again the shape is fine, so there goes.
  1606. 1:16:52Grew to fill.
  1607. 1:16:53And then if it's touching the mouse pointer,
  1608. 1:16:56that is if the cat to whom this script or this program,
  1609. 1:16:59any time I attach puzzle pieces MIT calls them a script
  1610. 1:17:03or like a program, if you will, let me go ahead then and choose a sound
  1611. 1:17:07and say play sound meow until done.
  1612. 1:17:10All right, so here it is to be clear.
  1613. 1:17:11When the green flag is clicked, ask the question,
  1614. 1:17:13if the cat is touching the mouse pointer then place sound meow.
  1615. 1:17:18Here we go.
  1616. 1:17:18Play.
  1617. 1:17:20[SILENCE]
  1618. 1:17:23All right, let's try again.
  1619. 1:17:25Play.
  1620. 1:17:26[SILENCE]
  1621. 1:17:28Huh.
  1622. 1:17:29I'm worried it's not Scratch's fault. Feels like mine.
  1623. 1:17:34What's the bug here?
  1624. 1:17:37Why doesn't this work?
  1625. 1:17:39Yeah, in back, who just turned.
  1626. 1:17:42AUDIENCE: [INAUDIBLE]
  1627. 1:17:47DAVID MALAN: Yeah, the problem is the moment I click that green flag,
  1628. 1:17:50Scratch asks the question, is the cat touching the mouse pointer?
  1629. 1:17:54And obviously it's not because the cursor was like up there a moment ago
  1630. 1:17:57and it's not down there.
  1631. 1:17:58It's fine if I move the cursor down there, but too late.
  1632. 1:18:01The program already asked the question.
  1633. 1:18:03The answer was no or false or zero, however you want to think about it,
  1634. 1:18:06so no sound was played.
  1635. 1:18:08So what might be the solution here be?
  1636. 1:18:10I could move my cursor quickly, but that feels
  1637. 1:18:12like never going to work out right.
  1638. 1:18:14Other solutions here?
  1639. 1:18:16Yeah, in way back?
  1640. 1:18:18Could you use the forever loop?
  1641. 1:18:20The Forever loop.
  1642. 1:18:21So I could indeed use this Forever loop because if I want my program
  1643. 1:18:24to just constantly listen to me, well let's literally do something forever,
  1644. 1:18:28or at least forever as long as the program is
  1645. 1:18:30running until I explicitly hit Stop.
  1646. 1:18:32So let me grab that.
  1647. 1:18:33Let me go to Control, let me grab the Forever block,
  1648. 1:18:36let me move the If inside of this Forever block, reconnect this,
  1649. 1:18:40go back up here, click the green flag, and now nothing's happened yet,
  1650. 1:18:43but let me try moving my cursor now.
  1651. 1:18:45[MEOW]
  1652. 1:18:47Oh.
  1653. 1:18:47So now.
  1654. 1:18:48[MEOW]
  1655. 1:18:49That's kind of cute.
  1656. 1:18:50So now the cat is actually responding and it's
  1657. 1:18:52going to keep doing this again and again.
  1658. 1:18:54So now we have this idea of taking these different ideas, these different puzzle
  1659. 1:18:58pieces, assembling them into something more complicated.
  1660. 1:19:01I could definitely put a name to this.
  1661. 1:19:03I could create a custom block, but for now
  1662. 1:19:05let's just consider what kind of more interactivity we can do.
  1663. 1:19:08Let me go ahead and do this.
  1664. 1:19:09By again grabbing a, when green flag clicked,
  1665. 1:19:12let me go ahead and click the video sensing,
  1666. 1:19:16and I'm going to rotate the laptop because otherwise we're
  1667. 1:19:18going to get a little inception thing here where the camera is picking up
  1668. 1:19:21the camera is up there.
  1669. 1:19:22So I'm going to go reveal to you what's inside the lectern
  1670. 1:19:25here while we rotate this.
  1671. 1:19:29Now that we have a non video backdrop, I'm going to say this.
  1672. 1:19:34Instead of the green flag clicked, actually, I'm
  1673. 1:19:37going to say when the video motion is greater than some arbitrary
  1674. 1:19:40measurement of motion, I'm going to go ahead and play sound meow until done.
  1675. 1:19:47And then I'm going to get out of the way.
  1676. 1:19:48So here's the cat.
  1677. 1:19:50We'll put them on top of there.
  1678. 1:19:53[MEOW]
  1679. 1:19:54OK.
  1680. 1:19:55All right, and here we go.
  1681. 1:19:57[MEOW]
  1682. 1:20:00So my hand is moving faster than 50 something or other,
  1683. 1:20:03whatever the unit of measure is.
  1684. 1:20:05[MEOW]
  1685. 1:20:06AUDIENCE: Aw.
  1686. 1:20:06DAVID MALAN: (LAUGHING) Thank you.
  1687. 1:20:08So now we have an even more interactive version.
  1688. 1:20:10[MEOW]
  1689. 1:20:12But I think if I sort of slowly.
  1690. 1:20:15[LAUGHING]
  1691. 1:20:17(LAUGHING) Right?
  1692. 1:20:18It's completely creepy, but I'm not like exceeding the threshold--
  1693. 1:20:23[MEOW]
  1694. 1:20:24Until finally my hand moves as fast as that.
  1695. 1:20:27And so here actually is an opportunity to show you
  1696. 1:20:29something a former student did.
  1697. 1:20:31Let me go ahead here and--
  1698. 1:20:32[MEOW TWICE]
  1699. 1:20:33OK, got to stop this.
  1700. 1:20:35Let me go ahead and zoom out of this in just a moment.
  1701. 1:20:38[MEOW]
  1702. 1:20:38If someone would be--
  1703. 1:20:39[LAUGHING]
  1704. 1:20:40(LAUGHING) If someone would be comfortable
  1705. 1:20:42coming up not only masked but also on camera on the internet
  1706. 1:20:44I thought we'd play one of your former classmate's projects here up on stage.
  1707. 1:20:48Would anyone like to volunteer here and be up on stage?
  1708. 1:20:51Who's that?
  1709. 1:20:51Yeah.
  1710. 1:20:52Come on down.
  1711. 1:20:52What's your name?
  1712. 1:20:53AUDIENCE: Sahar.
  1713. 1:20:54DAVID MALAN: Sahar.
  1714. 1:20:55All right, come on down.
  1715. 1:20:57Let me get it set up for you here.
  1716. 1:20:58[MEOW]
  1717. 1:20:59[APPLAUSE]
  1718. 1:21:05[MEOW]
  1719. 1:21:10All right, let me go ahead and full screen this here.
  1720. 1:21:13So this is whack-a-mole by one of your firmer predecessors.
  1721. 1:21:17It's going to use the camera focusing on your head, which will have
  1722. 1:21:20to position inside of this rectangle.
  1723. 1:21:22Have you ever played the whack-a-mole game at an arcade?
  1724. 1:21:24AUDIENCE: Yeah.
  1725. 1:21:25DAVID MALAN: OK.
  1726. 1:21:25So for those who haven't, these little moles pop up
  1727. 1:21:27and with a very fuzzy hammer you sort of hit down.
  1728. 1:21:29You though, if you don't mind, you're going
  1729. 1:21:31to use your head to do this virtually.
  1730. 1:21:34So let's line up your head with this red rectangle, if you could,
  1731. 1:21:39we'll do beginner.
  1732. 1:21:40[MUSIC PLAYING]
  1733. 1:21:41All right, here we go.
  1734. 1:21:42Sahar.
  1735. 1:21:44Give it a moment.
  1736. 1:21:45OK, come a little closer.
  1737. 1:21:47[DINGING]
  1738. 1:21:48And now hit the moles with your head.
  1739. 1:21:50[DING]
  1740. 1:21:51There we go, one point.
  1741. 1:21:53[DING]
  1742. 1:21:53One point.
  1743. 1:21:56[DINGING]
  1744. 1:21:58Nice.
  1745. 1:22:0015 seconds to go.
  1746. 1:22:01There we go.
  1747. 1:22:01Oh yeah.
  1748. 1:22:02One point.
  1749. 1:22:04[LAUGHING]
  1750. 1:22:06[DINGING]
  1751. 1:22:07Six seconds.
  1752. 1:22:09AUDIENCE: Oh no.
  1753. 1:22:10DAVID MALAN: There we go.
  1754. 1:22:11Quick!
  1755. 1:22:12[DINGING]
  1756. 1:22:14All right, a round of applause for Sahar.
  1757. 1:22:16Thank you.
  1758. 1:22:18[APPLAUSE]
  1759. 1:22:24So beyond having a little bit of fun here,
  1760. 1:22:26the goal was to demonstrate that by using
  1761. 1:22:28some fairly simple, primitive, some basic building blocks
  1762. 1:22:31but assembling them in a fun way with some music, maybe
  1763. 1:22:34some new costumes or artwork, you can really bring programs to life.
  1764. 1:22:37But at the end of the day, the only puzzle pieces really involved
  1765. 1:22:40were ones like the ones I just dragged and dropped and a few more,
  1766. 1:22:43because there were clearly lots of moles.
  1767. 1:22:45So the student probably created a few different sprites, not a single cap,
  1768. 1:22:49but at least four different moles.
  1769. 1:22:50They had like some kind of graphic on the screen that showed Sahar
  1770. 1:22:53where to position her head.
  1771. 1:22:54There were some kind of timer, maybe a variable
  1772. 1:22:57that every second was counting down.
  1773. 1:22:59So you can imagine taking what looks like a pretty impressive project
  1774. 1:23:02at first glance, and perhaps overwhelming
  1775. 1:23:04to solve yourself, but just think about what are the basic building blocks?
  1776. 1:23:07And pluck off one piece of the puzzle, so to speak, at a time.
  1777. 1:23:12So indeed if we rewind a little bit.
  1778. 1:23:15Let me go ahead here and introduce a program
  1779. 1:23:17that I myself made back in graduate school
  1780. 1:23:20when Scratch was first being developed by MIT.
  1781. 1:23:23Let me go ahead and open here, give me just one second,
  1782. 1:23:26something that I called back in the day Oscar Time that
  1783. 1:23:30looks a little something like this.
  1784. 1:23:32If I fullscreen it and hit Play.
  1785. 1:23:34[MUSIC - SESAME STREET, "I LOVE TRASH"]
  1786. 1:23:38OSCAR THE GROUCH: (SINGING) Oh, I love trash.
  1787. 1:23:40DAVID MALAN: So you'll notice a piece of trash is falling.
  1788. 1:23:42I can click on it and drag and as I get close and close to the trash can notice
  1789. 1:23:45OSCAR THE GROUCH: (SINGING) Anything ragged or--
  1790. 1:23:47DAVID MALAN: It wants to go in, it seems.
  1791. 1:23:49And if I let go--
  1792. 1:23:50OSCAR THE GROUCH: (SINGING) Yes, I--
  1793. 1:23:52DAVID MALAN: One point.
  1794. 1:23:54Here comes another.
  1795. 1:23:54OSCAR THE GROUCH: (SINGING) If you really want to see something trashy--
  1796. 1:23:56DAVID MALAN: I'll do the same, two points.
  1797. 1:23:57OSCAR THE GROUCH: (SINGING) I have here a sneaker that's tattered and worn--
  1798. 1:24:00DAVID MALAN: There's a sneaker falling from the sky,
  1799. 1:24:01so another sprite of some sort.
  1800. 1:24:03OSCAR THE GROUCH: (SINGING) The laces are torn.
  1801. 1:24:05A gift from my mother--
  1802. 1:24:07DAVID MALAN: I can also get just a little lazy
  1803. 1:24:09and just let them fall into the trash themself if I want to.
  1804. 1:24:13So you can see it doesn't have to do with my mouse cursor,
  1805. 1:24:15it has to do apparently with the distance here.
  1806. 1:24:18Let's listen a little further.
  1807. 1:24:19I think some additional trash is about to make its appearance.
  1808. 1:24:23Presumably there's some kind of variable that's keeping track of this score.
  1809. 1:24:26OSCAR THE GROUCH: (SINGING) I love--
  1810. 1:24:28DAVID MALAN: OK, let's see what the last chorus here is.
  1811. 1:24:30OSCAR THE GROUCH: (SINGING) Rotten stuff.
  1812. 1:24:32I have here some newspaper, crusty and
  1813. 1:24:35DAVID MALAN: OK, and thus he continues.
  1814. 1:24:37And the song actually goes on and on and on
  1815. 1:24:40and I do not have fond memories of implementing this and hearing
  1816. 1:24:43this song for like 10 straight hours, but it's
  1817. 1:24:46a good example to just consider how was this program composed?
  1818. 1:24:50How did I go about implementing it the first time around?
  1819. 1:24:52And let me go ahead and open up some programs now
  1820. 1:24:54that I wrote in advance just so that we could
  1821. 1:24:56see how these things are assembled.
  1822. 1:24:58Honestly, the first thing I probably did was probably
  1823. 1:25:02to do something a little like this.
  1824. 1:25:04Here is just a version of the program where
  1825. 1:25:07I set out to solve just one problem first
  1826. 1:25:09of planting a lamp post in the program.
  1827. 1:25:12Right?
  1828. 1:25:12I kind of had a vision of what I wanted.
  1829. 1:25:14You know, it evolved over time, certainly,
  1830. 1:25:15but I knew I wanted trash to fall, I wanted
  1831. 1:25:17a cute little Oscar the Grouch to pop out
  1832. 1:25:19of the trashcan, and some other stuff, but wow that's a lot
  1833. 1:25:22to just tackle all at once.
  1834. 1:25:23I'm going to start easy, download a picture of a lamp post,
  1835. 1:25:26and then drag and drop it into the stage as a costume and boom, that's
  1836. 1:25:30version one.
  1837. 1:25:31It doesn't functionally do anything.
  1838. 1:25:33I mean, literally that's the code that I wrote to do this.
  1839. 1:25:36All I did was use like the Backdrops feature
  1840. 1:25:38and drag and drop and move things around,
  1841. 1:25:41but it got me to version one of my program.
  1842. 1:25:44Then what might version two be?
  1843. 1:25:46Well I considered what piece of functionality
  1844. 1:25:48frankly might be the easiest to pluck off next and the trash can.
  1845. 1:25:52That seems like a pretty core piece of functionality.
  1846. 1:25:54It just needs to sit there most of the time.
  1847. 1:25:56So the next thing I probably did was to open up,
  1848. 1:25:59for instance, the trash can version here that looks a little something now
  1849. 1:26:05like this.
  1850. 1:26:06So this time I'll show you what's inside here.
  1851. 1:26:08There is some code, but not much.
  1852. 1:26:10Notice at bottom right I change the default cat to a picture of a trashcan,
  1853. 1:26:14instead, but it's the same principle that I can control.
  1854. 1:26:17And then over here I added this code.
  1855. 1:26:20When the green flag is clicked, switch the costume
  1856. 1:26:23to something I arbitrarily called Oscar 1.
  1857. 1:26:25So I found a couple of different pictures
  1858. 1:26:26of a trash can, one that looks closed, one that looks partly open,
  1859. 1:26:29and eventually one that has Oscar coming out,
  1860. 1:26:32and I just gave them different names.
  1861. 1:26:33So I said Switch to Oscar 1, which is the closed one by default,
  1862. 1:26:36then forever do the following: if touching the mouse pointer,
  1863. 1:26:40then switch the costume to Oscar 2, else switch to Oscar 1.
  1864. 1:26:45That is to say, I just wanted to implement this idea of the can opening
  1865. 1:26:49and closing, even if it's not exactly what I wanted ultimately,
  1866. 1:26:52I just wanted to make some forward progress.
  1867. 1:26:54So here, when I run this program by clicking Play, notice what happens.
  1868. 1:26:59Nothing yet, but if I get closer to the trash can,
  1869. 1:27:03it indeed pops open because it's forever listening
  1870. 1:27:07for whether the sprite, the trash can in this case,
  1871. 1:27:10is touching the mouse pointer.
  1872. 1:27:11And that's it.
  1873. 1:27:12That was version 2, if you will.
  1874. 1:27:15If I went in now and added the lamp post and compose the program together,
  1875. 1:27:18now we're starting to make progress.
  1876. 1:27:20Right?
  1877. 1:27:20Now it would look a little something more like the program
  1878. 1:27:22I intended ultimately to create.
  1879. 1:27:25What piece did I probably bite off after that?
  1880. 1:27:27Well, I think what I did is I probably decided
  1881. 1:27:30let me implement one of the pieces of trash, not the shoe in the newspaper
  1882. 1:27:33all at once.
  1883. 1:27:34Let's just get one piece of trash working correctly first.
  1884. 1:27:37So let me go ahead and open this one.
  1885. 1:27:40And again, all of these examples will be available on the course's website
  1886. 1:27:43so you can see all of these examples, too.
  1887. 1:27:46It's not terribly long, I just implement it in advance
  1888. 1:27:48so we could flip through kind of quickly.
  1889. 1:27:50Here's what I did here.
  1890. 1:27:52On the right hand side, I turned my sprite into a piece of trash
  1891. 1:27:56this time instead of a cat, instead of a trash can,
  1892. 1:27:58and I also created, with Carter's help, a second sprite, this one a floor.
  1893. 1:28:04It's literally just a black line because I just wanted initially
  1894. 1:28:07to have some notion of a floor so I could detect
  1895. 1:28:09if the trash is touching the floor.
  1896. 1:28:12Now without seeing the code yet, just hearing that description,
  1897. 1:28:15why might I have wanted the second sprite and this black line for a floor
  1898. 1:28:20with the trash intending to fall from the sky?
  1899. 1:28:22What might I have been thinking?
  1900. 1:28:24Like what problem might I be trying to solve?
  1901. 1:28:26Yeah?
  1902. 1:28:26AUDIENCE: You don't want the first sprite to go through it.
  1903. 1:28:28DAVID MALAN: Yeah, you don't want the first sprite to start at the top,
  1904. 1:28:31go through, and then boom, you completely lose it.
  1905. 1:28:34That would not be a very useful thing.
  1906. 1:28:36Or it would seem to maybe eat up more and more of the computer's memory
  1907. 1:28:39if the trash is just endlessly falling and I can't grab it.
  1908. 1:28:42It might be a little traumatic if you tried to get it
  1909. 1:28:44and you can't pull it back out and you can't fix the program.
  1910. 1:28:46So I just wanted the thing to stop.
  1911. 1:28:48So how might I have implemented this?
  1912. 1:28:50Let's look at the code at left.
  1913. 1:28:51Here I have a bit of randomness, like I proposed earlier exists.
  1914. 1:28:56There's this blue function called Go To x,
  1915. 1:28:59y that lets me move a sprite to any position,
  1916. 1:29:03up, down, left, right, I picked a random x location, either here or over here,
  1917. 1:29:07negative 240 to positive 240, and then a y value of 180, which is the top.
  1918. 1:29:12This just makes the game more interesting.
  1919. 1:29:14It's kind of lame pretty quickly if the trash always falls from the same spot.
  1920. 1:29:18Here's this a little bit of randomness, like most any game would have,
  1921. 1:29:21that spices things up.
  1922. 1:29:23So now if I click the green flag, you'll see that it just falls,
  1923. 1:29:26nothing interesting is going to happen, but it
  1924. 1:29:28does stop when it touches the black line because notice what we did here.
  1925. 1:29:33I'm forever asking the question if the distance of the sprite, the trash,
  1926. 1:29:37is to the floor is greater than zero, that's fine.
  1927. 1:29:41Change the y location by negative 3.
  1928. 1:29:44So move it down 3 pixels, down 3 pixels, until the distance to the floor
  1929. 1:29:48is not greater than zero, it is zero or even negative, at which point
  1930. 1:29:52it should just stop moving altogether.
  1931. 1:29:54There's other ways we could have implemented this,
  1932. 1:29:56but this felt like a nice, clean way that logically, just
  1933. 1:29:58made it make sense.
  1934. 1:29:59OK, now I got some trash falling, I got a trash can that opens and closes,
  1935. 1:30:03I have a lamp post, now I'm a good three steps into the program.
  1936. 1:30:08We're making progress.
  1937. 1:30:09If we consider one or two final pieces, something
  1938. 1:30:12like the dragging of the trash, let me go ahead and open up this version 2.
  1939. 1:30:17Dragging the trash requires a different type of question.
  1940. 1:30:21Let me zoom in here.
  1941. 1:30:22Here's the piece of trash.
  1942. 1:30:24I only need one sprite, no floor here because I just
  1943. 1:30:26want the human to move it up, down, left, right and the human's
  1944. 1:30:29not going to physically be able to move it outside of the world.
  1945. 1:30:32If we zoom in on this code, the way we've solved this is as follows.
  1946. 1:30:36We're using that And conjunction that we glimpsed earlier because when
  1947. 1:30:40the green flag is clicked, we're forever asking this question or really
  1948. 1:30:44these questions, plural, if the mouse is down
  1949. 1:30:47and the trash is touching the mouse pointer, that's equivalent
  1950. 1:30:53logically to clicking on the trash.
  1951. 1:30:55Go ahead and move the trash to the mouse pointer.
  1952. 1:30:58So again it takes this very familiar idea
  1953. 1:31:00that you and I take for granted every day on Macs and PCs of clicking
  1954. 1:31:04and dragging and dropping.
  1955. 1:31:05How is that implemented?
  1956. 1:31:06Well Mac OS or Windows are probably asking a question.
  1957. 1:31:10For every icon, is the mouse down and is the icon touching the mouse?
  1958. 1:31:15If so, go to the location of the mouse forever
  1959. 1:31:19while the mouse button is clicked down.
  1960. 1:31:21So how does this work in reality now?
  1961. 1:31:23Let me go ahead and click on the Play.
  1962. 1:31:25Nothing happens at first, but if I click on it, I can move it up,
  1963. 1:31:30down, left, right.
  1964. 1:31:31It doesn't move thereafter.
  1965. 1:31:33So I now need to kind of combine this idea of dragging with falling,
  1966. 1:31:36but I bet I could just start to use just one single program.
  1967. 1:31:39Right now I'm using separate ones to show different ideas,
  1968. 1:31:42but now that's another bite out of the problem.
  1969. 1:31:45If we do one last one, something like the scorekeeping
  1970. 1:31:48is interesting, because recall that every time we dragged a piece of trash
  1971. 1:31:51into the can, Oscar popped out and told us the current score.
  1972. 1:31:54So let me go ahead and find this one, Oscar variables,
  1973. 1:31:59and let me zoom in on this one.
  1974. 1:32:01This one is longer because we combined all of these elements.
  1975. 1:32:04So this is the kind of thing that if you looked at first glance, like,
  1976. 1:32:07I have no idea how I would have implemented this
  1977. 1:32:09from nothing, from scratch literally.
  1978. 1:32:12But again, if you take your vision and componenitize it
  1979. 1:32:16into these smaller, bite-sized problems, you
  1980. 1:32:18could take these baby steps, so to speak, and then
  1981. 1:32:21solve everything collectively.
  1982. 1:32:22So what's new here is this bottom one.
  1983. 1:32:25Forever do the following: if the trash is touching
  1984. 1:32:30Oscar, the other sprite that we've now added to the program,
  1985. 1:32:33change the score by 1.
  1986. 1:32:35This is an orange and indeed if we poke around
  1987. 1:32:37we'll see that orange is a variable, like an x or y but with a better name,
  1988. 1:32:42changing it means to add 1 or if it's negative subtract 1.
  1989. 1:32:46Then go ahead and have the trash go to pick random.
  1990. 1:32:51What is this all about?
  1991. 1:32:53Well, let me show you what it's doing and then we can infer backwards.
  1992. 1:32:56Let me go ahead and hit Play.
  1993. 1:32:58All right, it's falling, I'm clicking and dragging it, I'm moving it over,
  1994. 1:33:01and I'm letting go.
  1995. 1:33:02All right, let me do it once more.
  1996. 1:33:04Letting go, let me stop.
  1997. 1:33:06Why do I have this function at the end called Go To x and y randomly?
  1998. 1:33:13Like what problem is this solving here?
  1999. 1:33:16Yeah, in way back.
  2000. 1:33:18AUDIENCE: Just the same track teleported to the top
  2001. 1:33:21after you put it in the trash can.
  2002. 1:33:23DAVID MALAN: Yeah, exactly.
  2003. 1:33:24Even though the human perceives this as like a lot of trash falling
  2004. 1:33:27from the sky, it's actually the same piece
  2005. 1:33:29of trash, just kind of being magically moved back to the top
  2006. 1:33:32as though it's a new one.
  2007. 1:33:33There, too, you have this idea of reusable code.
  2008. 1:33:36If you were constantly copying and pasting your pieces of trash
  2009. 1:33:40and creating 20 pieces of trash, 30 pieces of trash, just because you
  2010. 1:33:43want the game to have that many levels, probably doing something wrong.
  2011. 1:33:46Reuse the code that you wrote, reuse the sprites that you wrote,
  2012. 1:33:49and that would give you not just correctness, but also a better design.
  2013. 1:33:54Well let's take a look at one final set of building blocks
  2014. 1:33:57that we can compose ultimately into something
  2015. 1:33:59particularly interactive as follows.
  2016. 1:34:02Let me go ahead and zoom out here and let
  2017. 1:34:03me propose that we implement something like some kind of maze-based game.
  2018. 1:34:08Let me go ahead here.
  2019. 1:34:09So I want to implement some maze-based game that
  2020. 1:34:13looks at first glance like this.
  2021. 1:34:15Let me hit Play.
  2022. 1:34:15It's not a very fun game yet, but here's a little Harvard
  2023. 1:34:18shield, a couple of black lines, this time vertical instead of horizontal,
  2024. 1:34:22but notice you can't quite see my hand here,
  2025. 1:34:24but I'm using my arrow keys to go down, to go up, to go left, to go right,
  2026. 1:34:28but if I keep going right, right, right, right, right, right,
  2027. 1:34:31right it's not going anywhere.
  2028. 1:34:32And left, left, left, left, left, left, left, left, left, left, left, left,
  2029. 1:34:35left it eventually stops.
  2030. 1:34:36So before we look at the code, how might this be working?
  2031. 1:34:41What kinds of scripts, collections of puzzle pieces,
  2032. 1:34:44might collectively help us implement this?
  2033. 1:34:47What do you think?
  2034. 1:34:48AUDIENCE: [INAUDIBLE]
  2035. 1:34:56DAVID MALAN: Perfect, yeah.
  2036. 1:34:57There's probably some question being asked, if touching the black line,
  2037. 1:35:00and it happens to be a couple of sprites, each of which
  2038. 1:35:03is just literally a vertical black line we're probably asking a question like,
  2039. 1:35:06are you touching it?
  2040. 1:35:07Is the distance to it zero or close to zero?
  2041. 1:35:10And if so, we just ignore the left or the right arrow at that point.
  2042. 1:35:16So that works.
  2043. 1:35:16But otherwise, if we're not touching a wall,
  2044. 1:35:18what are we probably doing instead forever here?
  2045. 1:35:22How is the movement working presumably?
  2046. 1:35:24Yeah and back.
  2047. 1:35:26Oh are you scratching?
  2048. 1:35:28OK, sure.
  2049. 1:35:29Let's go on.
  2050. 1:35:30AUDIENCE: [INAUDIBLE]
  2051. 1:35:33DAVID MALAN: Sorry, say a little louder.
  2052. 1:35:35AUDIENCE: Presumably it's continually looking for you to hit the arrow keys
  2053. 1:35:38and then moving when you do.
  2054. 1:35:40DAVID MALAN: Exactly.
  2055. 1:35:41It's continually, forever listening for the arrow keys up, down, left, right,
  2056. 1:35:44and if the up arrow is pressed, we're probably
  2057. 1:35:47changing the y by a positive value.
  2058. 1:35:49If the down arrow is pressed, we're going down by y,
  2059. 1:35:52and left and right accordingly.
  2060. 1:35:54So let's actually take a quick look.
  2061. 1:35:55If I zoom out here and take a look at the code that implements this,
  2062. 1:35:59there's a lot going on at first glance, but let's see.
  2063. 1:36:01First of all, let me drag some stuff out of the way
  2064. 1:36:03because it's kind of overwhelming at first glance,
  2065. 1:36:05especially if you, for instance, were poking around online as for problem set
  2066. 1:36:090 just to get inspiration, most projects out there
  2067. 1:36:11are going to look overwhelming at first glance
  2068. 1:36:13until you start to wrap your mind around what's going on.
  2069. 1:36:16But in this case, we've implemented some abstractions
  2070. 1:36:19from the get go to explain to ourselves and to anyone else looking
  2071. 1:36:22at the code what's going on.
  2072. 1:36:24This is that program with the two black lines and the Harvard shield going up,
  2073. 1:36:29down, left, and right.
  2074. 1:36:30It initially puts the shield in the middle, 0,0, then
  2075. 1:36:33forever listens for keyboard, as I think you were describing,
  2076. 1:36:37and it feels for the walls, as I think you were describing.
  2077. 1:36:40Now how is that implemented?
  2078. 1:36:42Don't know yet.
  2079. 1:36:42These are custom blocks we created as abstractions to kind of hide
  2080. 1:36:46those implementation details because honestly that's
  2081. 1:36:48all I need to know right now.
  2082. 1:36:50But, as aspiring programmers, if we're curious now,
  2083. 1:36:52let's scroll down to the actual implementation
  2084. 1:36:55of listening for keyboard.
  2085. 1:36:57This is the one on the left and it is a little long,
  2086. 1:36:59but it's a lot of similar structure.
  2087. 1:37:02We're doing the following, if the up arrow is pressed, then change y by 1.
  2088. 1:37:07Go up.
  2089. 1:37:08If the down arrow is pressed, then change y by negative 1.
  2090. 1:37:11Go down.
  2091. 1:37:12Right arrow, left arrow, and that's it.
  2092. 1:37:15So it just assembles all of those ideas, combines it
  2093. 1:37:17into one new block just because it's kind of overwhelming,
  2094. 1:37:20let's just implement it once and tuck it away.
  2095. 1:37:22And if we scroll now over to the Feel for Walls function,
  2096. 1:37:26this now is asking the question as hypothesized,
  2097. 1:37:30if I'm touching the left wall, change my x value by 1, sort of move away from it
  2098. 1:37:35a little bit.
  2099. 1:37:35If I'm touching the right wall, then move x by negative 1
  2100. 1:37:38to move a little bit away from it.
  2101. 1:37:40So it kind of bounces off the wall.
  2102. 1:37:42Just in case it slightly went over, we keep the crest within those two walls.
  2103. 1:37:47All right, then a couple of more pieces here to introduce.
  2104. 1:37:51What if we want to actually add some kind of adversary or opponent
  2105. 1:37:54to this game?
  2106. 1:37:55Well, let me go ahead to maybe this one here where the adversary in this game
  2107. 1:38:02might, for instance, be designed to be bouncing to stand in your way.
  2108. 1:38:05This is like a maze and you're trying to get the Harvard shield from the bottom
  2109. 1:38:08to the top or vice versa.
  2110. 1:38:09Uh oh, Yale is in the way and it seems to be automatically bouncing
  2111. 1:38:14back and forth here.
  2112. 1:38:15Well, let me ask someone else.
  2113. 1:38:16Hypothesize.
  2114. 1:38:17How is this working?
  2115. 1:38:19This is an idea you have, this as an idea you see.
  2116. 1:38:21Let's reverse engineer in your head how it works.
  2117. 1:38:26How might this be working?
  2118. 1:38:27Yeah, in back.
  2119. 1:38:28AUDIENCE: If the Yale symbol is touching a right wall or left wall,
  2120. 1:38:32then have it bounce.
  2121. 1:38:34DAVID MALAN: Yeah, so if the Yale symbol is
  2122. 1:38:36touching the left wall or the right wall, we somehow have it bounce.
  2123. 1:38:39And indeed we'll see there's a puzzle piece that can do exactly
  2124. 1:38:41that technically off the edge, as we'll see,
  2125. 1:38:44but there's another way we can do this.
  2126. 1:38:45Let's look at the code.
  2127. 1:38:46The way we ourselves can implement exactly
  2128. 1:38:49that idea bounce is just with a little bit of logic.
  2129. 1:38:52So here's what this version of the program is doing.
  2130. 1:38:54It's moving Yale by default to 0,0 just to arbitrarily put it somewhere,
  2131. 1:38:58pointing it direction 90 degrees, which means just horizontally, essentially,
  2132. 1:39:03and then it's forever doing this: if touching the left wall
  2133. 1:39:06or touching the right wall, here's our translation of bounce.
  2134. 1:39:10We're just turning 180 degrees.
  2135. 1:39:11And the nice thing about that is we don't
  2136. 1:39:13have to worry if we're going from right to left or left to right.
  2137. 1:39:16180 degrees is going to work on both of the walls.
  2138. 1:39:19And that's it.
  2139. 1:39:21After we do that, we just move one step, one pixel, at a time
  2140. 1:39:24but we're doing it forever so something is happening continually
  2141. 1:39:28and the Yale icon is bouncing back and forth.
  2142. 1:39:30Well one final piece here, what if now we
  2143. 1:39:33want another adversary, a more advanced adversary down the road for instance,
  2144. 1:39:39to go and follow us wherever we are such that this time
  2145. 1:39:44we want the other sprite to not just bounce back and forth,
  2146. 1:39:51but literally follow us no matter where we go.
  2147. 1:39:55How might this be implemented on the screen?
  2148. 1:39:59I bet it's another forever block, but what's inside?
  2149. 1:40:01AUDIENCE: So forever get the location of the of the Harvard shield
  2150. 1:40:05and move one step towards it.
  2151. 1:40:06DAVID MALAN: Yeah, forever point at the location of the Harvard shield
  2152. 1:40:09and go one step toward it.
  2153. 1:40:11This is just going to go on forever if I just give up, at least in this version.
  2154. 1:40:15Notice it's sort of twitching back and forth because it goes one
  2155. 1:40:18pixel then one pixel then one pixel.
  2156. 1:40:20It's sort of in a frantic state here.
  2157. 1:40:21We haven't finished the game yet, but if we see inside, we'll see exactly that.
  2158. 1:40:25It didn't take much to implement this simple idea.
  2159. 1:40:28Go to a random position just to make it kind of fair,
  2160. 1:40:30initially, then forever point towards Harvard,
  2161. 1:40:33which is what we called the Harvard crest sprite, move one step.
  2162. 1:40:37Suppose we now wanted to make a more advanced level.
  2163. 1:40:39What's a minor change I could logically make to this code just
  2164. 1:40:42to make MIT even better at this?
  2165. 1:40:45AUDIENCE: Change the number of steps to two.
  2166. 1:40:46DAVID MALAN: All right, change the number of steps to two.
  2167. 1:40:48So let's try that.
  2168. 1:40:49So now they got twice as fast.
  2169. 1:40:51Let me go ahead and just get this out of the way.
  2170. 1:40:53Oops, let me make it a fair fight.
  2171. 1:40:56Green flag.
  2172. 1:40:58All right, I unfortunately am still moving one pixel at a time,
  2173. 1:41:01so this isn't going to end well.
  2174. 1:41:03It caught up to me.
  2175. 1:41:04And if we're really aggressive and do something like 20 steps at a time,
  2176. 1:41:10click the green flag.
  2177. 1:41:11Jesus, OK, so that's how you might then make your levels progressively
  2178. 1:41:16harder and harder.
  2179. 1:41:17So it's not an accident that we chose these particular examples
  2180. 1:41:20here involving these particular schools because we have one more
  2181. 1:41:23demonstration we thought we'd introduce today
  2182. 1:41:25if we could get one other volunteer to come up and play
  2183. 1:41:30what was called by one of your predecessors Ivy's Hardest Game.
  2184. 1:41:34Let's see, you in the middle.
  2185. 1:41:35Do you want to come on up?
  2186. 1:41:36What's your name?
  2187. 1:41:37AUDIENCE: Celeste.
  2188. 1:41:38DAVID MALAN: Say again?
  2189. 1:41:39AUDIENCE: Celeste.
  2190. 1:41:40DAVID MALAN: Come a little closer, actually.
  2191. 1:41:41Sorry, hard to hear here.
  2192. 1:41:44All right, round of applause here if we could, too.
  2193. 1:41:47[APPLAUSE]
  2194. 1:41:53OK, sorry, what was your name?
  2195. 1:41:54AUDIENCE: Celeste.
  2196. 1:41:55DAVID MALAN: Ceweste
  2197. 1:41:55AUDIENCE: Celeste.
  2198. 1:41:56DAVID MALAN: Celeste.
  2199. 1:41:56AUDIENCE: Yes.
  2200. 1:41:57DAVID MALAN: Come on over.
  2201. 1:41:57Nice to meet you, too.
  2202. 1:41:59So here we have on this other screen Ivy's Hardest Game
  2203. 1:42:02written by a former CS50 student.
  2204. 1:42:04I think you'll see that it combines these same principles.
  2205. 1:42:07The maze is clearly a little more advanced.
  2206. 1:42:09The goal at hand is to initially move the Harvard crest to the sprite all
  2207. 1:42:14the way on the right so that you catch up to him in this case,
  2208. 1:42:17but you'll see that there's different levels
  2209. 1:42:18and different levels of sophistication.
  2210. 1:42:21So if you're up for it, you can use just these arrow keys up, down, left, right.
  2211. 1:42:24You'll be controlling the Harvard sprite and if we
  2212. 1:42:27could raise the volume just a little bit, we'll make this our final example.
  2213. 1:42:32Here we go, clicking the green flag.
  2214. 1:42:34[MUSIC PLAYING]
  2215. 1:42:38Feeling ready?
  2216. 1:42:39AUDIENCE: Yep.
  2217. 1:42:40DAVID MALAN: Spacebar.
  2218. 1:42:41[MUSIC - MC HAMMER, "U CAN'T TOUCH THIS"]
  2219. 1:42:43MC HAMMER: (SINGING) Can't touch this.
  2220. 1:42:45You can't touch this.
  2221. 1:42:48You can't touch this.
  2222. 1:42:52Can't touch this.
  2223. 1:42:55My, my, my, my music--
  2224. 1:42:56DAVID MALAN: Excellent.
  2225. 1:42:57MC HAMMER: (SINGING) so hard.
  2226. 1:42:58Makes me want to say, oh my Lord.
  2227. 1:43:00Thank you for blessing me--
  2228. 1:43:02DAVID MALAN: Two Yales now.
  2229. 1:43:03MC HAMMER: (SINGING) Feels good when you know you're down.
  2230. 1:43:06A super dope homeboy--
  2231. 1:43:07AUDIENCE: Oh!
  2232. 1:43:07DAVID MALAN: Oh!
  2233. 1:43:09Keep going.
  2234. 1:43:10MC HAMMER: (SINGING) You can't touch this.
  2235. 1:43:12I told you, homeboy.
  2236. 1:43:13Can't touch this.
  2237. 1:43:15Yeah, that's how living--
  2238. 1:43:16DAVID MALAN: All right.
  2239. 1:43:17MC HAMMER: (SINGING) Can't touch this.
  2240. 1:43:19Look at my eyes, man.
  2241. 1:43:20You can't touch this.
  2242. 1:43:23You let me bust the funky lyrics.
  2243. 1:43:25You can't touch this.
  2244. 1:43:26Fresh new kicks and pants.
  2245. 1:43:27You got it like that and you know you want to dance.
  2246. 1:43:29So move out of your seat and get a fly girl and catch this beat.
  2247. 1:43:33[LAUGHING]
  2248. 1:43:33Hold on.
  2249. 1:43:34Pump a little bit and let them know what's going on like that, like that.
  2250. 1:43:38Cold on a mission, so fall on back.
  2251. 1:43:39Let them know that you're too--
  2252. 1:43:41DAVID MALAN: There you go.
  2253. 1:43:42There you go.
  2254. 1:43:43[APPLAUSE]
  2255. 1:43:46MC HAMMER: (SINGING) Can't touch this.
  2256. 1:43:48Why you standing there, man?
  2257. 1:43:50You can't touch this.
  2258. 1:43:51Yo, sound the bell.
  2259. 1:43:52School's in, sucker.
  2260. 1:43:54Can't touch this.
  2261. 1:43:54Give me a song or rhythm, making them sweat that's what give them.
  2262. 1:43:58[CHEERING]
  2263. 1:43:59They know.
  2264. 1:44:00You talking the Hammer when you're talking about a show.
  2265. 1:44:02That's hyped and tight.
  2266. 1:44:03Singers are sweating so them a wipe or a tame to learn.
  2267. 1:44:06DAVID MALAN: Second to last level.
  2268. 1:44:08Oh!
  2269. 1:44:08MC HAMMER: (SINGING) That chart's legit.
  2270. 1:44:10Either work hard or you might as well quit.
  2271. 1:44:13That word because you know--
  2272. 1:44:14DAVID MALAN: Oh!
  2273. 1:44:15Keep going, keep going!
  2274. 1:44:17Yes!
  2275. 1:44:18MC HAMMER: (SINGING) You can't touch this.
  2276. 1:44:20DAVID MALAN: You're almost there.
  2277. 1:44:22MC HAMMER: (SINGING) Break it down.
  2278. 1:44:23DAVID MALAN: There you go.
  2279. 1:44:24Go, go, go!
  2280. 1:44:26Oh.
  2281. 1:44:27One more.
  2282. 1:44:30Yes!
  2283. 1:44:31[CHEERING]
  2284. 1:44:32There you go.
  2285. 1:44:36MC HAMMER: (SINGING) Stop, Hammer time.
  2286. 1:44:38"Go with the flow," it is said.
  2287. 1:44:39If you can't groove to this, then you're probably dead.
  2288. 1:44:42So wave your hands in the air, bust a few moves,
  2289. 1:44:44run your fingers through your hair.
  2290. 1:44:45This is it.
  2291. 1:44:45For a winner.
  2292. 1:44:46Dance to this and you're going to get thinner.
  2293. 1:44:49Now move, slide your rump.
  2294. 1:44:50Just for a minute let's all do the bump.
  2295. 1:44:53[CHEERING]
  2296. 1:44:54DAVID MALAN: Yes!
  2297. 1:44:55[APPLAUSE]
  2298. 1:44:56Congratulations.
  2299. 1:45:03All right, that's it for CS50.
  2300. 1:45:05Welcome to the class.
  2301. 1:45:06We'll see you next time.
  2302. 1:45:08[MUSIC PLAYING]
  2303. 1:46:26DAVID J. MALAN: All right.
  2304. 1:46:27So this is CS50.
  2305. 1:46:29And this is week 1, the one in which you learn a new language, which
  2306. 1:46:33is something we technically said last week, at least if you had never
  2307. 1:46:36played with this graphical language known as Scratch before, which itself
  2308. 1:46:39was a programming language.
  2309. 1:46:41But today, as promised, we transition to something
  2310. 1:46:43a little more traditional, a little more text-based,
  2311. 1:46:45not puzzle piece- or block-based, known as C.
  2312. 1:46:48This is an older language.
  2313. 1:46:49It's been around for decades.
  2314. 1:46:50But it's a language that underlies so many of today's more modern languages,
  2315. 1:46:54among them something called Python that we'll also
  2316. 1:46:57come to in a few weeks' time.
  2317. 1:46:58Indeed, at the end of the semester, the goal
  2318. 1:47:00is for you to feel that you've not learned Scratch,
  2319. 1:47:02you've not learned C, or even Python, for that matter,
  2320. 1:47:04but fundamentally that you've learned how to program.
  2321. 1:47:07Unfortunately, when you learn how to program
  2322. 1:47:09with a more traditional language like this, there's just so much distraction.
  2323. 1:47:13Last week I described all of the syntax, all of the weird punctuation
  2324. 1:47:17that you see in this, like the hash symbol, these angled brackets,
  2325. 1:47:19parentheses, curly braces, backslash n, and more.
  2326. 1:47:22Well, today we're not going to reveal what all of those little particulars
  2327. 1:47:26mean.
  2328. 1:47:27But by next week, will this no longer look like the proverbial Greek
  2329. 1:47:31to you, a language that, presumably, you've never actually seen or typed
  2330. 1:47:35before.
  2331. 1:47:36But to do that, we'll explore some of the very same topics as last week.
  2332. 1:47:40So recall that, via Scratch-- and presumably via problem set 1--
  2333. 1:47:43we took a look at things called functions that are actions or verbs.
  2334. 1:47:46And related to functions were arguments like inputs.
  2335. 1:47:49And related to some functions were returned values like outputs.
  2336. 1:47:52Then we talked a bit about conditionals, forks in the road, so to speak,
  2337. 1:47:56Boolean expressions, which are just yes/no questions or true/false
  2338. 1:47:59questions, loops, which let you do things again and again, variables,
  2339. 1:48:03like in math, that let you store values temporarily,
  2340. 1:48:05and then even other topics still.
  2341. 1:48:07So if you were comfortable on the heels of problem set 0 and last week,
  2342. 1:48:11realize that all of these topics are going to remain with us.
  2343. 1:48:14So really, today is just about acquiring all the more of a mental model for how
  2344. 1:48:18you translate those ideas into, presumably, a very cryptic new syntax--
  2345. 1:48:22a new syntax, frankly, that's actually more
  2346. 1:48:25simple in some ways than your own human language,
  2347. 1:48:27be it English or something else, because there's far fewer vocabulary words.
  2348. 1:48:31There's actually far less syntax that you might
  2349. 1:48:33have in, say, a typical human language.
  2350. 1:48:35But you need to be with these computer languages all the more precise
  2351. 1:48:39so that you're most, ultimately, correct,
  2352. 1:48:41and ultimately will see to your code is successful along a few other lines
  2353. 1:48:46as well.
  2354. 1:48:46So if you think about the last time you kind of wandered around not really
  2355. 1:48:49knowing what you were doing or encountered something new--
  2356. 1:48:51might not have been that long ago, entering Harvard Yard for the very
  2357. 1:48:54first time, or Old Campus or the like, be it in Cambridge or New Haven--
  2358. 1:48:58you didn't really need to know how to do everything as a first year.
  2359. 1:49:01You didn't need to know who everyone was,
  2360. 1:49:03where everything was, how Harvard or Yale, or anything else for that matter,
  2361. 1:49:07worked.
  2362. 1:49:07You sort of got by day to day by just focusing on those things that matter.
  2363. 1:49:10And anything you didn't really understand,
  2364. 1:49:12you sort of turned a blind eye to until it's important.
  2365. 1:49:14And that's, indeed, what we're going to do today.
  2366. 1:49:16And really, for the next several weeks, we'll
  2367. 1:49:18focus on details that are initially important
  2368. 1:49:21and try to wave our hands, so to speak, at details that, yeah, eventually
  2369. 1:49:24we'll get to, might be interesting.
  2370. 1:49:25But for now, they might be distractions.
  2371. 1:49:27And by distractions, I really mean some of that syntax
  2372. 1:49:29to which I alluded earlier.
  2373. 1:49:31So by the end of today-- and really, by the end of problem set 1,
  2374. 1:49:34your first foray, presumably, into this language called C--
  2375. 1:49:37you'll have written some code.
  2376. 1:49:39And you'll be asking yourself-- we'll be asking yourselves--
  2377. 1:49:41just how good is that code?
  2378. 1:49:43Well, first and foremost, per last week, be it in Scratch
  2379. 1:49:46or phone book form, code ultimately needs to be correct, to be well done.
  2380. 1:49:51You want the problem to be solved correctly.
  2381. 1:49:53So that one sort of goes without saying.
  2382. 1:49:55And along the way this term, we'll provide you with tools and techniques
  2383. 1:49:59so you don't have to just sit there sort of endlessly trying an input,
  2384. 1:50:02checking the output, trying another input, checking the output.
  2385. 1:50:05There's a lot of automation tools in the real world--
  2386. 1:50:07and in this class and others like it-- that
  2387. 1:50:09will help facilitate you answering that question for yourself, is my code
  2388. 1:50:13correct, according to our specifications or the like.
  2389. 1:50:15But then something that's going to take more time
  2390. 1:50:18and you're probably not going to feel 100% comfortable with the first week,
  2391. 1:50:21the first weeks, is just how well designed your code is.
  2392. 1:50:24It's one thing to speak English or write English,
  2393. 1:50:27but it's another thing-- or any language, for that matter.
  2394. 1:50:30But it's another thing to speak it or write it well.
  2395. 1:50:32And we spend all these years in middle school, high school, presumably,
  2396. 1:50:35writing papers and other documents, getting grades and feedback on them
  2397. 1:50:38as to how well formulated your arguments were, how well structured
  2398. 1:50:41your paper was, and the like.
  2399. 1:50:43And there's that same idea in programming.
  2400. 1:50:44It doesn't matter necessarily that you've just solved a problem correctly.
  2401. 1:50:49If your code is a complete visual mess, or if it's crazy long,
  2402. 1:50:53it's going to be really hard for someone else
  2403. 1:50:55to wrap their mind around what your code is doing and, indeed, to be confident
  2404. 1:50:59if it is correct.
  2405. 1:51:00And honestly, you-- the next morning, the next year,
  2406. 1:51:04the next time you look at that code-- might have no idea
  2407. 1:51:07what you yourself were even thinking.
  2408. 1:51:09But you will if you focus, too, on designing good code,
  2409. 1:51:13getting your algorithms efficient, getting your code nice and clean,
  2410. 1:51:16and even making sure your code looks pretty, which
  2411. 1:51:19we'd describe as a matter of style.
  2412. 1:51:20So in the written human world, having punctuation in the right place,
  2413. 1:51:24capitalization and the like-- the sort of way you write an essay
  2414. 1:51:27but not necessarily send a text message--
  2415. 1:51:29relates to style, for instance.
  2416. 1:51:31And so good style in code is going to have
  2417. 1:51:33a few of these characteristics that are pretty easily taught and remembered.
  2418. 1:51:36But you just have to start to get in the habit of writing code in a certain way.
  2419. 1:51:41So these three axes, so to speak, correctness, design, and style,
  2420. 1:51:44are really the overarching goals when writing code that
  2421. 1:51:48ultimately is going to look like this.
  2422. 1:51:50So this program we conjectured last week does
  2423. 1:51:52what if you run it on a Mac or PC or somewhere else, presumably?
  2424. 1:51:56What does it do?
  2425. 1:51:57Yeah?
  2426. 1:51:59AUDIENCE: [INAUDIBLE].
  2427. 1:52:00DAVID J. MALAN: It just prints, Hello, world.
  2428. 1:52:02And honestly, that's kind of atrocious that you
  2429. 1:52:04need to hit your keyboard keys this many times with this cryptic syntax just
  2430. 1:52:08to get a program to say, Hello, world.
  2431. 1:52:09So a spoiler-- in a few weeks' time when we
  2432. 1:52:11introduce other, more modern languages, like Python,
  2433. 1:52:14you can distill this same logic into literally one line of code.
  2434. 1:52:18And so we're getting there, ultimately.
  2435. 1:52:20But it's helpful to understand what it is that's going on here,
  2436. 1:52:23because even though this is a pretty cryptic syntax,
  2437. 1:52:25there's nothing after this week and, really, next week that you shouldn't
  2438. 1:52:28be able to understand even about something that right now looks
  2439. 1:52:30a little something like this.
  2440. 1:52:32So how do you write code?
  2441. 1:52:33Well, I've given us sort of the answer to a problem.
  2442. 1:52:35How do you print, Hello, world, on the screen?
  2443. 1:52:37So what do I do with this code?
  2444. 1:52:39Well, we're in the habit of typically writing things with, like, Microsoft
  2445. 1:52:42Word or Google documents.
  2446. 1:52:43And yeah, I could open up Word or Google Docs or Pages or the like
  2447. 1:52:48and just literally transcribe that character for character,
  2448. 1:52:50save it, and boom, I've got a program.
  2449. 1:52:53But the problem, per last week, is that computers only understand or speak
  2450. 1:52:56what other language, so to speak?
  2451. 1:52:59AUDIENCE: [INAUDIBLE].
  2452. 1:53:00DAVID J. MALAN: Yeah, so binary, zeros and ones.
  2453. 1:53:02And so this, obviously, is not zeros and ones.
  2454. 1:53:04So it doesn't matter if I put it in a Word doc, Google Doc, Pages file,
  2455. 1:53:07or the like.
  2456. 1:53:07The computer is not going to understand it until I somehow
  2457. 1:53:10translate it to zeros and ones.
  2458. 1:53:11And honestly, none of those tools that I rattled off
  2459. 1:53:14are really appropriate for programming.
  2460. 1:53:15Why?
  2461. 1:53:16Well, they come with features like bold facing and italics
  2462. 1:53:19and sort of fluffy, aesthetic stuff that has no functional impact on what
  2463. 1:53:22you're trying to do with your code.
  2464. 1:53:24And they don't have the ability, it would
  2465. 1:53:26seem, to convert that code ultimately to zeros and ones.
  2466. 1:53:29But tools that do have this capability might
  2467. 1:53:32be called Integrated Development Environments, or IDEs,
  2468. 1:53:36or, more simply, text editors.
  2469. 1:53:38A text editor is a tool that a programmer uses perhaps every day
  2470. 1:53:42to write their code.
  2471. 1:53:44And it's a simple program-- here, for instance, a very popular one
  2472. 1:53:46called Visual Studio Code, or VS Code.
  2473. 1:53:49And at the top here, you see that I've actually
  2474. 1:53:51created in advance before class a very simple empty file called "hello.c."
  2475. 1:53:56Why?
  2476. 1:53:57Well, .c indicates by convention that this is going to be a file in which
  2477. 1:54:00there is C code.
  2478. 1:54:01It's not .docx, which would mean in this file is a Microsoft Word document,
  2479. 1:54:06or .pages is a Pages file.
  2480. 1:54:08This is .c, which means in this file is going to be text in the language called
  2481. 1:54:12C. This number 1 here is just an automatic line number that's going help
  2482. 1:54:16me keep track of how long or short this program is.
  2483. 1:54:18And the cursor is just blinking there, waiting
  2484. 1:54:21for me to start typing some code.
  2485. 1:54:23Well, let me go ahead and type out exactly the same code.
  2486. 1:54:26For me, it comes pretty comfortably from memory.
  2487. 1:54:28So I'm going to go ahead and include something called standardio.h--
  2488. 1:54:31more on that later.
  2489. 1:54:32I'm going to magically type int main(void), whatever that means--
  2490. 1:54:37we'll come back to that later--
  2491. 1:54:38one of these curly braces and then a sibling there that closes the same.
  2492. 1:54:43Then I'm going to hit Tab to indent a few spaces.
  2493. 1:54:46And then I'm going to type not print, but printf, then "Hello, world," /n,
  2494. 1:54:52close quote, close parenthesis, semicolon.
  2495. 1:54:55And I dare say this was essentially the very first program I wrote some
  2496. 1:55:0025 years ago.
  2497. 1:55:01I wrote it to say, "Hi, CS50."
  2498. 1:55:03Now it just says the more canonical, conventional, "Hello, world."
  2499. 1:55:06But that's it.
  2500. 1:55:07That's my very first program.
  2501. 1:55:08And all I need to now do is maybe hit Command-S or Control-S
  2502. 1:55:11to save the file.
  2503. 1:55:12And voila, I am a programmer.
  2504. 1:55:15The catch though, is, OK, how do I run this?
  2505. 1:55:17Like, on your Mac or PC, how do you run a program?
  2506. 1:55:19Well, usually double-click an icon.
  2507. 1:55:21On your phone, you tap an icon.
  2508. 1:55:23In this environment that we're using and that many programmers-- dare
  2509. 1:55:26say most programmers-- use, you don't have immediately a nice, pretty icon
  2510. 1:55:31to double-click on.
  2511. 1:55:32That's very user friendly, but it's not very necessary.
  2512. 1:55:35Especially when you get more comfortable with programming,
  2513. 1:55:38you're going to want to type commands because it's just faster than pointing
  2514. 1:55:41and clicking a mouse.
  2515. 1:55:42And you're going to want to automate things,
  2516. 1:55:43which is a lot easier if it's all command or text-based, as opposed
  2517. 1:55:46to mouse and muscular movements.
  2518. 1:55:49And so here I have my program.
  2519. 1:55:52It lives in this file called "hello.c."
  2520. 1:55:54I need to now convert it, though, to zeros and ones.
  2521. 1:55:58Well, how do I go about doing this, and how am I going to get from this
  2522. 1:56:02so-called code--
  2523. 1:56:03or source code, as it's conventionally called--
  2524. 1:56:06to this, these zeros and ones that we'll now start calling machine code.
  2525. 1:56:11The zeros and ones from last week can be used not only
  2526. 1:56:13to represent numbers and letters, colors, audio, video, and more.
  2527. 1:56:18It can also represent instructions to a computer, like print, or play a sound,
  2528. 1:56:24or delete a file, or save a file.
  2529. 1:56:26All the sort of basics of a computer somehow
  2530. 1:56:28can be represented by other patterns of zeros and ones.
  2531. 1:56:32And just like last week, it depends on the context
  2532. 1:56:34in which these numbers are stored.
  2533. 1:56:36Sometimes they're interpreted as numbers, like in a spreadsheet.
  2534. 1:56:39Sometimes they're interpreted as colors.
  2535. 1:56:41Sometimes they're interpreted as instructions, commands to your computer
  2536. 1:56:46to do very low-level operations, like print something on the screen.
  2537. 1:56:50So fortunately, last week's definition of computer science of problem solving
  2538. 1:56:55is a nice mental model for exactly the goal at hand.
  2539. 1:56:58I have some input, AKA source code.
  2540. 1:57:00I want to output ultimately machine code, those zeros and ones.
  2541. 1:57:05I certainly don't want to do this kind of process by hand.
  2542. 1:57:07So hopefully there's an algorithm implemented by some special program
  2543. 1:57:11that does exactly that.
  2544. 1:57:12And those of you who do have some prior experience,
  2545. 1:57:14this program might be called a?
  2546. 1:57:16A compiler.
  2547. 1:57:18So a few of you have, indeed, programmed before.
  2548. 1:57:20Not all languages use compilers.
  2549. 1:57:21C, in fact, is a language that does use a compiler.
  2550. 1:57:24And so I just need to find myself--
  2551. 1:57:27on my computer somewhere, presumably-- a so-called compiler,
  2552. 1:57:31a program whose purpose in life is to convert one language to another.
  2553. 1:57:35And source code written textually in C, like we saw a moment ago,
  2554. 1:57:40is source code.
  2555. 1:57:41The machine code is the corresponding zeros and ones.
  2556. 1:57:44So let me go back to the same programming environment called
  2557. 1:57:48Visual Studio Code or VS Code.
  2558. 1:57:50This is typically a program you or any programmer on the internet
  2559. 1:57:53can download onto their own Mac or PC and be on their way with whatever
  2560. 1:57:57computer you own writing some code.
  2561. 1:57:59A downside, though, of that approach is that all of us
  2562. 1:58:02have slightly different versions of Macs or PCs.
  2563. 1:58:04We have slightly different versions of operating systems.
  2564. 1:58:07They may or may not be up to date.
  2565. 1:58:08It's just a technical support nightmare to create a uniform environment,
  2566. 1:58:13especially for an introductory class, where everyone should ideally
  2567. 1:58:15be on the same page so we can get you up and running quickly.
  2568. 1:58:19And so I'm actually using a cloud-based version of VS Code, something
  2569. 1:58:23that you only need a browser to access.
  2570. 1:58:25And then you can be on any computer, today or tomorrow.
  2571. 1:58:28By the end of the semester, we're going to get you out of the cloud,
  2572. 1:58:32so to speak, as best we can and get you onto your own Mac or PC,
  2573. 1:58:36so that after this class, especially if it's the only CS class you ever take,
  2574. 1:58:39you feel like you can continue programming in any number of languages,
  2575. 1:58:43even with CS50 behind you.
  2576. 1:58:45But for now, wonderfully, the browser version of VS Code
  2577. 1:58:47should pretty much be identical to what the eventual downloadable
  2578. 1:58:51version of the same would be.
  2579. 1:58:53And you'll see in problem set 1 how to access this
  2580. 1:58:55and how to get going yourself with your first programs.
  2581. 1:58:58But I haven't mentioned this bottom part of the screen,
  2582. 1:59:01this bottom part of the screen.
  2583. 1:59:03And this is an area where we have what's called a terminal window.
  2584. 1:59:06So this is sort of old-school technology that allows you, with a keyboard,
  2585. 1:59:10to interact with a computer, wherever it may be-- on your lap, in your pocket,
  2586. 1:59:15or even, in this case, in the cloud.
  2587. 1:59:17So on the top-hand portion of this screen
  2588. 1:59:20is my text editor, like tabbed windows, like in many programs, where
  2589. 1:59:24I can just create files and write code.
  2590. 1:59:26The bottom of the screen here, my so-called terminal window,
  2591. 1:59:30gives me the ability to run commands on a server
  2592. 1:59:33that currently I have exclusive access to.
  2593. 1:59:35So because I logged into VS Code with my account online,
  2594. 1:59:39I have my own sort of virtual server, if you will, in the cloud--
  2595. 1:59:44otherwise known as, in this context, a container.
  2596. 1:59:46This has its own operating system for me, its own hard drive,
  2597. 1:59:49if you will, where I can save and create files of my own,
  2598. 1:59:52separate from yours and vice versa.
  2599. 1:59:54And it's at this very simple prompt, which
  2600. 1:59:57is conventionally-- but not always-- abbreviated by a dollar sign,
  2601. 2:00:00has nothing to do with currency.
  2602. 2:00:01It just means, type your commands here.
  2603. 2:00:03This is where I'm going to be able to type commands,
  2604. 2:00:05like compile my source code into machine code.
  2605. 2:00:09So it's a Command Line Interface, or CLI, on top of an operating system
  2606. 2:00:15that you might not have ever used or seen, but it's very popular,
  2607. 2:00:18called Linux.
  2608. 2:00:19Odds are almost all of us in this room are using Mac OS or Windows right now,
  2609. 2:00:23but we're all going to start using an operating system called Linux, which
  2610. 2:00:26is in a family of operating systems that offer not only this command
  2611. 2:00:30line interface, but are used not just for programming, but for serving
  2612. 2:00:33websites and developing applications and the like.
  2613. 2:00:35And it's, indeed, a familiar and very powerful interface, as we'll see.
  2614. 2:00:40So how do I go about making this file, hello.c, into a program?
  2615. 2:00:45There's no icon to double-click, but there is a command.
  2616. 2:00:48I can type, make hello, at this dollar sign prompt, go ahead and hit Enter,
  2617. 2:00:54and nothing appears to happen.
  2618. 2:00:56But that's a good thing.
  2619. 2:00:57And as we'll see in programming, almost always,
  2620. 2:00:59if you don't see anything go wrong, that means everything went right.
  2621. 2:01:02So this is going to be a rarity at first,
  2622. 2:01:04but this is a good thing that it just seems to do nothing.
  2623. 2:01:07But now there is in the folder in my accounts
  2624. 2:01:11in this on the cloud a file called "hello."
  2625. 2:01:15And it's a bit of a weird command, but you'll get familiar with it
  2626. 2:01:18before long.
  2627. 2:01:19. just means go into my current folder.
  2628. 2:01:22/hello means run the program called "hello" in this current folder.
  2629. 2:01:28So ./hello, and then Enter, and voila, now I'm actually not just programming,
  2630. 2:01:32but running my actual code.
  2631. 2:01:35So what have I just done?
  2632. 2:01:38Let me go ahead and do this.
  2633. 2:01:40I'm going to go ahead and open up the sidebar of this program,
  2634. 2:01:42and you'll see in problem set 1 how to do this.
  2635. 2:01:44And this might look a little different based on your own configuration.
  2636. 2:01:48Even the color scheme I'm using might ultimately look different from yours,
  2637. 2:01:51because it supports a nice colorful theme.
  2638. 2:01:52So you can have different colors and brightnesses depending
  2639. 2:01:56on your mood or the time of day.
  2640. 2:01:58What I've opened here, though, is what is called in VS Code Explorer,
  2641. 2:02:01and this is just all of the files in my cloud account.
  2642. 2:02:04And there's not many right now.
  2643. 2:02:05There's only two.
  2644. 2:02:06One is the file called hello.c, and it's highlighted
  2645. 2:02:09because I've got it open right there.
  2646. 2:02:10And the other is a file called "hello," which is brand new
  2647. 2:02:14and was created when I ran that command.
  2648. 2:02:17And what's now worth noting is that now things are getting a little more
  2649. 2:02:21like Mac OS and Windows.
  2650. 2:02:22Like on the left-hand side, you have a GUI, a Graphical User Interface.
  2651. 2:02:26But on the bottom here, again, you have a CLI, Command Line Interface.
  2652. 2:02:30These are just different ways to interact with computers,
  2653. 2:02:32and you'll get comfortable with both.
  2654. 2:02:34And honestly, you're certainly familiar and comfortable with GUIs already,
  2655. 2:02:37so it's the command line one with which we'll spend some time.
  2656. 2:02:40Now suppose that I just wanted to do something
  2657. 2:02:43more than compile this program.
  2658. 2:02:45Suppose I wanted to go ahead and remove it.
  2659. 2:02:47Like, uh-uh, no, I made a mistake.
  2660. 2:02:48I want to say, "Hello, CS50," not "Hello, world."
  2661. 2:02:51I could just hover up here, like in any software, and I could right-click,
  2662. 2:02:55and I could poke around, and there, delete permanently.
  2663. 2:02:57So most of us might have that instinct on a Mac or PC.
  2664. 2:03:00You right-click or Control-click, and you poke around.
  2665. 2:03:02But in a command line interface, let me do this instead.
  2666. 2:03:05The command for removing or deleting a file
  2667. 2:03:08in the world of Linux, this other operating system,
  2668. 2:03:12is just a type rm for remove, and then "hello," Enter.
  2669. 2:03:16It's a somewhat cryptic confirmation message, but this just means,
  2670. 2:03:19are you sure?
  2671. 2:03:19I'm going to go ahead and type Y for Yes.
  2672. 2:03:21And now when I hit Enter, watch what happens
  2673. 2:03:24at top left in the Explorer, the GUI, the graphical interface.
  2674. 2:03:28Voila, it disappears.
  2675. 2:03:30Not terribly exciting, but this just means
  2676. 2:03:32this is a graphical version of what we're seeing here.
  2677. 2:03:35And in fact, if you want to never use the GUI again--
  2678. 2:03:38I'll go ahead and close it with a keyboard shortcut here--
  2679. 2:03:41you can forever just type ls for list and hit Enter.
  2680. 2:03:45And you will see in the command line interface
  2681. 2:03:48all of the files in your current folder.
  2682. 2:03:50So anything you can do with a mouse, you can
  2683. 2:03:52do with this command line interface.
  2684. 2:03:54And indeed, we'll see many more things that you can do as well.
  2685. 2:03:57But the inventors of this, this operating system and its predecessors,
  2686. 2:04:01were very succinct.
  2687. 2:04:02Like, the command is rm for remove.
  2688. 2:04:04The command is ls for list.
  2689. 2:04:06It's very terse.
  2690. 2:04:06Why?
  2691. 2:04:07Because it's just faster to type.
  2692. 2:04:10So before we forge ahead with making something more interesting than
  2693. 2:04:14just "Hello, world," let me pause here to see
  2694. 2:04:16if there's questions on source code or machine
  2695. 2:04:19code or compiler or this command line interface.
  2696. 2:04:24Yeah?
  2697. 2:04:25AUDIENCE: [INAUDIBLE].
  2698. 2:04:26DAVID J. MALAN: Really good question, and let me recap.
  2699. 2:04:28If I were to make changes to the program,
  2700. 2:04:30run it, and then maybe make other changes and try to rerun it,
  2701. 2:04:33would those changes be reflected, even though I've reworded slightly.
  2702. 2:04:37Well, let's do this.
  2703. 2:04:37I already removed the old version.
  2704. 2:04:39So let me go ahead and point out that if I do ./hello now,
  2705. 2:04:43I'm going to see some kind of error because I just deleted the file.
  2706. 2:04:47No such file or directory, so it's not terribly user friendly,
  2707. 2:04:50but it's saying what the problem is.
  2708. 2:04:51Let me go ahead and remake it by typing make hello.
  2709. 2:04:55Now if I type ls, I'll see not one but two files again, and one of them
  2710. 2:04:59is even green with a little asterisk to indicate that it's executable.
  2711. 2:05:03It's sort of the textual version of something
  2712. 2:05:05you could double-click in our human world.
  2713. 2:05:07So now, of course, if I run hello, we're back where I started, "Hello, world."
  2714. 2:05:10But now suppose I change it to "Hello, CS50," like I did years ago.
  2715. 2:05:15Let me go ahead and save the file with Command-S or Control-S. Down here now,
  2716. 2:05:21let me run ./hello again, and voila.
  2717. 2:05:23Huh.
  2718. 2:05:25So let me ask someone else to answer that question.
  2719. 2:05:27What's the missing step?
  2720. 2:05:29Why did it not say, "Hello, CS50."
  2721. 2:05:31Yeah?
  2722. 2:05:32AUDIENCE: [INAUDIBLE].
  2723. 2:05:33DAVID J. MALAN: Yeah, so I didn't compile it again.
  2724. 2:05:35So sort of newbie mistake, you're going to make this mistake and many others
  2725. 2:05:38before long.
  2726. 2:05:38But now let me go ahead and remake hello, enter.
  2727. 2:05:42It's going to seemingly make the same program.
  2728. 2:05:45But this time when I run it, it's, "Hello, CS50."
  2729. 2:05:49Any other questions on some of these building blocks?
  2730. 2:05:53And we'll come back to all the crazy syntax I typed before long.
  2731. 2:05:56But for now, we're focusing on just the output.
  2732. 2:05:58Yeah?
  2733. 2:05:59AUDIENCE: [INAUDIBLE].
  2734. 2:06:00DAVID J. MALAN: When I keep running make,
  2735. 2:06:02it creates a new version of the machine code.
  2736. 2:06:05So it keeps changing the hello program and the hello file, and that's it.
  2737. 2:06:09There's no make file, per se.
  2738. 2:06:12AUDIENCE: [INAUDIBLE].
  2739. 2:06:13DAVID J. MALAN: Good question, no.
  2740. 2:06:15If I open up that directory, you'll see that there's just the one.
  2741. 2:06:18And it doesn't matter how many times I run make hello--
  2742. 2:06:21three, four, five-- it just keeps overwriting the original.
  2743. 2:06:25So it's kind of like just saving in the world of Google Docs or Microsoft
  2744. 2:06:28Word or the like.
  2745. 2:06:29But there's an additional step today.
  2746. 2:06:31We have to then convert my words to the computer's, the zeros and ones.
  2747. 2:06:36Yeah, in front.
  2748. 2:06:37AUDIENCE: [INAUDIBLE].
  2749. 2:06:38DAVID J. MALAN: Oh, what happens if I run hello.c?
  2750. 2:06:40So let me go ahead and do ./hello.c, which is a mistake you'll invariably
  2751. 2:06:45make early on.
  2752. 2:06:46Permission denied.
  2753. 2:06:47So what does that mean?
  2754. 2:06:48This is where the error messages mean something
  2755. 2:06:50to the people who designed the operating system, but it's a little cryptic.
  2756. 2:06:53It's not that you don't have access to the file.
  2757. 2:06:55It means that it's not executable.
  2758. 2:06:57This is not something you have permission to run,
  2759. 2:07:00but you do have permission to read or write it-- that is, change it.
  2760. 2:07:04AUDIENCE: [INAUDIBLE].
  2761. 2:07:06DAVID J. MALAN: Oh, really good question.
  2762. 2:07:08So if I have named my file, hello dot C, or more generally something
  2763. 2:07:11dot C, of the things that Make does is it automatically
  2764. 2:07:15picks the file name for me.
  2765. 2:07:17And we'll discuss a bit--
  2766. 2:07:18we'll discuss this a bit more next week.
  2767. 2:07:20Make itself-- is kind of the first of white lies today--
  2768. 2:07:23itself is not a compiler.
  2769. 2:07:25It's a program that knows how to find and use the compiler on the system
  2770. 2:07:30and automatically create the program.
  2771. 2:07:33If I use, as we'll discuss next week, the actual compiler myself,
  2772. 2:07:37I have to type a much longer sequence of commands to specify explicitly
  2773. 2:07:41what do I want the name of my program to be.
  2774. 2:07:43Make is a nice program, especially in week 1,
  2775. 2:07:45because it just automates all of that for us.
  2776. 2:07:47And so here, we have now a program that very simply prints
  2777. 2:07:51something on the screen.
  2778. 2:07:52So let's not put this into the context of where
  2779. 2:07:54we left off last time in the context of Scratch and inputs and outputs.
  2780. 2:07:58So we discuss the last time, of course, functions and arguments.
  2781. 2:08:01Functions, again, are those actions and verbs like say, or ask, or the like.
  2782. 2:08:07And the arguments were the inputs to those functions,
  2783. 2:08:09generally in those little white ovals that, in Scratch, you
  2784. 2:08:11could type words or numbers into.
  2785. 2:08:13We'll see, in all of the languages we're going to see this term,
  2786. 2:08:16have that same capability.
  2787. 2:08:18And let's just start to translate one of these things to another.
  2788. 2:08:20So for instance, let's put this same program in C,
  2789. 2:08:24in the context of Scratch.
  2790. 2:08:26This is what Hello, World looked like last week in the form of one function.
  2791. 2:08:29This week, of course, it looks like print.
  2792. 2:08:32And then the parentheses, notice, are kind of
  2793. 2:08:34deliberately designed in the world of Scratch to resemble that same shape.
  2794. 2:08:38Even though this is a white oval, you kind of get
  2795. 2:08:40that it's kind of evoking that same idea with the parentheses.
  2796. 2:08:45Technically the function in C, it's not called say.
  2797. 2:08:49It's not even called print.
  2798. 2:08:50It's called printf.
  2799. 2:08:51The F stands for formatted, but we'll see what that means in a moment.
  2800. 2:08:55But printf is the closest analogous function
  2801. 2:08:57for say in the world of C. Notice if, though, you
  2802. 2:09:00want to print something like Hello, World or Hello CS50 in C,
  2803. 2:09:05you don't just write the words as we did last week.
  2804. 2:09:08You also had an add what, if you notice already
  2805. 2:09:11what's missing from this version.
  2806. 2:09:13Yeah, so the double quotes on the left and the right.
  2807. 2:09:15So, that's necessary in C whenever you have a string of words.
  2808. 2:09:21And I'm using that word deliberately.
  2809. 2:09:22Whenever you have multiple words like this, this is known as a string
  2810. 2:09:26as we'll see.
  2811. 2:09:27And you have to put it in double quotes, not single quotes.
  2812. 2:09:30You have to put it in double quotes.
  2813. 2:09:32There's one other stupid thing that we need to have in my C code
  2814. 2:09:36in order to get this function to do something ultimately, which is what?
  2815. 2:09:40Semicolon.
  2816. 2:09:41So just like in our human world, you eventually
  2817. 2:09:44got into the habit of using, at least in formal writing, periods.
  2818. 2:09:47Semicolon is generally what you use to finish your thought
  2819. 2:09:50in the world of programming with C.
  2820. 2:09:53All right, so we have that function in place.
  2821. 2:09:55Now, what does this really fit into in terms of the mental model?
  2822. 2:09:59Well, functions take arguments.
  2823. 2:10:01And it turns out functions can have different types of outputs.
  2824. 2:10:04And we've actually seen both already last week.
  2825. 2:10:07One type of output from a function can be something called a side effect.
  2826. 2:10:11And it generally refers to something visual,
  2827. 2:10:13like something appearing on the screen or a sound playing from your computer.
  2828. 2:10:17It's sort of a side effect of the function doing its thing.
  2829. 2:10:20And indeed, last week we saw this in the context of passing in something
  2830. 2:10:24like Hello, World as input to the say function.
  2831. 2:10:27And we saw on the screen Hello, World, but it was kind of a one off.
  2832. 2:10:31It's one and done.
  2833. 2:10:32You can't actually do anything with that visual output
  2834. 2:10:35other than consume it, visually, with your human eyes.
  2835. 2:10:38But sometimes, recall last week, we had functions like the ask block that
  2836. 2:10:43actually returned me some value.
  2837. 2:10:44Remember the ask, what's your name.
  2838. 2:10:47It handed me back whatever answer the human typed in.
  2839. 2:10:50It didn't just arbitrarily display it on the screen.
  2840. 2:10:52The cat didn't necessarily say it on the screen.
  2841. 2:10:55It was stored, instead, in that special variable that was called answer.
  2842. 2:11:01Because some functions have not side effects but return values.
  2843. 2:11:05They hand you back an output that you can use and reuse,
  2844. 2:11:09unlike the side effect, which, again displays and that's it.
  2845. 2:11:11You can't sort of catch it and hold on to it.
  2846. 2:11:14So, in the context of last week, we had the ask block.
  2847. 2:11:17And that had this special answer return value.
  2848. 2:11:20In C, we're going to see in just a moment,
  2849. 2:11:22we could translate this as follows.
  2850. 2:11:25The closest match I can propose for the ask block
  2851. 2:11:29is a function that we're going to start calling get string.
  2852. 2:11:31String is, again, a word, a set of words, like a phrase
  2853. 2:11:34or a sentence in programming.
  2854. 2:11:36It, too, is a function insofar as it takes input and pretty much--
  2855. 2:11:41this isn't always true-- but very often when
  2856. 2:11:43you have a word in C followed by an open parenthesis and a closed parenthesis,
  2857. 2:11:48it's most likely the name of a function.
  2858. 2:11:50And we're going to see that there's some exceptions to that.
  2859. 2:11:53But for now this indeed looks like a function
  2860. 2:11:55because it matches that pattern.
  2861. 2:11:57If I want to ask the question, what's your name, question mark--
  2862. 2:12:00and I'm even going to deliberately put a space there just to kind of move
  2863. 2:12:03the cursor a little bit over so that the human isn't typing literally
  2864. 2:12:07after the question mark.
  2865. 2:12:08So that's just the nitpicky aesthetic.
  2866. 2:12:10This is perhaps the closest analog to just asking that question.
  2867. 2:12:14But because the ask block returns a value,
  2868. 2:12:18the analog here forget string is that it, too, returns a value.
  2869. 2:12:22It doesn't just print the human's input.
  2870. 2:12:23It hands it back to you in the form of a variable, a.k.a. return value,
  2871. 2:12:28that I can then use and reuse.
  2872. 2:12:30Now ideally it would be as simple as this literally
  2873. 2:12:33saying answer on the left equals.
  2874. 2:12:36And this is where things start to diverge
  2875. 2:12:38from math and sort of our human world.
  2876. 2:12:40This equal sign, henceforth, is not the equal sign.
  2877. 2:12:44It is the assignment operator.
  2878. 2:12:46To assign a value means to store a value in some variable.
  2879. 2:12:50And you read these things, weirdly, right to left.
  2880. 2:12:53So here is a function called get string.
  2881. 2:12:55I claim that it's going to return to you whatever
  2882. 2:12:58the human types in as their name.
  2883. 2:13:00It's going to get stored over here on the left because
  2884. 2:13:03of this so-called assignment operator, that yes is an equal sign.
  2885. 2:13:06But it doesn't mean equality in this context.
  2886. 2:13:08It makes things equal.
  2887. 2:13:10But it does so by copying the value on the right into the thing on the left.
  2888. 2:13:14Unfortunately, we're not quite done yet with C.
  2889. 2:13:16And this is where, again, it gets a little annoying at first
  2890. 2:13:19where Scratch just let us express our ideas without so much syntax.
  2891. 2:13:23In C when you have a variable you don't just
  2892. 2:13:27give it a name like you did in Scratch.
  2893. 2:13:29You also have to tell the computer in advance what type of value
  2894. 2:13:33it is storing.
  2895. 2:13:34String is one such type of value.
  2896. 2:13:37Int, for integer, is going to be another.
  2897. 2:13:40And there's even more than that we'll see today and beyond.
  2898. 2:13:42And this is partly an answer to the question that came up one or more times
  2899. 2:13:46last week, which was how does a computer distinguish this pattern of zeros
  2900. 2:13:49and ones from this.
  2901. 2:13:51Like is this a letter, a number, a color, a piece of video.
  2902. 2:13:55And I just claimed last week that it totally depends on the program.
  2903. 2:13:58It depends on the context.
  2904. 2:13:59And that's true.
  2905. 2:14:00But within those programs, it often depends
  2906. 2:14:04on what the human programmer said the type of the value is.
  2907. 2:14:08If this specifies that the string, which means
  2908. 2:14:10interpret the following zeros and ones that
  2909. 2:14:12are stored in my program as words or letters, more generally.
  2910. 2:14:16If it's an int for integer, it would be implying, by the programmer,
  2911. 2:14:20treat the following zeros and ones in my program as a number,
  2912. 2:14:24an integer, not a string.
  2913. 2:14:26So here's where this week, unlike with Scratch,
  2914. 2:14:29which is kind of figures out what you mean, with C in a lot of languages
  2915. 2:14:33you have to be this pedantic and tell it what you mean.
  2916. 2:14:36There's still one stupid thing missing from my code here.
  2917. 2:14:39What's still missing here?
  2918. 2:14:40Yeah.
  2919. 2:14:41AUDIENCE: [INAUDIBLE]
  2920. 2:14:42DAVID J. MALAN: And we still need the stupid semicolon.
  2921. 2:14:44And I'm sort of impugning it here.
  2922. 2:14:45Because honestly, these are the kinds of stupid mistakes
  2923. 2:14:48you're going to make today, tomorrow, this weekend, next week,
  2924. 2:14:50a few weeks from now, until you start to notice this and recognize it
  2925. 2:14:54as well as you do English or whatever your spoken language is.
  2926. 2:14:58Yeah, question.
  2927. 2:14:59Good question.
  2928. 2:15:00Suppose I mix apples and oranges, so to speak,
  2929. 2:15:03and I try to put a string in an int or an int in a string,
  2930. 2:15:06the compiler is going to complain.
  2931. 2:15:08So when I run that make command as I did earlier,
  2932. 2:15:10it's not going to be nice and blissfully quiet and just give me another prompt.
  2933. 2:15:14It's going to yell at me with honestly a very cryptic
  2934. 2:15:17looking error message until we get the muscle memory for reading it.
  2935. 2:15:20Other questions.
  2936. 2:15:23Ah, what happened to the backslash n.
  2937. 2:15:24So, we'll come back to that in just a moment, if we may.
  2938. 2:15:26Because I have deliberately omitted it here but we did have it earlier.
  2939. 2:15:29And we'll see the different behavior in a sec.
  2940. 2:15:32Other questions.
  2941. 2:15:36Yeah, not at all nitpicky.
  2942. 2:15:37These are the kinds of things that just matter.
  2943. 2:15:39And it's going to take time to recognize and develop this muscle memory.
  2944. 2:15:43Everything I've typed here except, for the W at the moment, is lowercase.
  2945. 2:15:48And the W is capitalized just because it's English.
  2946. 2:15:50Everything else is lowercase.
  2947. 2:15:51And this kind of varies by language and also context.
  2948. 2:15:54So, in many languages the convention is to use all lowercase letters
  2949. 2:15:58for your variable names.
  2950. 2:16:00Other languages might use some capitals, as well.
  2951. 2:16:02But we'll talk about that before long.
  2952. 2:16:04But this is the kind of thing that matters
  2953. 2:16:05and is hard to see at first, especially when a little S doesn't look that
  2954. 2:16:09different when it's on your tiny laptop screen from a capital S.
  2955. 2:16:12But you'll start to develop these instincts.
  2956. 2:16:15All right, so besides this particular block,
  2957. 2:16:18let's go ahead and consider how we can go about implementing this now in code.
  2958. 2:16:22So let me switch back to VS Code here.
  2959. 2:16:24This was the program I had earlier.
  2960. 2:16:26And let me go ahead and undo my CS50 change.
  2961. 2:16:28And this time just rerun it.
  2962. 2:16:30Rerun Make on Hello with the original version with the backslash n.
  2963. 2:16:35Enter, nothing bad seems to have happened.
  2964. 2:16:37So dot slash Hello, enter Hello, World.
  2965. 2:16:40Now, if you're curious, this is a good instinct
  2966. 2:16:43to start to acquire what happens if I get rid of this.
  2967. 2:16:45Well, I'm probably not going to break things too badly.
  2968. 2:16:47So let's try.
  2969. 2:16:48Let me go ahead now and do Make Hello.
  2970. 2:16:51Still compile.
  2971. 2:16:52So it's not a really bad mistake.
  2972. 2:16:53So let me go ahead and run dot slash Hello.
  2973. 2:16:56What's the difference here?
  2974. 2:16:58Yeah, what do you see that's different?
  2975. 2:17:01Yeah, the dollar sign, my so-called prompt, stayed on the same line.
  2976. 2:17:05Why?
  2977. 2:17:05Well, we can presumably infer now that the backslash
  2978. 2:17:08n is some fancy notation for saying create a new line,
  2979. 2:17:12move the cursor, so to speak, to the next line.
  2980. 2:17:14Notice that the cursor will move to the next line in my terminal window.
  2981. 2:17:18If I keep hitting it, it just automatically,
  2982. 2:17:20by nature of hitting enter, does it.
  2983. 2:17:22But it'd be kind of stupid if when you run a program in this world,
  2984. 2:17:25simple as it is, if the next command is now
  2985. 2:17:28weirdly spaced in the middle of the terminal with the dollar sign,
  2986. 2:17:31it just looks sloppy.
  2987. 2:17:33It's really just an aesthetic argument.
  2988. 2:17:35And notice that it's not acceptable or correct to do this, to hit enter there.
  2989. 2:17:40Let me go ahead and save that, though, and see what happens.
  2990. 2:17:43Let me go ahead now and run Make Hello enter.
  2991. 2:17:47Oh my god, like four errors.
  2992. 2:17:49This is like, what, 10 lines of errors for a one line program.
  2993. 2:17:53And this is where, again, you'll start to develop the instincts for just
  2994. 2:17:56reading this stuff.
  2995. 2:17:57These kinds of tools, like the compiler tool we're using,
  2996. 2:18:00were not designed necessarily with user friendliness in mind.
  2997. 2:18:03That's changed over the decades, but certainly early
  2998. 2:18:06on it's really just meant to be correct and precise with its errors.
  2999. 2:18:09So what did I do here?
  3000. 2:18:11Missing terminating close quote character,
  3001. 2:18:13long story short, when you have a string in C,
  3002. 2:18:17your double quotes just have to be on the same line just because.
  3003. 2:18:20Now, there's the slight white lie.
  3004. 2:18:22There's ways around this.
  3005. 2:18:23But the best way around it is to use this so-called escape sequence.
  3006. 2:18:29To escape something means generally to put a backslash, and then
  3007. 2:18:32a special symbol like n for new line.
  3008. 2:18:34And this is just the agreed upon way that humans, decades ago, decided,
  3009. 2:18:39OK you don't just hit your enter key.
  3010. 2:18:42You instead put backslash n and that tells the computer
  3011. 2:18:46to move the cursor to the new line.
  3012. 2:18:49So again, kind of cryptic.
  3013. 2:18:50But once you know it, that's it.
  3014. 2:18:52It's just another word in our vocabulary.
  3015. 2:18:55So now let me transition to making my program a little more interactive.
  3016. 2:18:58Instead of just saying Hello, world, let me
  3017. 2:19:00change it like last week to say Hello, David,
  3018. 2:19:02or whoever is interacting with the program.
  3019. 2:19:04So I'm going to do string answer gets, get string,
  3020. 2:19:07quote unquote, what's your name.
  3021. 2:19:11I'm not going to bother with a new line here.
  3022. 2:19:13I could.
  3023. 2:19:13This is now just a judgment call.
  3024. 2:19:15I deliberately want the human to type their name on the same line
  3025. 2:19:17just because.
  3026. 2:19:18And how do I now print this?
  3027. 2:19:20Well last week recall we used say.
  3028. 2:19:22And then we use the other block called join.
  3029. 2:19:25So the idea here is the same.
  3030. 2:19:27But the syntax this week is going to be a little different.
  3031. 2:19:30It's going to be printf, which prints something on the screen.
  3032. 2:19:33I'm going to go ahead and say Hello comma.
  3033. 2:19:38And let me just go with this initially with the backslash n, semicolon.
  3034. 2:19:43Let me go ahead and recompile my code.
  3035. 2:19:46Whoops, damn doesn't work still.
  3036. 2:19:50And look at all these errors.
  3037. 2:19:51There's more errors than code I wrote.
  3038. 2:19:54But what's going on here?
  3039. 2:19:56Well, this is actually something, a mistake you'll see,
  3040. 2:19:58somewhat often, at least initially.
  3041. 2:20:01And let's start to glean what's going on here.
  3042. 2:20:03So here, if I look at the very first line of output after the dollar sign--
  3043. 2:20:06so even though it jumped down the screen pretty fast,
  3044. 2:20:09I wrote Make Hello at the dollar sign, prompt.
  3045. 2:20:12And then here's the first error.
  3046. 2:20:14On Hello dot C, line 5--
  3047. 2:20:17technically character 5, but generally line is enough to get you going--
  3048. 2:20:21there's an error, use of undeclared identifier string.
  3049. 2:20:24Did you mean standard in?
  3050. 2:20:27So, I didn't.
  3051. 2:20:28And this is not an obvious solution at first.
  3052. 2:20:30But you'll start to recognize these patterns in error messages.
  3053. 2:20:34It turns out that if I want to use string, I actually have to do this.
  3054. 2:20:39I have to include another library up here, another line of code,
  3055. 2:20:43rather, called CS50 dot H. We'll come back
  3056. 2:20:46to what this means in just a moment.
  3057. 2:20:48But if I now retroactively say, all right, what does standard I/O
  3058. 2:20:54do for us up here.
  3059. 2:20:55Before I added that new line, what is standard I/O doing?
  3060. 2:20:59Well, if you think back to Scratch, there
  3061. 2:21:01were a few examples with the camera and with the speech to-- the text to voice.
  3062. 2:21:07Remember I had to poke around in the extensions button.
  3063. 2:21:10And then I had to load it into Scratch.
  3064. 2:21:12It didn't come natively with Scratch.
  3065. 2:21:14C is quite like that.
  3066. 2:21:15Some functions come with the language.
  3067. 2:21:18But for the most part, if you want to use a function, an action or a verb
  3068. 2:21:22like printf, you have to load that extension, so to speak,
  3069. 2:21:26that more traditionally is called a library.
  3070. 2:21:29So there is a standard I/O library, STD I/O, standard I/O,
  3071. 2:21:35where I/O just means input and output.
  3072. 2:21:37Which means, just like in MIT's World, there
  3073. 2:21:39was an extension for doing text to voice or for using your camera.
  3074. 2:21:43In C, there's an extension, a.k.a.
  3075. 2:21:45a library, for doing standard input and output.
  3076. 2:21:49And so if you want to use any functions related to standard input and output,
  3077. 2:21:53like text from a keyboard, you have to include standard I/O dot
  3078. 2:21:58H. And then can you use printf.
  3079. 2:22:02Same goes here.
  3080. 2:22:03Get string, it turns out, is a function that CS50 wrote some time ago.
  3081. 2:22:08And as we'll see over the coming weeks, it just
  3082. 2:22:10makes it way easier to get input from a user.
  3083. 2:22:14C is very good with printf at printing output on the screen.
  3084. 2:22:18C makes it really annoying and hard, as we'll see in a few weeks,
  3085. 2:22:21to just get input from the user.
  3086. 2:22:23So we wrote a function called get_string,
  3087. 2:22:25but the only way you can use that is to load the extension,
  3088. 2:22:29a.k.a. load the library called CS50.
  3089. 2:22:32And we'll come back in time, like, why is it .h, why is it a hash symbol.
  3090. 2:22:35But for now, standard I/O is a library that
  3091. 2:22:39gives you access to printf and input- and output-related stuff.
  3092. 2:22:42CS50 is a second library that provides you
  3093. 2:22:45with access to functions that don't come with C
  3094. 2:22:48that include something like get_string.
  3095. 2:22:51So with that said, we've now kind of teased apart
  3096. 2:22:55at a high level what lines 2 and now 1 are doing.
  3097. 2:22:58Let me go ahead and rerun make hello.
  3098. 2:23:00Now it worked.
  3099. 2:23:01So all those crazy error messages were resolved by just one fix,
  3100. 2:23:05so key takeaway is not to get overwhelmed by the sheer number
  3101. 2:23:07of errors.
  3102. 2:23:08Let me now do ./hello and if I type in my name, what am I going to say?
  3103. 2:23:16What do you think?
  3104. 2:23:19Yeah, hello answer, because the computer is going to take me literally.
  3105. 2:23:24And it turns out that if you just write "hello,
  3106. 2:23:26answer" all in the double quotes, you're really just passing
  3107. 2:23:29English as the input to the printf function,
  3108. 2:23:32you're not actually passing in the variable.
  3109. 2:23:34And unfortunately in C, it's not quite as
  3110. 2:23:37easy to plug things in to other things that you've typed.
  3111. 2:23:40Remember in Scratch, there was not just the Save block
  3112. 2:23:43but the Join block, which was kind of pretty,
  3113. 2:23:45you can combine apples and oranges--
  3114. 2:23:47or was it apple and banana?
  3115. 2:23:48Then we changed it to hello and then the answer that the human typed in.
  3116. 2:23:52In C, the syntax is going to be a little different.
  3117. 2:23:54You tell the computer inside of your double quotes that you want to have
  3118. 2:23:59a placeholder there, a so-called format code. %s means, hey, computer,
  3119. 2:24:05put a string here eventually.
  3120. 2:24:08Then outside of your quotes, you just add a comma and then you type
  3121. 2:24:12in whatever variable you want the computer to plug in at that %s location
  3122. 2:24:18for you.
  3123. 2:24:19So %s is a format code which serves as a placeholder.
  3124. 2:24:23And now the printf function was designed by humans years
  3125. 2:24:26ago to figure out how to do the apple and banana
  3126. 2:24:28thing of joining two words together.
  3127. 2:24:30It's not nearly as user-friendly as it is in Scratch,
  3128. 2:24:33but it's a very common paradigm.
  3129. 2:24:35So let me try and rerun this now. make hello.
  3130. 2:24:38No errors, that's good.
  3131. 2:24:40./hello.
  3132. 2:24:41What's my name, David?
  3133. 2:24:42If I type Enter now, now it's hello.
  3134. 2:24:45David.
  3135. 2:24:46And the printf, here's the F in printf.
  3136. 2:24:48It formats its input for you by using these placeholders for things like
  3137. 2:24:53strings, represented again by %s.
  3138. 2:24:58So a quick question then, if I focus here on line 7 for just a moment
  3139. 2:25:02and even zoom in here, how many inputs is printf taking as a function?
  3140. 2:25:09A moment ago, I'll admit that it was taking one input, "hello, world,"
  3141. 2:25:13quote unquote.
  3142. 2:25:14How many inputs might you infer printf is taking now?
  3143. 2:25:192.
  3144. 2:25:20And it's implied by this comma here, which is separating the first one,
  3145. 2:25:25quote, unquote, "hello, %s" from the second one, answer.
  3146. 2:25:29And then just as a quick safety check here, why is it not 3?
  3147. 2:25:32Because there's obviously two commas here.
  3148. 2:25:35Why is it not actually 3 arguments or inputs?
  3149. 2:25:38AUDIENCE: [INAUDIBLE]
  3150. 2:25:42DAVID J. MALAN: Exactly.
  3151. 2:25:43The comma to the left is actually part of my English grammar,
  3152. 2:25:46that's all, so same syntax.
  3153. 2:25:47And, again, here's where programming can just be confusing
  3154. 2:25:50early on because we're using the same special punctuation to mean
  3155. 2:25:52different things, it just depends on the context.
  3156. 2:25:55And so now is actually a good time to point out
  3157. 2:25:57all of the somewhat pretty colors that have been popping up on the screen
  3158. 2:26:01here--
  3159. 2:26:02even though I wasn't going to a format menu, I wasn't boldfacing things,
  3160. 2:26:06I certainly wasn't changing things to red or blue or whatnot--
  3161. 2:26:08that's because a text editor like VS Code syntax highlights for you.
  3162. 2:26:13This is a feature of so many different programming environments nowadays,
  3163. 2:26:17VS Code does it as well.
  3164. 2:26:18If your text editor understands the language that you're programming in--
  3165. 2:26:23C, in this case--
  3166. 2:26:24it highlights in different colors the different types of ideas in your code.
  3167. 2:26:28So, for instance, string and answer here are in black,
  3168. 2:26:31but get_string a function is in this sort of nasty brown-yellow
  3169. 2:26:35here right now, but that's just how it displays on the screen.
  3170. 2:26:38The string, though, here in red is kind of jumping out at me,
  3171. 2:26:41and that's marginally useful.
  3172. 2:26:42The %s is in blue.
  3173. 2:26:44That's kind of nice, because it's jumping out at me.
  3174. 2:26:46And so it's just using different colors to make different things on the screen
  3175. 2:26:49pop so you can focus on how these ideas interrelate
  3176. 2:26:53and, honestly, when you might make a mistake.
  3177. 2:26:55For instance, let me accidentally leave off this quote here.
  3178. 2:26:58And now all of a sudden, notice if I delete the quote,
  3179. 2:27:03the colors start to get a little awry.
  3180. 2:27:05But if I go back there and put it back, now everything's back in place.
  3181. 2:27:09What's another feature of this text editor?
  3182. 2:27:11Notice when my cursor is next to this parenthesis, which
  3183. 2:27:15demarcates the end of the inputs to the function,
  3184. 2:27:18notice that highlighted in green here is the opening parenthesis.
  3185. 2:27:21Why?
  3186. 2:27:22It's just a visually useful thing, especially when
  3187. 2:27:24you start writing more and more code, just to make
  3188. 2:27:26sure your parentheses are lining up.
  3189. 2:27:28And that's true for these curly braces over here on the left and the right.
  3190. 2:27:31We'll come back to those in a moment.
  3191. 2:27:33If I put my cursor there, you can see that these things correspond
  3192. 2:27:36to one another.
  3193. 2:27:37So it's nothing in your code fundamentally, it's just the editor
  3194. 2:27:40trying to help you, the human, program.
  3195. 2:27:42And you can even see it, though it's a little subtle--
  3196. 2:27:45see these four dots here and these four dots here?
  3197. 2:27:48That's my indentation.
  3198. 2:27:49I configured VS Code to indent by four spaces, which
  3199. 2:27:53is a very common convention.
  3200. 2:27:54Any time I hit the Tab key, this too can help you make sure--
  3201. 2:27:58once we have more interesting and longer programs--
  3202. 2:28:00that everything lines up nice and neatly.
  3203. 2:28:04Phew.
  3204. 2:28:05All right, any questions then on printf or more?
  3205. 2:28:07Yeah.
  3206. 2:28:08AUDIENCE: [? Would ?] the printf [INAUDIBLE]??
  3207. 2:28:11DAVID J. MALAN: Short answer, yes. printf
  3208. 2:28:12can handle more than one type of variable or value.
  3209. 2:28:16%s is one.
  3210. 2:28:17We're going to see %i is another for plugging in an integer.
  3211. 2:28:20You can have multiple i's, multiple s's, and even other symbols too.
  3212. 2:28:24We'll come back to that in just a little bit.
  3213. 2:28:26printf can take many more arguments than just these two.
  3214. 2:28:29This is just meant to be representative.
  3215. 2:28:32Yeah, over here.
  3216. 2:28:34Can you declare variables within the printf?
  3217. 2:28:36No.
  3218. 2:28:37The only variable I'm using right now is answer,
  3219. 2:28:39and it's got to be done outside the context of printf in this case.
  3220. 2:28:43Good question, we'll see more of that before long.
  3221. 2:28:46Yeah, in back.
  3222. 2:28:47AUDIENCE: [INAUDIBLE]
  3223. 2:28:49DAVID J. MALAN: How do we download the CS50 library?
  3224. 2:28:51So we will show you in problems set 1 exactly how to do that.
  3225. 2:28:55It's automatically done for you in our version of VS Code in the cloud.
  3226. 2:28:58If, ultimately, you program on your own Mac or PC, either initially or later
  3227. 2:29:01on, it's also installable online.
  3228. 2:29:03But if you want to ask that via online or afterward,
  3229. 2:29:07we can point you in the right direction.
  3230. 2:29:08But PSet 1 will itself.
  3231. 2:29:10Yeah.
  3232. 2:29:11AUDIENCE: [INAUDIBLE]
  3233. 2:29:13DAVID J. MALAN: String is the type of the variable or, more properly,
  3234. 2:29:16the data type of the variable.
  3235. 2:29:19int is another keyword I alluded to earlier, I haven't used it yet.
  3236. 2:29:22int, for integer, is going to be another type, or data type, of variable.
  3237. 2:29:26AUDIENCE: OK. [? Thank you. ?]
  3238. 2:29:27DAVID J. MALAN: Yeah.
  3239. 2:29:28AUDIENCE: [INAUDIBLE]
  3240. 2:29:29DAVID J. MALAN: Oh, good question.
  3241. 2:29:31Could I go ahead and just plug in this function,
  3242. 2:29:34kind of like we did in Scratch, getting rid of the variable altogether
  3243. 2:29:39and just do this, which recall, is reminiscent of what
  3244. 2:29:42I did in Scratch by plopping block on top of block on block?
  3245. 2:29:45Am I answering that right?
  3246. 2:29:48Can I put string in front of get_string?
  3247. 2:29:50No.
  3248. 2:29:50You only put the word string in front of a variable
  3249. 2:29:53that you want to make string.
  3250. 2:29:55And even though I'm apparently answering the wrong question,
  3251. 2:29:57let me go ahead and zoom out, save this, do make hello again.
  3252. 2:30:01Seems to compile OK.
  3253. 2:30:03If I run ./hello, type in David, voila.
  3254. 2:30:06That, too, works.
  3255. 2:30:07And so, actually, let's go down this rabbit hole for just a moment.
  3256. 2:30:10Clearly, it's still correct--
  3257. 2:30:12at least, based on my limited testing.
  3258. 2:30:14Is this better designed or worse designed?
  3259. 2:30:18Let's open that question like we did last week.
  3260. 2:30:20Yeah?
  3261. 2:30:21Yeah, I kind of agree with that.
  3262. 2:30:23Reasonable people could disagree, but I do
  3263. 2:30:26agree that this seems harder to read because I start reading here,
  3264. 2:30:29but wait a minute. get_string is going to get used first,
  3265. 2:30:32and then it's going to give me back a value.
  3266. 2:30:34So, yeah, it just feels like it was nicer to read top to bottom,
  3267. 2:30:37I would say.
  3268. 2:30:38Your thoughts?
  3269. 2:30:38AUDIENCE: [INAUDIBLE]
  3270. 2:30:39DAVID J. MALAN: Yeah.
  3271. 2:30:40And so this is useful if I only want to print out the person's name once.
  3272. 2:30:44If I want to use it later in a longer program, I'm out of luck,
  3273. 2:30:47and so I haven't saved it in a variable.
  3274. 2:30:49So I think, long story short, we could debate this all day long.
  3275. 2:30:53But in this case, eh, if you can make a reasonable argument one
  3276. 2:30:56way or the other, that's a pretty solid ground to stand on.
  3277. 2:30:59But, invariably, reasonable people are going
  3278. 2:31:01to disagree, whether first-time programmers or many years after that.
  3279. 2:31:05So let's frame this one last example in the context of the same process
  3280. 2:31:09of taking inputs and outputs.
  3281. 2:31:11The functions we've been talking about all
  3282. 2:31:13take inputs, otherwise now known as arguments, or parameters, pretty much
  3283. 2:31:17synonymous.
  3284. 2:31:18That's just the fancy word for an input to a function.
  3285. 2:31:21And some functions have either side effects, like we saw--
  3286. 2:31:25printing something, saying something on the screen,
  3287. 2:31:27sort of visually or audibly--
  3288. 2:31:28or they return a value, which is a reusable value, like name or answer,
  3289. 2:31:33in this case.
  3290. 2:31:35If we look then at what we did last time in the world of Scratch last week,
  3291. 2:31:39the input was what's your name, the function was ask,
  3292. 2:31:41and the return value was answer.
  3293. 2:31:44And now let's take a look at this block, which is honestly a more user-friendly
  3294. 2:31:49version of what we just did with the %s.
  3295. 2:31:51Last week we said save, then join, then hello and answer.
  3296. 2:31:54But the interesting takeaway there was not how to say hello anything.
  3297. 2:31:58It was the fact that in Scratch 2, the output of one function,
  3298. 2:32:03like the green join, could become the input to another function,
  3299. 2:32:08the purple say.
  3300. 2:32:09The syntax in C is admittedly pretty different,
  3301. 2:32:12but the idea is essentially the same.
  3302. 2:32:14Here, though, we have hello, a placeholder,
  3303. 2:32:18but we have to, in this world of C, tell printf
  3304. 2:32:21what we want to plug in for that placeholder.
  3305. 2:32:25It's just different.
  3306. 2:32:25But that's the way to do it.
  3307. 2:32:27When we get to Python and other languages later in the term,
  3308. 2:32:29there's actually easier ways to do this.
  3309. 2:32:31But this is a very common paradigm, particularly when
  3310. 2:32:34you want to format your data in some way.
  3311. 2:32:37All right, let's then take a step back to where we began,
  3312. 2:32:40which was with that whole program, which had the include
  3313. 2:32:43and it had int main(void) and all of this other cryptic syntax.
  3314. 2:32:47This Scratch piece last week was kind of like the go-to
  3315. 2:32:51whenever you want to have a main part of your program.
  3316. 2:32:53It's not the only way to start a Scratch program.
  3317. 2:32:55You could listen for clicks or other things, not just the green flag.
  3318. 2:32:59But this was probably the most popular place to start a program in Scratch.
  3319. 2:33:03In C, the closest analog is to literally write this out.
  3320. 2:33:07So just like last week, if you were in the habit of dragging and dropping
  3321. 2:33:10when green flag clicked, as a C programmer,
  3322. 2:33:13the first thing you would do is after creating an empty file,
  3323. 2:33:15like I did with hello.c, you'd probably type int
  3324. 2:33:18main(void) open curly brace, closed curly brace,
  3325. 2:33:22and then you can put all of your code inside of those curly braces.
  3326. 2:33:26So just like Scratch had this sort of magnetic nature
  3327. 2:33:29to it where the puzzle pieces would snap together, C, as a text-based language,
  3328. 2:33:33tends to use these curly braces, one of them opened, the other one closed.
  3329. 2:33:38And anything inside of those braces, so to speak,
  3330. 2:33:41is part of this puzzle piece, a.k.a.
  3331. 2:33:44main.
  3332. 2:33:45So what was atop them?
  3333. 2:33:47We went down this rabbit hole moment ago with these things called header files,
  3334. 2:33:50even though I didn't call them by this name.
  3335. 2:33:52But, indeed, when we have a whole program in Scratch, super easy.
  3336. 2:33:56Just have the one green flag clicked and then say hello, world.
  3337. 2:33:59There's no special syntax.
  3338. 2:34:00After all, it's meant to be very user-friendly and graphical.
  3339. 2:34:03In C, though, you technically can't just put int main(void) printf hello, world.
  3340. 2:34:09You also need this.
  3341. 2:34:10Because, again, you need to tell the compiler to load the library--
  3342. 2:34:16code that someone else wrote-- so that the compiler knows what printf even is.
  3343. 2:34:22You have to load the CS50 library whenever
  3344. 2:34:24you want to use get_string or other functions, like get_int,
  3345. 2:34:28as we'll soon see.
  3346. 2:34:29Otherwise, the compiler won't know what get_string is.
  3347. 2:34:32You just have to do it this way.
  3348. 2:34:35The specific file name I'm mentioning here,
  3349. 2:34:37stdio.h, cs50.h, is what C programmers called a call a header file.
  3350. 2:34:44We'll see eventually what's inside of those files.
  3351. 2:34:46But long story short, it's like a menu of all of the available functions.
  3352. 2:34:51So in cs50.h, there's a menu mentioning get_string, get_int,
  3353. 2:34:54and a bunch of other stuff.
  3354. 2:34:56And in stdio.h, there's a menu of functions, among which are printf.
  3355. 2:35:01And that menu is what prepares the compiler
  3356. 2:35:04to know how to implement those same functions.
  3357. 2:35:08All right, let me pause here.
  3358. 2:35:10Question.
  3359. 2:35:11AUDIENCE: [INAUDIBLE]
  3360. 2:35:15DAVID J. MALAN: Not quite.
  3361. 2:35:16A library provides all of the functionality we're talking about.
  3362. 2:35:20A header file is the very specific mechanism via which you include it.
  3363. 2:35:25And we'll discuss this more next week.
  3364. 2:35:27For now, they're essentially the same, but we'll discuss
  3365. 2:35:30nuances between the two next week.
  3366. 2:35:32Yeah, the library would be standard I/O. The library would CS50.
  3367. 2:35:36The corresponding header file is stdio.h, cs50.h.
  3368. 2:35:41Indeed.
  3369. 2:35:42Other questions.
  3370. 2:35:42Yeah.
  3371. 2:35:43AUDIENCE: [INAUDIBLE]
  3372. 2:35:45DAVID J. MALAN: Indeed.
  3373. 2:35:46That, too, is on the menu.
  3374. 2:35:48We'll come back to that.
  3375. 2:35:49But the word string--
  3376. 2:35:50incredibly common in the world of programming, it's not a CS50 idea--
  3377. 2:35:54but in C, there's technically no such data type as string by default.
  3378. 2:35:59We have sort of conjured it up to simplify the first few weeks.
  3379. 2:36:02That's a training wheel that we'll very deliberately, in a few weeks,
  3380. 2:36:05take away, and we'll see why we've been using get_string and string.
  3381. 2:36:09Because C otherwise makes things quite more challenging early on,
  3382. 2:36:14which then gets besides the point for us.
  3383. 2:36:16Yeah.
  3384. 2:36:17AUDIENCE: [INAUDIBLE]
  3385. 2:36:19DAVID J. MALAN: Yes.
  3386. 2:36:20Early on, you will have to use whatever is prescribed by the specification.
  3387. 2:36:23That will include CS50's functions.
  3388. 2:36:24Long story short, you referred, I think, a moment ago to another function
  3389. 2:36:28called scanf, we won't talk about for a few weeks.
  3390. 2:36:30Long story short, in C, it's pretty easy and possible to get input from a user.
  3391. 2:36:36The catch is that it's really easy to do it dangerously.
  3392. 2:36:40And C, because it's an older, lower-level language, so to speak,
  3393. 2:36:45that gives you pretty much ultimate control over your computer's hardware.
  3394. 2:36:49It's very easy to make mistakes.
  3395. 2:36:51And, indeed, that's too why we use the library,
  3396. 2:36:55so your code won't crash unintendedly.
  3397. 2:36:58All right, so with this in mind, we have this now mapping
  3398. 2:37:01between the Scratch version and the other.
  3399. 2:37:03Let me just give you a quick tour of some of the other placeholders and data
  3400. 2:37:06types that students will start seeing as we assemble more interesting programs.
  3401. 2:37:10In the world of Linux, here is a non-exhaustive list
  3402. 2:37:13of commands with which you'll get familiar over the next few weeks
  3403. 2:37:16by playing with problem sets.
  3404. 2:37:18We've only seen two of these so far, ls for list, rm for others.
  3405. 2:37:22But I mention them now just so that it doesn't
  3406. 2:37:24feel too foreign when you see them on screen or online in a problem set.
  3407. 2:37:30cp is going to stand for copy.
  3408. 2:37:32mkdir is going to stand for make directory. mv is
  3409. 2:37:35going to stand for move or rename.
  3410. 2:37:38rmdir is going to be remove directory, and cd is going to be for change /
  3411. 2:37:44and let me show you this last one here first,
  3412. 2:37:46only because it's something you'll use so commonly.
  3413. 2:37:49If I go back to my code here on the screen, I'm going to go ahead
  3414. 2:37:53and re-open the little GUI on the left-hand side, the so-called Explorer,
  3415. 2:37:58revealing that I've got two files, hello and hello.c
  3416. 2:38:01so nothing has changed since there.
  3417. 2:38:02Suppose now that it's a few weeks into class
  3418. 2:38:05and I want to start organizing the code I'm
  3419. 2:38:07writing so that I have a folder for this week or next week,
  3420. 2:38:10or maybe a folder for problem set 1, problem set 2.
  3421. 2:38:13I can do this in a few ways.
  3422. 2:38:15In the GUI, I can go up here and do what most of you
  3423. 2:38:18would do instinctively on a Mac or PC.
  3424. 2:38:19You look for like a folder icon, you click it,
  3425. 2:38:22and then you name a folder like PSet1, Enter.
  3426. 2:38:25Voila, you've got a folder called PSet1.
  3427. 2:38:28I can confirm as much with my command line interface by typing what command?
  3428. 2:38:34How can I list what's in my folder?
  3429. 2:38:36Yeah, so ls for list.
  3430. 2:38:38And now I see hello--
  3431. 2:38:39and it's green with an asterisk because that's
  3432. 2:38:41my executable, my runnable program--
  3433. 2:38:43hello.c, which is my source code, and now PSet1 with a slash
  3434. 2:38:46at the end, which just implies that it's indeed a folder.
  3435. 2:38:50All right, I didn't really want to do it that way.
  3436. 2:38:52I'd like to do it more advanced.
  3437. 2:38:53So let me go ahead and right-click on PSet1, delete permanently.
  3438. 2:38:57I get a scary irreversible error message.
  3439. 2:38:59But there's nothing in it, so that's fine.
  3440. 2:39:01Now I've deleted it using the GUI.
  3441. 2:39:03But now let me go ahead and start doing the same thing from the command line.
  3442. 2:39:08And if you're wondering how things keep disappearing,
  3443. 2:39:11if you hit Control-L in your terminal window or explicitly type clear,
  3444. 2:39:15it will delete everything you previously typed just to clean things up.
  3445. 2:39:18In practice, you don't need to be doing this often.
  3446. 2:39:20I'm doing it just to keep our focus on my latest commands.
  3447. 2:39:23If I do-- what was the command to make a new directory?
  3448. 2:39:26AUDIENCE: [INAUDIBLE]
  3449. 2:39:28DAVID J. MALAN: Yeah, so mkdir, make directory.
  3450. 2:39:30Let me create PSet1, Enter.
  3451. 2:39:32And notice at left, there's my PSet1.
  3452. 2:39:34If I want to get a little overzealous, plan for next week,
  3453. 2:39:37here's my PSet2 directory.
  3454. 2:39:39Suppose now I want to open those folders on a Mac or PC or in this GUI,
  3455. 2:39:44I could double-click on it like this, and you'd
  3456. 2:39:46see this little arrow is moving.
  3457. 2:39:48It's not doing anything because there's nothing in there, but that's fine.
  3458. 2:39:51But suppose again I want to get more comfortable with my command line.
  3459. 2:39:55Notice if I type ls now, I see all four same things.
  3460. 2:39:59Let me change directories with cd space PSet1 Enter.
  3461. 2:40:05And now notice two things will have happened.
  3462. 2:40:08One, my prompt has changed slightly to remind me where I am,
  3463. 2:40:14just to keep me sane so that I don't forget what folder I'm actually in.
  3464. 2:40:17So here is just a visual reminder of what folder I'm currently in.
  3465. 2:40:21If I type ls now, what should I see after hitting Enter?
  3466. 2:40:26Nothing, because I've only created empty folders so far.
  3467. 2:40:29And, indeed, I see nothing.
  3468. 2:40:31If I wanted to create a folder called Mario for a program that might be
  3469. 2:40:35called Mario this week, I can do that.
  3470. 2:40:37Now if I type ls, there is Mario.
  3471. 2:40:40Now if I do cd Mario, notice my prompt's going
  3472. 2:40:42to change to be a little more precise.
  3473. 2:40:44Now I'm in PSet1/Mario.
  3474. 2:40:47And notice what's happening at top left.
  3475. 2:40:49Nothing now, because these folders are collapsed.
  3476. 2:40:51But if I click the little triangle, there I see Mario.
  3477. 2:40:54Nothing's going on in there because there's no files yet.
  3478. 2:40:56But suppose now I want to create a file called mario.c.
  3479. 2:41:00I could go up here, I could click the little plus icon, and use the GUI.
  3480. 2:41:04Or I can just type code mario.c.
  3481. 2:41:07Voila.
  3482. 2:41:08That creates a new tab for me.
  3483. 2:41:10I'm not going to write any code in here yet, but I am going to save the file.
  3484. 2:41:13And now at top left, you'll see that mario.c appears.
  3485. 2:41:16So at some point, you can eventually just close the Explorer.
  3486. 2:41:19Because, again, it's not providing you with any new information.
  3487. 2:41:22It's maybe more user-friendly, but there's
  3488. 2:41:23nothing you can't do at the command line that you could do with the GUI.
  3489. 2:41:27All right, but now I'm kind of stuck.
  3490. 2:41:29How do I get out of this folder?
  3491. 2:41:32In my Mac or PC world, I'd probably click
  3492. 2:41:34the Back button or something like that or just close it and start all over.
  3493. 2:41:37In the terminal window, I can do cd dot dot.
  3494. 2:41:42Dot dot is a nickname, if you will, for the parent directory.
  3495. 2:41:46That is, the previous directory.
  3496. 2:41:48So if I hit Enter now, notice I'm going to close the Mario folder,
  3497. 2:41:52a.k.a. directory, and now I'm back in PSet1.
  3498. 2:41:56Or, if I want to be fancy, let me go back into Mario temporarily.
  3499. 2:42:00If I type ls, there's mario.c, just to orient us.
  3500. 2:42:03If I want to do multiple things at a time, I could do cd../..
  3501. 2:42:09which goes to my parent to my grandparent all in one breath.
  3502. 2:42:13And voila, now I'm back in my default folder, if you will.
  3503. 2:42:16And one last little trick of the trade, if I'm in PSet1/Mario like I
  3504. 2:42:20was a moment ago, and you're just tired of all the navigation,
  3505. 2:42:24if you just type cd and hit Enter, it'll whisk you
  3506. 2:42:26away back to your default folder, and you don't have
  3507. 2:42:29to worry about getting there manually.
  3508. 2:42:31Recall a bit ago, though, that I was running hello as this, ./hello.
  3509. 2:42:38If dot refers to my parent, perhaps infer here syntactically,
  3510. 2:42:42what does a single dot mean instead?
  3511. 2:42:46It means this directory, your current directory.
  3512. 2:42:49Why is that necessary?
  3513. 2:42:50It just makes super explicit to the computer
  3514. 2:42:52that I want the program called hello that's installed here,
  3515. 2:42:55not in some random other folder on my hard drive, so to speak.
  3516. 2:42:59I want the one that's right here instead.
  3517. 2:43:02All right, so besides these commands, there's
  3518. 2:43:04going to be others that we encounter over time.
  3519. 2:43:06Those are kind of the basics.
  3520. 2:43:07That allows you to wean yourself off of a GUI, Graphical User Interface,
  3521. 2:43:11and start using more comfortably, with practice and time,
  3522. 2:43:14a command line interface instead.
  3523. 2:43:16Well, what about those other types, now back in the world of C?
  3524. 2:43:19Those commands were not C. Those are just command-specific to a command line
  3525. 2:43:23interface, like in Linux, which, again, we're using in the cloud.
  3526. 2:43:28It's an alternative to Mac OS and Windows.
  3527. 2:43:30Back in the world of C now, we've seen strings, which are words.
  3528. 2:43:34I mentioned int or integer, but there's others as well.
  3529. 2:43:38In the world of C, we've seen string, we will see int.
  3530. 2:43:42If you want a bigger integer, there's something literally called a long.
  3531. 2:43:46If you want a single character, there's something called a char.
  3532. 2:43:49If you want a Boolean value, true or false, there is a bool.
  3533. 2:43:53And if you want a floating-point value--
  3534. 2:43:56a fancy way of saying a real number, something with a decimal point in it--
  3535. 2:43:59that is what C and other languages call a float.
  3536. 2:44:03And if you want even more numbers after the decimal point that
  3537. 2:44:06is more precision, you can use something called a double.
  3538. 2:44:10That is to say, here is, again, an example in programming
  3539. 2:44:14where it's up to you now to provide the computer with hints, essentially,
  3540. 2:44:17that it will rely on to know what is this pattern of zeros and ones.
  3541. 2:44:21Is it a number, a letter?
  3542. 2:44:23Is it a sound, an image, a color, or the like?
  3543. 2:44:26These are the types of data types that provide exactly those hints.
  3544. 2:44:30What are the functions that come in the menu that is the CS50 library?
  3545. 2:44:35We talked about standard I/O, and that's just one function so far, printf.
  3546. 2:44:39In the CS50 library, you can see that it follows a pattern.
  3547. 2:44:42The C50 library exists largely for the first few weeks
  3548. 2:44:45of the class to make our lives easier when you just want to get user input.
  3549. 2:44:51So if you want to get a string, like a word or words from the human,
  3550. 2:44:53you use get_string.
  3551. 2:44:54If you want to get an integer from the user, you're going to use get_int.
  3552. 2:44:57When you want to get any of those other data types, for the most part,
  3553. 2:45:01you use get_ something else.
  3554. 2:45:03And they're indeed all lowercase by convention.
  3555. 2:45:06What about printf?
  3556. 2:45:07If we have the ability now to store different types of data
  3557. 2:45:10and we have functions with which to get different types of data,
  3558. 2:45:13how might you go about printing different types of data?
  3559. 2:45:16Well, we've seen %s for string, %i for integer, %c for char,
  3560. 2:45:23%f for a float or a double, those real numbers I described earlier,
  3561. 2:45:30and then %li for a long integer.
  3562. 2:45:33So here's the first example of inconsistencies.
  3563. 2:45:36In an ideal world, that would just be %l and we'd move on.
  3564. 2:45:38It's %li instead in this case.
  3565. 2:45:42That's printf and some of its format codes.
  3566. 2:45:45What more might we do?
  3567. 2:45:47Well, in C, as we'll see--
  3568. 2:45:49no pun intended-- there is a whole bunch of operators.
  3569. 2:45:51And, indeed, computers, one of the first things they did
  3570. 2:45:54was a lot of math and calculations, so there's a lot of operators like these.
  3571. 2:45:57Computers, and in turn, C, really good at addition, subtraction,
  3572. 2:46:01multiplication, division, and even the percent sign,
  3573. 2:46:04which is the remainder operator.
  3574. 2:46:05There's a special symbol in C and other languages
  3575. 2:46:08just for getting the remainder, when you divide one number by another.
  3576. 2:46:13There are other features in the world of C, like variables, as we've seen.
  3577. 2:46:18And there's also what is of playfully called syntactic sugar that
  3578. 2:46:22makes it easier over time to write fewer characters
  3579. 2:46:27but express your thoughts the same.
  3580. 2:46:29So just as a single example of this, as a single example,
  3581. 2:46:33consider this use of a variable last week.
  3582. 2:46:37Here in Scratch is how you might set a variable called counter to 0.
  3583. 2:46:41In C, it's going to be similar.
  3584. 2:46:43If you want the variable to be called counter,
  3585. 2:46:46you literally write the word counter, or whatever you want it to be called.
  3586. 2:46:49You then use the assignment operator, a.k.a. the equals sign,
  3587. 2:46:53and you assign it whatever its initial value should be here on the right.
  3588. 2:46:56So, again, the 0 is going to get copied from right to left into the variable
  3589. 2:47:01because of that single equal sign.
  3590. 2:47:02But this isn't sufficient in C. What else
  3591. 2:47:05is missing on the right-hand side, instinctively now?
  3592. 2:47:08Even if you've never programmed in this before.
  3593. 2:47:11Yeah, in front.
  3594. 2:47:12AUDIENCE: Semicolon.
  3595. 2:47:13DAVID J. MALAN: A semicolon at the end.
  3596. 2:47:14And one other thing, I think, is probably missing.
  3597. 2:47:16Again.
  3598. 2:47:17AUDIENCE: A data type.
  3599. 2:47:18DAVID J. MALAN: A data type.
  3600. 2:47:19So if we can keep going back and forth here,
  3601. 2:47:22what data type seems appropriate intuitively for counter?
  3602. 2:47:26int for integer.
  3603. 2:47:27So, indeed, we need to tell the computer when
  3604. 2:47:29creating a variable what type of data we want,
  3605. 2:47:32and we need to finish our thought with the semicolon.
  3606. 2:47:35So there might be a counterpart there.
  3607. 2:47:38What about in Scratch if we wanted to increment that counter variable?
  3608. 2:47:43We had this very user-friendly puzzle piece last time
  3609. 2:47:45that was change counter by 1, or add 1 to counter.
  3610. 2:47:49In C, here's where things get a little more interesting.
  3611. 2:47:54And pretty commonly done, you might do this. counter = counter + 1;
  3612. 2:47:58with a semicolon.
  3613. 2:47:59And this is where, again, it's important to note, the equal sign,
  3614. 2:48:02it's not equality.
  3615. 2:48:03Otherwise, this makes no sense.
  3616. 2:48:05counter cannot equal counter plus 1, right?
  3617. 2:48:08That just doesn't work if we're talking about integers here.
  3618. 2:48:11That's because the equal sign is assignment.
  3619. 2:48:13So it can certainly be the case that you calculate
  3620. 2:48:15counter plus 1, whatever that is, then you update the value of counter
  3621. 2:48:19from right to left to be that new value.
  3622. 2:48:22This, as we'll see, is a very common thing
  3623. 2:48:25to do in programming just to kind of count upward, for whatever reason.
  3624. 2:48:29You can write this more succinctly.
  3625. 2:48:30This code here is what we'll call syntactic sugar, sort
  3626. 2:48:34of a fancy way of saying the same thing with fewer words or fewer characters
  3627. 2:48:39on the screen.
  3628. 2:48:40This also adds 1, or whatever number you type over here,
  3629. 2:48:44to the variable on the left.
  3630. 2:48:46And there's one other form of syntactic sugar we're going to start seeing too,
  3631. 2:48:49and it's even more terse than this.
  3632. 2:48:51That too will increment counter by 1 by literally changing its value by 1.
  3633. 2:48:56Or if you change it to minus minus, subtracting 1 from it.
  3634. 2:48:59You can't do that with 2 and 3 and 4, but you
  3635. 2:49:02can do it by default with just plus plus or minus minus adding or subtracting 1.
  3636. 2:49:07Yeah.
  3637. 2:49:08AUDIENCE: [INAUDIBLE]
  3638. 2:49:12DAVID J. MALAN: Ah, so when you are changing a variable that already
  3639. 2:49:15has been created, as we did with the code that looked like this,
  3640. 2:49:20you no longer need to remind the computer what the data type is.
  3641. 2:49:23Thankfully, the computer is at least as smart as that.
  3642. 2:49:27It will remember the type of the data that you intended.
  3643. 2:49:31Other questions or comments on this?
  3644. 2:49:34All right, that's quite a lot.
  3645. 2:49:36Why don't we go ahead and here take a 10-minute break?
  3646. 2:49:38And we'll be back, we'll start writing some code.
  3647. 2:49:41All right, so we are back.
  3648. 2:49:44We've just looked at some of the basics of compiling,
  3649. 2:49:48even if it doesn't quite feel that basic.
  3650. 2:49:50But now, let's actually start focusing really
  3651. 2:49:52on writing more and more code, more and more interesting
  3652. 2:49:55code, kind of like we dove into Scratch last week.
  3653. 2:49:58So here I have these code open.
  3654. 2:50:00I've closed the GUI.
  3655. 2:50:01I'm going to focus more on my terminal window and my code editors.
  3656. 2:50:04Many different ways I can create new files, but I want to create something
  3657. 2:50:07called a calculator.
  3658. 2:50:08So, again, within this environment of VS Code,
  3659. 2:50:11I can literally write the code command which is VS Code specific,
  3660. 2:50:15and it just creates a new file for me automatically.
  3661. 2:50:18Or I could do that in the GUI.
  3662. 2:50:20I'm going to go ahead and create this file called calculator.c
  3663. 2:50:23and I'm going to go ahead and include some familiar things.
  3664. 2:50:25So I'm just going to go ahead and proactively include cs50.h, stdio.h.
  3665. 2:50:30I'm going to go ahead from memory and do the int void main--
  3666. 2:50:33more on that next week, why it's int, why it's void, and so forth.
  3667. 2:50:38And now let me just implement a very simple calculator.
  3668. 2:50:40We saw some mathematical operators, like plus and the like.
  3669. 2:50:44So let's actually use this.
  3670. 2:50:45So let me go ahead and first give myself a variable
  3671. 2:50:48called x, sort of like grade school math or algebra.
  3672. 2:50:52Let me go ahead then and get an int, which is new,
  3673. 2:50:55but I mentioned this exists.
  3674. 2:50:57And then let me just ask the user for whatever their x value is.
  3675. 2:51:00The thing in the quotes is just the English, or the string
  3676. 2:51:03that I'm printing on the screen. so I could say anything I want.
  3677. 2:51:06I'm just going to say x colon to prompt the user accordingly.
  3678. 2:51:09Now I'm going to go ahead and get another variable called y.
  3679. 2:51:12I'm going to get int again.
  3680. 2:51:13And now, I'm going to prompt the user for y.
  3681. 2:51:16And I'm just very nitpickly using a space just
  3682. 2:51:18to move the cursor so it doesn't look too messy on the screen.
  3683. 2:51:22And then lastly, let me go ahead and just print out the sum of x and y.
  3684. 2:51:27In an ideal world, I would just say something like printf x + y.
  3685. 2:51:31But that is not valid in C. The first argument, recall, in printf
  3686. 2:51:36has to be a string in double quotes.
  3687. 2:51:39So if I want to print out the value of an integer,
  3688. 2:51:43I need to put something in quotes here, maybe followed by a newline,
  3689. 2:51:47if I want to move the cursor as well.
  3690. 2:51:49So, again, we only glimpsed it briefly, but what
  3691. 2:51:51do I replace these question marks with if I want a placeholder for an integer?
  3692. 2:51:55AUDIENCE: [INAUDIBLE]
  3693. 2:51:56DAVID J. MALAN: Yeah, so %i.
  3694. 2:51:57Just like %s was string, %i is integer.
  3695. 2:52:00So I change this %i.
  3696. 2:52:02And now if I want to add x and y, for instance, super-- simple calculator,
  3697. 2:52:06doesn't do much of anything other than addition of two integers--
  3698. 2:52:09I think this works.
  3699. 2:52:11And, again, it looks definitely cryptic at first glance.
  3700. 2:52:14It would be if programming weren't this cryptic.
  3701. 2:52:16Other languages will clean this up for us.
  3702. 2:52:18But, again, if you focus on the basics, printf takes one input first--
  3703. 2:52:22which is a format string with English or whatever language,
  3704. 2:52:26some placeholders, maybe--
  3705. 2:52:27then it takes potentially more arguments after the comma,
  3706. 2:52:31like the value of x plus y.
  3707. 2:52:33All right, let me go ahead now and make calculator,
  3708. 2:52:36which, again, compiles my source code in C,
  3709. 2:52:41pictured above, and converts it into corresponding machine
  3710. 2:52:44code, or zeros and ones.
  3711. 2:52:46No error messages.
  3712. 2:52:47so that's already good.
  3713. 2:52:48Now I do ./calculator.
  3714. 2:52:50Let's do 1 plus 1 and Enter.
  3715. 2:52:53Voila.
  3716. 2:52:54Now I have the makings of a calculator.
  3717. 2:52:57Now let's start to tinker with this a little bit.
  3718. 2:53:00What if I instead had done this?
  3719. 2:53:02int z = x + y and then plug-in z here.
  3720. 2:53:08If I rerun make calculator, Enter, rerun ./calculator, type in 1 plus 1,
  3721. 2:53:14still equals 2, and let me claim that it will work for other values as well--
  3722. 2:53:20which of these versions is better designed?
  3723. 2:53:22If both seem to be correct at very cursory glance, is this version better
  3724. 2:53:27or is the previous one without the z?
  3725. 2:53:30OK, so this one is arguably better because I've now got a reusable
  3726. 2:53:34variable called z that I cannot only print but, heck,
  3727. 2:53:36if my program is longer, I can use it elsewhere.
  3728. 2:53:39Counterthoughts?
  3729. 2:53:40AUDIENCE: [INAUDIBLE]
  3730. 2:53:41DAVID J. MALAN: Yeah.
  3731. 2:53:42Debatable, like before, because it depends on my intent.
  3732. 2:53:44And, honestly, I think a pretty good argument
  3733. 2:53:46can be made for the first version.
  3734. 2:53:48Because if I have no intention of-- as you note--
  3735. 2:53:50using that variable again, you know what?
  3736. 2:53:53Maybe I might as well do this, just because it's
  3737. 2:53:55one less thing to think about.
  3738. 2:53:57It's one less distraction.
  3739. 2:53:58It's one less line of code to have to understand.
  3740. 2:54:00It's just a little tighter.
  3741. 2:54:02So here, again, it does depend on your intention.
  3742. 2:54:04But this field is pretty reasonable.
  3743. 2:54:07And I think, as someone noted earlier, when
  3744. 2:54:09I did the same thing with get_string, that, yeah, maybe kind of crossed
  3745. 2:54:13s line because get_string and the what's your name inside of it,
  3746. 2:54:16it was just so much longer.
  3747. 2:54:17But x + y, eh, it's not that hard to wrap our mind around what's
  3748. 2:54:20going on inside of the printf argument.
  3749. 2:54:23So, again, these are the kinds of thoughts that hopefully you'll
  3750. 2:54:25acquire the instinct for on not necessarily reaching
  3751. 2:54:28the same answer as someone else, but, again, the thought
  3752. 2:54:30process is what matters here.
  3753. 2:54:33All right, so how might I enhance this program a little bit?
  3754. 2:54:36Let's just talk about style for just a moment.
  3755. 2:54:38So x and y, at least in this case, are pretty reasonable variable names.
  3756. 2:54:42Why?
  3757. 2:54:43Because that's the go-to variable names in math
  3758. 2:54:45when you're adding two things together.
  3759. 2:54:47So x and y seem pretty reasonable.
  3760. 2:54:48I could have done something like, well, maybe my first variable
  3761. 2:54:53should be called first number and my next variable
  3762. 2:54:56should be called second number.
  3763. 2:54:58And then down here, I would have to change this
  3764. 2:55:00to first number plus second number.
  3765. 2:55:04Like, eh, this isn't really adding anything semantically
  3766. 2:55:07to help my comprehension.
  3767. 2:55:08But that would be one other direction we could have taken things.
  3768. 2:55:11So if you have very simple ideas that are conventionally
  3769. 2:55:14expressed with common variable names like x and y, totally fine here.
  3770. 2:55:18What if I want to annotate this program and remind myself what it is it does?
  3771. 2:55:22Well, I can add in C what are called comments.
  3772. 2:55:25With a slash slash, two forward slashes, you can write a note to yourself,
  3773. 2:55:30like prompt user for x.
  3774. 2:55:32And then down here, I could do something like prompt user
  3775. 2:55:35for y, just to remind myself what I'm doing there.
  3776. 2:55:37And down here, perform addition.
  3777. 2:55:40Now, in this case, I'm not sure these commands are really
  3778. 2:55:42adding all that much.
  3779. 2:55:44Because in the time it took me to write and eventually read these comments,
  3780. 2:55:47I could have just read the three lines of code.
  3781. 2:55:49But as our programs get more sophisticated
  3782. 2:55:52and you start to learn more syntax--
  3783. 2:55:55that, honestly, you might forget the next day, the next week,
  3784. 2:55:58the next month-- might be useful to have these notes to self that
  3785. 2:56:01reminds you of what your code is doing or maybe even
  3786. 2:56:04how it is doing that thing.
  3787. 2:56:06With these early programs, not really necessary,
  3788. 2:56:09doesn't really add all that much to our comprehension,
  3789. 2:56:11but it is a mechanism you have in place that
  3790. 2:56:14can help you actually remind yourself or remind someone
  3791. 2:56:18else what it is that's going on.
  3792. 2:56:20Well, let me go ahead and rerun this again in this current version,
  3793. 2:56:23make calculator.
  3794. 2:56:24And here, too, you might think I'm typing crazy fast--
  3795. 2:56:27not really.
  3796. 2:56:27I'm hitting Tab a lot.
  3797. 2:56:28So it turns out that Linux, the operating system
  3798. 2:56:32we're using here in the cloud--
  3799. 2:56:33but, actually, Windows and Mac OS nowadays support this too--
  3800. 2:56:36supports autocomplete.
  3801. 2:56:38So if you only have one program that starts with C-A-L,
  3802. 2:56:42you don't have to finish writing calculator, you can just hit Tab,
  3803. 2:56:45and the computer will finish your thought for you.
  3804. 2:56:47The other thing you can do is if you hit Up and keep going up,
  3805. 2:56:51you'll scroll through your entire history of commands.
  3806. 2:56:54So there too, I've been saving some keystrokes
  3807. 2:56:56by hitting Up quickly rather than retyping the same darn thing again
  3808. 2:56:59and again.
  3809. 2:56:59So, again, just another little convenience
  3810. 2:57:02to make programming and interacting with the command line interface even faster.
  3811. 2:57:05All right, let me go ahead and just make sure it's compiled in the current form.
  3812. 2:57:09The comments have no functional impact.
  3813. 2:57:11These green things are just notes to self.
  3814. 2:57:13Let me run calculator with maybe-- how about this?
  3815. 2:57:15Instead of 1 plus 1, how about 1 billion--
  3816. 2:57:22whoops, let's do that again.
  3817. 2:57:23Wa, da, da.
  3818. 2:57:241 million, 1 billion, and another 1 billion, and that answer is 2 billion.
  3819. 2:57:30All right, so that seems correct.
  3820. 2:57:31Let's run this program one more time.
  3821. 2:57:33How about 2 billion plus another 2 billion?
  3822. 2:57:39Did you know that?
  3823. 2:57:42So, apparently, it's not so correct.
  3824. 2:57:45And, clearly, running 1 plus 1 was not the most robust testing of my code
  3825. 2:57:49here.
  3826. 2:57:50What might have gone wrong?
  3827. 2:57:53What might have gone wrong?
  3828. 2:57:54Yeah.
  3829. 2:57:55AUDIENCE: [INAUDIBLE]
  3830. 2:57:57DAVID J. MALAN: Yeah.
  3831. 2:57:58The computer probably ran out of space with bits.
  3832. 2:58:00So it turns out with these data types-- we've been talking about string and int
  3833. 2:58:05and also float and char and those other things-- they all use a specific,
  3834. 2:58:09and, most importantly, finite number of bits to represent them.
  3835. 2:58:13It can vary by computer.
  3836. 2:58:14Newer computers use more bits, older computers tended to use fewer bits.
  3837. 2:58:18It's not necessarily standardized for all of these data types.
  3838. 2:58:21But in this case, in this environment, it is using 32 bits for an integer.
  3839. 2:58:28That's a lot.
  3840. 2:58:28So with 32 bits, you can count pretty high.
  3841. 2:58:30This is 64 light bulbs on the stage and could count even higher.
  3842. 2:58:34An int is only using half of these, or we have two integers here on the stage.
  3843. 2:58:38Now, if you think back to last week, we talked about 8 bits at one point.
  3844. 2:58:42And if you have 8 bits, 8 zeros and ones, you can count as high as 256--
  3845. 2:58:47just a good number to generally remember as trivia.
  3846. 2:58:498 bits gives you 256 permutations of zeros and ones.
  3847. 2:58:5332 gives you roughly how many, if anyone knows?
  3848. 2:58:57It's 2 to the 32 power.
  3849. 2:58:59So it's roughly 4 billion, 2 to the 32.
  3850. 2:59:02If you don't know that, it's fine.
  3851. 2:59:04Most programmers, though, eventually remember these kinds of heuristics.
  3852. 2:59:07So it's roughly 4 billion.
  3853. 2:59:08So that feels like enough.
  3854. 2:59:102 billion plus 2 billion is exactly 4 billion.
  3855. 2:59:13And that actually should fit in a 32-bit integer.
  3856. 2:59:17The catch is that my Mac, your PC, and the like
  3857. 2:59:20also like to support negative numbers.
  3858. 2:59:22And if you want to support both positive and negative numbers, that technically
  3859. 2:59:26means with 32-bit integers, you can count as high
  3860. 2:59:29as roughly 2 billion positive or 2 billion negative
  3861. 2:59:33in the other direction.
  3862. 2:59:34That's still 4 billion, give or take, but it's only half as many
  3863. 2:59:38in one direction or the other.
  3864. 2:59:39So how could I go about implementing a correct calculator here?
  3865. 2:59:44What might the solution be?
  3866. 2:59:47Yeah, so not just li, which was for long integer.
  3867. 2:59:50I have to make one more change, which is to the data type itself.
  3868. 2:59:54So let me go back up here and change x from an int to a long, a.k.a.
  3869. 2:59:59long integer.
  3870. 3:00:00And then let me change y as well.
  3871. 3:00:02And then let me change the format code per the little cheat sheet we had up
  3872. 3:00:05a few minutes ago to li.
  3873. 3:00:07Let me recompile the calculator--
  3874. 3:00:10seems to work OK.
  3875. 3:00:11Let's rerun it.
  3876. 3:00:12Now let's do 1 plus 1.
  3877. 3:00:14That's should obviously be the same.
  3878. 3:00:15Now let's do 2 billion and another 2 billion
  3879. 3:00:20and cross our fingers this time.
  3880. 3:00:22Now we're counting as high as 4 billion.
  3881. 3:00:24And we can go way higher than 4 billion, but we're only
  3882. 3:00:27kicking the can down the street a bit.
  3883. 3:00:29Even though we're now using--
  3884. 3:00:31with a long--
  3885. 3:00:3264 bits, which is as long as this stage now, that's still a finite value.
  3886. 3:00:37It might be a really big value, but it's still finite.
  3887. 3:00:40And we'll come back at the end of today to these kinds
  3888. 3:00:42of fundamental limitations.
  3889. 3:00:44Because arguably now, my calculator is correct for like millions,
  3890. 3:00:48billions of possible inputs but not all.
  3891. 3:00:51And that's problematic if you actually want
  3892. 3:00:53to use my calculator for any possible inputs, not just
  3893. 3:00:58ones that are roughly less than, say, 2 billion, as in this case.
  3894. 3:01:03All right, any questions then on that?
  3895. 3:01:05But it's really just a precursor for all the problems
  3896. 3:01:07that we're going to have to eventually deal with later on.
  3897. 3:01:10AUDIENCE: [INAUDIBLE]
  3898. 3:01:15DAVID J. MALAN: A good question.
  3899. 3:01:17Yes.
  3900. 3:01:17If we were still using z, we would also have to change it to a long.
  3901. 3:01:20Otherwise, we'd be ignoring 32 of the bits that
  3902. 3:01:23had been added together via the longs.
  3903. 3:01:25Good question.
  3904. 3:01:27All right, so how about we spice things up with maybe not just addition here,
  3905. 3:01:32how about something with some conditions?
  3906. 3:01:35Let's start to ask some actual questions.
  3907. 3:01:37So a moment ago, recall that we had just the declaration of variables.
  3908. 3:01:44Now let's look back at something in Scratch that
  3909. 3:01:46looked a little something like this, a bunch of puzzle pieces
  3910. 3:01:48asking questions by way of these conditionals
  3911. 3:01:50and then these Boolean expressions here in green, maybe saying something
  3912. 3:01:53like x is less than y.
  3913. 3:01:55In C, this actually maps pretty cleanly.
  3914. 3:01:58It's much cleaner from left to right than it was with printf and join.
  3915. 3:02:02Here, we have just code that looks like this.
  3916. 3:02:04If, a space, two parentheses and then x less than y,
  3917. 3:02:09and then we have something like printf there in the middle.
  3918. 3:02:12So here, it's actually kind of a nice mapping.
  3919. 3:02:14Notice that, just as the yellow puzzle piece in Scratch
  3920. 3:02:16is kind of hugging the purple puzzle piece,
  3921. 3:02:18that's effectively the role that these curly braces are playing.
  3922. 3:02:21They're sort of encapsulating all of the code on the inside.
  3923. 3:02:24The parentheses represent the Boolean expression
  3924. 3:02:27that needs to be asked and answered to decide whether or not to do this thing.
  3925. 3:02:32And here's an exception to what I alluded to earlier.
  3926. 3:02:34Usually, when you see a word and then a parenthesis, something,
  3927. 3:02:38and then closed parenthesis, I claimed that's usually a function.
  3928. 3:02:42And I'm still feeling pretty good about that claim.
  3929. 3:02:44But there are exceptions.
  3930. 3:02:45And the word if is not a function.
  3931. 3:02:48It's just a programming construct.
  3932. 3:02:50It's a feature of the C language that similarly uses parentheses, just
  3933. 3:02:55for different purposes for a Boolean expression.
  3934. 3:02:58How about something like this?
  3935. 3:02:59Last week, if you wanted to have a two-way fork in the road,
  3936. 3:03:02go this way or that way, you can have if and else.
  3937. 3:03:05In C, that would look a little something like this.
  3938. 3:03:08And if we add in the printf's, it now looks quite like the same,
  3939. 3:03:11but it adds, of course, the word else and then a couple of more curly braces.
  3940. 3:03:15As an aside, in C, It's not strictly necessary to have curly braces
  3941. 3:03:21if you have only one line of code indented underneath.
  3942. 3:03:25For best practice, though, do so anyway, because it makes super clear to you
  3943. 3:03:30and ultimately anyone else reading your code
  3944. 3:03:31that you intend for just that one or more line of code to execute.
  3945. 3:03:35How about this from last week?
  3946. 3:03:37Here was a three-way fork in the road.
  3947. 3:03:38If x is less than y, else if x is greater than y, else if x equals y.
  3948. 3:03:45Now, here's where you have some disparities between Scratch
  3949. 3:03:47and C. Scratch uses an equals sign for equality, to compare two values.
  3950. 3:03:52C uses a single equals sign for assignment from right
  3951. 3:03:55to left, minor difference between the two worlds.
  3952. 3:03:58In C, we could implement the same code like this, the addition being
  3953. 3:04:02just this additional else if.
  3954. 3:04:04And if we add in the printf's, it looks a little something now like this.
  3955. 3:04:08This is correct both in the Scratch world and in the C world.
  3956. 3:04:12But could someone make a claim that this is not, again, well-designed?
  3957. 3:04:16Exactly.
  3958. 3:04:17We don't need the last if.
  3959. 3:04:18We need the else, at least, but we don't need the last if.
  3960. 3:04:21Because, at least in the world of comparing integers,
  3961. 3:04:24it's either going to be less than, greater than, or equal to.
  3962. 3:04:27There is no other case.
  3963. 3:04:28So you can save a few seconds, if you will,
  3964. 3:04:31of your program running-- a blink of the eye-- by only asking two questions
  3965. 3:04:35and then inferring what the answer to the third
  3966. 3:04:37must be just by nature of your own human logic here.
  3967. 3:04:41Now, why is that a good thing?
  3968. 3:04:42If, for instance, x and y happen to equal each other--
  3969. 3:04:46I type in 1 and 1 for both values, either in Scratch or in the C world--
  3970. 3:04:51in the case of this version, you're sort of stupidly
  3971. 3:04:55asking three questions, all of which are going to get asked
  3972. 3:04:59even though the answer is no, no, yes.
  3973. 3:05:02That is false, false, true.
  3974. 3:05:05That seems to be unnecessary because if we instead optimize this code,
  3975. 3:05:09get rid of the unnecessary if and just do as you proposed logically--
  3976. 3:05:13else print that x is equal to y--
  3977. 3:05:16now if x indeed equals y because they're both 1 or some other value,
  3978. 3:05:20now you're only going to ask two questions, so 2/3 as many questions,
  3979. 3:05:26and then you're going to get your same correct result.
  3980. 3:05:29So, again, a minor detail, but, again, the kinds of things
  3981. 3:05:32you should be thinking about, not only as
  3982. 3:05:33you write your code to be correct but also write
  3983. 3:05:36it to be well-designed as well.
  3984. 3:05:38All right, so why don't we go ahead and translate this
  3985. 3:05:41into the context of an actual program here?
  3986. 3:05:44I'll create a blank window here.
  3987. 3:05:46And let's do something with points, like points on my own very first CS50
  3988. 3:05:50problem set.
  3989. 3:05:51Let me go ahead and run code of points.c.
  3990. 3:05:54That's just going to give me a new text file.
  3991. 3:05:56And then up here, I'm going to do my usual, include cs50.h.
  3992. 3:06:00include stdio.h.
  3993. 3:06:03int main void.
  3994. 3:06:04So a lot of boilerplate, so to speak, in these early programs.
  3995. 3:06:08And now, let's see.
  3996. 3:06:09Let's ask the user, how many points did they
  3997. 3:06:12lose on their most recent CS50 PSet?
  3998. 3:06:15So sort of evoke my photograph of my own very first PSet last week
  3999. 3:06:19where I lost a couple of points myself.
  4000. 3:06:20So int points = get_int.
  4001. 3:06:23Then I'll ask a question in English like, how many points did you lose,
  4002. 3:06:27question mark, space?
  4003. 3:06:29And then once I have this answer, let's now ask some questions of it.
  4004. 3:06:33So if points is less than 2--
  4005. 3:06:36borrowing the syntax that we saw on the screen a moment ago--
  4006. 3:06:40let's go ahead and print out something explanatory
  4007. 3:06:42like you lost fewer points than me, backslash n.
  4008. 3:06:49else if points greater than 2--
  4009. 3:06:52which is, again how many I lost--
  4010. 3:06:53I'm going to go ahead and print out you lost more points than me, backslash n.
  4011. 3:06:59else if-- wait a minute, else seems to be sufficient logically here.
  4012. 3:07:03I'm just going to go ahead and print out something
  4013. 3:07:05like you lost the same number of points as me, backslash n.
  4014. 3:07:12So, really, just a straightforward application of that simple idea
  4015. 3:07:16but to a concrete scenario here.
  4016. 3:07:18So let me go ahead and save this.
  4017. 3:07:21Let me go ahead and run make points, Enter.
  4018. 3:07:24No errors, that's good.
  4019. 3:07:26Run points.
  4020. 3:07:27And then, how many points did you lose?
  4021. 3:07:29How about, it's 1 point?
  4022. 3:07:31All right, you lost fewer points than me.
  4023. 3:07:32How about 0 points?
  4024. 3:07:34Even better.
  4025. 3:07:34How about 3 points?
  4026. 3:07:36And so forth.
  4027. 3:07:37So, again, we have the ability to express in C now pretty basic idea
  4028. 3:07:40from last week in reality, which is this notion of conditionals and asking
  4029. 3:07:44questions.
  4030. 3:07:46There's something subtle here, though, that's maybe not super well-designed
  4031. 3:07:50that someone might call a magic number.
  4032. 3:07:53This is programming speak for something I've done here.
  4033. 3:07:56There's a bit of redundancy unrelated to the if and the else and the else.
  4034. 3:08:01But is there something I typed twice just to ask, perhaps, for the obvious?
  4035. 3:08:07Exactly, I've hard-coded, so to speak, manually typed out the number 2--
  4036. 3:08:11in two locations, in this case--
  4037. 3:08:13that did not come from the user.
  4038. 3:08:15So, apparently, once I compile this, this is it.
  4039. 3:08:18You're always comparing yourself to me in like, 1996,
  4040. 3:08:21which for better or for worse, is all the program can do.
  4041. 3:08:24But this is an example too of a magic number in the sense
  4042. 3:08:27like, wait, where did that 2 come from, and why is it in two places?
  4043. 3:08:31It feels like we are setting the stage for just a higher probability
  4044. 3:08:35of screwing up down the road.
  4045. 3:08:36Because the longer this code gets, suppose I'm comparing against 2 points
  4046. 3:08:39elsewhere--
  4047. 3:08:402, 3, 4, 5 places--
  4048. 3:08:42am I going to keep typing the number 2?
  4049. 3:08:45Like, yeah, that's fine.
  4050. 3:08:46It's correct.
  4051. 3:08:46It's going to work.
  4052. 3:08:47But, honestly, eventually, you're going to screw up,
  4053. 3:08:49and you're going to miss one of the 2's, you're going to change it to a 3,
  4054. 3:08:52because maybe I did worse the next year, or 1, I did better.
  4055. 3:08:54And you don't want these numbers to get out of sync.
  4056. 3:08:57So what would be a logical improvement to this design,
  4057. 3:09:01rather than hard-coding the same number sort of magically
  4058. 3:09:04in two or more places?
  4059. 3:09:07Yeah, why don't I make a variable that I can use in there?
  4060. 3:09:09So, for instance, I could create a variable
  4061. 3:09:11like this, another integer called mine.
  4062. 3:09:14And I'm just going to initialize it to 2.
  4063. 3:09:16And then I'm going to change mentions of 2 to this.
  4064. 3:09:19And mine is a pretty reasonable name for a variable insofar
  4065. 3:09:23as it refers to exactly whose points are in question.
  4066. 3:09:27There's a risk here, though, minor though it is.
  4067. 3:09:29I could accidentally change mine at some point.
  4068. 3:09:32Maybe I forget what mine represents, and I do some addition or subtraction.
  4069. 3:09:36So there's a way to tell the computer "don't trust me,
  4070. 3:09:39because I'm going to screw up eventually"
  4071. 3:09:40by making a variable constant too.
  4072. 3:09:43So a constant in a programming language--
  4073. 3:09:45this did not exist in Scratch--
  4074. 3:09:47is just an additional hint to the computer that essentially enables
  4075. 3:09:50you to program more defensively.
  4076. 3:09:52If you don't trust yourself necessarily to not
  4077. 3:09:55screw up later, or honestly, in practice,
  4078. 3:09:57if you know that number should never change, make it constant
  4079. 3:10:01and never think about it again.
  4080. 3:10:02This tells the compiler to make sure that even you later in your code cannot
  4081. 3:10:08change the number 2.
  4082. 3:10:09And another convention in C and other languages, when you have a constant,
  4083. 3:10:14it's often common to just capitalize the variable.
  4084. 3:10:16Kind of like you're yelling, but it really just
  4085. 3:10:18visually makes it stand out.
  4086. 3:10:20So it's kind of like a nice rule of thumb
  4087. 3:10:21that helps you realize, oh, that must be a constant.
  4088. 3:10:24Capitalization alone does not make it constant.
  4089. 3:10:27The word const does.
  4090. 3:10:28But the capitalization is just a visual reminder
  4091. 3:10:31that this is somewhere, somehow a constant.
  4092. 3:10:35So just a minor refinement, but, again, we're
  4093. 3:10:37sort of getting better at programming just by instilling
  4094. 3:10:41these kinds of heuristics.
  4095. 3:10:43Questions, then, on conditionals in C or these constants?
  4096. 3:10:48Yeah.
  4097. 3:10:48AUDIENCE: Why do you not use semicolons after line 9 and line 13?
  4098. 3:10:53DAVID J. MALAN: Yeah, why do you not use a semicolon in lines 9, 13?
  4099. 3:10:58Just because.
  4100. 3:10:59This is the way the language was designed.
  4101. 3:11:01And it's confusing early on.
  4102. 3:11:03Generally speaking, when you're using conditionals-- and eventually,
  4103. 3:11:07we'll see loops--
  4104. 3:11:08there's no semicolons involved.
  4105. 3:11:09For now, assume that semicolons usually finish your thought after a function.
  4106. 3:11:14That's not 100% reliable of a heuristic, but it'll get you most of the way
  4107. 3:11:18there.
  4108. 3:11:19And just because.
  4109. 3:11:20Left hand was not talking to the right hand when some of these languages
  4110. 3:11:23were designed.
  4111. 3:11:25All right, so let's do something else.
  4112. 3:11:27How about this?
  4113. 3:11:28If I have the ability to ask something conditionally--
  4114. 3:11:31is this thing true or is this other thing--
  4115. 3:11:33could I write a very simple program that does something basic like,
  4116. 3:11:36tells me if a number the human types is even or odd?
  4117. 3:11:39Well, let me just get the framework for that in place.
  4118. 3:11:42Let me go ahead and write code of a parity--
  4119. 3:11:44is a fancy way of saying even or odd.
  4120. 3:11:47And let me go ahead and include cs50.h, include stdio.h, int main void--
  4121. 3:11:53again, more on those down the road.
  4122. 3:11:55But, for now, I'm going to go ahead and get a number n from the user
  4123. 3:11:59by calling get_int and asking them for whatever n is.
  4124. 3:12:03And then now I'm going to introduce some pseudocode.
  4125. 3:12:07So here's the first example of a program,
  4126. 3:12:08honestly, that I'm not really sure how to proceed.
  4127. 3:12:12So let me just resort to some pseudocode using comments.
  4128. 3:12:14Eventually, I'll get rid of this and write actual code.
  4129. 3:12:17But if n is even, then print--
  4130. 3:12:22actually, let me just print that.
  4131. 3:12:24Let me just go ahead and say printf, quote unquote, "even",
  4132. 3:12:27because I know how to use printf.
  4133. 3:12:29else-- all right, I know how to printf odd,
  4134. 3:12:33so let me just say printf, quote unquote, "odd".
  4135. 3:12:35So here, I've sort of taken a bite out of the problem, if you will.
  4136. 3:12:39And let me go ahead and put in my little placeholders.
  4137. 3:12:42I want to do some kind of conditions.
  4138. 3:12:44So if, question marks now, let me go ahead and fill in the blanks here.
  4139. 3:12:49else I'll put this here.
  4140. 3:12:51So I think I'm OK now.
  4141. 3:12:53I'm getting closer to solving this.
  4142. 3:12:55But I still have this question mark here.
  4143. 3:12:59How, using syntax we've seen, might I determine if n is even or odd?
  4144. 3:13:06What do you think?
  4145. 3:13:07Nice.
  4146. 3:13:08There's this little operator I mentioned by name earlier, the remainder
  4147. 3:13:12operator, that will let you do exactly that.
  4148. 3:13:14If you divide any number by 2, that mathematical heuristic
  4149. 3:13:16is going to tell you if it's even or odd based on whether there's
  4150. 3:13:19a remainder of 0 or 1.
  4151. 3:13:21And that's nice because the alternative would seem to be doing something stupid
  4152. 3:13:25like if n == 0 or if n equals 2 or n equals 4--
  4153. 3:13:33your code would be infinitely long if you had to ask all possible questions.
  4154. 3:13:37But if I do n divided by 2 and look at the remainder--
  4155. 3:13:43it's a little cryptic, but this will indeed do the trick.
  4156. 3:13:47So the percent sign is the remainder operator.
  4157. 3:13:51It does numerator divided by denominator and returns not the result of that
  4158. 3:13:56but, rather, the remainder of that.
  4159. 3:13:58So if you divide anything by 2, it's going to be a 0 or 1 remainder.
  4160. 3:14:02And if, indeed, 2 divides into n evenly, giving you 0,
  4161. 3:14:06then you're going to print even.
  4162. 3:14:08Else, it's got to be odd.
  4163. 3:14:10But there is something odd-- pun intended-- in this highlighted line.
  4164. 3:14:14What is another new piece of syntax, apparently, besides the percent sign?
  4165. 3:14:20What's a little off there?
  4166. 3:14:21Yeah.
  4167. 3:14:24Yeah, so that's not a typo.
  4168. 3:14:25And I even caught myself verbally saying it a moment ago,
  4169. 3:14:28just because it's so ingrained.
  4170. 3:14:29What must this mean here?
  4171. 3:14:32Yeah.
  4172. 3:14:33AUDIENCE: [INAUDIBLE]
  4173. 3:14:34DAVID J. MALAN: Yeah, if something's equivalent to the other.
  4174. 3:14:36So now this is the equality operator.
  4175. 3:14:38It's not assignment from right to left.
  4176. 3:14:40And this one too is an example of, literally,
  4177. 3:14:42humans not really planning ahead, perhaps, left hand
  4178. 3:14:45not talking to right hand in that someone decided,
  4179. 3:14:47let's use the equals sign for assignment.
  4180. 3:14:49And then some number of minutes or days later, people are like, damn,
  4181. 3:14:52how do we now compare for equality?
  4182. 3:14:53Well, let's just use two.
  4183. 3:14:55And if you think this is a little weird, in some languages, like JavaScript,
  4184. 3:14:58there's a third version where you use three equal signs.
  4185. 3:15:01So, again, it's humans that design these languages.
  4186. 3:15:03So if you're ever frustrated by them, confused by them, eh, admittedly,
  4187. 3:15:06it might just not have been the best design.
  4188. 3:15:08But we just kind of have to live with it ever since.
  4189. 3:15:11So let me go ahead and zoom out here.
  4190. 3:15:12Let me go ahead and make parity here.
  4191. 3:15:15So make parity-- and, again, parity is just the name of my file, parity.c.
  4192. 3:15:20./parity, type in a number like 2.
  4193. 3:15:23That's indeed even.
  4194. 3:15:244, that's indeed even.
  4195. 3:15:263, that's indeed odd, and so forth.
  4196. 3:15:29If we continue testing, presumably, we'll get the same kinds of answers.
  4197. 3:15:32How about something else?
  4198. 3:15:34Let me go ahead now and let me start copying and pasting some of this code
  4199. 3:15:37because, admittedly, it's getting a little tedious to keep typing out
  4200. 3:15:40all of that boilerplate at the top.
  4201. 3:15:42Let me create a program called agree.c that's
  4202. 3:15:46reminiscent of any of those forms you have
  4203. 3:15:48to agree to online with a checkbox or typing in yes or no or the like.
  4204. 3:15:52So let me throw away all the guts of this main program
  4205. 3:15:55and now ask something like this.
  4206. 3:15:57Let me go ahead and prompt user to agree to something.
  4207. 3:16:01I'm going to go ahead and say, how about get_string do you agree--
  4208. 3:16:06whatever the question might be-- and I want the human to type y or n
  4209. 3:16:12for yes or no, respectively.
  4210. 3:16:13So if it's only a single character, actually, I
  4211. 3:16:16can actually get by with just get_char.
  4212. 3:16:18Not used it before, but it was on our menu
  4213. 3:16:20of functions from the CS50 library.
  4214. 3:16:22And if I want to get the user's response,
  4215. 3:16:25the return value should be a char also on the left.
  4216. 3:16:28So now we've seen strings, ints, and now chars,
  4217. 3:16:31if we only care about a single letter.
  4218. 3:16:33And now let's go ahead, check whether user agreed.
  4219. 3:16:38So how about if c == "y", then let me go ahead and, inside of my curly braces,
  4220. 3:16:47print out agreed or some such sentence like that.
  4221. 3:16:51else if they did not type c-- or you know what?
  4222. 3:16:54Let's be explicit here, just so they can't
  4223. 3:16:56type z or b or some random letter.
  4224. 3:16:59else if c=="n" n for no, then let me go ahead and print out not agreed,
  4225. 3:17:07or something like that.
  4226. 3:17:07And I'm just going to ignore the user if they don't cooperate
  4227. 3:17:10and they type z or b or something that's not y or n.
  4228. 3:17:14All right, let me go ahead now and compile this code, make agree, ./agree.
  4229. 3:17:21All right, do I agree?
  4230. 3:17:22Yes.
  4231. 3:17:22Let's go with the default. OK, so that seems to work.
  4232. 3:17:25No, I don't agree this time.
  4233. 3:17:27That seems to work.
  4234. 3:17:28How about my caps lock key is on or I'm just really yelling, capital Y?
  4235. 3:17:33It ignores me.
  4236. 3:17:34Capital N, it ignores me.
  4237. 3:17:37So, obviously, a bug, at least if I want to tolerate uppercase and lowercase,
  4238. 3:17:41which is kind of reasonable.
  4239. 3:17:43So what would be the possible solutions here, do you think?
  4240. 3:17:48How do I solve this and tolerate both capital and lowercase?
  4241. 3:17:51Maybe what's the simplest, most naive implementation?
  4242. 3:17:54AUDIENCE: [INAUDIBLE]
  4243. 3:17:56DAVID J. MALAN: Yeah, so why don't I just ask two questions?
  4244. 3:17:58Or you know what, even more simplistic based only on what we've seen before--
  4245. 3:18:03if you will, let me just copy and paste some of this code.
  4246. 3:18:06Change this to an else-- whoops, not in caps-- else if "Y".
  4247. 3:18:11And then I bet I could do the same thing with n.
  4248. 3:18:13But here too, just like with Scratch, as soon
  4249. 3:18:15as you start to find yourself copying and pasting,
  4250. 3:18:17you're probably doing something wrong.
  4251. 3:18:19And what you said verbally, if I may, was actually better.
  4252. 3:18:22Because you're implying that I could just say something like OR c == "Y"
  4253. 3:18:29or, down here, c == "N".
  4254. 3:18:32The catch is, you can't use the word OR in C. It's actually two vertical bars.
  4255. 3:18:39So you can express one question or another.
  4256. 3:18:43You only need one of the answers to be yes or true,
  4257. 3:18:46and you use two vertical bars.
  4258. 3:18:48By contrast, just so you've seen it, if you
  4259. 3:18:50wanted to check if something is equal to something AND something else,
  4260. 3:18:54you could use two ampersands.
  4261. 3:18:56This logically would make no sense here, though.
  4262. 3:18:59Certainly, what the human typed can't both be lowercase and uppercase.
  4263. 3:19:02That just makes no sense.
  4264. 3:19:03So in this case, we do want OR.
  4265. 3:19:05But that allows me to tighten my code up.
  4266. 3:19:07I don't have to start copying and pasting whole branches.
  4267. 3:19:09I can now ask two questions at once.
  4268. 3:19:13Questions, then, on this variation?
  4269. 3:19:16Really good question.
  4270. 3:19:17Can you convert the input to all lowercase?
  4271. 3:19:19Absolutely, you could.
  4272. 3:19:20We don't have the capability yet.
  4273. 3:19:22It turns out that's going to require--
  4274. 3:19:24to be easy, another library, though we could do it
  4275. 3:19:27ourselves knowing a little bit about ASCII or Unicode from last week.
  4276. 3:19:30But, yes, that would be an alternative, but more on that a different time.
  4277. 3:19:34Other questions?
  4278. 3:19:34AUDIENCE: [INAUDIBLE]
  4279. 3:19:37DAVID J. MALAN: Good question.
  4280. 3:19:38Unfortunately, you have to be explicit in C. You can't just say this,
  4281. 3:19:41even though that's kind of how you might think about it.
  4282. 3:19:44You have to ask a complete question using the equality sign twice
  4283. 3:19:49in this case.
  4284. 3:19:50Let me ask a question now too.
  4285. 3:19:51It's not a typo.
  4286. 3:19:53I deliberately used single quotes around all of my single letters here.
  4287. 3:19:57Why might that be?
  4288. 3:19:59Previously, we used double quotes for anything that looked like text.
  4289. 3:20:03Yeah.
  4290. 3:20:05Correct, string is double quotes for multiple characters-- or even one,
  4291. 3:20:08technically, but yes.
  4292. 3:20:10And single quotes for single characters.
  4293. 3:20:14Because my data type is different.
  4294. 3:20:15I chose the simple route of just using a single char.
  4295. 3:20:18In fact, this program won't work with Y-E-S
  4296. 3:20:21or N-O. That's not supported at the moment-- more on that another time.
  4297. 3:20:25I had to use single quotes because that's how C does it.
  4298. 3:20:27If you're dealing with single characters,
  4299. 3:20:29a.k.a. chars, use single quotes.
  4300. 3:20:31If it's a string--
  4301. 3:20:32even if it's one single character in a string
  4302. 3:20:36as though you're starting to write out a longer word or sentence--
  4303. 3:20:39that would be double quotes.
  4304. 3:20:40And we'll see why this is before long too.
  4305. 3:20:42But, again, just things to keep in mind whenever writing code
  4306. 3:20:46in this particular language.
  4307. 3:20:48Yeah, down here.
  4308. 3:20:50So, short answer, if I'm understanding correctly, this would be incorrect.
  4309. 3:20:56And this would be even more incorrect.
  4310. 3:20:58But if you don't mind, let me kick the can a couple of weeks
  4311. 3:21:00on this as to why this doesn't work.
  4312. 3:21:02The most pleasant way to do this would indeed be to do something like this.
  4313. 3:21:06But even this is a slippery slope, because what
  4314. 3:21:08if the user does something weird, like they capitalize just the Y?
  4315. 3:21:12You can imagine this getting messy quickly.
  4316. 3:21:13I like your idea earlier about just forcing everything
  4317. 3:21:16to lowercase just to standardize things.
  4318. 3:21:18Unfortunately, you cannot compare strings for equality like this
  4319. 3:21:22for, again, reasons will come to before long.
  4320. 3:21:24So for today, we're keeping it simple, even though, arguably, it's
  4321. 3:21:27not nearly as user-friendly to only tolerate individual letters.
  4322. 3:21:31And there's a question over here.
  4323. 3:21:34On the US English keyboard it's shift and then
  4324. 3:21:36the backslash key above Return, but depending on your keyboard,
  4325. 3:21:40it will vary.
  4326. 3:21:42All right, so let's actually now look back
  4327. 3:21:45at something we did a little bit of last week.
  4328. 3:21:47Let me go ahead and open a file called meow.c,
  4329. 3:21:49because, recall, that's what we had Scratch do initially.
  4330. 3:21:52Let me include not the C50 library this time,
  4331. 3:21:55but just stdio.h because I only want printf for this demo.
  4332. 3:21:59Let me go ahead now and just print out meow.
  4333. 3:22:02And then if I want the cat to meow three times, like it did last week,
  4334. 3:22:06meow, meow, meow.
  4335. 3:22:07Save it.
  4336. 3:22:08make meow, ./meow.
  4337. 3:22:10Voila.
  4338. 3:22:11The program is written-- correct, I claim.
  4339. 3:22:14It ran.
  4340. 3:22:14It compiled OK.
  4341. 3:22:15But, again, this was the beginning of our conversation
  4342. 3:22:17last week of not being particularly well-designed.
  4343. 3:22:20And if someone wants to maybe point out the now obvious,
  4344. 3:22:23why is this not well-designed, necessarily?
  4345. 3:22:28Yeah, it's just repetition, right?
  4346. 3:22:29Again, I literally resorted to copy-paste.
  4347. 3:22:31That should be the signal that you're probably
  4348. 3:22:33doing something wrong or, at best, just lazy of you, in this case.
  4349. 3:22:37So the solution, as you might glean from last week,
  4350. 3:22:40is probably going to be one of those things called loops.
  4351. 3:22:42So let's just take a look at some of the syntax for loops in C.
  4352. 3:22:45But, again, no new ideas, it's just some new syntax
  4353. 3:22:48that'll take some getting used to.
  4354. 3:22:49In Scratch, if you wanted to meow forever with something like this,
  4355. 3:22:53there's not a forever keyword in C, so this one's a little weird to look at.
  4356. 3:22:57But this is the best we can do.
  4357. 3:22:59It turns out there is a keyword called while in C.
  4358. 3:23:03And that kind of has the right semantics,
  4359. 3:23:05because it's like while I do something again and again,
  4360. 3:23:08that's the best I can do.
  4361. 3:23:10But just like an if condition or an else if condition,
  4362. 3:23:14those took a Boolean expression in parentheses,
  4363. 3:23:18a while loop also takes a Boolean expression in parentheses.
  4364. 3:23:21So I have to ask a question.
  4365. 3:23:22Now, if I want to do something forever, I could kind of stupidly just
  4366. 3:23:26say while 2 is greater than 1, while 3 is greater than 2,
  4367. 3:23:30or just something completely arbitrary.
  4368. 3:23:32But that should rub you the wrong way, because like, why 2 versus 1?
  4369. 3:23:36Why 3-- if you want true, just say true.
  4370. 3:23:41So it turns out in C, there are special keywords, true and false,
  4371. 3:23:45that are literally true and false, respectively.
  4372. 3:23:48I could also put the number 1 for true and the number 0 for false,
  4373. 3:23:53but most people would just say true to be explicit.
  4374. 3:23:56So it's a little hackish, if you will, but very conventional.
  4375. 3:23:59There's no forever keyword in C. If I want to then print meow forever,
  4376. 3:24:03I'm going to just use something like printf here.
  4377. 3:24:06So, again, not perfect translation from one
  4378. 3:24:08to the other, but absolutely possible in C. What about this?
  4379. 3:24:11This is a little more common if you want to do something
  4380. 3:24:14a finite number of times, like repeat 3.
  4381. 3:24:17There's a few different ways we can do this in C. Here's one approach.
  4382. 3:24:21And here's where C-- like a lot of text-based languages,
  4383. 3:24:25you kind of have to whip out that toolkit of all of the basic building
  4384. 3:24:28blocks and think about, all right, how can I
  4385. 3:24:31build a little machine in software that does something some number of times?
  4386. 3:24:35Well, let me give myself a variable called counter, set it equal to 0.
  4387. 3:24:40Let me create a loop whose Boolean expression is counter less than 3,
  4388. 3:24:46the idea being here, why don't I just kind of count 1, 2, 3?
  4389. 3:24:50So how do I implement this physicality in code?
  4390. 3:24:53I give myself a variable, set it to 0, 0 fingers up.
  4391. 3:24:57Now, I ask the question, is counter less than 3?
  4392. 3:25:00If so, go ahead and print out meow.
  4393. 3:25:02And just intuitively, even if you've never seen C code or any code
  4394. 3:25:06before Scratch, what more do I need to do?
  4395. 3:25:09I've left room here for one more line of logic.
  4396. 3:25:12Yeah.
  4397. 3:25:13We have to increase counter.
  4398. 3:25:15So I need code like I showed earlier, like counter equals counter plus 1.
  4399. 3:25:19And so here's where programming sometimes
  4400. 3:25:21becomes a bit more like plumbing.
  4401. 3:25:22You can't just say what you mean, like you couldn't Scratch.
  4402. 3:25:25You have to build a little sort of software machine
  4403. 3:25:28that initializes a value, does something, increments it, checks it.
  4404. 3:25:31And so it's kind of like this software-based machine,
  4405. 3:25:34but together, that's just using some familiar building blocks.
  4406. 3:25:37But this is pretty common.
  4407. 3:25:38Just like in Scratch, you might have used loops a bunch
  4408. 3:25:40of times, pretty common in C.
  4409. 3:25:42So can we tighten this code up?
  4410. 3:25:44This is correct, but here are some conventions that are popular.
  4411. 3:25:48If you're going to count, just say i.
  4412. 3:25:51A convention in programming-- with, at least,
  4413. 3:25:52languages like C-- is just use i as an integer if all its purpose is
  4414. 3:25:57is to count from like, 0 on up.
  4415. 3:25:59Counter is not wrong.
  4416. 3:26:01It's not bad.
  4417. 3:26:01It's just more verbose than you need to be.
  4418. 3:26:04Just call it i.
  4419. 3:26:05You don't need more semantics than that.
  4420. 3:26:07All right, what else can I do here?
  4421. 3:26:08There's another opportunity to tighten up this code.
  4422. 3:26:12Do you recall?
  4423. 3:26:12Yeah.
  4424. 3:26:14Yeah, that syntactic sugar that does nothing new,
  4425. 3:26:17but it does it more succinctly.
  4426. 3:26:19I can change this to either the intermediate format or even tighter
  4427. 3:26:23format of just i++.
  4428. 3:26:25Now, this is pretty canonical.
  4429. 3:26:27This is how most people would implement something
  4430. 3:26:31three times using a loop in C--
  4431. 3:26:34using a while loop, that is.
  4432. 3:26:36Turns out that it's so common in C and other languages
  4433. 3:26:39to do something finitely many times, there's a couple of ways to do it.
  4434. 3:26:43In this model, to be clear, the logic, though,
  4435. 3:26:46is that we start by initializing the variable, like I've highlighted here.
  4436. 3:26:49We then ask the question, is i less than 0?
  4437. 3:26:52If so, everything that's indented inside the curly braces
  4438. 3:26:56gets executed-- namely, meow then the update.
  4439. 3:26:59Then the computer is going to have to recheck the condition
  4440. 3:27:02to make sure that i hasn't gotten so big that it's greater than 3.
  4441. 3:27:06But if not, it then does this again and it does this again.
  4442. 3:27:09And then it repeats, constantly checking the condition
  4443. 3:27:12and executing what's in the block, checking the condition
  4444. 3:27:14and executing what's in the block.
  4445. 3:27:15After three times of that, the condition is going to be false, or a no answer,
  4446. 3:27:20and that's it for the code.
  4447. 3:27:21It just proceeds to whatever's down here, just like with Scratch.
  4448. 3:27:24It jumps to the next blocks down below.
  4449. 3:27:27All right, what's another way, though, to do this?
  4450. 3:27:30Well, I've deliberately been counting from 0--
  4451. 3:27:32and that's a programming convention, right?
  4452. 3:27:33We started last week with all the light bulbs off, which was 0.
  4453. 3:27:36So it's pretty reasonable to start counting at 0's, just
  4454. 3:27:39like you would here.
  4455. 3:27:39Like, no fingers are up, this is 0--
  4456. 3:27:41fingers on your hand.
  4457. 3:27:43But if you prefer, you could start counting at i equals 1.
  4458. 3:27:47But then you don't want to do it while i is less than 3,
  4459. 3:27:51you want to do i is less than or equal to 3.
  4460. 3:27:54On most keyboards, there's no symbol for less than or equal to or greater than
  4461. 3:27:58or equal to, so in C, you use two characters, less than
  4462. 3:28:02and then an equals sign with no spaces in between.
  4463. 3:28:05That just means less than or equal to.
  4464. 3:28:08We could change it to set i to 2 and make this condition be less than
  4465. 3:28:12or equal to 4.
  4466. 3:28:13We could make this be a 10 and less than or equal to 12.
  4467. 3:28:18But, again, just stick with the basics.
  4468. 3:28:20Start at 0 and count on up would be the convention.
  4469. 3:28:23Or if you prefer to count down, that's fine too.
  4470. 3:28:27Set i to 3 and then do this so long as i is greater than 0,
  4471. 3:28:31but you have to decrement instead of increment.
  4472. 3:28:34So, again, we could do this all day long.
  4473. 3:28:36There's literally an infinite number of ways to implement this idea.
  4474. 3:28:39And that's why I keep emphasizing convention.
  4475. 3:28:41Call the variable i for something like this,
  4476. 3:28:43initialize it to 0 for something like this, and just generally count up,
  4477. 3:28:47unless you really prefer to count down.
  4478. 3:28:49Again, just certain human conventions.
  4479. 3:28:51All right, how about another way to do this?
  4480. 3:28:55This is what's called a for loop in C, also very common.
  4481. 3:28:59It's not quite as straightforward in that it doesn't really read top
  4482. 3:29:02to bottom in exactly the same way.
  4483. 3:29:04This kind of has a lot more logic tucked into its first line.
  4484. 3:29:07But it does exactly the same thing.
  4485. 3:29:09What happens here is--
  4486. 3:29:11notice that inside the parentheses, next to the word for,
  4487. 3:29:15there's two semicolons-- which is another weird use of syntax.
  4488. 3:29:18They're not at the end of the line, now they're
  4489. 3:29:20in the middle of the parentheses.
  4490. 3:29:21But that's what the humans chose years ago.
  4491. 3:29:24The first thing before the semicolons initializes your variable, int i = 0.
  4492. 3:29:30The next thing is the condition that's going to constantly get
  4493. 3:29:34checked every cycle through this loop.
  4494. 3:29:36And the last thing is going to be what you do after each loop, which
  4495. 3:29:41in this case is going to be count up.
  4496. 3:29:42So, again, if I rewind we initialize i to 0.
  4497. 3:29:45We then ask the question, is i less than 3?
  4498. 3:29:48If so, execute what's inside of the loop.
  4499. 3:29:52Then the computer does this, it does the update, incrementing i by 1.
  4500. 3:29:58And then it's not going to blindly meow again.
  4501. 3:30:01It's going to check again the condition, is i less than 3?
  4502. 3:30:04Then it's going to meow if so.
  4503. 3:30:06Then it might go ahead and increment i and check the condition again.
  4504. 3:30:10So, again, this does not read quite the same simple fashion top to bottom.
  4505. 3:30:14You kind of read it left to right and then jump around.
  4506. 3:30:16But, again, the initialization, the constant Boolean expression
  4507. 3:30:21being checked, and the update after each time
  4508. 3:30:24does the exact same thing as what we saw a moment ago in this while loop format.
  4509. 3:30:32Which one is better?
  4510. 3:30:34Eh, they're the same.
  4511. 3:30:35I think most people would probably eventually use
  4512. 3:30:37a for loop once comfortable, but just because is really the answer there.
  4513. 3:30:42All right, any questions, then, on loops as we've translated them to C?
  4514. 3:30:45Yeah.
  4515. 3:30:46AUDIENCE: [INAUDIBLE]
  4516. 3:30:47DAVID J. MALAN: A for loop and while loop
  4517. 3:30:49can both be used to do exactly the same thing.
  4518. 3:30:53There are subtle differences with issues of scope,
  4519. 3:30:56which we'll discuss before long, where when you
  4520. 3:30:58create a variable in a for loop--
  4521. 3:31:00notice that it was, again, inside of those parentheses, which
  4522. 3:31:04technically means it's only going to exist in these four lines of code.
  4523. 3:31:08By contrast, with the while loop, I declared my variable outside
  4524. 3:31:12of the loop.
  4525. 3:31:13That variable is going to continue to exist elsewhere in my program.
  4526. 3:31:17So that's one of the minor differences there.
  4527. 3:31:20Good question.
  4528. 3:31:20But you'll see some others over time.
  4529. 3:31:22All right, so we claim then that it's better in some form
  4530. 3:31:26to do this with loops.
  4531. 3:31:27So let's actually jump back to the code.
  4532. 3:31:29Let me go ahead and now re-implement meowing with a for loop, for instance.
  4533. 3:31:33So how about for int i = 0, i less than 3, i++.
  4534. 3:31:39Then inside my curly braces, let me go ahead and print out with printf, meow,
  4535. 3:31:44with a newline and a semicolon.
  4536. 3:31:46So I did it pretty quickly just because I've long acquired the muscle memory.
  4537. 3:31:50But if I now make meow, no errors there.
  4538. 3:31:53Run ./meow.
  4539. 3:31:54And I see meow, meow, meow.
  4540. 3:31:57Well, let's do now what we did last week, which
  4541. 3:31:59was to begin to make our own custom functions, if you will,
  4542. 3:32:03by using our own in C. So here's where the syntax gets a little funky,
  4543. 3:32:09but we'll explain over time what each of these keywords is doing.
  4544. 3:32:13If I want to create a function called meow--
  4545. 3:32:17because the authors of C did not create a function called meow decades ago--
  4546. 3:32:21I need to give it a name, like meow.
  4547. 3:32:23I need to specify if it takes any inputs.
  4548. 3:32:26For now, I'm going to say no.
  4549. 3:32:28And I'm going to explicitly say no by writing the special word void.
  4550. 3:32:34It's also necessary when implementing a function in C--
  4551. 3:32:37which was not necessary in Scratch--
  4552. 3:32:38to specify what its return type is.
  4553. 3:32:41But for now, I'm just going to say that meow is the name of the function,
  4554. 3:32:45it takes no inputs--
  4555. 3:32:46and that's what the void in parentheses means--
  4556. 3:32:49and it does not return anything like ask did,
  4557. 3:32:54or like get_string or get_int does.
  4558. 3:32:56meow's purpose in life is just to have side effects, visual side effects
  4559. 3:32:59by printing something on the screen.
  4560. 3:33:01So what is meow going to do?
  4561. 3:33:04I'm going to have it quite simply say printf,
  4562. 3:33:06quote unquote, "meow", backslash n.
  4563. 3:33:10And now, just like in Scratch, I can now just call
  4564. 3:33:14a brand new function called meow.
  4565. 3:33:16And here's where too, if you really don't like the curly braces,
  4566. 3:33:19technically speaking, you can get rid of them when there's
  4567. 3:33:22only one line of code inside your loop.
  4568. 3:33:24But, again, stylistically, I would encourage
  4569. 3:33:27you to preserve them to make super clear to yourself and others
  4570. 3:33:30what it is that's going on.
  4571. 3:33:32Let me go ahead and save this and do make meow.
  4572. 3:33:35Whoops.
  4573. 3:33:36Darn.
  4574. 3:33:37All right, what did I do?
  4575. 3:33:38Something stupid.
  4576. 3:33:39AUDIENCE: [INAUDIBLE]
  4577. 3:33:39DAVID J. MALAN: Yeah, so 0 does not belong there.
  4578. 3:33:42I meant to hit parenthesis.
  4579. 3:33:44So let me rerun make meow.
  4580. 3:33:46OK, fixed.
  4581. 3:33:48My mistake.
  4582. 3:33:49All right, it's still working OK.
  4583. 3:33:51But recall what I did in Scratch, kind of out of sight, out of mind.
  4584. 3:33:54And just to make a point, let me just highlight this and move it
  4585. 3:33:57way down in the file.
  4586. 3:33:59Because, again, now that meow exists, it's an abstraction.
  4587. 3:34:02I just know a meow function exists.
  4588. 3:34:04I want to be able to use it.
  4589. 3:34:06So let me scroll back up.
  4590. 3:34:08My main function is the same.
  4591. 3:34:09Let me go ahead and make meow again.
  4592. 3:34:12And now, just by moving that function, I've created all these lines of errors.
  4593. 3:34:17And let's look at the first.
  4594. 3:34:18Again, the rule of thumb here-- it's a little small,
  4595. 3:34:21but it says meow.c in bold-- which is the name of the file where the bug is--
  4596. 3:34:255 is the line number, and 20 is the character.
  4597. 3:34:27So line number is enough alone.
  4598. 3:34:30Let's see.
  4599. 3:34:32Oh, this is what happens when I scrolled up too far.
  4600. 3:34:36Sorry.
  4601. 3:34:37This is the error we're now looking at, line 7.
  4602. 3:34:39I was looking at the old error message from earlier before I fixed the 0.
  4603. 3:34:43meow.c line 7.
  4604. 3:34:45All right, apparently, C does not know what the meow function is.
  4605. 3:34:49Implicit declaration of function meow is invalid in C99.
  4606. 3:34:53Well, what does that mean?
  4607. 3:34:54Declaration of function means your creation of a function.
  4608. 3:34:57Like, I'm declaring that meow exists, but I haven't apparently
  4609. 3:35:01defined it yet.
  4610. 3:35:02And then C99 is the version of C from the year 1999,
  4611. 3:35:06which we generally use here, it's one of the more recent versions.
  4612. 3:35:09So why is that the case?
  4613. 3:35:12Can you infer from the mere fact that I just moved meow to the bottom
  4614. 3:35:16of the file-- which was fine in Scratch but now is bad--
  4615. 3:35:19why is that?
  4616. 3:35:20AUDIENCE: [INAUDIBLE]
  4617. 3:35:21DAVID J. MALAN: Yeah, C is just kind of old school.
  4618. 3:35:23It reads your code top to bottom.
  4619. 3:35:25And if it does not know what meow is when you first try to use it,
  4620. 3:35:30it just freaks out and prints out these error messages.
  4621. 3:35:32So the solution is, quite simply, don't do that, just leave it where it was.
  4622. 3:35:38But you can imagine this getting a little annoying over time, if only
  4623. 3:35:42because main is, by name, the main part of your program.
  4624. 3:35:46And, honestly, it would just be nice if main were always
  4625. 3:35:49at the top of your code.
  4626. 3:35:51Because if you want to understand what a file is doing,
  4627. 3:35:53it makes sense to just read it top to bottom.
  4628. 3:35:55Well, there is a solution to this.
  4629. 3:35:57You can put functions in different orders with main at the top so long
  4630. 3:36:02as you-- and this is perhaps the only time copy paste is appropriate--
  4631. 3:36:07so long as you leave a little breadcrumb for the compiler
  4632. 3:36:10at the very top of your file that literally
  4633. 3:36:13repeats the return value, the name, and the arguments
  4634. 3:36:17to that function, semicolon.
  4635. 3:36:19This is, so to speak, declaring your function--
  4636. 3:36:22and the real fancy way is this is a prototype.
  4637. 3:36:25It's like, what is this thing going to look like?
  4638. 3:36:27But the semicolon means I'm not going to deal with this yet.
  4639. 3:36:30I'm going to actually define the function
  4640. 3:36:32or implement it down below here.
  4641. 3:36:34This is kind of a stupid detail.
  4642. 3:36:36More recent languages get rid of this need,
  4643. 3:36:40you can put your functions in any order.
  4644. 3:36:41But, again, if you just think about the basics
  4645. 3:36:43of programming languages like this one here--
  4646. 3:36:46and as you noted--
  4647. 3:36:47it must just be reading your code top to bottom.
  4648. 3:36:49So annoying, yes, but explained, yes too.
  4649. 3:36:53So let me go ahead and make meow one more time, ./meow, still working OK.
  4650. 3:36:58And let me make one final enhancement to this meow program here.
  4651. 3:37:02Let me go ahead now and say something like this.
  4652. 3:37:05Let me go ahead and say, all right, wouldn't it
  4653. 3:37:07be nice if my meow function could do something for me some number of times?
  4654. 3:37:12So suppose I want to do this.
  4655. 3:37:14This meow function at the moment is going to meow three times.
  4656. 3:37:17But suppose I want to meow n times, where n is just
  4657. 3:37:21some number provided by the user.
  4658. 3:37:23Well, just like in Scratch, custom functions can take inputs,
  4659. 3:37:27I just presently am saying void.
  4660. 3:37:30But if I change this to int n, thereby telling the compiler,
  4661. 3:37:34hey, meow still doesn't return something,
  4662. 3:37:38but it does take something as input.
  4663. 3:37:40It takes an integer, and I want to call it n.
  4664. 3:37:43So this is another way of declaring a variable
  4665. 3:37:46but a way of declaring a variable that gets handed into,
  4666. 3:37:48as input, the function.
  4667. 3:37:50So now if I tighten up main here, now I can actually do something really cool
  4668. 3:37:55just like in Scratch, which is this.
  4669. 3:37:58If I now look at this code-- let me Zoom in here--
  4670. 3:38:01now my main program is really well-written in the sense
  4671. 3:38:04that it just says what it does, meow three times.
  4672. 3:38:07This works, though, because I defined meow as now taking an input,
  4673. 3:38:11an integer called n, and then using n in my now familiar for loop.
  4674. 3:38:17There's one change.
  4675. 3:38:18You might have caught my one mistake.
  4676. 3:38:21I also have to remind myself up here to make that change too.
  4677. 3:38:25Again, this is one of the only redundancies or copy-paste
  4678. 3:38:27that's sort of reasonable.
  4679. 3:38:29But there, I have now a better version.
  4680. 3:38:32So let me go ahead and rerun this, make meow, ./meow.
  4681. 3:38:36Voila.
  4682. 3:38:36So, again, no change in correctness but now,
  4683. 3:38:39again, we're sort of modularizing our code.
  4684. 3:38:41And, heck, what you could do now-- and this is just a tease about a feature
  4685. 3:38:44down the road--
  4686. 3:38:45those header files we talked about early, those libraries,
  4687. 3:38:48this is the kind of modularization we're talking about.
  4688. 3:38:51We, the staff, wrote a function called get_string, get_int, and so forth,
  4689. 3:38:54we put it in a file called CS50, and we put little breadcrumbs-- specifically,
  4690. 3:39:01these things called prototypes--
  4691. 3:39:03in cs50.h.
  4692. 3:39:05So that when you all, as aspiring programmers, include cs50.h,
  4693. 3:39:10you are sort of secretly telling the compiler at the very top of your code
  4694. 3:39:14what the menu of available functions is.
  4695. 3:39:16Why?
  4696. 3:39:16Because in CS50 is lines like these-- obviously, not for meow,
  4697. 3:39:21but for get_string, get_int, and so forth.
  4698. 3:39:24And stdio.h is the same lines of code for things like printf.
  4699. 3:39:29So that's all that's going on there.
  4700. 3:39:31It's just a way of telling the computer in advance what functions to expect.
  4701. 3:39:38All right, any questions, then, on these here?
  4702. 3:39:43Correct.
  4703. 3:39:44So if you don't mind, I want to continue to wave
  4704. 3:39:47my hand at that detail for today.
  4705. 3:39:49Indeed, int main void is a little weird, because what would the input domain be?
  4706. 3:39:53We have no mechanism for providing input yet.
  4707. 3:39:55And what does it mean for main to return anything?
  4708. 3:39:57Like, who is it returning to?
  4709. 3:39:59For another day, if we may.
  4710. 3:40:00They're going to come into play but that, for now,
  4711. 3:40:02today is just something you should take at face value,
  4712. 3:40:05as necessary copy-paste to begin programs.
  4713. 3:40:08So meow is a function that takes an input, the number of times to meow,
  4714. 3:40:11but it didn't actually have a return value, hence the void.
  4715. 3:40:14But what if we actually want to create our own function that
  4716. 3:40:17not only takes 0 or more inputs as arguments
  4717. 3:40:20but also returns some value, maybe an int, maybe a float, maybe something
  4718. 3:40:24else altogether?
  4719. 3:40:24Well, it turns out, in C, we can do that as well.
  4720. 3:40:27Let me go ahead and create a new file here called discount.
  4721. 3:40:31And let's implement a quick program via which
  4722. 3:40:33we can discount some regular price by some percentage,
  4723. 3:40:35as though there's a sale going on in a store.
  4724. 3:40:37Let me go ahead and include our usual cs50.h followed by stdio.h at the top.
  4725. 3:40:44Let me give myself int main void as before.
  4726. 3:40:47And inside of main, let's go ahead and do something simple.
  4727. 3:40:50Let's give ourselves a float called regular,
  4728. 3:40:52representing the regular price of something in a store.
  4729. 3:40:55Let's go ahead and get a float from the user asking them
  4730. 3:40:58what that regular price is.
  4731. 3:41:00Then, next, let's go ahead and declare a second variable-- also a float--
  4732. 3:41:04called sale, ultimately representing the sale price
  4733. 3:41:07after some percentage discount off.
  4734. 3:41:09And let's go ahead and simply calculate whatever regular is.
  4735. 3:41:13And, say, 15% off is a pretty good discount.
  4736. 3:41:15So let's go ahead and discount regular, whatever it is, by 15%,
  4737. 3:41:20which is equivalent, of course, to multiplying it with the asterisk
  4738. 3:41:23by 0.85.
  4739. 3:41:25Of course, if we're taking off 15%, we multiply the regular price by 0.85.
  4740. 3:41:30Now, let's go ahead and print out the results here.
  4741. 3:41:32Let me go ahead and say printf sale price, colon--
  4742. 3:41:36let me go ahead and %f, but, more specifically,
  4743. 3:41:38%.2f because, at least in US currency we typically show cents to two decimal
  4744. 3:41:43places--
  4745. 3:41:44followed by a newline.
  4746. 3:41:45And then let me go ahead and plug in the value of sale.
  4747. 3:41:48All right, let's go down here and do make discount, Enter.
  4748. 3:41:52So far, so good-- ./discount.
  4749. 3:41:54And the regular price is maybe $100.
  4750. 3:41:57So the sale price should be $85.
  4751. 3:41:59So our arithmetic seems to be correct here.
  4752. 3:42:01But let's fast-forward now in time.
  4753. 3:42:02Suppose that we find ourselves discounting
  4754. 3:42:04a lot of prices in an application, maybe a website
  4755. 3:42:07like Amazon where they're offering some kind of percentage discount.
  4756. 3:42:10And it'd be nice to have a reusable function that
  4757. 3:42:13just does this arithmetic for us, simple though it may be.
  4758. 3:42:16So let's go ahead and modify discount this time
  4759. 3:42:18to give ourselves our own function called discount,
  4760. 3:42:22for instance, that takes an input--
  4761. 3:42:23like the regular price that you want to discount--
  4762. 3:42:25and then it also returns a value.
  4763. 3:42:28It doesn't just print it out.
  4764. 3:42:29It returns a value, namely, a float that represents what the sale price is.
  4765. 3:42:34So let me go down below main and go ahead
  4766. 3:42:37and define a function that's going to return a float,
  4767. 3:42:39because we're dealing with dollar amount still.
  4768. 3:42:42The function is going to be called discount.
  4769. 3:42:43And it's going to take one input, like the price that we want to discount.
  4770. 3:42:47In here, I'm going to do something very simple.
  4771. 3:42:50I'm going to say float sale equals whatever that price is times 0.85.
  4772. 3:42:55And then I'm going to go ahead and return sale.
  4773. 3:42:58Now, for that matter, I can actually tighten this up a bit.
  4774. 3:43:00If I'm only declaring a variable to store a value that I'm then
  4775. 3:43:04returning with this keyword return, I actually don't even need that variable.
  4776. 3:43:09So I can delete the second line.
  4777. 3:43:11And I can actually just go ahead and get rid of that variable
  4778. 3:43:13altogether and immediately return whatever the arithmetic
  4779. 3:43:16result is of taking the price input, the argument that's being passed in,
  4780. 3:43:20times 0.85.
  4781. 3:43:21So very simple function that simply does the discounting for me.
  4782. 3:43:25As always, let me go ahead and copy-paste--
  4783. 3:43:29the only time it's OK to copy-paste-- the prototype of that function, so
  4784. 3:43:32the top of the file, so that when compiling this code,
  4785. 3:43:35main has already seen the word discount before.
  4786. 3:43:38And now let me go into the code here.
  4787. 3:43:40And instead of doing the math myself in main,
  4788. 3:43:43let me presume that we have some function already
  4789. 3:43:46in our toolkit called discount that lets me discount the regular price
  4790. 3:43:50and return that value.
  4791. 3:43:52And then down here, my code doesn't need to change.
  4792. 3:43:54I'm still going to print out sale the variable in which I'm
  4793. 3:43:58storing that result. But notice what I've done here.
  4794. 3:44:00I've sort of abstracted the way the notion
  4795. 3:44:02of taking a discount by creating my own function that takes a float called
  4796. 3:44:06price, or anything else as input.
  4797. 3:44:07It does a little bit of math, simple though it is here,
  4798. 3:44:10and then it returns a value.
  4799. 3:44:12But notice that discount is not printing that value.
  4800. 3:44:14It's literally using this other keyword called
  4801. 3:44:17return so that I can hand back that value, just like get_string hands
  4802. 3:44:21back a value, just like get_int back an integer without printing it
  4803. 3:44:25for you-- so that I up here on line 9 can go ahead and store
  4804. 3:44:29that value in a variable if I want and then actually print it out.
  4805. 3:44:33Let me go ahead now and recompile this code with make discount.
  4806. 3:44:38Let me go ahead and do ./discount.
  4807. 3:44:40And let's, again, do $100.
  4808. 3:44:43Sale price is going to be $85 as well.
  4809. 3:44:46Now, it turns out that functions don't have to take just 0 or 1 argument
  4810. 3:44:50as input.
  4811. 3:44:51They can actually take 2 or 3 or more.
  4812. 3:44:53So, in fact, suppose we wanted to now enhance this version of my program
  4813. 3:44:57and take in as input to the discount function, not just the price
  4814. 3:45:01that I want to discount but also the percentage off,
  4815. 3:45:03thereby allowing us to support not just 15% off but any number of percentage
  4816. 3:45:08points off.
  4817. 3:45:08Well, let me go up here and declare an int, say, and call it percent_off.
  4818. 3:45:13And let me ask the user for how many percentage
  4819. 3:45:15points they want to take off.
  4820. 3:45:17So I'm going to say percent_off inside of the prompt here,
  4821. 3:45:21get that int called percent_off.
  4822. 3:45:23And now in addition to passing in regular as an input
  4823. 3:45:26to the discount function, I'm also going to pass in percent_off.
  4824. 3:45:30But I need to tell the computer that it is taking now two arguments,
  4825. 3:45:34and the way I do this is just with a comma
  4826. 3:45:37down here in the function's own definition.
  4827. 3:45:39Here is going to be a percentage argument, a second argument,
  4828. 3:45:43per the comma.
  4829. 3:45:44And I'm now going to use that percentage in a slightly familiar way.
  4830. 3:45:50I don't want to just do percentage like this, because, of course,
  4831. 3:45:53that's going to increase the size of the total price.
  4832. 3:45:56I actually need to do a little bit of real-world math where if this is
  4833. 3:45:59a percentage off, like the number 15 for 15 percentage points,
  4834. 3:46:03I need to do 100 minus that many percentage points,
  4835. 3:46:06thereby giving me 100 minus 15--
  4836. 3:46:0885.
  4837. 3:46:09And then I need to divide that by 100 in order now
  4838. 3:46:13to give myself 0.85 times the price that was passed in.
  4839. 3:46:18But if I go ahead now and save this, run, make discount one last time,
  4840. 3:46:22I notice that I've actually got an error here.
  4841. 3:46:24What have I done wrong?
  4842. 3:46:26Well, I need to change that prototype too.
  4843. 3:46:28And, again, this is admittedly an annoying aspect of C
  4844. 3:46:30that you have to maintain consistency here.
  4845. 3:46:32But that's fine.
  4846. 3:46:33I'm just going to go up here, change this to int
  4847. 3:46:35percentage-- spelling incorrectly.
  4848. 3:46:37And now let me retry compilation, make discount,
  4849. 3:46:40crossing my fingers this time.
  4850. 3:46:42Worked OK. ./discount, and voila, $100.
  4851. 3:46:46And percent off, say, 15 points.
  4852. 3:46:49And, voila, $85.
  4853. 3:46:52Now, it's worth noting that I've deliberately
  4854. 3:46:55returned the results of my math from this function.
  4855. 3:46:58I haven't just done the math on the original variable that's being passed.
  4856. 3:47:01In fact, if we take a look at this second version
  4857. 3:47:03where discount is now taking a price argument and a percentage argument,
  4858. 3:47:07notice that I'm not doing something like this.
  4859. 3:47:10I'm not just saying price equals price times 100
  4860. 3:47:14minus percentage divided by 100 and leaving at that.
  4861. 3:47:18The problem there is that this variable price is going
  4862. 3:47:21to be scoped to that discount function.
  4863. 3:47:24And we'll encounter this again before long, but this notion of scope
  4864. 3:47:27just refers to where in which a variable actually lives or exists
  4865. 3:47:32or is accessible.
  4866. 3:47:33So it turns out if I change price in the context of this discount
  4867. 3:47:36function, that's not going to have a lasting effect.
  4868. 3:47:38If I actually want to get the result back
  4869. 3:47:40to the function that used the discount function, namely, main,
  4870. 3:47:43I actually do need to take this approach of actually returning
  4871. 3:47:47the value explicitly so that ultimately I'm handing back the discounted price.
  4872. 3:47:51All right.
  4873. 3:47:52Well, let's go ahead and maybe how about let's just
  4874. 3:47:54use these primitives in just a few different ways.
  4875. 3:47:57How about a little game of yesteryear, Super Mario Brothers?
  4876. 3:48:02And in the original Super Mario Brothers and in bunches of variants,
  4877. 3:48:05so you have these side-scrolling worlds that
  4878. 3:48:08look like this where there's some coins in the sky hidden behind these question
  4879. 3:48:11marks.
  4880. 3:48:11So let's just use this as a visual to consider how in C could
  4881. 3:48:15I start to make something semi-graphical.
  4882. 3:48:17Like, not actual colors or fanciness, that feels like too much too soon--
  4883. 3:48:20just something like printing out some question marks.
  4884. 3:48:23Well, if I go back over here, let me create that actual file
  4885. 3:48:26that I alluded to earlier.
  4886. 3:48:27So let me code up mario.c.
  4887. 3:48:30Let me go ahead and include stdio.h, int main void, again,
  4888. 3:48:34which we'll continue to copy-paste for today.
  4889. 3:48:36And then let me just go ahead and do something simple like 1, 2, 3, 4,
  4890. 3:48:40and a newline.
  4891. 3:48:41All right, this is what we might call ASCII art, which
  4892. 3:48:44just means graphics but really just implemented with your keyboard.
  4893. 3:48:47And if I make mario and do ./mario, it's not nearly as engaging visually
  4894. 3:48:52as this, but it's the beginning of this kind of map for a game.
  4895. 3:48:55Well, if I wanted to now print out of those things dynamically,
  4896. 3:49:00let me go back to my code here.
  4897. 3:49:01And instead of printing out for all at once,
  4898. 3:49:03I could do something like four int i gets 0, i less than 4, i plus plus.
  4899. 3:49:08And then inside here, I could just print out one of them at a time.
  4900. 3:49:13Let me save that, make mario.
  4901. 3:49:15And, at the risk of disappointing, so close
  4902. 3:49:20but I made a mistake, just a stupid aesthetic.
  4903. 3:49:23The prompt is not on the new line.
  4904. 3:49:25How could I move it?
  4905. 3:49:27AUDIENCE: [INAUDIBLE]
  4906. 3:49:29DAVID J. MALAN: Yeah, I need an escape character, the backslash n.
  4907. 3:49:31But should I put it here?
  4908. 3:49:35OK, no, because that's going to put it after everyone,
  4909. 3:49:37and it's going to make this thing vertical instead of horizontal.
  4910. 3:49:40So, logically, just like in Scratch, put it at the end of the loop, so something
  4911. 3:49:44out here.
  4912. 3:49:44And just print out, for instance, only, quote unquote, new line.
  4913. 3:49:48And now if I do make mario again, ./mario, OK.
  4914. 3:49:51We're back in business.
  4915. 3:49:52But a little better designed in that now I'm
  4916. 3:49:54not repeating myself multiple times, I'm doing this again and again.
  4917. 3:49:57But let's do one other thing here with mario.
  4918. 3:50:00Let me go ahead and ask the user how many question marks or coins to print.
  4919. 3:50:05The catch here is that there's another type of loop that's helpful for this,
  4920. 3:50:09and it's called a do while loop, generally.
  4921. 3:50:12A do while loop is similar to a while loop,
  4922. 3:50:15but it checks the condition last instead of first.
  4923. 3:50:19Recall earlier on the slide, we had while,
  4924. 3:50:21open parenthesis, closed parenthesis.
  4925. 3:50:22And I kept claiming that we check whether i is less than-- whatever
  4926. 3:50:25it was, 3 in advance again and again.
  4927. 3:50:29A do while loop just inverts the logic so that you can actually
  4928. 3:50:32do something like this.
  4929. 3:50:34At the top of this program, I'm going to go ahead now
  4930. 3:50:36and give myself a variable n like this of type integer.
  4931. 3:50:40And then I'm going to do, literally, the following with the keyword do.
  4932. 3:50:44n equals get_int-- and I'm going to ask the user for the width,
  4933. 3:50:48like the number of dollar signs to print.
  4934. 3:50:51And I'm going to do this while n is less than, say, 1.
  4935. 3:50:56So this is a little cryptic, but the salient differences
  4936. 3:50:59are the Boolean expression is now at the bottom of my block of code,
  4937. 3:51:04not at the top.
  4938. 3:51:05Now, why is this?
  4939. 3:51:07Well, the difference here if I make mario is--
  4940. 3:51:11whoops.
  4941. 3:51:12I need to add cs50.h, because I'm now using get_int.
  4942. 3:51:16If I now compile this version of Mario and do ./mario,
  4943. 3:51:22a do while loop is helpful when you want to do something no matter what first
  4944. 3:51:26and then check some condition or some Boolean expression to see if maybe,
  4945. 3:51:30in this case, the user cooperated.
  4946. 3:51:32It would make no sense if the user typed in, say, 0,
  4947. 3:51:35because there's no work to be done.
  4948. 3:51:37It'd be really weird if they said negative 100,
  4949. 3:51:39because that makes no sense logically.
  4950. 3:51:41So with this simple construct here, I am doing the following
  4951. 3:51:46while n is less than 1.
  4952. 3:51:48The implication is that as soon as n equals 1 or is bigger than 1,
  4953. 3:51:53I'm going to break out of this loop, and I've got myself
  4954. 3:51:55a variable called n containing, essentially, a positive value, 1
  4955. 3:52:00through 2 billion or so.
  4956. 3:52:03And I can now use this, for instance, here, change the 4 to an n
  4957. 3:52:07so now my program is completely dynamic.
  4958. 3:52:09Let me go ahead and do make mario, ./mario again.
  4959. 3:52:13And I'll do 4, still works.
  4960. 3:52:15I'll do 40, still works.
  4961. 3:52:18And the difference here with the do while is if something like this
  4962. 3:52:22involves getting user input, well, there's no question to ask.
  4963. 3:52:25The user hasn't given you anything yet.
  4964. 3:52:27So you have to do something first, then check, and break out of the loop
  4965. 3:52:31if the human has, for instance, cooperated, in this case.
  4966. 3:52:35All right, well why don't we escalate to something
  4967. 3:52:37more like this in the same game, where you're underground as Mario,
  4968. 3:52:41and this is like a two-dimensional wall that's popping up here?
  4969. 3:52:45It looks like a 3 by 3, for instance, for the sake of discussion.
  4970. 3:52:48And it's like, made of bricks, so I'll use maybe hash symbols this time.
  4971. 3:52:51Well, it turns out that we can nest--
  4972. 3:52:53that is, combine-- some of these same ideas as follows.
  4973. 3:52:57Let me go ahead now and change back to this code.
  4974. 3:53:01And I'm going to keep the do while loop from before.
  4975. 3:53:05And I'm going to ask, though, this question,
  4976. 3:53:07what's the size of this square?
  4977. 3:53:09I'm going to assume it's n by n, so 3 by 3, 4 by 4, whatever.
  4978. 3:53:13So I'm just going to ask for the size of this square of bricks.
  4979. 3:53:16And now, how do I do this?
  4980. 3:53:18Well, I'm going to go ahead, for instance, and print out--
  4981. 3:53:20how about for int i = 0, i less than n, i++.
  4982. 3:53:25Let me just keep it simple and print out something
  4983. 3:53:27like this, just a single hash symbol that is a brick,
  4984. 3:53:32and a newline after it.
  4985. 3:53:34All right, let's make mario.
  4986. 3:53:36Run mario of 3.
  4987. 3:53:38OK, that's close to being it.
  4988. 3:53:40I've got a column.
  4989. 3:53:41All right, but I need it to be wider.
  4990. 3:53:43So the solution last time was to get rid of the newline
  4991. 3:53:45and then maybe put the newline here, after the loop.
  4992. 3:53:49All right, so let's do make mario, ./mario, and type in 3 and huh.
  4993. 3:53:55All right, so I kind of need to combine these two ideas somehow.
  4994. 3:54:00So how might we solve this problem?
  4995. 3:54:04I want to print rows and columns, not row or column.
  4996. 3:54:10How do I do this?
  4997. 3:54:12Yeah.
  4998. 3:54:12AUDIENCE: Add another loop in the for loop.
  4999. 3:54:15DAVID J. MALAN: Yeah.
  5000. 3:54:15Add another loop in the for loop, right?
  5001. 3:54:17If you use one loop conceptually to kind of count the rows from top
  5002. 3:54:21to bottom, and then within each row, you then
  5003. 3:54:24sort of typewriter style-- old school typewriter--
  5004. 3:54:26do like, character, character, character, character horizontally,
  5005. 3:54:30I think we could do exactly what we want to achieve here.
  5006. 3:54:32So how about this?
  5007. 3:54:33Let me get rid of this line and get rid of this line for now.
  5008. 3:54:36And let me just give myself another loop on the inside.
  5009. 3:54:39And since I'm already using i, another reasonable convention
  5010. 3:54:42here would be to say something like j.
  5011. 3:54:45So j also gets 0, j is less than n, j++.
  5012. 3:54:49And now, what's going to happen?
  5013. 3:54:51Let me go ahead and print out just one of these things at a time.
  5014. 3:54:56And let me save and let me run this.
  5015. 3:54:58Let me see how close we are.
  5016. 3:54:59Make mario 3.
  5017. 3:55:01OK, three, that's clearly wrong, but I see nine things there on the screen.
  5018. 3:55:06So we're close.
  5019. 3:55:07What's the one fix I need now to move the old school typewriter head
  5020. 3:55:12down to the next row when appropriate?
  5021. 3:55:15What do you think?
  5022. 3:55:17Yeah, I need one of these backslash n's.
  5023. 3:55:19And let me add some comments now to help everyone visualize what I've done.
  5024. 3:55:23For each row, for each column, how about print a brick--
  5025. 3:55:30just to kind of explain the logic?
  5026. 3:55:33And so I add that because now move to next row,
  5027. 3:55:37I could do something like this with a backslash n.
  5028. 3:55:40So here is where the comments, really, my pseudocode
  5029. 3:55:43actually kind of illuminates the situation a bit.
  5030. 3:55:46Let me go ahead and recompile mario, ./mario 3, now we're talking.
  5031. 3:55:51It's not a perfect square, just because these hash symbols
  5032. 3:55:53are a little taller than they are wide, but that's just a font detail here.
  5033. 3:55:57Now I've done something that's quite more akin to something like this.
  5034. 3:56:03All right, so let me pause here and see if there are any questions.
  5035. 3:56:08Again, the code's getting a little more complicated,
  5036. 3:56:10but we're just building more complicated programs like in Scratch,
  5037. 3:56:14with familiar puzzle pieces-- some variables,
  5038. 3:56:15some loops, some conditionals.
  5039. 3:56:17It's all the same as before.
  5040. 3:56:19Yeah.
  5041. 3:56:20Can you multiply strings in C?
  5042. 3:56:22No.
  5043. 3:56:22But ask that same question again in a few weeks when we get to Python,
  5044. 3:56:25and the answer will be yes.
  5045. 3:56:27Other questions.
  5046. 3:56:28Yeah.
  5047. 3:56:29In C, you must specify the return type, the name
  5048. 3:56:32of the function, and the inputs, or arguments,
  5049. 3:56:34to the function in that order.
  5050. 3:56:35And if none of them are applicable, you write the word void.
  5051. 3:56:39So same question as earlier, let me kick that can a week or so,
  5052. 3:56:42and we'll come back to that and we'll see why.
  5053. 3:56:44But for now, just take on faith that you need to do that with main.
  5054. 3:56:47Because main is a little special, similar to the
  5055. 3:56:49when green flag is clicked.
  5056. 3:56:51It too was a little special as well.
  5057. 3:56:54Yeah
  5058. 3:56:55AUDIENCE: [INAUDIBLE]
  5059. 3:57:01DAVID J. MALAN: Yes.
  5060. 3:57:02If you want to get out of a loop early, you could do this.
  5061. 3:57:05So let me answer this question this way.
  5062. 3:57:08An alternative to a do while loop would be to do something like this.
  5063. 3:57:14How about while true--
  5064. 3:57:15so do the following forever--
  5065. 3:57:18let me go ahead and get an inch from the user for the size of this thing.
  5066. 3:57:23If n is greater than 0--
  5067. 3:57:26that is, a positive integer--
  5068. 3:57:28then go ahead and use a new keyword called break.
  5069. 3:57:32This is identical to what we just did.
  5070. 3:57:35It's just a little longer.
  5071. 3:57:37It's like a couple extra lines, a lot of them are blank.
  5072. 3:57:39And so it's just an alternative.
  5073. 3:57:41But a do while does the same thing but a little tighter--
  5074. 3:57:43if that's in answer to your question.
  5075. 3:57:47All right, so let's now introduce, finally, a sequence of problems
  5076. 3:57:51that I've kind of been brushing under the rug,
  5077. 3:57:53though we did see a little bit of evidence of this earlier
  5078. 3:57:55when we tried to add 2 billion and 2 billion,
  5079. 3:57:57and it overflowed the number of bits in an int, so to speak.
  5080. 3:58:02Let me go ahead and code up a program called calculator again.
  5081. 3:58:06But I'm going to go ahead now and change this to floats.
  5082. 3:58:09So I'm going to change x to a float, and I'm going to use get_float.
  5083. 3:58:12And a float, again, is just a floating point value,
  5084. 3:58:15which is a fancy way of saying a real number with a decimal point in it.
  5085. 3:58:19And down here, I'm going to go ahead and use %f for float.
  5086. 3:58:22And I'm going to go ahead now and do one more thing.
  5087. 3:58:24Instead of addition, I want to do something fancier, like division,
  5088. 3:58:27so divide x by y.
  5089. 3:58:29And I'm going to give myself another third float called z,
  5090. 3:58:32as we did at the beginning of today.
  5091. 3:58:33And I'm going to print out z instead of x and y explicitly.
  5092. 3:58:37So I'm going to go ahead now and do make calculator, ./calculator.
  5093. 3:58:42And let's do something like, oh, 2/3.
  5094. 3:58:442 divided by 3 is 0.66667.
  5095. 3:58:47So that's what you would rather expect.
  5096. 3:58:49Let me run it again, 1/10.
  5097. 3:58:52All right, so 0.1, and a bunch of zeros.
  5098. 3:58:54That too is what you would rather expect.
  5099. 3:58:56But now let me get a little curious.
  5100. 3:58:58It turns out that in C, you can modify the behavior of these format
  5101. 3:59:02codes a little bit.
  5102. 3:59:03By default, you get 6 or so digits.
  5103. 3:59:05Suppose that you want to get exactly 2 digits.
  5104. 3:59:07You can more succinctly say 0.2 before the f and after the percent.
  5105. 3:59:11This is the kind of thing that's hard to remember, but you Google it,
  5106. 3:59:14and you find that, OK, format code for floats
  5107. 3:59:16uses 0.2 to do two decimal points.
  5108. 3:59:19So let me do make calculator again, ./calculator.
  5109. 3:59:23How about 2/3?
  5110. 3:59:240.67.
  5111. 3:59:25So it handles the display of significant digits for us here.
  5112. 3:59:28And now let me go ahead and do 1/10 and 0.10.
  5113. 3:59:32So it's adhering to that.
  5114. 3:59:33Well, maybe I really want a lot of precision, right?
  5115. 3:59:35I've got a really powerful computer.
  5116. 3:59:37Let me see 50 numbers after the decimal point.
  5117. 3:59:39That's a lot of significant digits.
  5118. 3:59:41Let me remake the calculator-- whoops, typo.
  5119. 3:59:44Let me remake the calculator, ./mario calculator.
  5120. 3:59:48And how about 2/3 again?
  5121. 3:59:51Well, that's interesting.
  5122. 3:59:54Pretty sure it's supposed to be a 0.6 with a line over it, right?
  5123. 3:59:58In grade school math.
  5124. 3:59:59All right, well, maybe that's just a bug.
  5125. 4:00:01How about 1/10?
  5126. 4:00:02OK, that's really getting funky.
  5127. 4:00:05So what's going on?
  5128. 4:00:06It seems that my program cannot only not do addition very well--
  5129. 4:00:10we eventually hit problems in the billions--
  5130. 4:00:12we can't even do very precise numbers here.
  5131. 4:00:16What's going on?
  5132. 4:00:19Exactly.
  5133. 4:00:19In a nutshell, the computer's approximating the answer
  5134. 4:00:22using that many numbers after the decimal point.
  5135. 4:00:25But the problem fundamentally is actually
  5136. 4:00:26very similar to that integer overflow from before.
  5137. 4:00:30And I'm using that now as a term of art.
  5138. 4:00:31Integers can overflow if you're trying to use more bits than you actually
  5139. 4:00:36have available to you.
  5140. 4:00:37You sort of change them all to ones, and then you're out of bits, so to speak.
  5141. 4:00:40Same thing here, but in the different context of floats--
  5142. 4:00:42if you only have 32 bits-- or, heck, if we
  5143. 4:00:45change to double and only have 64 bits, that's a lot of precision,
  5144. 4:00:48but it's not infinite.
  5145. 4:00:50And, yet, pretty sure there's an infinite number of real numbers.
  5146. 4:00:54In the world, which is to say a computer with finite memory cannot possibly
  5147. 4:00:59represent all possible numbers in the world.
  5148. 4:01:01Because, again, there's not an infinite number
  5149. 4:01:03of permutations of 32 or 64 bits.
  5150. 4:01:06It might be a lot, in the billions or more, but it's still finite.
  5151. 4:01:10And so, indeed, this is the computer's closest approximation
  5152. 4:01:13to what's actually going on there.
  5153. 4:01:15And so this is an example of what we would actually generally call
  5154. 4:01:18floating-point imprecision.
  5155. 4:01:21Floating-point imprecision refers to the inability for computers fundamentally
  5156. 4:01:26to represent all possible real numbers 100%
  5157. 4:01:29precisely, at least by default in languages like C. Thankfully,
  5158. 4:01:33in the world of scientific computing and so forth,
  5159. 4:01:35there are solutions to this problem that just give you more digits.
  5160. 4:01:38But the problem fundamentally is still going to be there.
  5161. 4:01:42So there's a reason I changed x and y to floats.
  5162. 4:01:44Let's see what would happen if we rewound a bit.
  5163. 4:01:47And instead of using floats for x and y, again, you say integer, so int x and y.
  5164. 4:01:52And let's go far back and use get_int as well,
  5165. 4:01:56thereby giving us integers x and y.
  5166. 4:01:59Let's still leave z as a float, because at the end of the day,
  5167. 4:02:01we want to be able to handle fractions or floating-point values.
  5168. 4:02:04But let's go ahead now and print out this value of z
  5169. 4:02:07having changed x and y now to ints.
  5170. 4:02:09make calculator, ./calculator, and let's do, say, 2 for the numerator,
  5171. 4:02:153 for the denominator.
  5172. 4:02:16And it's not 0.666, and it's not even rounding oddly.
  5173. 4:02:21It's just all zeros this time.
  5174. 4:02:23So why is that?
  5175. 4:02:24Well, it turns out that C, when dividing an integer by an integer,
  5176. 4:02:28is always going to give you back an integer, an int.
  5177. 4:02:31The problem is that floating-point values don't fit in ints.
  5178. 4:02:34Only the integral part to the left of the decimal point does.
  5179. 4:02:37Everything at and beyond the decimal point itself get thrown away,
  5180. 4:02:41known as a feature in C called truncation.
  5181. 4:02:44When dividing an integer by an integer, you get back an integer.
  5182. 4:02:47But if you're trying to then store what's actually a floating point
  5183. 4:02:51result in that integer, C is just going to throw away everything
  5184. 4:02:54at and beyond the decimal point, leaving us with this case,
  5185. 4:02:57in just the 0 from what should have been 0.666666 and so forth.
  5186. 4:03:03So let's see one more example, in fact.
  5187. 4:03:05Let me go back to my terminal here.
  5188. 4:03:06Let me do ./calculator again.
  5189. 4:03:08And let's do 4/3.
  5190. 4:03:09This time, It should be 1.33333 and so forth.
  5191. 4:03:13But let's see, 4 divided by 3, both as integers, this time gives us 1.0000,
  5192. 4:03:20but there too the answer should be 1.333.
  5193. 4:03:23But the floating-point part is getting truncated or thrown away,
  5194. 4:03:27leaving us with just 1.
  5195. 4:03:29So how do we solve this?
  5196. 4:03:30Well, certainly, we could just use floats from the get-go, as I did.
  5197. 4:03:33But if, by nature of your program, you only have access to integers--
  5198. 4:03:37or maybe even longs, for which the same problem would occur--
  5199. 4:03:40what we can actually do is called type conversion.
  5200. 4:03:44And we can explicitly tell the computer that we actually
  5201. 4:03:47want to treat this int as though it's a floating-point value.
  5202. 4:03:50And we can do that for both x and y.
  5203. 4:03:52So let me go back to my code here, and I have a couple of options, in fact.
  5204. 4:03:55I can convert y to a float by doing this, I can cast y to a float
  5205. 4:04:01by literally writing the type float inside of parentheses
  5206. 4:04:04right before the y.
  5207. 4:04:05And if I really want to be explicit, I can also do the same to x.
  5208. 4:04:08But, strictly speaking, it suffices to just change one or the other,
  5209. 4:04:12not necessarily both.
  5210. 4:04:14Let me go ahead now and do make calculator again, ./calculator,
  5211. 4:04:19and let's try 2 divided by 3.
  5212. 4:04:21And now, we're back to an answer that's closer to correct.
  5213. 4:04:25But, indeed, we're still having some rounding issues there.
  5214. 4:04:27Let's run it one more time for 4 divided by 3.
  5215. 4:04:31There too we're closer to the right answer, at least.
  5216. 4:04:33But we still have that floating-point imprecision,
  5217. 4:04:36but that's going to be another problem altogether to solve.
  5218. 4:04:39And here in a little more detail is that issue
  5219. 4:04:41of integer overflow, which is in the context of ints.
  5220. 4:04:44Suppose that we think back to last week when we had three bits,
  5221. 4:04:48and we counted from 0 to 7, 0, 1, 2, 3, 4, 5, 6, 7.
  5222. 4:04:53I think I asked the question, how would we count to 8?
  5223. 4:04:56Someone proposed, well, we need a fourth bit.
  5224. 4:04:58That's fine if you have a fourth bit, if you have access
  5225. 4:05:01to another light bulb or transistor.
  5226. 4:05:03If you don't, though, the next number after this is technically 1000.
  5227. 4:05:09But if you don't have space for or hardware for that fourth bit,
  5228. 4:05:13you might as well just be representing the number 0.
  5229. 4:05:16So in the world of integers, if you're only using three bits,
  5230. 4:05:19those three bits eventually overflow when you count past 7.
  5231. 4:05:23Because what should be 8 can't fit, so to speak, so it rolls back over to 0.
  5232. 4:05:28And as arcane as this problem might seem,
  5233. 4:05:30we humans have done this a couple of times.
  5234. 4:05:33You might recall knowing about or reading
  5235. 4:05:35about the Y2K problem, where a lot of people
  5236. 4:05:37thought the world was going to end.
  5237. 4:05:38Why?
  5238. 4:05:38Because on January 1st of 2000, a lot of computers,
  5239. 4:05:43presumably, were going to update their clocks from 1999 to the year 2000.
  5240. 4:05:48The problem is, though, for decades, for efficiency, we humans
  5241. 4:05:51were honestly in the habit of not storing years as four digits.
  5242. 4:05:54Why?
  5243. 4:05:55Because that's just a lot of space to waste, especially since centuries
  5244. 4:05:58don't happen that often.
  5245. 4:05:59So a lot of computer systems, especially early on when
  5246. 4:06:02hardware was very expensive and memory was very tight,
  5247. 4:06:05just stored the last two digits of any year.
  5248. 4:06:08The problem, of course, on January 1st of 2000 is that 99 rolls over to 100.
  5249. 4:06:14But if you don't have room for another digit it's just 00.
  5250. 4:06:19And if your code assumes a prefix of 19, well, we just went from the year
  5251. 4:06:231999 back to the year 1900.
  5252. 4:06:26Thankfully, long story short, a lot of people wrote a lot of code
  5253. 4:06:29in a lot of old languages and mostly warded off this problem,
  5254. 4:06:32so the world did not end.
  5255. 4:06:34The next time the world might end though, is on January 19, 2038.
  5256. 4:06:39Now, that might feel like a long time away,
  5257. 4:06:42but so did the year 2000, at one point.
  5258. 4:06:44Why might clocks again break in today's modern computers in 2038,
  5259. 4:06:51might you think?
  5260. 4:06:52AUDIENCE: [INAUDIBLE]
  5261. 4:06:54DAVID J. MALAN: Indeed.
  5262. 4:06:54So this refers to some number of seconds.
  5263. 4:06:57So it turns out that the way computers generally keep track of time
  5264. 4:07:00is they count the total number of seconds since the epoch, which
  5265. 4:07:04is defined as January 1, 1970.
  5266. 4:07:06Why?
  5267. 4:07:07It was just a good year to start counting at,
  5268. 4:07:09when computers really came onto the scene.
  5269. 4:07:11Unfortunately, most computers used 32 bits to count the number of seconds
  5270. 4:07:16since January 1, 1970, the implication of which is we
  5271. 4:07:20can only count up to roughly 2 billion seconds.
  5272. 4:07:232 billion seconds is going to happen in 2038, at which 30 11's
  5273. 4:07:29are going to roll over as follows.
  5274. 4:07:31That number 2 billion, which is the max--
  5275. 4:07:34because if you're representing positive and negative numbers,
  5276. 4:07:37recall that you can only count as high as positive 2 billion
  5277. 4:07:39or negative 2 billion--
  5278. 4:07:41looks like this.
  5279. 4:07:42This is roughly the number 2 billion in binary.
  5280. 4:07:44It's all ones with one zero way over here.
  5281. 4:07:47If I count one second past that 2 billion number, give or take--
  5282. 4:07:50that means, all right, I add 1, I carry the 1--
  5283. 4:07:54it's just like 9's becoming 0's in decimal.
  5284. 4:07:57If I keep this sort of simple animation and I keep carrying the 1,
  5285. 4:08:01carrying the 1, carrying the 1, 1 second after 2 billion seconds, give or take,
  5286. 4:08:05I have this number in the computer's memory.
  5287. 4:08:08So there's still 1 bit that's a 1 all the way to the left.
  5288. 4:08:11Unfortunately, that bit often represents negativity,
  5289. 4:08:16whereby if that first bit is negative, that represents that the rest of it
  5290. 4:08:20somehow represents a negative number.
  5291. 4:08:22It's not negative 0.
  5292. 4:08:23There's a fancier representation.
  5293. 4:08:24But a very big, positive number very suddenly
  5294. 4:08:27becomes a very big, negative number.
  5295. 4:08:29And that number is roughly negative 2 billion.
  5296. 4:08:32That means computers in 2038 on that date
  5297. 4:08:35are going to accidentally think that it's
  5298. 4:08:37been negative 2 billion seconds since January 1, 1970, which is going to make
  5299. 4:08:43computers potentially think it's 1901.
  5300. 4:08:46So what is the solution to the 2038 problem, perhaps?
  5301. 4:08:50Y2K was because we were using two digits for years.
  5302. 4:08:53What about 2038?
  5303. 4:08:55More bits.
  5304. 4:08:55And, thankfully, we're getting a little better at lessons learned here,
  5305. 4:09:00and computers now are increasingly using 64 bits.
  5306. 4:09:03And all of us will be long gone by the time we run out
  5307. 4:09:05of that number of seconds, so it's someone else's problem
  5308. 4:09:08many, many years from now.
  5309. 4:09:09But that's really the fundamental solution.
  5310. 4:09:11If you're running up against something finite, well,
  5311. 4:09:13just kick the can further and just give yourself more bits.
  5312. 4:09:16And, frankly, because hardware is so much cheaper these days,
  5313. 4:09:18computers are so much faster, it's not as big of a deal
  5314. 4:09:21as it might have been decades ago.
  5315. 4:09:22But that's indeed the solution.
  5316. 4:09:24But this arises in very common contexts.
  5317. 4:09:27In fact, let me go ahead and write a real quick program here called pennies.
  5318. 4:09:32You might think that just converting dollars to pennies in US currency
  5319. 4:09:35might be simple, but let me go ahead and do this.
  5320. 4:09:37In pennies.c, I'm going to go ahead and include cs50.h.
  5321. 4:09:41And I'm going to include stdio.h, int main void as my starting point.
  5322. 4:09:48And now down here, I'm going to do this.
  5323. 4:09:50I'm going to get a float called amount, and I'm
  5324. 4:09:52going to ask the user for some amount of dollars, so a dollar amount,
  5325. 4:09:56and I'm going to store that in a variable called amount.
  5326. 4:09:59Then I'm going to simply convert that amount to pennies by doing, say, how
  5327. 4:10:07about amount times 100?
  5328. 4:10:10And then I'm going to go ahead and print out that the number of pennies is %i--
  5329. 4:10:16because that's just an integer in pennies--
  5330. 4:10:18backslash n, quote unquote, comma, pennies.
  5331. 4:10:22All right, so if I didn't make any mistakes here, let me make pennies,
  5332. 4:10:26./pennies.
  5333. 4:10:27And suppose I have, say, $0.99, so 0.99.
  5334. 4:10:31That's 99 pennies.
  5335. 4:10:32Suppose I have $1.23.
  5336. 4:10:35That's pretty good.
  5337. 4:10:36Suppose I have $4.20.
  5338. 4:10:39Huh.
  5339. 4:10:41There's that imprecision issue.
  5340. 4:10:42And this isn't even that big of an amount.
  5341. 4:10:45Now, not a big deal if the cashier gives you one penny less than you're owed,
  5342. 4:10:49but you can imagine this adding up.
  5343. 4:10:50You can imagine this being worrisome for financial implications,
  5344. 4:10:54for financial transactions, for scientific measurements and the like.
  5345. 4:10:57My program can't even handle this.
  5346. 4:10:59Well, there are some solutions here.
  5347. 4:11:01And it looks like what's really happening--
  5348. 4:11:04if I print it out using the %f with a 0.50 or whatever to see more decimal
  5349. 4:11:08points--
  5350. 4:11:09presumably, the computer is struggling to represent $4.20 precisely.
  5351. 4:11:14It's probably storing 4 dollars and 19.9999-something cents.
  5352. 4:11:20So it's close, but it's not quite there.
  5353. 4:11:23So I could at least solve this by rounding up, for instance.
  5354. 4:11:28And it turns out there is a round function out there.
  5355. 4:11:31And it turns out that it's in a library called the math library.
  5356. 4:11:33And you would know this by looking at online documentation and the like,
  5357. 4:11:36as we'll point you to.
  5358. 4:11:37And if I now make pennies again and do ./pennies, I can now do $4.20.
  5359. 4:11:43And, voila.
  5360. 4:11:44Now it's correct.
  5361. 4:11:46So at least in this context, it seems like a solvable problem.
  5362. 4:11:49But it's certainly something I need to be mindful of, nonetheless.
  5363. 4:11:53Unfortunately, even professional, full-time programmers over the years
  5364. 4:11:57have not been particularly attentive to these kinds of details.
  5365. 4:12:00And in a class like this, the goal is not just to teach you programming
  5366. 4:12:03but to really teach you what's going on underneath the hood, so to speak,
  5367. 4:12:06so that you have a bottom-up understanding of how data
  5368. 4:12:09is represented, how computers are manipulating it,
  5369. 4:12:11so that you are not on the failing end of some program having some bug.
  5370. 4:12:16And so that we as a society are not beholden to those kinds of mistakes
  5371. 4:12:19too.
  5372. 4:12:19And this happens, unfortunately, all of the time.
  5373. 4:12:22This is a Boeing airplane that a few years ago needed
  5374. 4:12:26to be rebooted after every 248 days.
  5375. 4:12:29Why?
  5376. 4:12:30Because this Boeing airplane software was using a 32-bit integer counting up
  5377. 4:12:34tenths of a second to keep track of something or other
  5378. 4:12:36related to its electrical power.
  5379. 4:12:38And, unfortunately, after 248 days of the airplane being continuously on--
  5380. 4:12:43which in the airline industry is apparently not
  5381. 4:12:45uncommon to make every dollar count, keeping the planes up and running
  5382. 4:12:49all the time--
  5383. 4:12:50the 32-bit number would roll over and the power
  5384. 4:12:54would shut off on the airplane as a side effect because of sort
  5385. 4:12:57of undefined behavior in that case.
  5386. 4:12:59The temporary solution by Boeing at the time was apparently, essentially,
  5387. 4:13:02sort of operating system style, well, have you rebooted your plane?
  5388. 4:13:06And that was indeed the fix until they rolled out an actual software patch.
  5389. 4:13:09This stuff really matters.
  5390. 4:13:11And the more hardware we carry around and the more we as a society
  5391. 4:13:14use these kinds of devices, the more of these problems
  5392. 4:13:17we're going to run into down the road.
  5393. 4:13:20That's it for CS50.
  5394. 4:13:21We'll see you next time.
  5395. 4:13:24[MUSIC PLAYING]
  5396. 4:14:42DAVID MALAN: This is CS50 and this is week 2.
  5397. 4:14:45Now that you have some programming experience under your belts,
  5398. 4:14:47in this more arcane language called c.
  5399. 4:14:50Among our goals today is to help you understand exactly what you have
  5400. 4:14:53been doing these past several days.
  5401. 4:14:54Wrestling with your first programs in C, so that you have more of a bottom
  5402. 4:14:58up understanding of what some of these commands do.
  5403. 4:15:00And, ultimately, what more we can do with this language.
  5404. 4:15:02So this recall was the very first program you wrote,
  5405. 4:15:06I wrote in this language called C, much more textual,
  5406. 4:15:09certainly, than the Scratch equivalent.
  5407. 4:15:11But at the end of the day, computers, your Mac, your PC,
  5408. 4:15:15VS Code doesn't understand this actual code.
  5409. 4:15:18What's the format into which we need to get any program that we write, just
  5410. 4:15:21to recap?
  5411. 4:15:22AUDIENCE: [INAUDIBLE]
  5412. 4:15:23DAVID MALAN: So binary, otherwise known as machine code.
  5413. 4:15:26Right?
  5414. 4:15:26The 0s and 1s that your computer actually does understand.
  5415. 4:15:30So somehow we need to get to this format.
  5416. 4:15:32And up until now, we've been using this command called make,
  5417. 4:15:34which is aptly named, because it lets you make programs.
  5418. 4:15:37And the invocation of that has been pretty simple.
  5419. 4:15:40Make hello looks in your current directory or folder for a file called
  5420. 4:15:44hello.c, implicitly, and then it compiles that into a file called hello,
  5421. 4:15:49which itself is executable, which just means runnable,
  5422. 4:15:51so that you can then do ./hello.
  5423. 4:15:54But it turns out that make is actually not a compiler itself.
  5424. 4:15:58It does help you make programs.
  5425. 4:16:00But make is this utility that comes on a lot of systems that makes it easier
  5426. 4:16:04to actually compile code by using an actual compiler,
  5427. 4:16:08the program that converts source code to machine code, on your own Mac, or PC,
  5428. 4:16:12or whatever cloud environment you might be using.
  5429. 4:16:14In fact, what make is doing for us, is actually,
  5430. 4:16:17running a command automatically known as clang, for C language.
  5431. 4:16:21And, so here, for instance, in VS Code, is that very first program again,
  5432. 4:16:25this time in the context of a text editor,
  5433. 4:16:27and I could compile this with make hello.
  5434. 4:16:30Let me go ahead and use the compiler itself manually.
  5435. 4:16:33And we'll see in a moment why we've been automating the process with make.
  5436. 4:16:36I'm going to run clang instead.
  5437. 4:16:39And then I'm going to run hello.c.
  5438. 4:16:41So it's a little different how the compiler's used.
  5439. 4:16:43It needs to know, explicitly, what the file is called.
  5440. 4:16:46I'll go ahead and run clang, hello.c, Enter.
  5441. 4:16:49Nothing seems to happen, which, generally speaking, is a good thing.
  5442. 4:16:52Because no errors have popped up.
  5443. 4:16:54And if I do ls for list, you'll see there is not a file called hello.
  5444. 4:17:00But there is a curiously-named file called a.out.
  5445. 4:17:03This is a historical convention, stands for assembler output.
  5446. 4:17:06And this is, just, the default file name for a program
  5447. 4:17:09that you might compile yourself, manually, using clang itself.
  5448. 4:17:13Let me go ahead now and point out that that's
  5449. 4:17:16kind of a stupid name for a program.
  5450. 4:17:17Even though it works, ./a.out would work.
  5451. 4:17:20But if you actually want to customize the name of your program,
  5452. 4:17:23we could just resort to make, or we could do explicitly
  5453. 4:17:26what make is doing for us.
  5454. 4:17:28It turns out, some programs, among them make,
  5455. 4:17:31support what are called command line arguments,
  5456. 4:17:33and more on those later today.
  5457. 4:17:34But these are literally words or numbers that you type at your prompt
  5458. 4:17:37after the name of a program that just influences its behavior in some way.
  5459. 4:17:41It modifies its behavior.
  5460. 4:17:44And it turns out, if you read the documentation for clang,
  5461. 4:17:47you can actually pass a -o, for output, command line argument, that
  5462. 4:17:52lets you specify, explicitly what do you want
  5463. 4:17:54your outputted program to be called?
  5464. 4:17:56And then you go ahead and type the name of the file that you actually
  5465. 4:17:58want to compile, from source code to machine code.
  5466. 4:18:01Let me hit Enter now.
  5467. 4:18:02Again, nothing seems to happen, and I type ls and voila.
  5468. 4:18:06Now we still have the old a.out, because I didn't delete it yet.
  5469. 4:18:09And I do have hello now.
  5470. 4:18:10So ./hello, voila, runs hello, world again.
  5471. 4:18:14And let me go ahead and remove this file.
  5472. 4:18:16I could, of course, resort to using the Explorer, on the left hand side.
  5473. 4:18:20Which, I am in the habit of closing, just to give us more room to see.
  5474. 4:18:23But I could go ahead and right-click or control-click on a.out
  5475. 4:18:26if I want to get rid of it.
  5476. 4:18:27Or again, let me focus on the command line interface.
  5477. 4:18:30And I can use--
  5478. 4:18:31anyone recall?
  5479. 4:18:32We didn't really use it much, but what command removes a file?
  5480. 4:18:35AUDIENCE: rm.
  5481. 4:18:36DAVID MALAN: So rm for remove. rm, a.out, Enter.
  5482. 4:18:40Remove regular file, a.out, y for yes, enter.
  5483. 4:18:44And now, if I do ls again, voila, it's gone.
  5484. 4:18:46All right, so, let's now enhance this program
  5485. 4:18:48to do the second version we ever did, which was to also include cs50.h,
  5486. 4:18:54so that we have access to functions like, get string, and the like.
  5487. 4:18:57Let me do string, name, gets, get string, what's your name,
  5488. 4:19:04question mark.
  5489. 4:19:05And now, let me go ahead and say hello to that name with our %s placeholder,
  5490. 4:19:10comma, name.
  5491. 4:19:11So this was version 2 of our program last time,
  5492. 4:19:13that very easily compiled with make hello, but notice the difference now.
  5493. 4:19:17If I want to compile this thing myself with clang, using
  5494. 4:19:20that same lesson learned, all right, let's do it.
  5495. 4:19:22clang-o, hello, just so I get a better name for the program, hello.c, Enter.
  5496. 4:19:29And a new error pops up that some of you might have encountered on your own.
  5497. 4:19:34So it's a bit arcane here, and there's this mention of a cryptic-looking path
  5498. 4:19:37with temp for temporary there.
  5499. 4:19:39But somehow, my issue's in main, as we can see here.
  5500. 4:19:42It somehow relates to hello.c.
  5501. 4:19:44Even though we might not have seen this language last time in class,
  5502. 4:19:47but there's an undefined reference to get string.
  5503. 4:19:50As though get string doesn't exist.
  5504. 4:19:52Now, your first instinct might be, well maybe I forgot cs50.h, but of course,
  5505. 4:19:55I didn't.
  5506. 4:19:56That's the very first line of my program.
  5507. 4:19:58But it turns out, make is doing something else for us, all this time.
  5508. 4:20:02Just putting cs50.h, or any header file at the top of your code,
  5509. 4:20:06for that matter, just teaches the compiler that a function will exist.
  5510. 4:20:10It, sort of, asks the compiler to-- it asks the compiler
  5511. 4:20:13to trust that I will, eventually, get around to implementing functions,
  5512. 4:20:16like get string, and cs50.h, and stdio.h, printf, therein.
  5513. 4:20:22But this error here, some kind of linker command, relates to the fact
  5514. 4:20:28that there's a separate process for actually
  5515. 4:20:30finding the 0s and 1s that cs50 compiled long ago for you.
  5516. 4:20:34That authors of this operating system compiled for you, long ago,
  5517. 4:20:38in the form of printf.
  5518. 4:20:39We need to, somehow, tell the compiler that we
  5519. 4:20:42need to link in code that someone else wrote,
  5520. 4:20:44the actual machine code that someone else wrote and then compiled.
  5521. 4:20:48So to do that, you'd have to type -lcs50, for instance,
  5522. 4:20:51at the end of the command.
  5523. 4:20:52So additionally, telling clang that, not only do you want to output
  5524. 4:20:55a file called hello, and you want to compile a file called hello.c,
  5525. 4:20:58you also want to quote-unquote link in a bunch of 0s and 1s
  5526. 4:21:03that collectively implement get string and printf.
  5527. 4:21:07So now, if I hit enter, this time it compiled OK.
  5528. 4:21:11And now if I run ./hello, it works as it did last week, just like that.
  5529. 4:21:17But honestly, this is just going to get really tedious, really quickly.
  5530. 4:21:20Notice, already, just to compile my code,
  5531. 4:21:22I have to run clang-o, hello, hello.c, lcs50,
  5532. 4:21:25and you're going to have to type more things, too.
  5533. 4:21:27If you wanted to use the math library, like, to use that round function,
  5534. 4:21:31you would also have to do -lm, typically,
  5535. 4:21:33to specify give me the math bits that someone else compiled.
  5536. 4:21:37And the commands just get longer and longer.
  5537. 4:21:39So moving forward, we won't have to resort to running clang itself,
  5538. 4:21:43but clang is, indeed, the compiler.
  5539. 4:21:45That is the program that converts from source code to machine code.
  5540. 4:21:48But we'll continue to use make because it just automates that process.
  5541. 4:21:52And the commands are only going to get more
  5542. 4:21:54cryptic the more sophisticated and more feature full year programs get.
  5543. 4:21:58And make, again, is just a tool that makes all that happen.
  5544. 4:22:03Let me pause there to see if there's any questions before then we
  5545. 4:22:08take a look further under the hood.
  5546. 4:22:10Yeah, in front.
  5547. 4:22:11AUDIENCE: Can you explain again what the -lcs50-- just why you put that?
  5548. 4:22:14DAVID MALAN: Sure, let me come back to that in a moment.
  5549. 4:22:16What does the -lcs50 mean?
  5550. 4:22:18We'll come back to that, visually, in just a moment.
  5551. 4:22:20But it means to link in the 0s and 1s that collectively
  5552. 4:22:23implement get string and printf.
  5553. 4:22:24But we'll see that, visually, in a sec.
  5554. 4:22:26Yeah, behind you.
  5555. 4:22:27AUDIENCE: [INAUDIBLE].
  5556. 4:22:31DAVID MALAN: Really good question.
  5557. 4:22:32How come I didn't have to link in standard I/O?
  5558. 4:22:35Because I used printf in version 1.
  5559. 4:22:37Standard I/O is just, literally, so standard that it's built in,
  5560. 4:22:40it just works for free.
  5561. 4:22:41CS50, of course, is not.
  5562. 4:22:43It did not come with the language C or the compiler.
  5563. 4:22:45We ourselves wrote it.
  5564. 4:22:46And other libraries, even though they might come with the language C,
  5565. 4:22:50they might not be enabled by default, generally for efficiency purposes.
  5566. 4:22:54So you're not loading more 0s and 1s into the computer's memory
  5567. 4:22:57than you need to.
  5568. 4:22:58So standard I/O is special, if you will.
  5569. 4:23:01Other questions?
  5570. 4:23:02Yeah?
  5571. 4:23:03AUDIENCE: [INAUDIBLE]
  5572. 4:23:05DAVID MALAN: Oh, what does the -o mean?
  5573. 4:23:07So -o is shorthand for the English word output,
  5574. 4:23:10and so -o is telling clang to please output a file called hello,
  5575. 4:23:15because the next thing I wrote after the command line
  5576. 4:23:18recall was clang -o hello, then the name of the file, then -lcs50.
  5577. 4:23:24And this is where these commands do get and stay fairly arcane.
  5578. 4:23:27It's just through muscle memory and practice
  5579. 4:23:29that you'll start to remember, oh what are the other commands that you--
  5580. 4:23:31what are the command line arguments you can provide to programs?
  5581. 4:23:34But we've seen this before.
  5582. 4:23:35Technically, when you run make hello, the program is called make,
  5583. 4:23:39hello is the command line argument.
  5584. 4:23:41It's an input to the make function, albeit,
  5585. 4:23:43typed at the prompt, that tells make what you want to make.
  5586. 4:23:46Even when I used rm a moment ago, and did rm of a.out,
  5587. 4:23:50the command line argument there was called a.out
  5588. 4:23:52and it's telling rm what to delete.
  5589. 4:23:55It is entirely dependent on the programs to decide what their conventions are,
  5590. 4:23:59whether you use dash this or dash that, but we'll
  5591. 4:24:02see over time, which ones actually matter in practice.
  5592. 4:24:05So to come back to the first question about what actually is happening there,
  5593. 4:24:10let's consider the code more closely.
  5594. 4:24:12So here is that first version of the code
  5595. 4:24:14again, with stdio.h and only printf, so no cs50 stuff yet.
  5596. 4:24:18Until we add it back in and had the second version,
  5597. 4:24:21where we actually get the human's name.
  5598. 4:24:23When you run this command, there's a few things
  5599. 4:24:27that are happening underneath the hood, and we
  5600. 4:24:28won't dwell on these kinds of details, indeed,
  5601. 4:24:30we'll abstract it away by using make.
  5602. 4:24:33But it's worth understanding from the get-go,
  5603. 4:24:35how much automation is going on, so that when you run these commands,
  5604. 4:24:38it's not magic.
  5605. 4:24:39You have this bottom-up understanding of what's going on.
  5606. 4:24:42So when we say you've been compiling your code with make,
  5607. 4:24:45that's a bit of an oversimplification.
  5608. 4:24:47Technically, every time you compile your code,
  5609. 4:24:51you're having the computer do four distinct things for you.
  5610. 4:24:53And this is not four distinct things that you need to memorize and remember
  5611. 4:24:57every time you run your program, what's happening,
  5612. 4:24:59but it helps to break it down into building blocks,
  5613. 4:25:02as to how we're getting from source code, like C, into 0s and 1s.
  5614. 4:25:06It turns out, that when you compile, quote-unquote, "your code," technically
  5615. 4:25:10speaking, you're doing four things automatically, and all at once.
  5616. 4:25:14Preprocessing it, compiling it, assembling it, and linking it.
  5617. 4:25:18Just humans decided, let's just call the whole process compiling.
  5618. 4:25:21But for a moment, let's consider what these steps are.
  5619. 4:25:24So preprocessing refers to this.
  5620. 4:25:26If we look at our source code, version 2 that uses the cs50 library
  5621. 4:25:30and therefore get string, notice that we have these include lines at top.
  5622. 4:25:34And they're kind of special versus all the other code
  5623. 4:25:36we've written, because they start with hash symbols, specifically.
  5624. 4:25:39And that's sort of a special syntax that means
  5625. 4:25:41that these are, technically, called preprocessor directives.
  5626. 4:25:44Fancy way of saying they're handled special versus the rest of your code.
  5627. 4:25:49In fact, if we focus on cs50.h, recall from last week
  5628. 4:25:54that I provided a hint as to what's actually in cs50.h, among other things.
  5629. 4:26:00What was the one salient thing that I said was in cs50.h and therefore,
  5630. 4:26:04why we were including it in the first place?
  5631. 4:26:07AUDIENCE: Get string?
  5632. 4:26:08DAVID MALAN: So get string, specifically,
  5633. 4:26:11the prototype for get string.
  5634. 4:26:13We haven't made many of our own functions yet,
  5635. 4:26:15but recall that any time we've made our own functions,
  5636. 4:26:18and we've written them below main in a file,
  5637. 4:26:20we've also had to, somewhat stupidly, copy paste
  5638. 4:26:23the prototype of the function at the top of the file,
  5639. 4:26:25just to teach the compiler that this function doesn't exist, yet,
  5640. 4:26:29it does down there, but it will exist.
  5641. 4:26:31Just trust me.
  5642. 4:26:32So again, that's what these prototypes are doing for us.
  5643. 4:26:35So therefore, in my code, If I want to use
  5644. 4:26:37a function like get string, or printf, for that matter,
  5645. 4:26:41they're not implemented clearly in the same file,
  5646. 4:26:43they're implemented elsewhere.
  5647. 4:26:44So I need to tell the compiler to trust me that they're
  5648. 4:26:46implemented somewhere else.
  5649. 4:26:48And so technically, inside of cs50.h, which
  5650. 4:26:51is installed somewhere in the cloud's hard drive, so to speak,
  5651. 4:26:54that you all are accessing via VS Code, there's a line that looks like this.
  5652. 4:26:59A prototype for the get string function that says the name of the functions
  5653. 4:27:03get string, it takes one input, or argument, called prompt,
  5654. 4:27:07and that type of that prompt is a string.
  5655. 4:27:09Get string, not surprisingly, has a return value and it returns a string.
  5656. 4:27:15So literally, that line and a bunch of others, are in cs50.h.
  5657. 4:27:19So rather than you all having to copy paste the prototype,
  5658. 4:27:22you can just trust that cs50 figured out what it is.
  5659. 4:27:25You can include cs50.h and the compiler is going
  5660. 4:27:29to go find that prototype for you.
  5661. 4:27:31Same thing in standard I/O. Someone else-- what
  5662. 4:27:33must clearly be in stdio.h, among other stuff, that
  5663. 4:27:37motivates our including stdio.h, too?
  5664. 4:27:41Yeah?
  5665. 4:27:42AUDIENCE: Printf.
  5666. 4:27:43DAVID MALAN: Printf, the prototype for printf,
  5667. 4:27:45and I'll just change it here in yellow, to be the same.
  5668. 4:27:48And it turns out, the format--
  5669. 4:27:49the prototype for printf is, actually, pretty fancy,
  5670. 4:27:52because, as you might have noticed, printf can take one argument, just
  5671. 4:27:56something to print, 2, if you want to plug a value into it, 3 or more.
  5672. 4:28:00So the dot dot dot just represents exactly that.
  5673. 4:28:02It's not quite as simple a prototype as get strain, but more on that
  5674. 4:28:06another time.
  5675. 4:28:07So what does it mean to preprocess your code?
  5676. 4:28:10The very first thing the compiler, clang, in this case,
  5677. 4:28:14is doing for you when it reads your code top-to-bottom, left-to-right, is it
  5678. 4:28:18notices, oh, here is hash include, oh, here's another hash include.
  5679. 4:28:22And it, essentially, finds those files on the hard drive, cs50.h, stdio.h,
  5680. 4:28:27and does the equivalent of copying and pasting them automatically
  5681. 4:28:31into your code at the very top.
  5682. 4:28:33Thereby teaching the compiler that gets string and printf
  5683. 4:28:36will eventually exist somewhere.
  5684. 4:28:38So that's the preprocessing step, whereby, again, it's
  5685. 4:28:42just doing a find-and-replace of anything that starts with hash include.
  5686. 4:28:46It's plugging in the files there so that you, essentially,
  5687. 4:28:48get all the prototypes you need automatically.
  5688. 4:28:52OK.
  5689. 4:28:53What does it mean, then, to compile the results?
  5690. 4:28:55Because at this point in the story, your code
  5691. 4:28:57now looks like this in the computer's memory.
  5692. 4:28:59It doesn't change your file, it's doing all
  5693. 4:29:01of this in the computer's memory, or RAM, for you.
  5694. 4:29:04But it, essentially, looks like this.
  5695. 4:29:06Well the next step is what's, technically, really compiling.
  5696. 4:29:09Even though again, we use compile as an umbrella term.
  5697. 4:29:12Compiling code in C means to take code that
  5698. 4:29:15now looks like this in the computer's memory
  5699. 4:29:18and turn it into something that looks like this.
  5700. 4:29:21Which is way more cryptic.
  5701. 4:29:22But it was just a few decades ago that, if you
  5702. 4:29:25were taking a class like CS50 in its earlier form,
  5703. 4:29:28we wouldn't be using C it didn't exist yet, we would actually be using this,
  5704. 4:29:32something called assembly language.
  5705. 4:29:33And there's different types of, or flavors of, assembly language.
  5706. 4:29:37But this is about as low level as you can get to what a computer really
  5707. 4:29:41understands, be it a Mac, or PC, or a phone,
  5708. 4:29:43before you start getting into actual 0s and 1s.
  5709. 4:29:46And most of this is cryptic.
  5710. 4:29:48I couldn't tell you what this is doing unless I thought it through carefully
  5711. 4:29:51and rewound mentally, years ago, from having studied it,
  5712. 4:29:54but let's highlight a few key words in yellow.
  5713. 4:29:57Notice that this assembly language that the computer is outputting
  5714. 4:30:01for you automatically, still has mention of main
  5715. 4:30:04and it has mention of get string, and it has mention of printf.
  5716. 4:30:07So there's some relationship to the C code we saw a moment ago.
  5717. 4:30:10And then if I highlight these other things,
  5718. 4:30:12these are what are called computer instructions.
  5719. 4:30:14At the end of the day, your Mac, your PC,
  5720. 4:30:17your phone actually only understands very basic instructions,
  5721. 4:30:20like addition, subtraction, division, multiplication, move into memory,
  5722. 4:30:25load from memory, print something to the screen, very basic operations.
  5723. 4:30:30And that's what you're seeing here.
  5724. 4:30:32These assembly instructions are what the computer actually
  5725. 4:30:37feeds into the brains of the computer, the CPU, the central processing unit.
  5726. 4:30:41And it's that Intel CPU, or whatever you have,
  5727. 4:30:44that understands this instruction, and this one, and this one, and this one.
  5728. 4:30:47And collectively, long story short, all they do
  5729. 4:30:50is print hello, world on the screen, but in a way
  5730. 4:30:52that the machine understands how to do.
  5731. 4:30:56So let me pause here.
  5732. 4:30:58Are there any questions on what we mean by preprocessing?
  5733. 4:31:01Which finds and replaces the hash includes symbols, among others,
  5734. 4:31:05and compiling, which technically takes your source code,
  5735. 4:31:08once preprocessed, and converts it to that stuff called assembly language.
  5736. 4:31:12AUDIENCE: [INAUDIBLE] each CPU has--
  5737. 4:31:14DAVID MALAN: Correct.
  5738. 4:31:15Each type of CPU has its own instruction set.
  5739. 4:31:18Indeed.
  5740. 4:31:19And as a teaser, this is why, at least back in the day, when
  5741. 4:31:23we used to install software from CD-ROMs, or some other type of media,
  5742. 4:31:27this is why you can't take a program that was sold for a Windows computer
  5743. 4:31:32and run it on a Mac, or vice-versa.
  5744. 4:31:33Because the commands, the instructions that those two products understand,
  5745. 4:31:38are actually different.
  5746. 4:31:39Now Microsoft, or any company, could generally write code in one language,
  5747. 4:31:44like C or another, and they can compile it twice, saving a PC version
  5748. 4:31:48and saving a Mac version.
  5749. 4:31:50It's twice as much work and sometimes you get into some incompatibilities,
  5750. 4:31:54but that's why these steps are somewhat distinct.
  5751. 4:31:57You can now use the same code and support even different platforms,
  5752. 4:32:00or systems, if you'd want.
  5753. 4:32:02All right.
  5754. 4:32:02Assembly, assembling.
  5755. 4:32:03Thankfully, this part is fairly straightforward, at least, in concept.
  5756. 4:32:07To assemble code, which is step three of four, that is just
  5757. 4:32:10happening for you every time you run make or, in turn, clang,
  5758. 4:32:14this assembly language, which the computer generated automatically
  5759. 4:32:17for you from your source code, is turned into 0s and 1s.
  5760. 4:32:21So that's the step that, last week, I simplified and said,
  5761. 4:32:25when you compile your code, you convert it to source code-- from source code
  5762. 4:32:28to machine code.
  5763. 4:32:29Technically, that happens when you assemble your code.
  5764. 4:32:31But no one in normal conversations says that, they just
  5765. 4:32:35say compile for all of these terms.
  5766. 4:32:37All right.
  5767. 4:32:38So that's assembling.
  5768. 4:32:41There's one final step.
  5769. 4:32:43Even in this simple program of getting the user's name
  5770. 4:32:46and then plugging it into printf, I'm using three different people's code,
  5771. 4:32:51if you will.
  5772. 4:32:51My own, which is in hello.c.
  5773. 4:32:54Some of CS50s, which is in hello.c, sorry-- which
  5774. 4:32:59is in cs50.c, which is not a file I've mentioned, yet,
  5775. 4:33:03but it stands to reason, that if there's a cs50.h that has prototypes,
  5776. 4:33:07turns out, the actual implementation of get string
  5777. 4:33:09and other things are in cs50.c.
  5778. 4:33:11And there's a third file somewhere on the hard drive
  5779. 4:33:15that's involved in compiling even this simple program.
  5780. 4:33:18hello.c, cs50.c, and by that logic, what might the other be?
  5781. 4:33:24Yeah?
  5782. 4:33:24AUDIENCE: stdio?
  5783. 4:33:26DAVID MALAN: Stdio.c.
  5784. 4:33:27And that's a bit of a white lie, because that's such a big, fancy library
  5785. 4:33:30that there's actually multiple files that compose it, but the same idea,
  5786. 4:33:34and we'll take the simplification.
  5787. 4:33:35So when I have this code, and I compile my code,
  5788. 4:33:40I get those 0s and 1s that end up taking hello.c and turning it, effectively,
  5789. 4:33:45into 0s and 1s that are combined with cs50.c, followed by stdio.c as well.
  5790. 4:33:51So let me rewind here.
  5791. 4:33:52Here might be the 0s and 1s for my code, the two lines of code that I wrote.
  5792. 4:33:57Here might be the 0s and 1s for what cs50 wrote some years ago in cs50.c.
  5793. 4:34:02Here might be the 0s and 1s that someone wrote for standard I/O decades ago.
  5794. 4:34:06The last and final step is that linking command
  5795. 4:34:09that links all of these 0s and 1s together,
  5796. 4:34:12essentially stitches them together into one single file called hello,
  5797. 4:34:18or called a.out, whatever you name it.
  5798. 4:34:20That last step is what combines all of these different programmers' 0s and 1s.
  5799. 4:34:25And my God, now we're really in the weeds.
  5800. 4:34:28Who wants to even think about running code at this level?
  5801. 4:34:31You shouldn't need to.
  5802. 4:34:32But it's not magic.
  5803. 4:34:33When you're running make, there's some very concrete steps
  5804. 4:34:36that are happening that humans have developed over the years,
  5805. 4:34:38over the decades, that breakdown this big problem of source code going
  5806. 4:34:41to 0s and 1s, or machine code, into these very specific steps.
  5807. 4:34:46But henceforth, you can call all of this compiling.
  5808. 4:34:50Questions?
  5809. 4:34:51Or confusion?
  5810. 4:34:52Yeah?
  5811. 4:34:52AUDIENCE: Can you explain again what a.out signifies?
  5812. 4:34:55DAVID MALAN: Sure.
  5813. 4:34:56What does a.out signify?
  5814. 4:34:57a.out is just the conventional, default file name for any program
  5815. 4:35:02that you compile directly with a compiler, like clang.
  5816. 4:35:05It's a meaningless name, though.
  5817. 4:35:07It stands for assembler output, and assembler might now sound familiar
  5818. 4:35:11from this assembling process.
  5819. 4:35:12It's a lame name for a computer program, and we
  5820. 4:35:15can override it by outputting something like hello, instead.
  5821. 4:35:20Yeah?
  5822. 4:35:21AUDIENCE: [INAUDIBLE]
  5823. 4:35:27DAVID MALAN: To recap, there are other prototypes in those files,
  5824. 4:35:32cs50.h, stdio.h, technically, they're all included on top of your file,
  5825. 4:35:36even though you, strictly speaking, don't need most of them,
  5826. 4:35:38but they are there, just in case you might want them.
  5827. 4:35:42And finally, any other questions?
  5828. 4:35:43Yeah?
  5829. 4:35:44AUDIENCE: [INAUDIBLE]
  5830. 4:35:48DAVID MALAN: Does it matter what order we're telling the computer to run?
  5831. 4:35:51Sometimes with libraries, yes, it matters
  5832. 4:35:53what order they are linked in together.
  5833. 4:35:55But for our purposes, it's really not going to matter.
  5834. 4:35:58It's going to-- make is going to take care of automating that process for us.
  5835. 4:36:03All right.
  5836. 4:36:03So with that said, henceforth, compiling, technically,
  5837. 4:36:06is these four things.
  5838. 4:36:06But we'll focus on it as a higher level concept, an abstraction,
  5839. 4:36:10known as compiling itself.
  5840. 4:36:14So another process that we'll now begin to focus on all the
  5841. 4:36:16more this week because, invariably, this past week you ran against--
  5842. 4:36:19ran up against some challenges.
  5843. 4:36:21You probably created your very first bugs, or mistakes, in a program
  5844. 4:36:24and so let's focus for a moment on actual techniques for debugging.
  5845. 4:36:28As you spend more time this semester, in the years
  5846. 4:36:31to come If you continue to program, you're never, frankly, probably,
  5847. 4:36:34going to write bug free code, ultimately.
  5848. 4:36:37Though your programs are going to get more featureful, more sophisticated,
  5849. 4:36:40and we're all going to start to make more sophisticated mistakes.
  5850. 4:36:44And to this day, I write buggy code all the time.
  5851. 4:36:46And I'm always horrified when I do it up here.
  5852. 4:36:48But hopefully, that won't happen too often.
  5853. 4:36:50But when it does, it's a process, now, of debugging, trying
  5854. 4:36:54to find the mistakes in your program.
  5855. 4:36:56You don't have to stare at your code, or shake your fist at your code.
  5856. 4:36:59There are actual tools that real world programmers
  5857. 4:37:02use to help debug their code and find these faults.
  5858. 4:37:06So what are some of the techniques and tools that folks use?
  5859. 4:37:08Well as an aside, if you've ever--
  5860. 4:37:13a bug in a program is a mistake, that's been around for some time.
  5861. 4:37:17If you've ever heard this tale, some 50 plus years ago, in 1947.
  5862. 4:37:22This is an entry in a log book written by a famous computer scientist known
  5863. 4:37:27as-- named Grace Hopper, who happened to be the one
  5864. 4:37:29to record the very first discovery of a quote-unquote actual bug in a computer.
  5865. 4:37:33This was like a moth that had flown into,
  5866. 4:37:36at the time, a very sophisticated system known as the Harvard Mark II computer,
  5867. 4:37:41very large, refrigerator-sized type systems,
  5868. 4:37:44in which an actual bug caused an issue.
  5869. 4:37:48The etymology of bug though, predates this particular instance,
  5870. 4:37:51but here you have, as any computer scientists might know, the example
  5871. 4:37:54of a first physical bug in a computer.
  5872. 4:37:57How, though, do you go about removing such a thing?
  5873. 4:37:59Well, let's consider a very simple scenario from last time,
  5874. 4:38:02for instance, when we were trying to print out various aspects of Mario,
  5875. 4:38:05like this column of 3 bricks.
  5876. 4:38:07Let's consider how I might go about implementing a program like this.
  5877. 4:38:10Let me switch back over to VS Code here, and I'm going to run--
  5878. 4:38:15write a program.
  5879. 4:38:17And I'm not going to trust myself, so I'm
  5880. 4:38:18going to call it buggy.c from the get-go,
  5881. 4:38:20knowing that I'm going to mess something up.
  5882. 4:38:22But I'm going to go ahead and include stdio.h.
  5883. 4:38:25And I'm going to define main, as usual.
  5884. 4:38:28So hopefully, no mistakes just yet.
  5885. 4:38:30And now, I want to print those 3 bricks on the screen using
  5886. 4:38:32just hashes for bricks.
  5887. 4:38:34So how about 4 int i get 0, i less than or equal to 3, i plus plus.
  5888. 4:38:40Now, inside of my curly braces, I'm going
  5889. 4:38:42to go ahead and print out a hash followed by a backslash n, semicolon.
  5890. 4:38:48All right, saving the file, doing make, buggy, Enter, it compiles.
  5891. 4:38:52So there's no syntactical errors, my code is syntactically correct.
  5892. 4:38:57But some of you have probably seen the logical error already,
  5893. 4:39:00because when I run this program I don't get
  5894. 4:39:03this picture, which was 3 bricks high, I seem to have 4 bricks instead.
  5895. 4:39:09Now, this might be jumping out at you, why it's happening,
  5896. 4:39:12but I've kept the program simple just so that we
  5897. 4:39:14don't have to find an actual bug, we can use a tool to find one that we already
  5898. 4:39:18know about, in this case.
  5899. 4:39:20What might be the first strategy for finding a bug like this,
  5900. 4:39:23rather than staring at your code, asking a question, trying to think
  5901. 4:39:27through the problem?
  5902. 4:39:28Well, let's actually try to diagnose the problem more proactively.
  5903. 4:39:31And the simplest way to do this now, and years from now,
  5904. 4:39:34is, honestly, going to be to use a function like printf.
  5905. 4:39:38Printf is a wonderfully useful function, not
  5906. 4:39:40for formatting-- printing formatted strings and all that, for
  5907. 4:39:42just looking inside the values of variables
  5908. 4:39:45that you might be curious about to see what's going on.
  5909. 4:39:48So you know what?
  5910. 4:39:49Let me do this.
  5911. 4:39:50I see that there's 4 coming out, but I intended 3.
  5912. 4:39:53So clearly, something's wrong with my i variables.
  5913. 4:39:56So let me be a little more pedantic.
  5914. 4:39:58Let me go inside of this loop and, temporarily,
  5915. 4:40:01say something explicit, like, i is--
  5916. 4:40:04&i /n, and then just plug in the value of i.
  5917. 4:40:09Right?
  5918. 4:40:09This is not the program I want to write, it's the program I'm temporarily
  5919. 4:40:13writing, because now I'm going to say make buggy, ./buggy.
  5920. 4:40:18And if I look, now, at the output, I have
  5921. 4:40:20some helpful diagnostic information. i is 0, and I get a hash, i is 1,
  5922. 4:40:25and I get a hash, 2 and I get a hash, 3 and I get hash.
  5923. 4:40:27OK, wait a minute.
  5924. 4:40:28I'm clearly going too many steps because, maybe, I
  5925. 4:40:30forgot that computers are, essentially, counting from 0,
  5926. 4:40:33and now, oh, it's less than or equal to.
  5927. 4:40:35Now you see it, right?
  5928. 4:40:37Again, trivial example, but just by using printf,
  5929. 4:40:40you can see inside of the computer's memory
  5930. 4:40:43by just printing stuff out like this.
  5931. 4:40:45And now, once you've figured it out, oh, so this should probably be less than 3,
  5932. 4:40:50or I should start counting from 1, there's
  5933. 4:40:52any number of ways I could fix this.
  5934. 4:40:53But the most conventional is probably just to say less than 3.
  5935. 4:40:56Now, I can delete my temporary print statement, rerun make buggy, ./buggy.
  5936. 4:41:03And, voila, problem solved.
  5937. 4:41:06All right, and to this day, I do this.
  5938. 4:41:08Whether it's making a command line application, or a web application,
  5939. 4:41:11or mobile application, It's very common to use
  5940. 4:41:13printf, or some equivalent in any language,
  5941. 4:41:15just to poke around and see what's inside the computer's memory.
  5942. 4:41:19Thankfully, there's more sophisticated tools than this.
  5943. 4:41:22Let me go ahead and reintroduce the bug here.
  5944. 4:41:25And let me reopen my sidebar at left here.
  5945. 4:41:28Let me now recompile the code to make sure it's current.
  5946. 4:41:32And I'm going to run a command called debug50.
  5947. 4:41:35Which is a command that's representative of a type of program
  5948. 4:41:39known as a debugger.
  5949. 4:41:41And this debugger is actually built into VS Code.
  5950. 4:41:43And all debug50 is doing for us is automating the process of starting
  5951. 4:41:47VS Code's built-in debugger.
  5952. 4:41:49So this isn't even a CS50-specific tool, we've
  5953. 4:41:52just given you a debug50 command to make it easier
  5954. 4:41:55to start it up from the get-go.
  5955. 4:41:57And the way you run this debugger is you say debug50, space, and then
  5956. 4:42:01the name of the program that you want to debug.
  5957. 4:42:04So, in this case, . /buggy.
  5958. 4:42:06So you don't mention your c-file.
  5959. 4:42:08You mention your already-compiled code.
  5960. 4:42:10And what this debugger is going to let me do is, most powerfully,
  5961. 4:42:16walk through my code step-by-step.
  5962. 4:42:19Because every program we've written thus far, runs from start to finish,
  5963. 4:42:23even if I'm not done thinking through each step at a time.
  5964. 4:42:26With a debugger, I can actually click on a line number
  5965. 4:42:30and say pause execution here, and the debugger
  5966. 4:42:33will let me walk through my code one step at a time, one second at a time,
  5967. 4:42:38one minute at a time, at my own human pace.
  5968. 4:42:41Which is super compelling when the programs get more complicated
  5969. 4:42:43and they might, otherwise, fly by on the screen.
  5970. 4:42:46So I'm going to click to the left of line 5.
  5971. 4:42:50And notice that these little red dots appear.
  5972. 4:42:52And if I click on one it stays, and gets even redder.
  5973. 4:42:55And I'm going to run debug50 on ./buggy.
  5974. 4:42:58And in just a moment, you'll see that a new panel opens on the left hand side.
  5975. 4:43:03It's doing some configuration of the screen.
  5976. 4:43:06Let me zoom out a little bit here so we can see more on the screen at once.
  5977. 4:43:10And sometimes, you'll see in VS Code that debug console opens up,
  5978. 4:43:14which looks very cryptic, just go back to terminal window if that happens.
  5979. 4:43:18Because at the terminal window is where you can still interact with your code.
  5980. 4:43:22And let's now take a look at what's going on.
  5981. 4:43:24If I zoom in on my buggy.c code here, you'll
  5982. 4:43:28notice that we have the same program as before, but highlighted in yellow
  5983. 4:43:35is line 5.
  5984. 4:43:36Not a coincidence, that's the line I set a so-called breakpoint at.
  5985. 4:43:39The little red dot means break here, pause execution here.
  5986. 4:43:44And the yellow line has not yet been executed.
  5987. 4:43:47But if I, now, at the top of my screen, notice these little arrows.
  5988. 4:43:51There's one for Play.
  5989. 4:43:53There's one for this, which, if I hover over it,
  5990. 4:43:55says Step Over, there's another that's going to say Step Into,
  5991. 4:43:58there's a third that says Step Out.
  5992. 4:44:00I'm just going to use the first of these, Step Over.
  5993. 4:44:02And I'm going to do this, and you'll see that the yellow highlight
  5994. 4:44:05moved from line 5 to line 7 because now it's ready,
  5995. 4:44:09but hasn't yet printed out that hash.
  5996. 4:44:12But the most powerful thing here, notice, is that top left here.
  5997. 4:44:16It's a little cryptic, because there's a bunch of things
  5998. 4:44:18going on that will make more sense over time, but at the top
  5999. 4:44:21there's a section called variables.
  6000. 4:44:22Below that, something called locals, which means
  6001. 4:44:25local to my current function, main.
  6002. 4:44:27And notice, there's my variable called i, and its current value is 0.
  6003. 4:44:31So now, once I click Step Over again, watch what happens.
  6004. 4:44:37We go from line 7 back to line 5.
  6005. 4:44:39But look in the terminal window, one of the hashes has printed.
  6006. 4:44:43But now, it's printed at my own pace.
  6007. 4:44:46I can think through this step-by-step.
  6008. 4:44:48Notice that i has not changed, yet.
  6009. 4:44:50It's still 0 because the yellow highlighted line hasn't yet executed.
  6010. 4:44:53But the moment I click Step Over, it's going to execute line 5.
  6011. 4:44:58Now, notice at top left, i has become 1, and nothing has printed, yet,
  6012. 4:45:05because now, highlighted is line 7.
  6013. 4:45:07So if I click Step Over again, we'll see the hash.
  6014. 4:45:12If I repeat this process at my own human, comfortable pace,
  6015. 4:45:16I can see my variables changing, I can see output changing on the screen,
  6016. 4:45:21and I can just think about should that have just happened.
  6017. 4:45:24I can pause and give thought to what's actually
  6018. 4:45:26going on without trying to race the computer and figure it all out at once.
  6019. 4:45:30I'm going to go ahead and stop here because we already
  6020. 4:45:32know what this particular problem is, and that brings me back
  6021. 4:45:35to my default terminal window.
  6022. 4:45:36But this debugger, let me disable the breakpoint now
  6023. 4:45:40so it doesn't keep breaking, this debugger
  6024. 4:45:42will be your friend moving forward in order
  6025. 4:45:45to step through your code step-by-step, at your own pace to figure out
  6026. 4:45:49where something has gone wrong.
  6027. 4:45:51Printf is great, but it gets annoying if you have to constantly add print this,
  6028. 4:45:54print this, print this, print this, recompile, rerun it, oh wait a minute,
  6029. 4:45:57print this, print this.
  6030. 4:45:59The debugger lets you do the equivalent, but automatically.
  6031. 4:46:04Questions on this debugger, which you'll see all the more hands-on over time?
  6032. 4:46:10Questions on debugger?
  6033. 4:46:11Yeah?
  6034. 4:46:12AUDIENCE: You were using a Step Over feature.
  6035. 4:46:14What do the other features in the debugger--
  6036. 4:46:17DAVID MALAN: Really good question.
  6037. 4:46:18We'll see this before long, but those other buttons that I glossed over,
  6038. 4:46:21step into and step out of, actually let you step into specific functions
  6039. 4:46:26if I had any more than main.
  6040. 4:46:28So if main called a function called something,
  6041. 4:46:31and something called a function called something else, instead of just
  6042. 4:46:34stepping over the entire execution of that function, I could step into it
  6043. 4:46:38and walk through its lines of code one by one.
  6044. 4:46:41So any time you have a problem set you're
  6045. 4:46:43working on that has multiple functions, you can set a breakpoint in main,
  6046. 4:46:46if you want, or you can set it inside of one of your additional functions
  6047. 4:46:50to focus your attention only on that.
  6048. 4:46:53And we'll see examples of that over time.
  6049. 4:46:56All right, so what else?
  6050. 4:46:58And what's the sort of, elephant in the room, so to speak,
  6051. 4:47:02is actually a duck in this case.
  6052. 4:47:04Why is there this duck and all of these ducks here?
  6053. 4:47:06Well, it turns out, a third, genuinely recommended, debugging technique
  6054. 4:47:10is talking through problems, talking through code with someone else.
  6055. 4:47:14Now, in the absence of having a family member, or a friend,
  6056. 4:47:16or a roommate who actually wants to hear you talk about code, of all things,
  6057. 4:47:20generally, programmers turn to a rubber duck, or other inanimate objects
  6058. 4:47:25if something animate is not available.
  6059. 4:47:27The idea behind rubber duck debugging, so to speak,
  6060. 4:47:31is that simply by looking at your code and talking it through, OK, on line 3,
  6061. 4:47:37I'm starting a 4 loop and I'm initializing i to 0.
  6062. 4:47:41OK, then, I'm printing out a hash.
  6063. 4:47:43Just by talking through your code, step-by-step, invariably,
  6064. 4:47:48finds you having the proverbial light bulb go off over your head,
  6065. 4:47:51because you realize, wait a minute I just said something stupid,
  6066. 4:47:53or I just said something wrong.
  6067. 4:47:54And this is really just a proxy for any other human, teaching fellow, teacher
  6068. 4:47:58or friend, colleague.
  6069. 4:48:00But in the absence of any of those people in the room,
  6070. 4:48:02you're welcome to take, on your way out today.
  6071. 4:48:04One of these little, rubber ducks and consider using it, for real, any time
  6072. 4:48:08you want to talk through one of your problems in CS50,
  6073. 4:48:12or maybe life more generally.
  6074. 4:48:13But having it there on your desk is just a way
  6075. 4:48:15to help you hear illogic in what you think
  6076. 4:48:19might, otherwise, be logical code.
  6077. 4:48:22So printf, debugging, rubber-duck debugging are just three of the ways,
  6078. 4:48:26you'll see over time, to get to the source of code
  6079. 4:48:29that you will write that has mistakes.
  6080. 4:48:31Which is going to happen, but it will empower you
  6081. 4:48:33all the more to solve those mistakes.
  6082. 4:48:36All right, any questions on debugging, in general, or these three techniques?
  6083. 4:48:41Yeah?
  6084. 4:48:42AUDIENCE: [INAUDIBLE]
  6085. 4:48:44DAVID MALAN: What's the difference between Step Over and Step Into?
  6086. 4:48:46At the moment, the only one that's applicable to the code I just wrote
  6087. 4:48:50is Step Over, because it means step over each line of code.
  6088. 4:48:53If, though, I had other functions that I had written in this program,
  6089. 4:48:58maybe lower down in the file, I could step into those function calls
  6090. 4:49:03and walk through them one at a time.
  6091. 4:49:05So we'll come back to this with an actual example,
  6092. 4:49:07but step into will allow me to do exactly that.
  6093. 4:49:10In fact, this is a perfect segue to doing a little something like this.
  6094. 4:49:13Let me go ahead and open up another file here.
  6095. 4:49:15And, actually, we'll use the same, buggy.
  6096. 4:49:17And we're going to write one other thing that's buggy, as well.
  6097. 4:49:20Let me go up here and include, as before, cs50.h.
  6098. 4:49:24Let me include stdio.h.
  6099. 4:49:28Let me do int main(void).
  6100. 4:49:29So all of this, I think, is correct, so far.
  6101. 4:49:32And let's do this, let's give myself an int called i,
  6102. 4:49:35and let's ask the user for a negative integer.
  6103. 4:49:38This is not a function that exists, technically, yet.
  6104. 4:49:41But I'm going to assume, for the sake of discussion, that it does.
  6105. 4:49:44Then, I'm just going to print out, with %i and a new line,
  6106. 4:49:47whatever the human typed in.
  6107. 4:49:49So at this point in the story, my program, I think, is correct.
  6108. 4:49:52Except for the fact that get negative int is not
  6109. 4:49:55a function in the CS50 library or anywhere else.
  6110. 4:49:57I'm going to need to invent it myself.
  6111. 4:49:59So suppose, in this case, that I declare a function called get negative int.
  6112. 4:50:05It's return type, so to speak, should be int, because, as its name suggests,
  6113. 4:50:09I want to hand the user back in integer, and it's going
  6114. 4:50:12to take no input to keep it simple.
  6115. 4:50:14So I'm just going to say void there.
  6116. 4:50:16No inputs, no special prompts, nothing like that.
  6117. 4:50:19Let me, now, give myself some curly braces.
  6118. 4:50:21And let me do something familiar, perhaps, from problem set 1.
  6119. 4:50:24Let me give myself a variable, like n, and let me do the following
  6120. 4:50:29within this block of code.
  6121. 4:50:31Assign n the value of get int, asking the user for a negative integer using
  6122. 4:50:37get int's own prompt.
  6123. 4:50:39And I want to do this while n is less than 0, because I
  6124. 4:50:43want to get a negative from the user.
  6125. 4:50:44And recall, from having used this block in the past,
  6126. 4:50:48I can now return n as the very last step to hand back
  6127. 4:50:52whatever the user has typed in, so long as they cooperated and gave me
  6128. 4:50:56an actual negative integer.
  6129. 4:50:58Now, I've deliberately made a mistake here,
  6130. 4:51:00and it's a subtle, silly, mathematical one,
  6131. 4:51:03but let me compile this program after copying the prototype up to the top,
  6132. 4:51:08so I don't make that mistake again.
  6133. 4:51:09Let me do make buggy, Enter.
  6134. 4:51:12And now, let me do ./buggy.
  6135. 4:51:14I'll give it a negative integer, like negative 50.
  6136. 4:51:18Uh-huh.
  6137. 4:51:19That did not take.
  6138. 4:51:23How about negative 5?
  6139. 4:51:25No.
  6140. 4:51:26How about 0?
  6141. 4:51:28All right.
  6142. 4:51:29So it's, clearly, working backwards, or incorrectly here, logically.
  6143. 4:51:33So how could I go about debugging this?
  6144. 4:51:35Well, I could do what I've done before?
  6145. 4:51:36I could use my printf technique and say something explicit like n is %i,
  6146. 4:51:43new line, comma n, just to print it out, let me recompile buggy,
  6147. 4:51:49let me rerun buggy, let me type in negative 50.
  6148. 4:51:52OK, n is negative 50.
  6149. 4:51:54So that didn't really help me at this point,
  6150. 4:51:57because that's the same as before.
  6151. 4:51:58So let me do this, debug50, ./buggy.
  6152. 4:52:02Oh, but I've made a mistake.
  6153. 4:52:04So I didn't set my breakpoint, yet.
  6154. 4:52:05So let me do this, and I'll set a breakpoint this time.
  6155. 4:52:09I could set it here, on line 8.
  6156. 4:52:11Let's do it in main, as before.
  6157. 4:52:13Let me rerun debug50, now.
  6158. 4:52:15On ./buggy.
  6159. 4:52:17That fancy user interface is going to pop up.
  6160. 4:52:19It's going to highlight the line that I set the breakpoint on.
  6161. 4:52:22Notice that, on the left hand side of the screen,
  6162. 4:52:25i is defaulting, at the moment to 0, because I haven't typed anything in,
  6163. 4:52:28yet.
  6164. 4:52:29But let me, now, Step Over this line that's highlighted in yellow,
  6165. 4:52:35and you'll see that I'm being prompted.
  6166. 4:52:36So let's type in my negative 50, Enter.
  6167. 4:52:40Notice now that I'm stuck in that function.
  6168. 4:52:45All right.
  6169. 4:52:46So clearly, the issue seems to be in my get negative int function.
  6170. 4:52:50So, OK, let me stop this execution.
  6171. 4:52:54My problem doesn't seem to be in main, per se, maybe it's down here.
  6172. 4:52:57So that's fine.
  6173. 4:52:58Let me set my same breakpoint at line 8.
  6174. 4:53:00Let me rerun debug50 one more time.
  6175. 4:53:02But this time, instead of just stepping over that line, let's step into it.
  6176. 4:53:07So notice line 8 is, again, highlighted in yellow.
  6177. 4:53:09In the past I've been clicking Step Over.
  6178. 4:53:11Let's click Step into, now.
  6179. 4:53:14When I click Step Into, boom, now, the debugger
  6180. 4:53:17jumps into that specific function.
  6181. 4:53:20Now, I can step through these lines of code, again and again.
  6182. 4:53:23I can see what the value of n is as I'm typing it in.
  6183. 4:53:25I can think through my logic, and voila.
  6184. 4:53:27Hopefully, once I've solved the issue, I can exit the debugger, fix my code,
  6185. 4:53:31and move on.
  6186. 4:53:33So Step Over just goes over the line, but executes it,
  6187. 4:53:36Step Into lets you go into other functions you've written.
  6188. 4:53:41So let's go ahead and do this.
  6189. 4:53:43We've got a bunch of possible approaches that we
  6190. 4:53:47can take to solving some problems let's go ahead
  6191. 4:53:49and pace ourselves today, though.
  6192. 4:53:50Let's take a five-minute break, here.
  6193. 4:53:52And when we come back, we'll take a look at that computer's memory
  6194. 4:53:54we've been talking about.
  6195. 4:53:55See you in five.
  6196. 4:53:57All right.
  6197. 4:54:00So let's dive back in.
  6198. 4:54:05Up until now, both, by way of week 1 and problems set 1, for the most part,
  6199. 4:54:11we've just translated from Scratch into C all of these basic building blocks,
  6200. 4:54:14like loops and conditionals, Boolean expressions, variables.
  6201. 4:54:17So sort of, more of the same.
  6202. 4:54:19But there are features in C that we've already stumbled across already,
  6203. 4:54:22like data types, the types of variables that doesn't exist in Scratch,
  6204. 4:54:26but that, in fact, does exist in other languages.
  6205. 4:54:28In fact, a few that we'll see before long.
  6206. 4:54:30So to summarize the types we saw last week, recall this little list here.
  6207. 4:54:34We had ints, and floats, and longs, and doubles, and chars,
  6208. 4:54:39there's also Booles and also string, which we've seen a few times.
  6209. 4:54:42But today, let's actually start to formalize what these things are,
  6210. 4:54:46and actually what your Mac and PC are doing when you manipulate bits
  6211. 4:54:50as an int versus a char, versus a string, versus something else.
  6212. 4:54:53And see if we can't put more tools into your toolkit, so to speak,
  6213. 4:54:56so we can start quickly writing more featureful, more sophisticated
  6214. 4:54:59programs in C.
  6215. 4:55:01So it turns out, that on most systems nowadays,
  6216. 4:55:04though this can vary by actual computer, this
  6217. 4:55:07is how large each of the data types, typically,
  6218. 4:55:10is in C. When you store a Boolean value, a 0 or 1, a true, a false, or true,
  6219. 4:55:15it actually uses 1 byte.
  6220. 4:55:17That's a little excessive, because, strictly speaking,
  6221. 4:55:19you only need 1 bit, which is 1/8 of this size.
  6222. 4:55:22But for simplicity, computers use a whole byte
  6223. 4:55:25to represent a Boole, true or false.
  6224. 4:55:28A char, we saw last week, is only 1 byte, or 8 bits.
  6225. 4:55:32And this is why ASCII, which uses 1 byte, or technically, only 7 bits early
  6226. 4:55:37on, was confined to only 256 maximally possible characters.
  6227. 4:55:41Notice that an int is 4 bytes, or 32 bits.
  6228. 4:55:46A float is also 4 bytes or 32 bits.
  6229. 4:55:48But the things that we call long, it's, literally, twice as long,
  6230. 4:55:528 bytes or 64 bits.
  6231. 4:55:53So is a double.
  6232. 4:55:54A double is 64 bits of precision for floating point values.
  6233. 4:55:58And a string, for today, we're going to leave as a question mark.
  6234. 4:56:01We'll come back to that, later today and next week,
  6235. 4:56:03as to how much space a string takes up, but, suffice it to say,
  6236. 4:56:06it's going to take up a variable amount of space,
  6237. 4:56:09depending on whether the string is short or long.
  6238. 4:56:11But we'll see exactly what that means, before long.
  6239. 4:56:14So here's a photograph of a typical piece of memory
  6240. 4:56:19inside of your Mac, or PC, or phone.
  6241. 4:56:22Odds are, it might be a little smaller in some devices.
  6242. 4:56:24This is known as RAM, or random access memory.
  6243. 4:56:27Each of these little black chips on this circuit
  6244. 4:56:29board, the green thing, these little black chips
  6245. 4:56:31are where 0s and 1s are actually stored.
  6246. 4:56:34Each of those stores some number of bytes.
  6247. 4:56:36Maybe megabytes, maybe even gigabytes, nowadays.
  6248. 4:56:39So let's focus on one of those chips, to give us a zoomed in version, thereof.
  6249. 4:56:45Let's consider the fact that, even though we don't have to care, exactly ,
  6250. 4:56:49how this kind of thing is made, if this is, like, 1 gigabyte of memory,
  6251. 4:56:53for the sake of discussion, it stands to reason that,
  6252. 4:56:56if this thing is storing 1 billion bytes, 1 gigabyte,
  6253. 4:57:00then we can number them, arbitrarily.
  6254. 4:57:02Maybe this will be byte 0, 1, 2, 3, 4, 5, 6, 7, 8.
  6255. 4:57:05Then, maybe, way down here in the bottom right corner is byte number 1 billion.
  6256. 4:57:09We can just number these things, as might be our convention.
  6257. 4:57:13Let's draw that graphically.
  6258. 4:57:14Not with a billion squares, but fewer than those.
  6259. 4:57:17And let's zoom in further, and consider that.
  6260. 4:57:19At this point in the story, let's abstract
  6261. 4:57:21away all the hardware, and all the little wires,
  6262. 4:57:23and just think of memory as taking up-- or, rather, just think of data
  6263. 4:57:27as taking up some number of bytes.
  6264. 4:57:30So, for instance, if you were to store a char in a computer's memory, which
  6265. 4:57:34was 1 byte, it might be stored at this top left-hand location
  6266. 4:57:38of this black chip of memory.
  6267. 4:57:40If you were to store something like an integer that uses 4 bytes, well,
  6268. 4:57:44it might use four of those bytes, but they're going to be contiguous
  6269. 4:57:47back-to-back-to-back, in this case.
  6270. 4:57:49If you were to store a long or a double, you might, actually, need 8 bytes.
  6271. 4:57:53So I'm filling in these squares to represent
  6272. 4:57:55how much memory and given variable of some data type would take up.
  6273. 4:58:001, or 4, or 8, in this case, here.
  6274. 4:58:03Well, from here, let's abstract away from all of the hardware
  6275. 4:58:06and really focus on memory as being a grid.
  6276. 4:58:08Or, really, like a canvas that we can paint any types of data
  6277. 4:58:11onto that we want.
  6278. 4:58:13At the end of the day, all of this data is just going to be 0s and 1s.
  6279. 4:58:16But it's up to you and I to build abstractions on top of that.
  6280. 4:58:20Things like actual numbers, colors, images, movies, and beyond.
  6281. 4:58:24But we'll start lower-level, here, first.
  6282. 4:58:26Suppose I had a program that needs three integers.
  6283. 4:58:30A simple program whose purpose in life is to average your three
  6284. 4:58:33scores on an exam, or some such thing.
  6285. 4:58:36Suppose that your three scores were these, 72, 73, not too bad, and 33,
  6286. 4:58:41which is particularly low.
  6287. 4:58:42Let's write a program that does this kind of averaging for us.
  6288. 4:58:47Let me go back to VS Code, here.
  6289. 4:58:49Let me open up a file called scores.c.
  6290. 4:58:52Let me implement this as follows.
  6291. 4:58:55Let me include stdio.h at the top, int main(void) as before.
  6292. 4:59:00Then, inside of main, let me declare score 1, which is 72.
  6293. 4:59:05Give me another score, 73.
  6294. 4:59:08Then, a third score, called score 3, which is going to be 33.
  6295. 4:59:11Now, I'm going to use printf to print out the average of those things,
  6296. 4:59:15and I can do this in a few different ways.
  6297. 4:59:16But I'm going to print out %f, and I'm going to do score 1, plus score 2,
  6298. 4:59:22plus score 3, divided by 3, close parentheses semicolon.
  6299. 4:59:28Some relatively simple arithmetic to compute the average of three scores,
  6300. 4:59:31if I'm curious what my average grade is in the class with these three
  6301. 4:59:34assessments.
  6302. 4:59:35Let me, now, do make scores.
  6303. 4:59:39All right, so I've somehow made an error already.
  6304. 4:59:43But this one is, actually, germane to a problem we, hopefully,
  6305. 4:59:49won't encounter too frequently.
  6306. 4:59:51What's going on here?
  6307. 4:59:52So underlined to score 1, plus score 2, plus score 3, divided by 3.
  6308. 4:59:55Format specifies type double, but the argument has type int, well,
  6309. 5:00:00what's going on here?
  6310. 5:00:02Because the arithmetic seems to check out.
  6311. 5:00:04Yeah?
  6312. 5:00:05AUDIENCE: So the computer is doing the math, but they basically [INAUDIBLE]
  6313. 5:00:08just gives out a value at the end because, well [INAUDIBLE]
  6314. 5:00:13DAVID MALAN: Correct.
  6315. 5:00:14And we'll come back to this in more detail,
  6316. 5:00:15but, indeed, what's happening here is I'm adding three ints together,
  6317. 5:00:18obviously, because I define them right up here.
  6318. 5:00:20And I'm dividing by another int, 3, but the catch
  6319. 5:00:23is, recall that C when it performs math, treats all of these things as integers.
  6320. 5:00:28But integers are not floating point value.
  6321. 5:00:30So if you actually want to get a precise, average for your score
  6322. 5:00:33without throwing away the remainder, everything after the decimal point,
  6323. 5:00:37it turns out, we're going to have to--
  6324. 5:00:39we're going to-- aww--
  6325. 5:00:41we're going to have to--
  6326. 5:00:42[LAUGHTER] we're going to have to convert this whole expression, somehow,
  6327. 5:00:46to a float.
  6328. 5:00:47And there's a few ways to do this but the easiest way,
  6329. 5:00:50for now, I'm going to go ahead and do this up here,
  6330. 5:00:52I'm going to change the divide by 3 to divide by 3.0.
  6331. 5:00:55Because it turns out, long story short, in C, so long as one of the values
  6332. 5:00:59participating in an arithmetic expression
  6333. 5:01:01like this is something like a float, the rest
  6334. 5:01:03will be treated as promoted to a floating point value as well.
  6335. 5:01:08So let me, now, recompile this code with make scores, Enter.
  6336. 5:01:13This time it worked OK, because I'm treating a float as a float.
  6337. 5:01:17Let me do . /scores, Enter.
  6338. 5:01:19All right, my average is 59.33333 and so forth.
  6339. 5:01:24All right.
  6340. 5:01:24So the math, presumably, checks out.
  6341. 5:01:27Floating point imprecision per last week aside.
  6342. 5:01:30But let's consider the design of this program.
  6343. 5:01:33What is, kind of, bad about it, or if we maintain this program longer term,
  6344. 5:01:40are we going to regret the design of this program?
  6345. 5:01:43What might not be ideal here?
  6346. 5:01:45Yeah?
  6347. 5:01:45AUDIENCE: [INAUDIBLE]
  6348. 5:01:54DAVID MALAN: Yeah, so in this case, I have hard coded my three scores.
  6349. 5:01:58So, if I'm hearing you correctly, this program
  6350. 5:02:01is only ever going to tell me this specific average.
  6351. 5:02:03I'm not even using something like, get int
  6352. 5:02:05or get float to get three different scores, so that's not good.
  6353. 5:02:09And suppose that we wait later in the semester,
  6354. 5:02:11I think other problems could arise.
  6355. 5:02:12Yeah?
  6356. 5:02:13AUDIENCE: Just thinking also somewhat of an issue
  6357. 5:02:15that you can't reuse that number.
  6358. 5:02:17DAVID MALAN: I can't reuse the number because I
  6359. 5:02:19haven't stored the average in some variable, which in this program, not
  6360. 5:02:23a big deal, but certainly, if I wanted to reuse it elsewhere,
  6361. 5:02:25that's a problem.
  6362. 5:02:26Let's fast-forward again, a little later in the semester,
  6363. 5:02:29I don't just have three test scores or exam scores,
  6364. 5:02:31maybe I have 4, or 5, or 6.
  6365. 5:02:33Where might this take us?
  6366. 5:02:34AUDIENCE: Yeah, if you ever want to have to take
  6367. 5:02:36the average of any number of scores other than 3, [INAUDIBLE]
  6368. 5:02:39DAVID MALAN: Yeah, I've sort of, capped this program at 3.
  6369. 5:02:42And honestly, this is, kind of, bordering on copy paste.
  6370. 5:02:45Even though the variables, yes, have different names; score 1, score 2,
  6371. 5:02:48score 3.
  6372. 5:02:49Imagine doing this for a whole grade book for a class.
  6373. 5:02:51Having to score 4, 5, 6, 11 10, 12, 20, 30, that's a lot of variables.
  6374. 5:02:57You can imagine just how ugly the code starts
  6375. 5:02:59to get if you're just defining variable after variable, after variable.
  6376. 5:03:02So it turns out, there are better ways, in languages like C,
  6377. 5:03:07if you want to have multiple values stored in memory that
  6378. 5:03:11happened to be of the same data type.
  6379. 5:03:13Let's take a look back at this memory, here,
  6380. 5:03:14to see what these things might look like in memory.
  6381. 5:03:16Here's that grid of memory.
  6382. 5:03:18Each of these recall represents a byte.
  6383. 5:03:20To be clear, if I store score 1 in memory first,
  6384. 5:03:23how many bytes will it take up?
  6385. 5:03:25AUDIENCE: [INAUDIBLE]
  6386. 5:03:26DAVID MALAN: So 4, a.k.a.
  6387. 5:03:2732 bits.
  6388. 5:03:28So I might draw a score 1 as filling up this part of the memory.
  6389. 5:03:32It's up to the computer as to whether it goes here, or down there, or wherever.
  6390. 5:03:36I'm just keeping the pictures clean for today, from the top-left on down.
  6391. 5:03:39If I, then, declare another variable, called score 2,
  6392. 5:03:42it might end up over there, also taking up 4 bytes.
  6393. 5:03:44And then score 3 might end up here.
  6394. 5:03:47So that's just representing what's going on inside of the computer's memory.
  6395. 5:03:51But technically speaking, to be clear, per week 0, what's
  6396. 5:03:54really being stored in the computer's memory, are patterns of 0s and 1s.
  6397. 5:03:5832 total, in this case, because 32 bits is 4 bytes.
  6398. 5:04:03But again, it gets boring quickly to think in and look
  6399. 5:04:07at binary all the time.
  6400. 5:04:09So we'll, generally, abstract this away as just using
  6401. 5:04:11decimal numbers, in this case, instead.
  6402. 5:04:13But there might be a better way to store, not just three of these things,
  6403. 5:04:18but maybe four, maybe, five, maybe 10, maybe, more,
  6404. 5:04:21by declaring one variable to store all of them, instead of 3, or 4, or 5,
  6405. 5:04:27or more individual variables.
  6406. 5:04:30The way to do this is by way of something known as an array.
  6407. 5:04:34An array is another type of data that allows you to store multiple values
  6408. 5:04:42of the same type back-to-back-to-back.
  6409. 5:04:45That is, to say, contiguously.
  6410. 5:04:46So an array can let you create memory for one int, or two, or three,
  6411. 5:04:54or even more than that, but describe them
  6412. 5:04:56all using the same variable name, the same one name.
  6413. 5:05:00So for instance, if, for one program, I only need three integers,
  6414. 5:05:05but I don't want to messily declare them as score 1, score 2, score 3,
  6415. 5:05:10I can do this, instead.
  6416. 5:05:11This is today's first new piece of syntax,
  6417. 5:05:13the square brackets that we're now seeing.
  6418. 5:05:15This line of code, here, is similar to int score 1 semicolon,
  6419. 5:05:21or int score 1 equals 72 semicolon.
  6420. 5:05:24This line of code is declaring for me, so to speak, an array of size 3.
  6421. 5:05:30And that array is going to store three integers.
  6422. 5:05:33Why?
  6423. 5:05:34Because the type of that array is an int, here.
  6424. 5:05:39The square brackets tell the computer how many ints you want.
  6425. 5:05:42In this case, 3.
  6426. 5:05:43And the name is, of course, scores.
  6427. 5:05:45Which, in English, I've deliberately pluralized
  6428. 5:05:47so that I can describe this array as storing multiple scores, indeed.
  6429. 5:05:52So if I want to now assign values to this variable, called scores,
  6430. 5:05:57I can do code like this.
  6431. 5:05:59I can say, scores bracket 0 equals 72, scores bracket 1 equals 73,
  6432. 5:06:04and scores bracket 2 equals 33.
  6433. 5:06:06The only thing weird there is, admittedly,
  6434. 5:06:08the square brackets which are still new.
  6435. 5:06:10But we're also, notice, 0 indexing things.
  6436. 5:06:14To zero index means to start counting at 0.
  6437. 5:06:16When we've talked about that before, our four loops
  6438. 5:06:18have, generally, been zero indexed.
  6439. 5:06:20Arrays in C are zero indexed.
  6440. 5:06:24And you do not have choice over that.
  6441. 5:06:25You can't start counting at 1 in arrays because you prefer to,
  6442. 5:06:28you'd be sacrificing one of the elements.
  6443. 5:06:31You have to start in arrays counting from 0.
  6444. 5:06:33So out of context, this doesn't solve a problem,
  6445. 5:06:37but it, definitely, is going to once we have more
  6446. 5:06:39than, even, three scores here.
  6447. 5:06:41In fact, let me change this program a little bit.
  6448. 5:06:44Let me go back to VS Code.
  6449. 5:06:45And delete these three lines, here.
  6450. 5:06:48And replace it with a scores variable that's
  6451. 5:06:51ready to store three total integers.
  6452. 5:06:54And then, initialize them as follows, scores bracket 0 is 72,
  6453. 5:06:58as before, scores bracket 1 is going to be 73, scores bracket 2
  6454. 5:07:02is going to be 33.
  6455. 5:07:04Notice, I do not need to say int before any of these lines,
  6456. 5:07:08because that's been taken care of, already,
  6457. 5:07:10for me on line 5, where I already specified that everything in this array
  6458. 5:07:14is going to be an int.
  6459. 5:07:17Now, down here, this code needs to change because I no longer have
  6460. 5:07:21three variables, score 1, 2, and 3.
  6461. 5:07:23I have 1 variable, but that I can index into.
  6462. 5:07:28I'm going to, here, then, do scores bracket 0, plus scores bracket 1,
  6463. 5:07:33plus scores bracket 2, which is equivalent to what I did earlier,
  6464. 5:07:37giving me back those three integers.
  6465. 5:07:39But notice, I'm using the same variable name, every time.
  6466. 5:07:42And again, I'm using this new square bracket notation to, quote-unquote,
  6467. 5:07:45index into the array to get at the first int, the second int, and the third,
  6468. 5:07:50and then, to do it again down here.
  6469. 5:07:53Now, this program, still not really solving all the problems we describe,
  6470. 5:07:56I still can only store three scores, but we'll come back
  6471. 5:07:58to something like that before long.
  6472. 5:08:00But for now, we're just introducing a new syntax and a new feature,
  6473. 5:08:03whereby, I can now store multiple values in the same variable.
  6474. 5:08:09Well, let's enhance this a bit more.
  6475. 5:08:11Instead of hard coding these scores, as was identified as a problem,
  6476. 5:08:14let's use get int to ask the user for a score.
  6477. 5:08:19Let's, then, use get int to ask the user for another score.
  6478. 5:08:22Let's use get int to ask the user for a third score,
  6479. 5:08:25storing them in those respective locations.
  6480. 5:08:28And, now, if I go ahead and save this program, recompile scores, huh.
  6481. 5:08:34I've messed up, here.
  6482. 5:08:35Now these errors should be getting a little familiar.
  6483. 5:08:38What mistake did I make?
  6484. 5:08:41Let me give folks a moment.
  6485. 5:08:42AUDIENCE: cs50.h
  6486. 5:08:43DAVID MALAN: cs50.h.
  6487. 5:08:45That was not intentional, so still making mistakes all these years later.
  6488. 5:08:48I need to include cs50.h.
  6489. 5:08:50Now, I'm going to go back to the bottom in the terminal window, make scores.
  6490. 5:08:53OK.
  6491. 5:08:54We're back in business, ./scores.
  6492. 5:08:55Now, the program is getting a little more interesting.
  6493. 5:08:58So maybe, this year was better and I got a 100, and a 99, and a 98, and there,
  6494. 5:09:02my average is 99.0000.
  6495. 5:09:05So now, it's a little more dynamic.
  6496. 5:09:06It's a little more interesting.
  6497. 5:09:07But it's still capping the number of scores at three, admittedly.
  6498. 5:09:10But now, I've introduced another, sort of, symptom of bad programming.
  6499. 5:09:15There's this expression in programming, too, called code smell, where like--
  6500. 5:09:18[SNIFFS AIR] something smells a little off.
  6501. 5:09:20And there's something off here in that I could do better with this code.
  6502. 5:09:24Does anyone see an opportunity to improve the design of this code, here,
  6503. 5:09:29if my goal, still, is to get three scores from the user but [SNIFF SNIFF]
  6504. 5:09:32without it smelling [SNIFF] kind of bad?
  6505. 5:09:34Yeah?
  6506. 5:09:35AUDIENCE: [INAUDIBLE] use a 4 loop?
  6507. 5:09:37That way you don't have to copy and paste all of those scores.
  6508. 5:09:40DAVID MALAN: Yeah, exactly.
  6509. 5:09:41Those lines of code are almost identical.
  6510. 5:09:43And honestly, the only thing that's changing is the number,
  6511. 5:09:45and it's just incrementing by 1.
  6512. 5:09:47We have all of the building blocks to do this better.
  6513. 5:09:49So let me go ahead and improve this.
  6514. 5:09:51Let me delete that code.
  6515. 5:09:53Let me, now, have a 4 loop.
  6516. 5:09:55So for int i get 0, i less than 3, i plus plus.
  6517. 5:10:00Then, inside of this 4 loop, I can distill all three
  6518. 5:10:03of those lines into something more generic,
  6519. 5:10:05like scores bracket i equals get int, and now, ask the user, just
  6520. 5:10:10once, via get int, for a score.
  6521. 5:10:13So this is where arrays start to get pretty powerful.
  6522. 5:10:16You don't have to hard code, that is, literally,
  6523. 5:10:18type in all of these magic numbers like 0, 1, and 2.
  6524. 5:10:20You can start to do it, programmatically,
  6525. 5:10:22as you propose with a loop.
  6526. 5:10:24So now, I've tightened things up.
  6527. 5:10:25I'm now, dynamically, getting three different scores,
  6528. 5:10:28but putting them in three different locations.
  6529. 5:10:31And so this program, ultimately, is going to work, pretty much, the same.
  6530. 5:10:34Make scores, ./scores, and 100, 99, 98, and we're back to the same answer.
  6531. 5:10:41But it's a little better designed, too.
  6532. 5:10:43If I really want to nitpick, there's something
  6533. 5:10:45that still smells, a little bit, here.
  6534. 5:10:47The fact that I have indeed, this magic number three, that really
  6535. 5:10:51has to be the same as this number here.
  6536. 5:10:54Otherwise, who knows what's going to go wrong.
  6537. 5:10:56So what might be a solution, per last week,
  6538. 5:10:58to cleaning that code up further, too?
  6539. 5:11:01AUDIENCE: [INAUDIBLE] the user's discretion
  6540. 5:11:04how many input scores [INAUDIBLE].
  6541. 5:11:06DAVID MALAN: OK, so we could leave it up to the user's discretion.
  6542. 5:11:09And so we could, actually, do something like this.
  6543. 5:11:11Let me take this a few steps ahead.
  6544. 5:11:13Let me say something like, int n gets get int, how many scores question mark,
  6545. 5:11:20then I could actually change this to an n, and then this to an n,
  6546. 5:11:24and, indeed, make the whole program dynamic?
  6547. 5:11:27Ask the human how many tests have there been this semester?
  6548. 5:11:29Then, you can type in each of those scores
  6549. 5:11:31because the loop is going to iterate that many times.
  6550. 5:11:33And then you'll get the average of one test, two test, three--
  6551. 5:11:37well, lost another-- or however many scores that were actually
  6552. 5:11:41specified by the user Yeah, question?
  6553. 5:11:45AUDIENCE: How many bits or bytes get used in an array?
  6554. 5:11:50DAVID MALAN: How many bytes are used in an array?
  6555. 5:11:52AUDIENCE: [INAUDIBLE] point of doing this is to save [INAUDIBLE]
  6556. 5:11:56DAVID MALAN: So the purpose of an array is not to save space.
  6557. 5:11:59It's to eliminate having multiple variable names
  6558. 5:12:03because that gets very messy quickly.
  6559. 5:12:05If you have score 1, score 2, score 3, dot, dot, dot, score 99,
  6560. 5:12:09that's, like, 99 different variables, potentially,
  6561. 5:12:12that you could collapse into one variable that has 99 locations.
  6562. 5:12:18At different indices, or indexes.
  6563. 5:12:20As someone would say, the index for an array
  6564. 5:12:22is whatever is in the square brackets.
  6565. 5:12:25AUDIENCE: [INAUDIBLE]
  6566. 5:12:35DAVID MALAN: So it's a good question.
  6567. 5:12:37So if you-- I'm using ints for everything--
  6568. 5:12:39and honestly, we don't really need ints for scores
  6569. 5:12:41because I'm not likely to get a 2 billion on a test anytime soon.
  6570. 5:12:46And so you could use different data types.
  6571. 5:12:47And that list we had on the screen, earlier, is not all of them.
  6572. 5:12:50There's a data type called short, which is shorter than an int,
  6573. 5:12:54you could, technically, use char, in some form or other data types as well.
  6574. 5:12:59Generally speaking, in the year 2021, these
  6575. 5:13:01tend to be over optima-- overly optimized decisions.
  6576. 5:13:05Everyone just uses ints, even though no one
  6577. 5:13:07is going to get a test score that's 2 billion, or more, because int is just,
  6578. 5:13:10kind of, the go-to.
  6579. 5:13:11Years ago, memory was expensive.
  6580. 5:13:14And every one of your instincts would have been
  6581. 5:13:16spot on because memory is so tight.
  6582. 5:13:18But, nowadays, we don't worry as much about it.
  6583. 5:13:21Yeah?
  6584. 5:13:21AUDIENCE: I have a question about the error [INAUDIBLE]..
  6585. 5:13:26Could it-- when you're doing a hash problem on the problem set--
  6586. 5:13:30DAVID MALAN: So what is the difference between dividing two ints
  6587. 5:13:34and not getting an error, as you might have encountered
  6588. 5:13:36in a program like cash, versus dividing two ints
  6589. 5:13:40and getting an error like I did a moment ago?
  6590. 5:13:42The problem with the scenario I created a moment ago was printf was involved.
  6591. 5:13:46And I was telling printf to use a %f, but I was giving printf the result
  6592. 5:13:52of dividing integers by another integer.
  6593. 5:13:54So it was printf that was yelling at me.
  6594. 5:13:57I'm guessing in the scenario you're describing, for something like cash,
  6595. 5:14:00printf was not involved in that particular line of code.
  6596. 5:14:03So that's the difference, there.
  6597. 5:14:05All right.
  6598. 5:14:05So we, now, have this ability to create an array.
  6599. 5:14:09And an array can store multiple values.
  6600. 5:14:11What, then, might we do that's more interesting than just storing numbers
  6601. 5:14:15in memory?
  6602. 5:14:16Well, let's take this one step further.
  6603. 5:14:18As opposed to just storing 72, 73, 33 or 100, 99, 98, at these given locations,
  6604. 5:14:25because again, an array gives you one variable name, but multiple locations,
  6605. 5:14:30or indices therein, bracket 0, bracket 1,
  6606. 5:14:32bracket 2 on up, if it were even bigger than that.
  6607. 5:14:35Let's, now, start to consider something more modest, like simple chars.
  6608. 5:14:40Chars, being 1 byte each, so they're even smaller,
  6609. 5:14:43they take up much less space.
  6610. 5:14:44And, indeed, if I wanted to say a message like,
  6611. 5:14:46hi I could use three variables.
  6612. 5:14:48If I wanted a program to print, hi, H-I exclamation point,
  6613. 5:14:52I could, of course, store those in three variables, like c1, c2, c3.
  6614. 5:14:57And let's, for the sake of discussion, let's whip this up real quickly.
  6615. 5:15:00Let me create a new program, now, in VS Code.
  6616. 5:15:03This time, I'm going to call it hi.c.
  6617. 5:15:07And I'm not going to bother with the CS50 library.
  6618. 5:15:09I just need the standard I/O one, for now.
  6619. 5:15:11int main(void).
  6620. 5:15:13And then, inside of main, I'm going to, simply, create three variables.
  6621. 5:15:16And this is already, hopefully, striking you as a bad idea.
  6622. 5:15:20But we'll go down this road, temporarily,
  6623. 5:15:22with c1, and c2, and, finally, c3.
  6624. 5:15:26Storing each character in the phrase I want to print,
  6625. 5:15:29and I'm going to print this in a different way than usual.
  6626. 5:15:33Now I'm dealing with chars.
  6627. 5:15:35And we've, generally, dealt with strings, which was easier last week.
  6628. 5:15:38But %c, %c, %c, will let me print out three chars, and like c1, c2, and c3.
  6629. 5:15:45So, kind of, a stupid way of printing out a string.
  6630. 5:15:48So we already have a solution to this problem last week.
  6631. 5:15:51But let's poke around at what's going on underneath the hood, here.
  6632. 5:15:54So let's make hi, ./hi.
  6633. 5:15:57And, voila no surprise.
  6634. 5:15:58But we, again, could have done this last week
  6635. 5:16:00with a string and just one variable, or even, 0, at that.
  6636. 5:16:03But let's start converting these characters
  6637. 5:16:07to their apparent numeric equivalents like we talked about in week 0 too.
  6638. 5:16:12Let me modify these %c's, just to be fun, to be %i's.
  6639. 5:16:16And let me add some spaces so there are gaps between each of them.
  6640. 5:16:20Let me, now, recompile hi, and let me rerun it.
  6641. 5:16:24Just to guess, what should I see on the screen now?
  6642. 5:16:29Any guesses?
  6643. 5:16:30Yeah?
  6644. 5:16:30AUDIENCE: The ASCII values?
  6645. 5:16:32DAVID MALAN: The ASCII values.
  6646. 5:16:34And it's intentional that I keep using the same word,
  6647. 5:16:36hi, because it should be, hopefully, the old friends, 72, 73, and 33.
  6648. 5:16:42Which, is to say, that c knows about ASCII, or equivalently, Unicode,
  6649. 5:16:46and can do this conversion for us automatically.
  6650. 5:16:48And it seems to be doing it implicitly for us, so to speak.
  6651. 5:16:51Notice that c1, c2 and c3 are, obviously, chars,
  6652. 5:16:55but printf is able to tolerate printing them as integers.
  6653. 5:16:58If I really want it to be pedantic, I could use this technique, again,
  6654. 5:17:03known as typecasting, where I can actually
  6655. 5:17:05convert one data type to another, if it makes logical sense to do so.
  6656. 5:17:10And we saw in week 0, chars, or characters,
  6657. 5:17:14are just numbers, like 72, 73, and 33.
  6658. 5:17:17So I can use this parenthetical expression to convert, incorrectly,
  6659. 5:17:21[LAUGHTER] three chars to three integers, instead.
  6660. 5:17:26So that's what I meant to type the first time.
  6661. 5:17:28There we go.
  6662. 5:17:29Strike two, today.
  6663. 5:17:30So parenthesis, int, close parenthesis says
  6664. 5:17:33take whatever variable comes after this, c1, c2, or c3 and convert it to an int.
  6665. 5:17:39The effect is going to be no different, make hi, and then rerunning whoops--
  6666. 5:17:42then running ./hi still works the same, but now I'm explicitly converting chars
  6667. 5:17:49to ints.
  6668. 5:17:49And we can do this all day long, chars to ints, floats to ints,
  6669. 5:17:53ints to floats.
  6670. 5:17:54Sometimes, it's equivalent.
  6671. 5:17:56Other times, you're going to lose information.
  6672. 5:17:58Taking a float to an int, just intuitively,
  6673. 5:18:01is going to throw away everything after the decimal point,
  6674. 5:18:04because an int has no decimal point.
  6675. 5:18:06But, for now, I'm going to rewind to the version of this
  6676. 5:18:09that just did implicit-type conversion, or implicit casting,
  6677. 5:18:13just to demonstrate that we can, indeed, see the values underneath the hood.
  6678. 5:18:17All right.
  6679. 5:18:18Let me go ahead and do this, now, the week 1 way.
  6680. 5:18:20This was kind of stupid.
  6681. 5:18:21Let's just do printf, quote-unquote--
  6682. 5:18:24Actually, let's do this, string s equals quote-unquote hi,
  6683. 5:18:28and then let's do a simple printf with %s, printing out s's there.
  6684. 5:18:33So now I've rewound to last week, where we began this story,
  6685. 5:18:36but you'll notice that, if we keep playing around with this--
  6686. 5:18:40whoops, what did I do here?
  6687. 5:18:43Oh, and let me introduce the C50 library here, more on that next before long.
  6688. 5:18:47Let me go ahead and recompile, rerun this,
  6689. 5:18:50we seem to be coding in circles, here.
  6690. 5:18:52Like, I've just done the same thing multiple, different ways.
  6691. 5:18:55But there's clearly an equivalence, then,
  6692. 5:18:57between sequences of chars and strings.
  6693. 5:19:01And if you do it the real pedantic way, you
  6694. 5:19:03have three different variables, c1, c2, c3, representing H-I exclamation point,
  6695. 5:19:07or you can just treat them all together like this h, i, exclamation point.
  6696. 5:19:12But it turns out that strings are actually
  6697. 5:19:16implemented by the computer in a pretty now familiar way.
  6698. 5:19:22What might a string actually be as of this point in the story?
  6699. 5:19:28Where are we going with this?
  6700. 5:19:29Let me try to look further back.
  6701. 5:19:31Yeah, in way back?
  6702. 5:19:32Yeah?
  6703. 5:19:32AUDIENCE: Can a string like this be an array of chars?
  6704. 5:19:34DAVID MALAN: Yeah, a string might be, and indeed is, just
  6705. 5:19:37an array of characters.
  6706. 5:19:39So last week we took for granted that strings exist.
  6707. 5:19:41Technically, strings exist, but they're implemented
  6708. 5:19:43as arrays of characters, which actually opens up
  6709. 5:19:47some interesting possibilities for us.
  6710. 5:19:50Because, let me see, let me see if I can do this.
  6711. 5:19:52Let me try to print out, now, three integers again.
  6712. 5:19:55But if string s is but an array, as you propose, maybe I can do s bracket 0,
  6713. 5:20:01s bracket 1, and s bracket 2.
  6714. 5:20:04So maybe I can start poking around inside of strings,
  6715. 5:20:07even though we didn't do this last week, so I
  6716. 5:20:09can get at those individual values.
  6717. 5:20:11So make hi, ./hi and, voila, there we go again.
  6718. 5:20:15It's the same 72, 73, 33, but now, I'm sort of, hopefully,
  6719. 5:20:20like, wrapping my mind around the fact that, all right,
  6720. 5:20:22a string is just an array of characters, and arrays, you
  6721. 5:20:25can index into them using this new square bracket notation.
  6722. 5:20:29So I can get at any one of these individual characters,
  6723. 5:20:32and, heck, convert it to an integer like we did in week 0.
  6724. 5:20:38Let me get a little curious now.
  6725. 5:20:41What else might be in the computer's memory?
  6726. 5:20:44Well, let's-- I'll go back to the depiction of these same things.
  6727. 5:20:47Here might be how we originally implemented hi
  6728. 5:20:50with three variables, c1, c2, c3.
  6729. 5:20:53Of course, that map to these decimal digits or equivalent,
  6730. 5:20:55these binary values.
  6731. 5:20:57But what was this looking like in memory?
  6732. 5:20:59Literally, when you create a string in memory, like this,
  6733. 5:21:02string s equals quote-unquote hi, let's consider what's going on
  6734. 5:21:05underneath the hood, so to speak.
  6735. 5:21:06Well, as an abstraction, a string, it's H-I exclamation point taking up,
  6736. 5:21:11it would seem, 3 bytes, right?
  6737. 5:21:13I've gotten rid of the bars, there, because if you
  6738. 5:21:15think of a string as a type, I'm just going to use one big box of size 3.
  6739. 5:21:19But technically, a string, we've just revealed, is an array,
  6740. 5:21:24and the array is of size 3.
  6741. 5:21:26So technically, if the string is called s,
  6742. 5:21:28s bracket 0 will give you the first character,
  6743. 5:21:30s bracket 1, the second, and s bracket 3, the third.
  6744. 5:21:34But let me ask this question now, if this, at the end of the day,
  6745. 5:21:37is the only thing in your computer memory
  6746. 5:21:40and the ability, like a canvas to draw 0s and 1s, or numbers, or characters,
  6747. 5:21:45or whatever on it, but that's it, like this
  6748. 5:21:46is what your Mac, and PC, and phone ultimately reduced to.
  6749. 5:21:50Suppose that I'm running a piece of software, like a text messenger,
  6750. 5:21:53and now I write down bye exclamation point.
  6751. 5:21:57Well, where might that go in memory?
  6752. 5:21:59Well, it might go here.
  6753. 5:22:00B-Y-E. And then the next thing I type might go here, here, here and so forth.
  6754. 5:22:03My memory just might get filled up, over time,
  6755. 5:22:05with things that you or someone else are typing.
  6756. 5:22:08But then how does the computer know if, potentially, B-Y-E exclamation point
  6757. 5:22:14is right after H-I exclamation point where one string ends and the next one
  6758. 5:22:20begins?
  6759. 5:22:23Right?
  6760. 5:22:23All we have are bytes, or 0s and 1s.
  6761. 5:22:27So if you were designing this, how would you
  6762. 5:22:29implement some kind of delimiter between the two?
  6763. 5:22:32Or figure out what the length of a string is?
  6764. 5:22:34What do you think?
  6765. 5:22:35AUDIENCE: A nul character.
  6766. 5:22:36DAVID MALAN: OK, so the right answer is use a nul character,
  6767. 5:22:39and for those who don't know, what does that mean?
  6768. 5:22:41AUDIENCE: It's special.
  6769. 5:22:43DAVID MALAN: Yeah, so it's a special character.
  6770. 5:22:45Let me describe it as a sentinel character.
  6771. 5:22:47Humans decided some time ago that you know
  6772. 5:22:49what, if we want to delineate where one string ends
  6773. 5:22:52and where the next one begins, we just need some special symbol.
  6774. 5:22:56And the symbol they'll use is generally written as backslash 0.
  6775. 5:22:59This is just shorthand notation for literally eight 0 bits.
  6776. 5:23:030, 0, 0, 0, 0, 0, 0, 0.
  6777. 5:23:06And the nickname for eight 0 bits, in this context,
  6778. 5:23:10is nul, N-U-L, so to speak.
  6779. 5:23:13And we can actually see this as follows.
  6780. 5:23:16If you look at the corresponding decimal digits,
  6781. 5:23:18like you could do by doing out the math or doing the conversion,
  6782. 5:23:20like we've done in code, you would see for storing hi, 72, 73, 33,
  6783. 5:23:25but then 1 extra byte that's sort of invisibly there, but that is all 0s.
  6784. 5:23:30And now I've just written it as the decimal number 0.
  6785. 5:23:33The implication of this is that the computer is apparently
  6786. 5:23:36using, not 3 bytes to store a word like hi, but 4 bytes.
  6787. 5:23:40Whatever the length of the string is, plus 1 for this special sentinel value
  6788. 5:23:46that demarcates the end of the string.
  6789. 5:23:48So we might draw it like this instead.
  6790. 5:23:50And this character is, again, pronounced nul, or written N-U-L.
  6791. 5:23:55So that's all, right?
  6792. 5:23:56If humans, at the end of the day, just have this canvas of memory,
  6793. 5:23:59they just needed to decide, all right, well,
  6794. 5:24:01how do we distinguish one string from another?
  6795. 5:24:04It's a lot easier with chars, individually, it's
  6796. 5:24:06a lot easier with ints, it's even easier With floats, why?
  6797. 5:24:09Because, per that chart earlier, every character is always 1 byte.
  6798. 5:24:13Every int is always 4 bytes.
  6799. 5:24:16Every long is always 8 bytes.
  6800. 5:24:19How long is a string?
  6801. 5:24:20Well, hi is 1, 2, 3 with an exclamation point.
  6802. 5:24:24Bye is 1, 2, 3, 4 with an exclamation point.
  6803. 5:24:27David is D-A-V-I-D, five without an exclamation point.
  6804. 5:24:30And so a string can be any number of bytes long,
  6805. 5:24:34so you somehow need to draw a line in the sand
  6806. 5:24:36to separate in memory one string from another.
  6807. 5:24:40So what's the implication of this?
  6808. 5:24:43Well, let me go back to code, here.
  6809. 5:24:45Let's actually poke around.
  6810. 5:24:46This is a bit dangerous, but I'm going to start looking at memory locations
  6811. 5:24:51past my string here.
  6812. 5:24:53So let me go ahead and recompile, make hi.
  6813. 5:24:57Whoops, what did I do here?
  6814. 5:24:59I forgot a format code.
  6815. 5:25:00Let me add one more %i.
  6816. 5:25:02Now let me go ahead and rerun make hi, ./hi, Enter.
  6817. 5:25:06There it is.
  6818. 5:25:07So you can actually see in the computer, unbeknownst to you
  6819. 5:25:10previously, that there's indeed something else going on there.
  6820. 5:25:14And if I were to make one other variant of this program--
  6821. 5:25:17let's get rid of just this one word and let's have two.
  6822. 5:25:19So let me give myself another string called t,
  6823. 5:25:21for instance, just this common convention with bye exclamation point.
  6824. 5:25:26Let me, then print out with %s.
  6825. 5:25:29And let me also print out with %s, whoops, printf, print out t, as well.
  6826. 5:25:35Let me recompile this program, and obviously the out--
  6827. 5:25:38ugh-- this is what happens when I go too fast.
  6828. 5:25:41All right, third mistake today, close quote.
  6829. 5:25:45As I was missing.
  6830. 5:25:46Make hi.
  6831. 5:25:47Fourth mistake today.
  6832. 5:25:49Make hi.
  6833. 5:25:50Dot slash hi.
  6834. 5:25:51OK, voila.
  6835. 5:25:52Now we have a program that's printing both hi and bye,
  6836. 5:25:54only so that we can consider what's going on in the computer's memory.
  6837. 5:25:58If s is storing hi and apparently one bonus byte that
  6838. 5:26:04demarcates the end of that string, bye is apparently
  6839. 5:26:07going to fit into the location directly after.
  6840. 5:26:10And it's wrapping around, but that's just an artist's rendition, here.
  6841. 5:26:13But bye, B-Y-E exclamation point is taking up
  6842. 5:26:161, 2, 3, 4, plus a fifth byte, as well.
  6843. 5:26:23All right, any questions on this underlying representation of strings?
  6844. 5:26:27And we'll contextualize this, before long,
  6845. 5:26:29so that this isn't just like, OK, who really cares?
  6846. 5:26:32This is going to be the source of actually implementing things.
  6847. 5:26:34In fact for problem set 2, like cryptography, and encryption,
  6848. 5:26:37and scrambling actual human messages.
  6849. 5:26:39But some questions first.
  6850. 5:26:40AUDIENCE: So normally if you were to not use string,
  6851. 5:26:44you would just make a character range that would declare,
  6852. 5:26:47how many characters there are so you know how many characters are
  6853. 5:26:50going to be there.
  6854. 5:26:51DAVID MALAN: A good question, too and let
  6855. 5:26:53me summarize as, if we were instead to use chars all the time,
  6856. 5:26:56we would indeed have to know in advance how many chars you want for a given
  6857. 5:26:59string that you're storing, how, then, does something like get string work,
  6858. 5:27:03because when you CS50 wrote the get string function,
  6859. 5:27:05we obviously don't know how long the words are
  6860. 5:27:07going to be that you all are typing in.
  6861. 5:27:09It turns out, two weeks from now we'll see that get string
  6862. 5:27:12uses a technique known as dynamic memory allocation.
  6863. 5:27:15And it's going to grow or shrink the array automatically for you.
  6864. 5:27:20But more on that soon.
  6865. 5:27:21Other questions?
  6866. 5:27:22AUDIENCE: Why are we using a nul value?
  6867. 5:27:25Isn't that wasting a byte?
  6868. 5:27:26DAVID MALAN: Good question.
  6869. 5:27:28Why are we using a nul value, isn't it wasting a byte?
  6870. 5:27:31Yes.
  6871. 5:27:31But I claim there's really no other way to distinguish the end of one string
  6872. 5:27:37from the start of another, unless we make some sort of notation in memory.
  6873. 5:27:44All we have, at the end of the day, inside of a computer, are bits.
  6874. 5:27:46Therefore, all we can do is spin those bits in some creative way
  6875. 5:27:50to solve this problem.
  6876. 5:27:51So we're minimally going to spend 1 byte to solve this problem.
  6877. 5:27:54Yeah?
  6878. 5:27:55AUDIENCE: How does our memory device know to enter a line when you type
  6879. 5:28:00the /n if we don't have it stored as a char?
  6880. 5:28:03DAVID MALAN: If you don't--
  6881. 5:28:05how does the computer know to move to a next line when you have a /n?
  6882. 5:28:08So /n, even though it looks like two characters,
  6883. 5:28:12it's actually stored as just 1 byte in the computer's memory.
  6884. 5:28:16There's a mapping between it and an actual number.
  6885. 5:28:18And you can see that, for instance, on the ASCII chart from the other day.
  6886. 5:28:21AUDIENCE: So with that being stored would be the [INAUDIBLE]..
  6887. 5:28:25DAVID MALAN: It would be.
  6888. 5:28:26If I had put a /n in my code here, right after the exclamation point here
  6889. 5:28:32and here, that would actually shift everything in memory because we would
  6890. 5:28:36need to make room for a /n here and another one over here.
  6891. 5:28:41So it would take two more bytes, exactly.
  6892. 5:28:43Other questions?
  6893. 5:28:43AUDIENCE: So if hi exclamation point is written in binary and ASCII
  6894. 5:28:50too as 72, 73, 33, if we are to write those numbers in the string,
  6895. 5:28:56and convert them into binary how would the computer know what's 72
  6896. 5:29:03and what's 8?
  6897. 5:29:04DAVID MALAN: And what's the last thing you said?
  6898. 5:29:06AUDIENCE: 8, for example.
  6899. 5:29:08DAVID MALAN: It's context sensitive.
  6900. 5:29:09So if, at the end of the day, all we're storing is these numbers,
  6901. 5:29:12like 72, 73, 33, recall that it's up to the program
  6902. 5:29:16to decide, based on context, how to interpret them.
  6903. 5:29:19And I simplified this story in week 0 saying that Photoshop interprets them
  6904. 5:29:23as RGB colors, and iMessage or a text messaging program
  6905. 5:29:27interprets them as letters, and Excel interprets them as numbers.
  6906. 5:29:31How those programs do it is by way of variables like string, and int,
  6907. 5:29:36and float.
  6908. 5:29:37And in fact, later this semester, we'll see
  6909. 5:29:39a data type via which you can represent a color as a triple of numbers,
  6910. 5:29:43and red value, a green value, and a blue value.
  6911. 5:29:46So we'll see other data types as well.
  6912. 5:29:48Yeah?
  6913. 5:29:49AUDIENCE: It seems easy enough to just add a nul thing at the end of the word,
  6914. 5:29:53so why do we have integers and long integers?
  6915. 5:29:56Why can't we make everything variable in its data size?
  6916. 5:29:59DAVID MALAN: Really interesting question.
  6917. 5:30:01Why could we not just make all data types variable in size?
  6918. 5:30:04And some languages, some libraries do exactly this.
  6919. 5:30:07C is an older language, and because memory was expensive
  6920. 5:30:11memory was limited.
  6921. 5:30:12The reality was you gain benefits from just
  6922. 5:30:14standardizing the size of these things.
  6923. 5:30:17You also get performance increases in the sense
  6924. 5:30:19that if you know every int is 4 bytes, you can very quickly,
  6925. 5:30:23and we'll see this next week, jump from integer to another,
  6926. 5:30:26to another in memory just by adding 4 inside of those square brackets.
  6927. 5:30:30You can very quickly poke around.
  6928. 5:30:32Whereas, if you had variable length numbers, you would have to,
  6929. 5:30:35kind of, follow, follow, follow, looking for the end of it.
  6930. 5:30:38Follow, follow-- you would have to look at more locations in memory.
  6931. 5:30:41So that's a topic we'll come back to.
  6932. 5:30:42But it was generally for efficiency.
  6933. 5:30:44And other question, yeah?
  6934. 5:30:46AUDIENCE: Why not store the nul character [INAUDIBLE]
  6935. 5:30:52DAVID MALAN: Good question why not store the--
  6936. 5:30:55why not store the nul character at the beginning?
  6937. 5:30:59You could-- let's see, why not store it at the beginning?
  6938. 5:31:06You could do that.
  6939. 5:31:09You could absolutely-- well, could you do this?
  6940. 5:31:15If you were to do that at the beginning--
  6941. 5:31:20short answer, no.
  6942. 5:31:21OK, now I retract that.
  6943. 5:31:22No, because I finally thought of a problem with this.
  6944. 5:31:24If you store it at the beginning instead,
  6945. 5:31:26we'll see in just a moment how you can actually write code
  6946. 5:31:29to figure out where the end of a string is,
  6947. 5:31:31and the problem there is wouldn't necessarily
  6948. 5:31:33know if you eventually hit a 0 at the end of the string,
  6949. 5:31:37because it's the number 0 in the context of Excel using some memory,
  6950. 5:31:41or if it's the context of some other data type, altogether.
  6951. 5:31:44So the fact that we've standardized--
  6952. 5:31:46the fact that we've standardized strings as ending with nul
  6953. 5:31:50means that we can reliably distinguish one variable from another in memory.
  6954. 5:31:54And that's actually a perfect segue way, now,
  6955. 5:31:56to actually using this primitive to building up
  6956. 5:31:59our own code that manipulates these things that are lower level.
  6957. 5:32:02So let me do this.
  6958. 5:32:03Let me create a new file called length.
  6959. 5:32:05And let's use this basic idea to figure out what the length of a string
  6960. 5:32:10is after it's been stored in a variable.
  6961. 5:32:14So let's do this.
  6962. 5:32:16Let me include both the CS50 header and the standard I/O header,
  6963. 5:32:20give myself int main(void) again here, and inside of main, do this.
  6964. 5:32:25Let me prompt the user for a string s and I'll ask them
  6965. 5:32:28for a string like their name, here.
  6966. 5:32:32And then let me name it more verbosely name this time.
  6967. 5:32:37Now let me go ahead and do this.
  6968. 5:32:39Let me iterate over every character in this string
  6969. 5:32:44in order to figure out what its length is.
  6970. 5:32:46So initially, I'm going to go ahead and say this,
  6971. 5:32:49int length equals 0, because I don't know what it is yet.
  6972. 5:32:52So we're going to start at 0.
  6973. 5:32:53And then while the following is true--
  6974. 5:32:56while-- let me-- do I want to do this?
  6975. 5:33:01Let me change this to i, just for clarity, let me do
  6976. 5:33:04this, while name bracket i does not equal that special nul character.
  6977. 5:33:10So I typed it on the slide is N-U-L, but you don't write N-U-L in code,
  6978. 5:33:13you actually use its numeric equivalent, which is /0 in single quotes.
  6979. 5:33:17While name bracket i does not equal the nul character, I'm going to go ahead
  6980. 5:33:23and increment i to i plus plus.
  6981. 5:33:26And then down here I'm going to print out the value of i
  6982. 5:33:29to see what we actually get, printing out the value of i.
  6983. 5:33:33All right, so what's going to happen here?
  6984. 5:33:35Let me run make length.
  6985. 5:33:37Fortunately no errors.
  6986. 5:33:39./length and let me type in something like H-I, exclamation point, Enter.
  6987. 5:33:43And I get 3.
  6988. 5:33:45Let me try bye, exclamation point, Enter.
  6989. 5:33:48And I get 4.
  6990. 5:33:50Let me try my own name, David, Enter.
  6991. 5:33:525, and so forth.
  6992. 5:33:54So what's actually going on here?
  6993. 5:33:56Well, it seems that by way of this 4 loop,
  6994. 5:33:58we are specifying a local variable called
  6995. 5:34:00i initialized to 0, because we're figuring out the length of the string
  6996. 5:34:03as we go.
  6997. 5:34:04I'm then asking the question, does location 0,
  6998. 5:34:08that is i in the name string, which we now know is an array,
  6999. 5:34:13does it not equal /0?
  7000. 5:34:15Because if it doesn't, that means it's an actual character like H, or B, or D.
  7001. 5:34:19So let's increment i.
  7002. 5:34:21Then, let's come back around to line 9 and let's ask the question again.
  7003. 5:34:25Now i equals 1.
  7004. 5:34:26So does name bracket 1 not equal /0?
  7005. 5:34:30Well, if it doesn't, and it won't if it's an i, or a y, or an a,
  7006. 5:34:36based on what I typed in, we're going to increment i once more.
  7007. 5:34:39Fast-forward to the end of the story, once I get to the end of the string,
  7008. 5:34:43technically, one space past the end of the string,
  7009. 5:34:46name bracket i will equal /0.
  7010. 5:34:49So I don't increment i anymore, I end up just printing the result.
  7011. 5:34:54So what we seem to have here with some low level C code, just this while loop,
  7012. 5:34:58is a program that figures out the length of a given string that's been typed in.
  7013. 5:35:03Let's practice our abstraction and decompose this into,
  7014. 5:35:06maybe, a helper function here.
  7015. 5:35:07Let me grab all of this code here, and assume,
  7016. 5:35:11for the sake of discussion for a moment, that I can call a function now called
  7017. 5:35:15string length.
  7018. 5:35:18And the length of the string is name that I want to get,
  7019. 5:35:21and then I'll go ahead and print out, just as before with %i,
  7020. 5:35:25the length of that string.
  7021. 5:35:26So now I'm abstracting away this notion of figuring out
  7022. 5:35:28the length of the string.
  7023. 5:35:29That's an opportunity for to me to create my own function.
  7024. 5:35:32If I want to create a function called string length,
  7025. 5:35:35I'll claim that I want to take a string as input,
  7026. 5:35:39and what should I have this function return as its return type?
  7027. 5:35:45What should get string presumably return?
  7028. 5:35:50Yeah?
  7029. 5:35:50AUDIENCE: Int.
  7030. 5:35:51DAVID MALAN: An int, right?
  7031. 5:35:52An int makes sense.
  7032. 5:35:53Float really wouldn't make sense because we're
  7033. 5:35:55measuring things that are integers.
  7034. 5:35:57In this case, the length of something.
  7035. 5:35:59So indeed, let's have it return an int.
  7036. 5:36:00I can use the same code as before, so I'm
  7037. 5:36:03going to paste what I cut earlier in the file.
  7038. 5:36:06The only thing I have to change is the name of the variable.
  7039. 5:36:10Because now this function, I decided arbitrarily
  7040. 5:36:14that I'm going to call it s, just to be more generic.
  7041. 5:36:17So I'm going to look at s bracket i at each location.
  7042. 5:36:20And I don't want to print it at the end, this would be a side effect.
  7043. 5:36:23What's the line of code I should include here if I actually
  7044. 5:36:25want to hand back the total length?
  7045. 5:36:28Yeah?
  7046. 5:36:28AUDIENCE: Return i.
  7047. 5:36:29DAVID MALAN: Say again?
  7048. 5:36:30AUDIENCE: Return i.
  7049. 5:36:31DAVID MALAN: Return i, in this case.
  7050. 5:36:33So I'm going return i, not print it.
  7051. 5:36:35Because now, my main function can use the return value stored in length
  7052. 5:36:40and print it on the next line itself.
  7053. 5:36:42I just need a prototype, so that's my one forgivable copy paste here.
  7054. 5:36:46I'm going to rerun make length.
  7055. 5:36:48Hopefully I didn't screw up.
  7056. 5:36:49I didn't. ./length, I'll type in hi-- oops--
  7057. 5:36:53I'll type in hi, again.
  7058. 5:36:55That works.
  7059. 5:36:56I'll type in bye again, and so forth.
  7060. 5:36:59So now we have a function that determines the length of a string.
  7061. 5:37:02Well, it turns out we didn't actually need this all along.
  7062. 5:37:05It turns out that we can get rid of my own custom string length function here.
  7063. 5:37:10I can definitely delete the whole implementation down here.
  7064. 5:37:12Because it turns out, in a file called string.h,
  7065. 5:37:16which is a new header file today, we actually have access to a function
  7066. 5:37:19called, more succinctly, strlen, S-T-R-L-E-N. Which,
  7067. 5:37:23literally does that.
  7068. 5:37:25This is a function that comes with C, albeit in the string.h header file,
  7069. 5:37:29and it does what we just implemented manually.
  7070. 5:37:33So here's an example of, admittedly, a wheel we just reinvented, but no more.
  7071. 5:37:37We don't have to do that.
  7072. 5:37:38And how do what kinds of functions exist?
  7073. 5:37:41Well, let me pop out of my browser here to a website that
  7074. 5:37:45is a CS50's incarnation of what are called manual pages.
  7075. 5:37:48It turns out that in a lot of systems, Macs, and Unix,
  7076. 5:37:52and Linux systems, including the Visual Studio Code
  7077. 5:37:55instance that we have in the cloud, there
  7078. 5:37:57are publicly accessible manual pages for functions.
  7079. 5:38:00They tend to be written very expertly, in a way that's
  7080. 5:38:04not very beginner-friendly.
  7081. 5:38:05So we have here at manual.cs50.io is CS50's version
  7082. 5:38:09of manual pages that have this less-comfortable mode that
  7083. 5:38:13give you a, sort of, cheat sheet of very frequently used,
  7084. 5:38:15helpful functions in C. And we've translated the expert
  7085. 5:38:19notation to things that a beginner can understand.
  7086. 5:38:22So, for instance, let me go ahead and search for a string up at the top here.
  7087. 5:38:26You'll see that there's documentation for our own get string function,
  7088. 5:38:30but more interestingly down here, there's
  7089. 5:38:32a whole bunch of string-related functions
  7090. 5:38:35that we haven't even seen most of, yet.
  7091. 5:38:36But there's indeed one here called strlen,
  7092. 5:38:38calculate the length of a string.
  7093. 5:38:40And so if I go to strlen here, I'll see some less-comfortable documentation
  7094. 5:38:46for this function.
  7095. 5:38:47And the way a manual page typically works,
  7096. 5:38:49whether in CS50's format or any other, system
  7097. 5:38:52is you see, typically, a synopsis of what header
  7098. 5:38:55files you need to use the function.
  7099. 5:38:57So you would copy paste these couple of lines here.
  7100. 5:39:00You see what the prototype is of the function so
  7101. 5:39:03that you know what its inputs are, if any, and its outputs are, if any.
  7102. 5:39:06Then down below you might see a description, which in this case,
  7103. 5:39:09is pretty straightforward.
  7104. 5:39:10This function calculates the length of s.
  7105. 5:39:12Then you see what the return value is, if any,
  7106. 5:39:15and you might even see an example, like this one that we've whipped up here.
  7107. 5:39:18So these manual pages which are again, accessible
  7108. 5:39:21here, and we'll link to these in the problem sets moving forward,
  7109. 5:39:23are pretty much the place to start when you want to figure out
  7110. 5:39:26has a wheel been invented already?
  7111. 5:39:29Is there a function that might help me solve some problems set problems
  7112. 5:39:32so that I don't have to really get into the weeds of doing all
  7113. 5:39:36of those lower-level steps as I've had.
  7114. 5:39:37Sometimes the answer is going to be yes, sometimes it's going to be no.
  7115. 5:39:40But again the point of our having just done this together
  7116. 5:39:43is to reveal that even the functions you start taking for
  7117. 5:39:46granted, they all reduce to some of these basic building blocks.
  7118. 5:39:50At the end of the day, this is all that's inside of your computer
  7119. 5:39:53is 0s and 1s.
  7120. 5:39:55We're just learning, now, how to harness those
  7121. 5:39:57and how to manipulate them ourselves.
  7122. 5:40:01Any questions here on this?
  7123. 5:40:05Any questions at all?
  7124. 5:40:07Yeah.
  7125. 5:40:08AUDIENCE: We did just see [INAUDIBLE] Is that so common
  7126. 5:40:16that we would have to specify it, or is it not?
  7127. 5:40:18DAVID MALAN: Good question.
  7128. 5:40:19Is it so common that you would have to specify it or not?
  7129. 5:40:22You do need to include its header files because that's
  7130. 5:40:24where all of those prototypes are.
  7131. 5:40:25You don't need to worry about linking it in with -l anything.
  7132. 5:40:29And in fact, moving forward, you do not ever
  7133. 5:40:31need to worry about linking in libraries when compiling your code.
  7134. 5:40:35We, the staff, have configured make to do all of that for you automatically.
  7135. 5:40:39We want you to understand that it is doing it,
  7136. 5:40:41but we'll take care of all of the -l's for you.
  7137. 5:40:43But the onus is on you for the prototypes and the header files.
  7138. 5:40:47Other questions on these representations or techniques?
  7139. 5:40:51Yeah?
  7140. 5:40:51AUDIENCE: [INAUDIBLE] exclamation mark.
  7141. 5:41:00How does it actually define the spaces [INAUDIBLE]??
  7142. 5:41:04DAVID MALAN: A good question.
  7143. 5:41:06If you were to have a string with actual spaces in it that is multiple words,
  7144. 5:41:09what would the computer actually do?
  7145. 5:41:11Well for this. let me go to asciichart.com.
  7146. 5:41:14Which is just a random website that's my go-to for the first 127 characters
  7147. 5:41:19of ASCII.
  7148. 5:41:20This is, in fact, what we had a screenshot of the other day.
  7149. 5:41:22And if you look here, it's a little non-obvious, but S-P is space.
  7150. 5:41:26If a computer were to store a space, it would actually store the decimal number
  7151. 5:41:2932, or technically, the pattern of 0s and 1s that represent the number 32.
  7152. 5:41:34All of the US English keys that you might type on a keyboard
  7153. 5:41:37can be represented with a number, and using Unicode can
  7154. 5:41:40you express even things like emojis and other languages.
  7155. 5:41:43Yeah?
  7156. 5:41:43AUDIENCE: Are only strings followed by nul number,
  7157. 5:41:47or let's say we had a series of numbers, would each one of them
  7158. 5:41:50be accompanied by nuls?
  7159. 5:41:52DAVID MALAN: Good question.
  7160. 5:41:53Only strings are accompanied by nuls at the end
  7161. 5:41:56because every other data type we've talked about thus far
  7162. 5:41:59is of well defined finite length.
  7163. 5:42:011 byte for char, 4 bytes for ints and so forth.
  7164. 5:42:04If we think back to last week, we did end the week with a couple of problems.
  7165. 5:42:08Integer overflow, because 4 bytes, heck, even 8 bytes is sometimes not enough.
  7166. 5:42:12We also talked about floating point imprecision.
  7167. 5:42:14Thankfully in the world of scientific computing and financial computing,
  7168. 5:42:17there are libraries you can use that draw inspiration
  7169. 5:42:21from this idea of a string, and they might
  7170. 5:42:23use 9 bytes for an integer value or maybe 20 bytes
  7171. 5:42:26that you can count really high.
  7172. 5:42:28But they will then start to manage that memory for you
  7173. 5:42:30and what they're really probably doing is just grabbing a whole bunch of bytes
  7174. 5:42:34and somehow remembering how long the sequence of bytes is.
  7175. 5:42:37That's how these higher-level libraries work, too.
  7176. 5:42:40All right, this has been a lot.
  7177. 5:42:41Let's take one more break here.
  7178. 5:42:43We'll do a seven-minute break here.
  7179. 5:42:44And when we come back, we'll flesh out a few more details.
  7180. 5:42:47All right.
  7181. 5:42:50So we just saw strlen as an example of a function that
  7182. 5:42:55comes in the string library.
  7183. 5:42:57Let's start to take more of these library functions out for a spin.
  7184. 5:42:59So we're not relying only on the built ins that we saw last week.
  7185. 5:43:03Let me switch over to VS Code.
  7186. 5:43:05And create a file called, say string.h.
  7187. 5:43:10to apply this lesson learned, as follows.
  7188. 5:43:12Let me include cs50.h, stdio.h, and this new thing,
  7189. 5:43:19string.h as well, at the top.
  7190. 5:43:21I'm going to do the usual int main(void) here.
  7191. 5:43:23And then in this program suppose, for the sake of discussion,
  7192. 5:43:26that I didn't know about %s for printf or, heck,
  7193. 5:43:29maybe early on there was no %s format code.
  7194. 5:43:33And so there was no easy way to print strings.
  7195. 5:43:36Well, at least if we know that strings are just arrays of characters,
  7196. 5:43:40we could use %c as a workaround, a solution to that,
  7197. 5:43:44sort of, contrived problem.
  7198. 5:43:45So let me ask myself for a string s by using get string here
  7199. 5:43:49and I'll ask the user for some input.
  7200. 5:43:51And then, let me print out say, output , and all I want to do is print back out
  7201. 5:43:57what the user typed.
  7202. 5:43:58Now, the simplest way to do this, of course, is going to be like last week,
  7203. 5:44:02printf %s, and plug in the s, and we're done.
  7204. 5:44:05But again, for the sake of discussion, I forgot about,
  7205. 5:44:07or someone didn't implement %s, so how else could we do this?
  7206. 5:44:12Well, in pseudo code, or in English what's the gist of how we could solve
  7207. 5:44:16this problem, printing out the string s on the screen without using %s?
  7208. 5:44:23How might we go about solving this?
  7209. 5:44:26Just in English, high-level?
  7210. 5:44:28What would your pseudo code look like?
  7211. 5:44:29Yeah?
  7212. 5:44:30AUDIENCE: You could just print each letter.
  7213. 5:44:33DAVID MALAN: OK, so just print each letter.
  7214. 5:44:35And maybe, more precisely, some kind of loop.
  7215. 5:44:37Like, let's iterate over all of the characters in s
  7216. 5:44:41and print one at a time.
  7217. 5:44:42So how can I do that?
  7218. 5:44:43Well, for int i, get 0 is kind of the go-to starting point for most loops,
  7219. 5:44:48i is less than--
  7220. 5:44:49OK, how long do I want to iterate?
  7221. 5:44:51Well, it's going to depend on what I type in,
  7222. 5:44:53but that's why we have strlen now.
  7223. 5:44:55So iterate up to the length of s, and then increment i with plus
  7224. 5:45:00plus on each iteration.
  7225. 5:45:01And then let's just print out %c with no new line,
  7226. 5:45:04because I want everything on the same line,
  7227. 5:45:07whatever the character is at s bracket i.
  7228. 5:45:12And then at the very end, I'll give myself
  7229. 5:45:14that new line, just to move the cursor down to the next line
  7230. 5:45:16so the dollar sign is not in a weird place.
  7231. 5:45:18All right, so let's see if I didn't screw up any of the code,
  7232. 5:45:21make string, Enter, so far so good, string and let me type in something
  7233. 5:45:26like, hi, Enter.
  7234. 5:45:28And I see output of hi, too.
  7235. 5:45:30Let me do it once more with bye, Enter, and that works, too.
  7236. 5:45:33Notice I very deliberately and quickly gave myself
  7237. 5:45:36two spaces here and one space here just because I, literally,
  7238. 5:45:39wanted these things to line up properly, and input is shorter than output.
  7239. 5:45:42But that was just a deliberate formatting detail.
  7240. 5:45:46So this code is correct.
  7241. 5:45:47Which is a claim I've made before, but it's not well-designed.
  7242. 5:45:53It is well-designed in that I'm using someone else's library function,
  7243. 5:45:57like, I've not reinvented a wheel, there's no line 15
  7244. 5:45:59or below, I didn't implement string length myself.
  7245. 5:46:02So I'm at least practicing what I've preached.
  7246. 5:46:07But there's still an imperfection, a suboptimality.
  7247. 5:46:12This one's really subtle though.
  7248. 5:46:15And you have to think about how loops work.
  7249. 5:46:18What am I doing that's not super efficient?
  7250. 5:46:22Yeah, in back?
  7251. 5:46:24AUDIENCE: [INAUDIBLE] over and over again.
  7252. 5:46:27DAVID MALAN: Yeah, this is a little subtle.
  7253. 5:46:29But if you think back to the basic definition of a 4 loop
  7254. 5:46:31and recall when I highlighted things last week, what happens?
  7255. 5:46:34Well, the first thing is that i gets set to 0.
  7256. 5:46:37Then we check the condition.
  7257. 5:46:38How do we check the condition?
  7258. 5:46:39We call strlen on s, we get back an answer
  7259. 5:46:42like 3 if it's a H-I exclamation point and 0 is less than 3, so that's fine,
  7260. 5:46:49and then we print out the character.
  7261. 5:46:50Then we increment i from 0 to 1.
  7262. 5:46:53We recheck the condition.
  7263. 5:46:54How do I recheck the condition?
  7264. 5:46:56I call strlen of s.
  7265. 5:46:58Get back the same answer, 3.
  7266. 5:47:01Compare 3 against 1.
  7267. 5:47:02We're still good.
  7268. 5:47:04So we print out another character. i gets incremented again, i is now 2.
  7269. 5:47:08We check the condition.
  7270. 5:47:10What's the condition?
  7271. 5:47:11Well, what's the string like the best?
  7272. 5:47:12It's still 3.
  7273. 5:47:132 is still less than 3.
  7274. 5:47:16So I keep asking the same question sort of stupidly
  7275. 5:47:19because the string is, presumably, never changing in length.
  7276. 5:47:22And indeed, every time I check that condition,
  7277. 5:47:24that function is going to get called.
  7278. 5:47:25And every time, the answer for hi is going to be 3.
  7279. 5:47:283.
  7280. 5:47:293.
  7281. 5:47:30So it's a marginal suboptimality, but I could do better, right?
  7282. 5:47:35Don't ask multiple times questions that you can remember the answer to.
  7283. 5:47:39So how could I remember the answer to this question and ask it just once?
  7284. 5:47:45How could I remember the answer to this question?
  7285. 5:47:49Let me see.
  7286. 5:47:49Yeah, back there?
  7287. 5:47:50AUDIENCE: Store it in a variable.
  7288. 5:47:51DAVID MALAN: So store it in a variable, right?
  7289. 5:47:53That's been our answer most any time we want to keep something around.
  7290. 5:47:56So how could I do this?
  7291. 5:47:57Well, I could do something like this, int, maybe, length equals strlen of s.
  7292. 5:48:02Then I can just change this function call.
  7293. 5:48:05Let me fix my spelling here.
  7294. 5:48:07Let me fix this to be comparing against length, and this is now OK.
  7295. 5:48:11Because now strlen is only called once on line 9.
  7296. 5:48:14And I'm reusing the value of that variable, a.k.a.
  7297. 5:48:17length, again, and again, and again.
  7298. 5:48:18So that's more efficient.
  7299. 5:48:19Turns out that 4 loops let you declare multiple variables at once,
  7300. 5:48:24so we can do this a little more elegantly all in one line.
  7301. 5:48:28And this is just some syntactic improvement.
  7302. 5:48:31I could actually do something like this, n equals strlen of s,
  7303. 5:48:36and then I could just say n here or I could call it length.
  7304. 5:48:39But heck, while I'm being succinct I'm just going to use n for number.
  7305. 5:48:41So now it's just a marginal change but I've now
  7306. 5:48:46declared two variables inside of my loop, i and n.
  7307. 5:48:50i is set to 0. n extends to the string length of s.
  7308. 5:48:53But now, hereafter, all of my condition checks are just, i less than n,
  7309. 5:48:57i less than n, and n is never changing.
  7310. 5:49:00All right, so a marginal improvement there.
  7311. 5:49:02Now that I've used this new function, let's
  7312. 5:49:04use some other functions that might be of interest.
  7313. 5:49:06Let me write a quick program here that capitalizes the beginning of--
  7314. 5:49:12changes to uppercase some string that the user types in.
  7315. 5:49:16So let me code a file called uppercase.c.
  7316. 5:49:19Up here I'll use my new friends, cs50.h, and standard I/O, and string.h.
  7317. 5:49:25So standard I/O, and string.h So just as before int main(void).
  7318. 5:49:31And then inside of main, what I'm going to do this time,
  7319. 5:49:33is let's ask the user for a string s using get string asking them
  7320. 5:49:38for the before value.
  7321. 5:49:39And then let me print out something like after.
  7322. 5:49:44So that it-- just so I can see what the uppercase version thereof is.
  7323. 5:49:48And then after this, let me do the following, for int, i
  7324. 5:49:52equals 0, oh, let's practice that same lesson,
  7325. 5:49:56so n equals the string length of s, i is less than n, i plus plus.
  7326. 5:50:02So really, nothing new, fundamentally yet.
  7327. 5:50:05How do I now convert characters from lowercase, if they are, to uppercase?
  7328. 5:50:11In other words, if I type in hi, H-I in lowercase,
  7329. 5:50:14I want my program, now, to uppercase everything to capital H, capital I.
  7330. 5:50:19Well how can I go about doing this?
  7331. 5:50:23Well you might recall that there is this--
  7332. 5:50:25you might recall that there is this ASCII chart.
  7333. 5:50:28So let's just consult this real quick on asciichart.com.
  7334. 5:50:31We've looked at this last week notice that a-- capital A is 65,
  7335. 5:50:35capital B is 66, capital C is 67, and heck, here's
  7336. 5:50:39lowercase a, lowercase b, lowercase c, and that's 97, 98, 99.
  7337. 5:50:43And if I actually do some math, there's a distance of 32.
  7338. 5:50:47Right?
  7339. 5:50:47So if I want to go from uppercase to lowercase,
  7340. 5:50:49I can do 65 plus 32 will give me 97 and that actually works out
  7341. 5:50:55across the board for everything else.
  7342. 5:50:5666 plus 32 gets me to 98 or lowercase b.
  7343. 5:51:00Or conversely, if you have a lowercase a, and its value is 97,
  7344. 5:51:04subtract 32 and boom, you have capital A. So there's some arithmetic involved.
  7345. 5:51:11But now that we know that strings are just arrays,
  7346. 5:51:13and we know that characters, which are in those arrays,
  7347. 5:51:17are just binary representations of numbers,
  7348. 5:51:20I think we can manipulate a few of these things as follows.
  7349. 5:51:23Let me go back to my program here, and first
  7350. 5:51:25ask the question, if the current character in the array during this loop
  7351. 5:51:29is lowercase, let's force it to uppercase.
  7352. 5:51:33So how am I going to do that?
  7353. 5:51:34If the character at s bracket i, the current location in the array,
  7354. 5:51:40is greater than or equal to lowercase a, and s bracket
  7355. 5:51:45i is less than or equal to lowercase z, kind of a weird Boolean
  7356. 5:51:50expression but it's completely legitimate, because in this array
  7357. 5:51:55s is a whole bunch of characters that the humans typed in,
  7358. 5:51:58because that's what a string is, greater than or equal to a might
  7359. 5:52:01be a little nonsensical because when have you ever
  7360. 5:52:03compared numbers to letters?
  7361. 5:52:05But we know from week 0 lowercase a is 97, lowercase z is, what is it, 1?
  7362. 5:52:11I don't even remember.
  7363. 5:52:12AUDIENCE: 132.
  7364. 5:52:13DAVID MALAN: What's that?
  7365. 5:52:14AUDIENCE: 132?
  7366. 5:52:14DAVID MALAN: 132, We know.
  7367. 5:52:16And so that would allow us to answer the question is the current letter
  7368. 5:52:20lowercase?
  7369. 5:52:21All right, so let me answer that question.
  7370. 5:52:24If it is, what do I want to print out?
  7371. 5:52:27I don't want to print out the letter itself,
  7372. 5:52:30I want to print out the letter minus 32, right?
  7373. 5:52:33Because if it happens to be a lowercase a, 97, 97 minus 32
  7374. 5:52:37gives me 65, which is uppercase A, and I know that
  7375. 5:52:39just from having stared at that chart in the past.
  7376. 5:52:43Else if the character is not between little a and big A,
  7377. 5:52:48I'm just going to print out the character
  7378. 5:52:50itself by printing s bracket i.
  7379. 5:52:52And at the very end of this, I'm going to print out a new line just
  7380. 5:52:55to move the cursor to the next line.
  7381. 5:52:57So again, it's a little wordy.
  7382. 5:52:59But this loop here, which I borrowed from our code previously,
  7383. 5:53:03just iterates over the string, a.k.a.
  7384. 5:53:05array, character-by-character, through its length.
  7385. 5:53:08This line 11 here is just asking the question
  7386. 5:53:11if that current character, the i-th character of s,
  7387. 5:53:15is greater than or equal to little a and less
  7388. 5:53:18than or equal to little z, that is between 97 and 132, then
  7389. 5:53:23we're going to go ahead and force it to uppercase instead.
  7390. 5:53:29All right, and let me zoom out here for just a second.
  7391. 5:53:33And sorry, I misspoke 122, which is what you might have said.
  7392. 5:53:38There's only 26 letters.
  7393. 5:53:39So 122 is little z.
  7394. 5:53:41Let me go ahead now and compile and run this program.
  7395. 5:53:44So make uppercase, ./uppercase, and let me type in hi in lowercase, Enter.
  7396. 5:53:50And there's the capitalized version, thereof.
  7397. 5:53:52Let me do it again, with my own name in lowercase,
  7398. 5:53:55and now it's capitalized as well.
  7399. 5:53:57Well, what could we do to improve this?
  7400. 5:53:59Well.
  7401. 5:53:59You know what?
  7402. 5:54:00Let's stop reinventing wheels.
  7403. 5:54:01Let's go to the manual pages.
  7404. 5:54:04So let me go here and search for something like, I don't know,
  7405. 5:54:07lowercase.
  7406. 5:54:08And there I go.
  7407. 5:54:09I did some auto complete here, our little search box
  7408. 5:54:12is saying that, OK there's an is-lower function,
  7409. 5:54:14check whether a character is lowercase.
  7410. 5:54:16Well how do I use this?
  7411. 5:54:17Well let me check, is lower, now I see the actual man page for this function.
  7412. 5:54:23Now we see, include ctype.h.
  7413. 5:54:26So that's the protot--
  7414. 5:54:27that's the header file I need to include.
  7415. 5:54:28This is the prototype for is-lower, it apparently takes a char as input
  7416. 5:54:32and returns an int.
  7417. 5:54:34Which is a little weird.
  7418. 5:54:35I feel like is-lower should return true or false.
  7419. 5:54:38So let's scroll down to the description and return value.
  7420. 5:54:42It returns, oh this is interesting.
  7421. 5:54:45And this is a convention in C. This function returns a non-zero int
  7422. 5:54:49if C is a lowercase letter and 0 if C is not a lowercase letter.
  7423. 5:54:55So it returns non-zero.
  7424. 5:54:57So like 1, negative 1, something that's not 0 if C is a lowercase letter,
  7425. 5:55:02and 0 if it is not a lowercase letter.
  7426. 5:55:05So how can we use this building block?
  7427. 5:55:07Let me go back to my code here.
  7428. 5:55:09Let me add this file, include ctype.h.
  7429. 5:55:13And down here, let me get rid of this cryptic expression, which
  7430. 5:55:17was kind of painful to come up with, and just ask this, is-lower s bracket i?
  7431. 5:55:26That should actually work but why?
  7432. 5:55:29Well is-lower, again, returns a non-zero value if the letter is lowercase.
  7433. 5:55:34Well, what does that mean?
  7434. 5:55:36That means it could return 1.
  7435. 5:55:37It could return negative 1.
  7436. 5:55:38It could return 50 or negative 50.
  7437. 5:55:40It's actually not precisely defined, why?
  7438. 5:55:42Just, because.
  7439. 5:55:43This was a common convention to use 0 to represent false and use
  7440. 5:55:48any other value to represent true.
  7441. 5:55:50And so it turns out, that inside of Boolean expressions,
  7442. 5:55:54if you put a value like a function call like this, that returns 0,
  7443. 5:55:59that's going to be equivalent to false.
  7444. 5:56:00It's like the answer being no, it is not lower.
  7445. 5:56:03But you can also, in parentheses, put the name
  7446. 5:56:06of the function and its arguments, and not compare it against anything.
  7447. 5:56:10Because we could do something like this, well if it's not equal to 0, then
  7448. 5:56:15it must be lowercase.
  7449. 5:56:16Because that's the definition, if it returns a non-zero value,
  7450. 5:56:19it's lowercase.
  7451. 5:56:20But a more succinct way to do that is just a bit more like English.
  7452. 5:56:23If it's is lower, then print out the character minus 32.
  7453. 5:56:28So this would be the common way of using one of these
  7454. 5:56:30is- functions to check if the answer is true or false.
  7455. 5:56:34AUDIENCE: [INAUDIBLE]
  7456. 5:56:37DAVID MALAN: OK, well we might be done.
  7457. 5:56:38OK.
  7458. 5:56:39AUDIENCE: [INAUDIBLE]
  7459. 5:56:41DAVID MALAN: No.
  7460. 5:56:42So it's not necessarily 1.
  7461. 5:56:43It would be incorrect to check for 1, or negative 1, or anything else.
  7462. 5:56:47You want to check for the opposite of 0.
  7463. 5:56:49So not equal 0.
  7464. 5:56:51Or more succinctly, like I did by just putting it into parentheses.
  7465. 5:56:56Let me see what happens here.
  7466. 5:56:58So this is great, but some of you might have spotted a better solution
  7467. 5:57:02to this problem.
  7468. 5:57:03A moment ago when we were on the manual pages searching
  7469. 5:57:06for things related to lowercase, what might be another building
  7470. 5:57:09block we can employ here?
  7471. 5:57:13Based on what's on the screen here?
  7472. 5:57:14Yeah?
  7473. 5:57:15AUDIENCE: To-upper.
  7474. 5:57:17DAVID MALAN: So to-upper.
  7475. 5:57:18There's a function that would literally do the uppercasing thing for me
  7476. 5:57:21so I don't have to get into the weeds of negative 32, plus 32.
  7477. 5:57:24I don't have to consult that chart.
  7478. 5:57:25Someone has solved this problem for me in the past.
  7479. 5:57:29And let's see if I can actually get back to it.
  7480. 5:57:33There we go.
  7481. 5:57:34Let me go ahead, now, and use this.
  7482. 5:57:36So instead of doing s bracket i minus 32,
  7483. 5:57:39let's use a function that someone else wrote, and just say to-upper, s bracket
  7484. 5:57:44i.
  7485. 5:57:44And now it's going to do the solution for me.
  7486. 5:57:47So if I rerun make uppercase, and then do, slowly, .uppercase, type in hi,
  7487. 5:57:54now it's working as expected.
  7488. 5:57:56And honestly, if I read the documentation for to-upper
  7489. 5:58:00by going back to its man page, or manual page, what you'll see
  7490. 5:58:03is that it says if it's lowercase, it will return the uppercase version
  7491. 5:58:08thereof.
  7492. 5:58:09If it's not lowercase, it's already uppercase, it's punctuation,
  7493. 5:58:13it will just return the original character.
  7494. 5:58:14Which means, thanks to this function, I can actually
  7495. 5:58:18tighten this up significantly, get rid of all of my conditional
  7496. 5:58:21there, and just print out the to-upper return value,
  7497. 5:58:26and leave it to whoever wrote that function to figure out
  7498. 5:58:29if something's uppercase or lowercase.
  7499. 5:58:33All right, questions on these kinds of tricks?
  7500. 5:58:38Again, it all reduces to week 0 basics, but we're just
  7501. 5:58:41building these abstractions on top.
  7502. 5:58:43Yeah?
  7503. 5:58:43AUDIENCE: I'm wondering if there's any way just
  7504. 5:58:45to import all packages under a certain subdomain instead
  7505. 5:58:49of having to do multiple [INAUDIBLE] statements,
  7506. 5:58:51kind of like a star [INAUDIBLE]
  7507. 5:58:52DAVID MALAN: Yes.
  7508. 5:58:53Unfortunately, no.
  7509. 5:58:54There is no easy way in C to say, give me everything.
  7510. 5:58:57That was for, historically, performance reasons.
  7511. 5:58:59They want you to be explicit as to what you want to include.
  7512. 5:59:03In other languages like Python, Java, one of which
  7513. 5:59:05we'll see later this term, you can say, give me everything.
  7514. 5:59:08But that, actually, tends to be best practice because it can slow down
  7515. 5:59:11execution or compilation of your code.
  7516. 5:59:14Yeah?
  7517. 5:59:14AUDIENCE: Does to-upper accommodate for special characters?
  7518. 5:59:17DAVID MALAN: Ah.
  7519. 5:59:17Does to-upper accommodate special characters like punctuation?
  7520. 5:59:20Yes.
  7521. 5:59:20If I read the documentation more pedantically,
  7522. 5:59:22we would see exactly that.
  7523. 5:59:23It will properly hand me back an exclamation point,
  7524. 5:59:27even if I passed it in.
  7525. 5:59:28So if I do make uppercase here, and let me do ./upper, sorry--
  7526. 5:59:33./uppercase, hi with an exclamation point, it's going to handle that, too,
  7527. 5:59:37pass it through unchanged Yeah?
  7528. 5:59:40AUDIENCE: Do we access to a function that would do all of that
  7529. 5:59:43but just to the screen rather than to [INAUDIBLE]
  7530. 5:59:45DAVID MALAN: Really good question, too.
  7531. 5:59:47No, we do not have access to a function that at least comes with C or comes
  7532. 5:59:52with CS50's library that will just force the whole thing to uppercase.
  7533. 5:59:56In C, that's actually easier said than done.
  7534. 5:59:58In Python, it's trivial.
  7535. 5:59:59So stay tuned for another language that will let us do exactly that.
  7536. 6:00:04All right, so what does this leave us with?
  7537. 6:00:06There's just a-- let's come full circle now,
  7538. 6:00:08to where we began today where we were talking about those command line
  7539. 6:00:11arguments.
  7540. 6:00:12Recall that we talked about rm taking command line argument.
  7541. 6:00:16The file you want to delete, we talked about clang
  7542. 6:00:18taking command line arguments, that again,
  7543. 6:00:20modify the behavior of the program.
  7544. 6:00:22How is it that maybe you and I can start to write programs that
  7545. 6:00:25actually take command line arguments?
  7546. 6:00:28Well here is where I can finally explain why
  7547. 6:00:31we've been typing int main(void) for the past week
  7548. 6:00:35and just asking that you take on faith that it's just the way you do things.
  7549. 6:00:38Well, by default in C, at least the most recent versions thereof,
  7550. 6:00:45there's only two official ways to write main functions.
  7551. 6:00:48You might see other formats online, but they're generally
  7552. 6:00:50not consistent with the current specification.
  7553. 6:00:53This, again, was sort of a boilerplate for the simplest
  7554. 6:00:56function we might write last week, and recall that we've
  7555. 6:00:59been doing this the whole time.
  7556. 6:01:00(Void) What that (void) means, for all of the programs I have written thus far
  7557. 6:01:05and you have written thus far, is that none of our programs
  7558. 6:01:08that we've written take command line arguments.
  7559. 6:01:11That's what the void there means.
  7560. 6:01:13It turns out that main is the way you can specify that your program does,
  7561. 6:01:18in fact, take command line arguments, that
  7562. 6:01:20is words after the command in your terminal window.
  7563. 6:01:24If you want to actually not use get int or get string,
  7564. 6:01:26you want the human to be able to say something, like hello, David
  7565. 6:01:30and hit Enter.
  7566. 6:01:31And just run-- print hello, David on the screen.
  7567. 6:01:34You can use command line arguments, words after the program name
  7568. 6:01:38on your command line.
  7569. 6:01:41So we're going to change this in a moment to be something more verbose,
  7570. 6:01:44but something that's now a bit more familiar syntactically.
  7571. 6:01:48If you change that (void) in main to be this incantation instead,
  7572. 6:01:52int, argc, comma, string, argv, open bracket, close bracket,
  7573. 6:01:57you are now giving yourself access to writing programs
  7574. 6:02:00that take command line arguments.
  7575. 6:02:03Argc, which stands for argument count is going
  7576. 6:02:06to be an integer that stores how many words the human typed at the prompt.
  7577. 6:02:10The C automatically gives that to you.
  7578. 6:02:13String argv stands for argument vector, that's
  7579. 6:02:16going to be an array of all of the words that the human typed at the prompt.
  7580. 6:02:21So with today's building block of an array,
  7581. 6:02:23we have the ability now to let the humans type as many words,
  7582. 6:02:26or as few words, as they want at the prompt.
  7583. 6:02:28C is going to automatically put them in an array called argv,
  7584. 6:02:31and it's going to tell us how many words there are in an int called argc.
  7585. 6:02:36The int, as the return type here, we'll come back to in just a moment.
  7586. 6:02:40Let's use this definition to make, maybe,
  7587. 6:02:43just a couple of simple programs.
  7588. 6:02:45But in problem set 2 will we actually use
  7589. 6:02:47this to control the behavior of your own code.
  7590. 6:02:50Let me code up a file called argv.0 just to keep it aptly named.
  7591. 6:02:57Let me include cs50.h.
  7592. 6:02:59Let me go ahead and include--
  7593. 6:03:01oops.
  7594. 6:03:02That is not the right name of a program, let's start that over.
  7595. 6:03:05Let's go ahead and code up argv.c.
  7596. 6:03:09And here we have--
  7597. 6:03:11include cs50.h, include stdio.h, int, main, not void,
  7598. 6:03:17let's actually say int, argc, string, argv, open bracket, close bracket.
  7599. 6:03:24No numbers in between because you don't know, in advance,
  7600. 6:03:26how many words the human's going to type at their prompt.
  7601. 6:03:29Now let's go ahead and do this.
  7602. 6:03:31Let's write a very simple program that just says, hello, David, hello, Carter,
  7603. 6:03:35whoever the name is that gets typed.
  7604. 6:03:36But not using get string, let's instead have the human just
  7605. 6:03:40type their name at the prompt, just like rm, just like clang, just like make,
  7606. 6:03:44so it's just one and done when you hit Enter.
  7607. 6:03:46No additional prompts.
  7608. 6:03:47Let me go ahead then and do this, printf, quote-unquote, hello,
  7609. 6:03:52comma, and instead of world today, I want to print out
  7610. 6:03:55whatever the human typed in.
  7611. 6:03:57So let's go ahead and do this, argv, bracket 0 for now.
  7612. 6:04:03But I don't think this is quite what I want because, of course,
  7613. 6:04:07that's going to literally print out argv, bracket, 0, bracket.
  7614. 6:04:12I need a placeholder, so let me put %s here and then put that here.
  7615. 6:04:16So if argv is an array, but it's an array of strings,
  7616. 6:04:20then argv bracket 0 is itself a single string.
  7617. 6:04:24And so it can be plugged into that %s placeholder.
  7618. 6:04:27Let me go ahead and save my program.
  7619. 6:04:30And compile argv, so far, so good.
  7620. 6:04:33Let me now type in my name after the name of the program.
  7621. 6:04:37So no get string.
  7622. 6:04:38I'm literally typing an extra word, my own name at the prompt, Enter.
  7623. 6:04:42OK, it's apparently a little buggy in a couple of ways.
  7624. 6:04:45I forgot my /n but that's not a huge deal.
  7625. 6:04:48But apparently, inside of argv is literally everything
  7626. 6:04:53that humans typed in including the name of the program.
  7627. 6:04:55So logically, how do I print out hello, David, or hello so-and-so and not
  7628. 6:05:00the actual name of the program?
  7629. 6:05:01What needs to change here?
  7630. 6:05:03Yeah?
  7631. 6:05:03AUDIENCE: Change the index to 1.
  7632. 6:05:05DAVID MALAN: Yeah.
  7633. 6:05:06So presumably index to 1, if that's the second thing I, or whichever human,
  7634. 6:05:10has typed at the prompt.
  7635. 6:05:11So let's do make argv again, ./argv, Enter.
  7636. 6:05:15Huh.
  7637. 6:05:16Hello, nul.
  7638. 6:05:17So this is another form of nul.
  7639. 6:05:19But this is user error, now, on my part.
  7640. 6:05:23I didn't do exactly what I said I would.
  7641. 6:05:25Yeah?
  7642. 6:05:25AUDIENCE: You forgot the parameter.
  7643. 6:05:26DAVID MALAN: Yeah, I forgot the parameter.
  7644. 6:05:28So that's actually, hm.
  7645. 6:05:29I should probably deal with that, somehow,
  7646. 6:05:31so that people aren't breaking my program
  7647. 6:05:33and printing out random things, like nul.
  7648. 6:05:35But if I do say argv, David, now you see hello, David.
  7649. 6:05:39I can get a little curious, like what's at location 2?
  7650. 6:05:42Well we can see, make argv, bracket, ./argv, David, Enter.
  7651. 6:05:47All right, so just nothing is there.
  7652. 6:05:49But it turns out, in a couple of weeks, we'll start really poking around memory
  7653. 6:05:52and see if we can't crash programs deliberately
  7654. 6:05:54because nothing is stopping me from saying,
  7655. 6:05:57oh what's at location 2 million, for instance?
  7656. 6:06:00We could really start to get curious.
  7657. 6:06:02But for now, we'll do the right thing.
  7658. 6:06:04But let's now make sure the human has typed in the right number of words.
  7659. 6:06:08So let's say this, if argc equals 2, that is the name of the program
  7660. 6:06:15and one more word after that, go ahead and trust that in argv 1,
  7661. 6:06:19as you proposed, is the person's name.
  7662. 6:06:21Else, let's go ahead and default here to something simple and basic,
  7663. 6:06:26like, well, if we don't get a name from the user, just say hello, world,
  7664. 6:06:30like always.
  7665. 6:06:31So now we're programming defensively.
  7666. 6:06:34This time the human, even if they screw up, they don't give us a name
  7667. 6:06:37or they give us too many names, we're just going to say hello, world,
  7668. 6:06:40because I now have some error handling here.
  7669. 6:06:42Because, again, argc is argument count, the number of words, total,
  7670. 6:06:46typed at the command line.
  7671. 6:06:48So make, argv, ./argv.
  7672. 6:06:51Let me make the same mistake as before.
  7673. 6:06:52OK.
  7674. 6:06:53I don't get this weird nul behavior.
  7675. 6:06:55I get something well-defined.
  7676. 6:06:56I could now do David.
  7677. 6:06:57I could do David Malan, but that's not currently supported.
  7678. 6:07:01I would need to alter my logic to support more than just two words
  7679. 6:07:05after the prompt.
  7680. 6:07:06So what's the point of this?
  7681. 6:07:08At the moment, it's just a simple exercise
  7682. 6:07:09to actually give myself a way of taking user input when they run the program.
  7683. 6:07:14Because, consider, it's just more convenient in
  7684. 6:07:16this new, command-line-interface world.
  7685. 6:07:18If you had to use get string every time you compile your code,
  7686. 6:07:23it'd be kind of annoying, right?
  7687. 6:07:24You type make, then you might get a prompt, what would you like to make?
  7688. 6:07:28Then you type in hello, or cash, or something else, then you hit Enter,
  7689. 6:07:31it just really slows the process.
  7690. 6:07:33But in this command-line-interface world,
  7691. 6:07:35if you support command line arguments, then you can use these little tricks.
  7692. 6:07:39Like, scrolling up and down in your history with your arrow keys.
  7693. 6:07:42You can just type commands more quickly because you can do it all at once.
  7694. 6:07:46And you don't have to keep prompting the user, more
  7695. 6:07:49pedantically, for more and more info.
  7696. 6:07:52So any questions then on command line arguments?
  7697. 6:07:54Which, finally, reveals why we had (void) initially,
  7698. 6:07:58but what more we can now put in main.
  7699. 6:08:00That's how you take command line arguments.
  7700. 6:08:03Yeah?
  7701. 6:08:04AUDIENCE: If you were to put--
  7702. 6:08:06if you were to use argv, and you were to put integers inside of it,
  7703. 6:08:11would it still give you, like, a string?
  7704. 6:08:14Would that still be considered string?
  7705. 6:08:15Or would you consider [INAUDIBLE]?
  7706. 6:08:17DAVID MALAN: Yes.
  7707. 6:08:18If you were to type at the command line something
  7708. 6:08:20like, not a word, but something like the number 42,
  7709. 6:08:24that would actually be treated as a string.
  7710. 6:08:27Why?
  7711. 6:08:28Because again, context matters.
  7712. 6:08:30So if your program is currently manipulating memory
  7713. 6:08:33as though its characters or strings, whatever those patterns of 0s and 1s
  7714. 6:08:36are, they will be interpreted as ASCII text, or Unicode text.
  7715. 6:08:41If we therefore go to the chart here, that might make you wonder, well,
  7716. 6:08:44then how do you distinguish numbers from letters in the context of something
  7717. 6:08:48like chars and strings?
  7718. 6:08:50Well, notice 65 is a, 97 is a, but also 49 is 1, and 50 is 2.
  7719. 6:08:58So the designers of ASCII, and then later Unicode,
  7720. 6:09:01realized well wait a minute, if we want to support programs
  7721. 6:09:04that let you type things that look like numbers,
  7722. 6:09:07even though they're not technically ints or floats,
  7723. 6:09:10we need a way in ASCII and Unicode to represent even numbers.
  7724. 6:09:14So here are your numbers.
  7725. 6:09:16And it's a little silly that we have numbers representing other numbers.
  7726. 6:09:19But again, if you're in the world of letters and characters,
  7727. 6:09:22you've got to come up with a mapping for everything.
  7728. 6:09:24And notice here, here's the dot.
  7729. 6:09:26Even if you were to represent 1.23 as a string, or as characters,
  7730. 6:09:30even the dot now is going to be represented as an ASCII character.
  7731. 6:09:35So again, context here matters.
  7732. 6:09:37All right, one final example to tease apart what this int is
  7733. 6:09:41and what it's been doing here for so long.
  7734. 6:09:44So I'm going to add one bit of logic to a new file
  7735. 6:09:49that I'm going to call exit.c.
  7736. 6:09:52So an exit.c.
  7737. 6:09:53We're going to introduce something that are generally known as exit status.
  7738. 6:09:57It turns out this is not a feature we've used yet,
  7739. 6:09:59but it's just useful to know about.
  7740. 6:10:01Especially when automating tests of your own code.
  7741. 6:10:04When it comes to figuring out if a program succeeded or failed.
  7742. 6:10:08It turns out that main has one more feature we haven't leveraged.
  7743. 6:10:13An ability to signal to the user whether something was successful or not.
  7744. 6:10:18And that's by way of main's return value.
  7745. 6:10:22So I'm going modify this program as follows, like this.
  7746. 6:10:26Suppose I want to write a similar program that
  7747. 6:10:29requires that the user type a word at the prompt.
  7748. 6:10:32So that argc has to be 2 for whatever design purpose.
  7749. 6:10:36If argc does not equal 2, I want to quit out of my program prematurely.
  7750. 6:10:43I want to insist that the user operate the program correctly.
  7751. 6:10:46So I might give them an error message like, missing command line argument /n.
  7752. 6:10:53But now I want to quit out of the program.
  7753. 6:10:55Now how can I do that?
  7754. 6:10:56The right way, quote-unquote, to do that is to return a value from main.
  7755. 6:11:01Now it's a little weird because no one called main yet,
  7756. 6:11:04right, main just gets called automatically,
  7757. 6:11:07but the convention is anytime something goes
  7758. 6:11:09wrong in a program you should return a non-zero value from main.
  7759. 6:11:141 is fine as a go-to.
  7760. 6:11:16We don't need to get into the weeds of having many different exit statuses,
  7761. 6:11:19so to speak.
  7762. 6:11:20But if you return 1, that is a clue to the system, the Mac, the PC, the cloud
  7763. 6:11:26device that's something went wrong.
  7764. 6:11:27Why?
  7765. 6:11:28Because 1 is not 0.
  7766. 6:11:29If everything works fine, like, let's go ahead and print out hello comma %s like
  7767. 6:11:35before, quote-unquote argv bracket 1.
  7768. 6:11:40So this is just a version of the program without an else.
  7769. 6:11:43So this is the same as doing, essentially,
  7770. 6:11:45an else here like I did earlier.
  7771. 6:11:47I want to signal to the computer that all is well.
  7772. 6:11:51And so I return 0.
  7773. 6:11:52But strictly speaking, if I'm already returning here,
  7774. 6:11:55I don't technically need, if I really want to be nit picky,
  7775. 6:11:58I don't technically need the else because the only way
  7776. 6:12:01I'm going to get to line 11 is if I didn't already return.
  7777. 6:12:05So what's going on here?
  7778. 6:12:07The only new thing here logically, is that for the first time ever,
  7779. 6:12:10I'm returning a value from main.
  7780. 6:12:13That's something I could always have done
  7781. 6:12:14because main has always been defined by us as taking an int as a return value.
  7782. 6:12:19By default, main automatically, sort of secretly, returns 0 for you.
  7783. 6:12:24If you've never once use the return keyword, which you probably
  7784. 6:12:27haven't in main, it just automatically returns 0
  7785. 6:12:29and the system assumes that all went well.
  7786. 6:12:31But now that we're starting to get a little more
  7787. 6:12:33sophisticated with our code, and you know,
  7788. 6:12:35the programmer, something went wrong, you can abort programs early.
  7789. 6:12:39You can exit out of them by returning some other value, besides 0, from main.
  7790. 6:12:44And this is fortuitous that it's an int, right?
  7791. 6:12:470 means everything worked.
  7792. 6:12:49Unfortunately, in programming, there are seemingly, an infinite number of things
  7793. 6:12:53that can go wrong.
  7794. 6:12:54And int gives you 4 billion possible codes
  7795. 6:12:57that you can use, a.k.a. exit statuses, to signify errors.
  7796. 6:13:00So if you've ever on your Mac or PC gotten some weird pop up
  7797. 6:13:04that an error happened, sometimes, there's a cryptic number in it.
  7798. 6:13:07Maybe it's positive, maybe it's negative.
  7799. 6:13:09It might say error code 123, or negative 49, or something like that.
  7800. 6:13:14What you're generally seeing, are these exit statuses, these return
  7801. 6:13:18values from main in a program that someone at Microsoft,
  7802. 6:13:21or Apple, or somewhere else wrote, something went wrong,
  7803. 6:13:25they are unnecessarily showing you, the user what the error code is.
  7804. 6:13:30If only, so that when you call customer support or submit a ticket,
  7805. 6:13:33you can tell them what exit status you encountered,
  7806. 6:13:36what error code you encounter.
  7807. 6:13:39All right, any questions on exit statuses,
  7808. 6:13:43which is the last of our new building blocks, for now?
  7809. 6:13:48Any questions at all?
  7810. 6:13:49Yeah?
  7811. 6:13:50AUDIENCE: [INAUDIBLE] You know how if you have get string or get int,
  7812. 6:13:57if you want to make [INAUDIBLE]
  7813. 6:13:59DAVID MALAN: No.
  7814. 6:14:00The question is can you do things again and again
  7815. 6:14:03at the command line like you could with get string and get int.
  7816. 6:14:06Which, by default, recall are automatically
  7817. 6:14:08designed to keep prompting the user in their own loop
  7818. 6:14:10until they give you an int, or a float, or the like with command line
  7819. 6:14:14arguments, no.
  7820. 6:14:15You're going to get an error message but then
  7821. 6:14:16you're going to be returned to your prompt.
  7822. 6:14:18And it's up to you to type it correctly the next time.
  7823. 6:14:21Good question.
  7824. 6:14:22Yeah?
  7825. 6:14:22AUDIENCE: [INAUDIBLE] automatically for you.
  7826. 6:14:27DAVID MALAN: If you do not return a value
  7827. 6:14:29explicitly main will automatically return 0 for you,
  7828. 6:14:32that is the way C simply works so it's not strictly necessary.
  7829. 6:14:36But now that we're starting to return values explicitly,
  7830. 6:14:39if something goes wrong, it would be good practice
  7831. 6:14:42to also start returning a value for main when something goes right
  7832. 6:14:45and there are no errors.
  7833. 6:14:48So let's now get out of the weeds and contextualize
  7834. 6:14:52this for some actual problems that we'll be solving in the coming days
  7835. 6:14:55by way of problems set 2 and beyond.
  7836. 6:14:57So here for instance--
  7837. 6:15:00So here for instance, is a problem that you might think back
  7838. 6:15:04to when you were a kid the readability of some text or some book,
  7839. 6:15:08the grade level in which some book is written.
  7840. 6:15:10If you're a young student, you might read at first-grade level
  7841. 6:15:14or third-grade level in the US.
  7842. 6:15:15Or, if you're in college presumably, you're
  7843. 6:15:17reading at a university-level of text.
  7844. 6:15:19But what does it mean for text, like in a book,
  7845. 6:15:22or in an essay, or something like that to correspond
  7846. 6:15:24to some kind of grade level?
  7847. 6:15:25Well, here's a quote-- a title of a childhood book.
  7848. 6:15:29One Fish, Two Fish, Red Fish, Blue Fish.
  7849. 6:15:31What might the grade level be for a book that has words like this?
  7850. 6:15:35Maybe, when you were a kid or if you have a siblings still reading
  7851. 6:15:37these things, what might the grade level of this thing be?
  7852. 6:15:43Any guesses?
  7853. 6:15:43Yeah?
  7854. 6:15:44AUDIENCE: Before grade 1.
  7855. 6:15:45DAVID MALAN: Sorry, again?
  7856. 6:15:46AUDIENCE: Before grade 1.
  7857. 6:15:47DAVID MALAN: Before grade 1 is, in fact, correct.
  7858. 6:15:49So that's for really young kids?
  7859. 6:15:51Why is that?
  7860. 6:15:52Well, let's consider.
  7861. 6:15:53These are pretty simple phrases, right?
  7862. 6:15:56One fish, two fish, red--
  7863. 6:15:57I mean there's not even verbs in these sentences,
  7864. 6:16:00they're just nouns and adjectives, and very short sentences.
  7865. 6:16:04And so that might be a heuristic we could use.
  7866. 6:16:06When analyzing text, well if the words are kind of short,
  7867. 6:16:09the sentences are kind of short, everything's very simple,
  7868. 6:16:11that's probably a very young, or early, grade level.
  7869. 6:16:14And so by one formulation, it might indeed be even before grade 1,
  7870. 6:16:17for someone quite young.
  7871. 6:16:18How about this?
  7872. 6:16:19Mr and Mrs. Dursley, of number 4, Privet Drive,
  7873. 6:16:22were proud to say that they were perfectly normal, thank you very much.
  7874. 6:16:25They were the last people you would expect
  7875. 6:16:27to be involved in anything strange or mysterious
  7876. 6:16:29because they just didn't hold with such nonsense.
  7877. 6:16:32And, onward.
  7878. 6:16:33All right, what grade level is this book?
  7879. 6:16:34AUDIENCE: Third.
  7880. 6:16:36DAVID MALAN: OK, I heard third.
  7881. 6:16:37AUDIENCE: What?
  7882. 6:16:38DAVID MALAN: Seventh, fifth.
  7883. 6:16:40OK, all over the place.
  7884. 6:16:41But grade 7, according to one particular measure.
  7885. 6:16:44And whether or not we can debate exactly what age you were when you read this,
  7886. 6:16:49and maybe you're feeling ahead of your time, or behind now.
  7887. 6:16:51But here, we have a snippet of text.
  7888. 6:16:55What makes this text assume an older audience, a more mature audience,
  7889. 6:17:00a higher grade level, would you think?
  7890. 6:17:03Yeah?
  7891. 6:17:04AUDIENCE: [INAUDIBLE]
  7892. 6:17:06DAVID MALAN: Yeah, it's longer, different types of words,
  7893. 6:17:09there's commas now in phrases, and so forth.
  7894. 6:17:11So there's just some kind of sophistication to this.
  7895. 6:17:13So it turns out for the upcoming problem set,
  7896. 6:17:16among the things you'll do is take, as input, texts like this
  7897. 6:17:19and analyze them.
  7898. 6:17:20Considering , well, how many words are in the text?
  7899. 6:17:23How many sentences are in the text?
  7900. 6:17:24How many letters are in the text?
  7901. 6:17:26And use those according to a well-defined formula to prescribe what,
  7902. 6:17:30exactly, the grade level of some actual text-- there's the third--
  7903. 6:17:33might actually be.
  7904. 6:17:34Well what else are we going to do in the coming days?
  7905. 6:17:37Well I've alluded to this notion of cryptography in the past.
  7906. 6:17:39This notion of scrambling information in such a way
  7907. 6:17:42that you can hide the contents of a message
  7908. 6:17:45from someone who might otherwise intercept it, right?
  7909. 6:17:47The earliest form of this might also be when you're younger,
  7910. 6:17:50and you're in class, and you're passing a note from one person to another,
  7911. 6:17:53from yourself to someone else.
  7912. 6:17:54You don't want to necessarily write a note in English,
  7913. 6:17:57or some other written, language you might want
  7914. 6:17:59to scramble it somehow, or encrypt it.
  7915. 6:18:01Maybe you change the As to a B, and the Bs to a C.
  7916. 6:18:04So that if the teacher snaps it up and intercepts it,
  7917. 6:18:07they can't actually understand what it is you've
  7918. 6:18:09written because it's encrypted.
  7919. 6:18:11So long as your friend, the recipient of this note,
  7920. 6:18:13knows how you manipulated it.
  7921. 6:18:16How you added or subtracted letters to each other,
  7922. 6:18:19they can decrypt it, which is to reverse that process.
  7923. 6:18:23So formally, in the world of cryptography and computer science,
  7924. 6:18:26this is another problem to solve.
  7925. 6:18:28Your input, though, when you have a message you want to send securely,
  7926. 6:18:31is what's generally known as plain text.
  7927. 6:18:33There's some algorithm that's going to then encipher, or encrypt
  7928. 6:18:37that information, into what's called ciphertext, which
  7929. 6:18:40is the scrambled version that theoretically can get safely
  7930. 6:18:42intercepted and your message has not been spoiled,
  7931. 6:18:45unless that intercept actually knows what algorithm
  7932. 6:18:48you used inside of this process.
  7933. 6:18:51So that would be generally known as a cipher.
  7934. 6:18:53The ciphers typically take, though, not one input, but two.
  7935. 6:18:57If, for instance, your cipher is as simple as A becomes B,
  7936. 6:19:01B becomes C, C becomes D, dot dot dot, Z becomes A,
  7937. 6:19:05you're essentially adding one to every letter and encrypting it.
  7938. 6:19:09Now that would be, what we call, the key.
  7939. 6:19:12You and the recipient both have to agree, presumably, before class,
  7940. 6:19:15in advance, what number you're going to use that day to rotate,
  7941. 6:19:19or change all of these letters by.
  7942. 6:19:21Because when you add 1, they upon receiving your ciphertext
  7943. 6:19:24have to subtract 1 to get back the answer.
  7944. 6:19:27For instance, if the input, plaintext, is hi, as before,
  7945. 6:19:31and the key is 1, the ciphertext using this simple rotational algorithm,
  7946. 6:19:37otherwise known as the Caesar cipher, might be ij exclamation point.
  7947. 6:19:41So it's similar, but it's at least scrambled at first glance.
  7948. 6:19:45And unless the teacher really cares to figure out
  7949. 6:19:47what algorithm are they using today, or what key are they using today,
  7950. 6:19:50it's probably sufficiently secure for your purposes.
  7951. 6:19:53How do you reverse the process?
  7952. 6:19:55Well, your friend gets this and reverses it by negative 1.
  7953. 6:19:58So I becomes H, J becomes I, and things like punctuation
  7954. 6:20:02remain untouched at least in this scheme.
  7955. 6:20:05So let's consider one final example here.
  7956. 6:20:07If the input to the algorithm is Uijtxbtdt50, and the key
  7957. 6:20:15this time is negative 1.
  7958. 6:20:17Such that now B should become A, and C should become B, and A should become A.
  7959. 6:20:23So we're going in the other direction.
  7960. 6:20:25How might we analyze this?
  7961. 6:20:27Well if we spread all the letters out, and we start from left to right,
  7962. 6:20:30and we start subtracting one letter, U becomes T, I becomes H, J becomes I,
  7963. 6:20:36T becomes S, X becomes W, A, was, D, T--
  7964. 6:20:41this was CS50.
  7965. 6:20:42We'll see you next time.
  7966. 6:20:43[APPLAUSE]
  7967. 6:20:44[MUSIC PLAYING]
  7968. 6:22:01DAVID J. MALAN: This is CS50, and this is already week three.
  7969. 6:22:06And even as we've gotten much more into the minutia of programming
  7970. 6:22:10and some of the C stuff that we've been doing
  7971. 6:22:11is all the more cryptic looking, recall that at the end of the day,
  7972. 6:22:15like, everything we've been doing ultimately fits into to this model.
  7973. 6:22:19So keep that in mind, particularly as things
  7974. 6:22:20seem like they're getting more complicated and more sophisticated.
  7975. 6:22:23It's just a process of learning a new language that ultimately
  7976. 6:22:26lets us express this process.
  7977. 6:22:28And of course, last week we really went into the weeds of like how
  7978. 6:22:31inputs and outputs are represented.
  7979. 6:22:33And this thing here, a photograph thereof, is called what?
  7980. 6:22:37This is what?
  7981. 6:22:39AUDIENCE: RAM.
  7982. 6:22:39DAVID J. MALAN: RAM, I heard--
  7983. 6:22:41Random Access Memory or just generally known as memory.
  7984. 6:22:44And recall that we looked at one of these little black chips
  7985. 6:22:46that contains all of the bytes--
  7986. 6:22:48all of the bits, ultimately.
  7987. 6:22:50It's just kind of a grid, sort of an artist grid, that
  7988. 6:22:52allows us to think about every one of these memory locations
  7989. 6:22:55as just having a number or an address, so to speak.
  7990. 6:22:58Like, this might be byte number 0 and then 1 and then 2
  7991. 6:23:01and then, maybe way down here again, something like 2 billion
  7992. 6:23:04if you have 2 gigabytes of memory.
  7993. 6:23:06And so as we did that, we started to explore how we could use this canvas
  7994. 6:23:10to create kind of our own information, our own inputs and outputs, not
  7995. 6:23:14just the basics like ints and floats and so forth.
  7996. 6:23:16But we also talked about strings.
  7997. 6:23:18And what is a string as you now know it?
  7998. 6:23:21How would you describe in layperson's terms a string?
  7999. 6:23:24Yeah, over there.
  8000. 6:23:25AUDIENCE: I was gonna say--
  8001. 6:23:26[AUDIO OUT]
  8002. 6:23:26DAVID J. MALAN: An array of characters.
  8003. 6:23:28And an array, meanwhile-- let's go there.
  8004. 6:23:30How might someone else define an array in more familiar now terms?
  8005. 6:23:34What would be an array?
  8006. 6:23:37Yeah.
  8007. 6:23:38AUDIENCE: Kind of like an indexed set of things.
  8008. 6:23:41DAVID J. MALAN: An indexed set of things-- not bad.
  8009. 6:23:43And I think a key characteristic to keep in mind with an array is that it
  8010. 6:23:46does actually pertain to memory.
  8011. 6:23:48And it's contiguous memory.
  8012. 6:23:50Byte after byte after byte is what constitutes an array.
  8013. 6:23:53And we'll see in a couple of weeks time that there's actually
  8014. 6:23:56more interesting ways to use this same primitive Canvas to stitch together
  8015. 6:24:00things that are sort of two directional even that have some kind of shape
  8016. 6:24:03to them.
  8017. 6:24:04But for now, all we've talked about is arrays and just using these things
  8018. 6:24:07from left to right, top to bottom, contiguously to represent information.
  8019. 6:24:11So today, we'll consider still an array.
  8020. 6:24:14But we won't focus so much on representation
  8021. 6:24:17of strings or other data types.
  8022. 6:24:18We'll actually now focus on the other part of that process,
  8023. 6:24:21of inputs becoming outputs, namely the thing in the middle--
  8024. 6:24:24algorithms.
  8025. 6:24:25But we have to keep in mind, even though every time we've looked at an array
  8026. 6:24:29thus far, certainly on the board like this, you as a human certainly
  8027. 6:24:32have the luxury of just kind of eyeballing
  8028. 6:24:34the whole thing with a bird's eye view and seeing where all of those numbers
  8029. 6:24:38are.
  8030. 6:24:38If I asked you where a particular number is,
  8031. 6:24:40like zero, odds are your eyes would go right to where it is,
  8032. 6:24:43and boom, problem solved in sort of one step.
  8033. 6:24:46But the catch is, with a computer that has this memory, even though you,
  8034. 6:24:51the human, can [INAUDIBLE] see everything at once, a computer cannot.
  8035. 6:24:55It's better to think of your computer's memory, your phone's memory,
  8036. 6:24:58or more specifically an array of memory like this
  8037. 6:25:01as really being a set of closed doors, not unlike lockers in a school.
  8038. 6:25:05And only by opening each of those doors can
  8039. 6:25:08the computer actually see what's in there,
  8040. 6:25:10which is to say that the computer, unlike you, doesn't
  8041. 6:25:12have this bird's eye view of all of the data in all these locations.
  8042. 6:25:16It has to much more methodically look here,
  8043. 6:25:19maybe look here, maybe look here, and so forth in order to find something.
  8044. 6:25:23Now fortunately, we already have some building blocks-- loops, conditions,
  8045. 6:25:28Boolean expressions, and the like--
  8046. 6:25:29where you could imagine writing some code
  8047. 6:25:31that very methodically goes from left to right or right to left or something
  8048. 6:25:36more sophisticated that actually finds something you're looking for.
  8049. 6:25:39And just remember that the conventions we've had since last week
  8050. 6:25:43now is that these arrays are zero indexed, so to speak.
  8051. 6:25:47To be zero indexed just means that the data type starts counting from zero.
  8052. 6:25:52So this is location 0, 1, 2, 3, 4, 5, 6.
  8053. 6:25:56And notice even though there are seven total doors here,
  8054. 6:25:59the right-most one, of course, is called 6
  8055. 6:26:02just because we've started counting at 0.
  8056. 6:26:04So in the general case, if you had n doors or n bytes of memory,
  8057. 6:26:090 would always be at the left, and n minus 1 would always be at the right.
  8058. 6:26:13That's sort of a generalization of just thinking about this kind of convention.
  8059. 6:26:18All right, so let's revisit the problem that we started the whole term off
  8060. 6:26:22with in week zero, which was this notion of searching.
  8061. 6:26:24And what does it mean to search for something?
  8062. 6:26:26Well, to find information-- and this, of course, is omnipresent.
  8063. 6:26:29Anytime you take out your phone, you're searching for a friend's contact.
  8064. 6:26:32Any time you pull up a browser, you're googling for this or that.
  8065. 6:26:35So search is kind of one of the most omnipresent topics and features
  8066. 6:26:39of any device these days.
  8067. 6:26:41So let's consider how the Googles, the Apples, the Microsofts of the world
  8068. 6:26:44are implementing something as seemingly familiar as this.
  8069. 6:26:48So here might be the problem statement.
  8070. 6:26:50We want some input to become some output.
  8071. 6:26:52What's that input going to be?
  8072. 6:26:54Maybe it's a bunch of closed doors like this out of which we want
  8073. 6:26:57to get back an answer, true or false.
  8074. 6:27:00Is something we're looking for there or not?
  8075. 6:27:03You can imagine taking this one step further and trying to find
  8076. 6:27:05where is the thing you're looking for.
  8077. 6:27:07But for now, let's just take one bite out of the problem.
  8078. 6:27:10Can we tell ourselves, true or false, is some number behind one
  8079. 6:27:14of these doors or lockers in memory?
  8080. 6:27:17But before we go there and start talking about ways to do that-- that is,
  8081. 6:27:22algorithms.
  8082. 6:27:22Let's consider how we might lay the foundation of, like,
  8083. 6:27:27comparing whether one algorithm is better than another.
  8084. 6:27:30We talked about correctness, and it sort of
  8085. 6:27:32goes without saying that any code you write, any algorithm you implement,
  8086. 6:27:35had better be correct.
  8087. 6:27:36Otherwise, what's the point if it doesn't give you the right answers?
  8088. 6:27:39But we also talked about design.
  8089. 6:27:41And in your own words, what do we mean when we say a program is better
  8090. 6:27:45designed at this stage than another?
  8091. 6:27:48How do you think about this notion of design now?
  8092. 6:27:52Yeah, in the middle?
  8093. 6:27:53AUDIENCE: Easier to understand or easier to institute.
  8094. 6:27:55DAVID J. MALAN: OK, so easier to understand.
  8095. 6:27:57I like that.
  8096. 6:27:58Other thoughts?
  8097. 6:27:58Yeah.
  8098. 6:27:59AUDIENCE: Efficiency.
  8099. 6:28:00DAVID J. MALAN: Efficiency, and what do you mean by efficiency precisely?
  8100. 6:28:03AUDIENCE: [INAUDIBLE]
  8101. 6:28:06DAVID J. MALAN: Nice.
  8102. 6:28:07It doesn't use up too much memory, and it isn't redundant.
  8103. 6:28:09So you can think about design along a few
  8104. 6:28:11of these axes-- sort of the quality of the code
  8105. 6:28:13but also the quality of the performance.
  8106. 6:28:15And as our programs get bigger and more sophisticated and just longer,
  8107. 6:28:20those kinds of things are really going to matter.
  8108. 6:28:22And in the real world, if you start writing code
  8109. 6:28:24not just by yourself but with someone else, getting the design
  8110. 6:28:26right is just going to make it easier to collaborate and ultimately produce,
  8111. 6:28:30write code, with just higher probability.
  8112. 6:28:33So let's consider how we might focus on exactly the second characteristic,
  8113. 6:28:36the efficiency, of an algorithm.
  8114. 6:28:38And the way we might talk about the efficiency of algorithms, just how fast
  8115. 6:28:42or how slow they are, is in terms of their running time.
  8116. 6:28:45That is to say, when they're running, how much time do they take?
  8117. 6:28:49And we might measure this in seconds or milliseconds or minutes
  8118. 6:28:52or just some number of steps in the general case
  8119. 6:28:54because presumably fewer steps, to your point, is better than more steps.
  8120. 6:28:58So how might we think about running times?
  8121. 6:29:00Well, there's one general notation we should define today.
  8122. 6:29:03So computer scientists tend to describe the running time of an algorithm
  8123. 6:29:07or a piece of code, for that matter, in terms of what's called big O notation.
  8124. 6:29:12This is literally a capitalized O, a big O.
  8125. 6:29:14And this generally means that the running time of some algorithm
  8126. 6:29:18is on the order of such and such, where such and such, we'll see,
  8127. 6:29:21is just going to be a very simple mathematical formula.
  8128. 6:29:24It's kind of a way of waving your hands mathematically
  8129. 6:29:26to convey the idea of just how fast or how slow some algorithm or code is
  8130. 6:29:31without getting into the weeds of like, it
  8131. 6:29:32took this many milliseconds or this many specific number of steps.
  8132. 6:29:36So you might recall then from week zero, I even introduced this picture
  8133. 6:29:40but without much context.
  8134. 6:29:41At the time, we just use this to compare those phone book algorithms.
  8135. 6:29:45Recall that this red straight line was the first algorithm,
  8136. 6:29:47one page at a time.
  8137. 6:29:49The yellow line that's still straight differed how if you recall?
  8138. 6:29:54That line represented what alternative algorithm?
  8139. 6:29:58Looking out and back.
  8140. 6:29:59What is that second algorithm?
  8141. 6:30:00Yeah, over there.
  8142. 6:30:01AUDIENCE: Like, two pages at a time.
  8143. 6:30:03DAVID J. MALAN: Two pages at a time, which was almost correct so long as we
  8144. 6:30:06potentially double back a page if maybe we go a little too far in the phone
  8145. 6:30:09book.
  8146. 6:30:10So it had a potential bug but arguably solvable.
  8147. 6:30:12This last algorithm, though, was the so-called divide and conquer
  8148. 6:30:15strategy where I sort of unnecessarily tore the phone book in half
  8149. 6:30:18and then in half and then in half, which,
  8150. 6:30:20as dramatic as that was unnecessarily, it actually took significantly bigger
  8151. 6:30:25bites out of the problem-- like 500 pages
  8152. 6:30:27the first time, another 250, another 125 versus just 1 or 2 bytes at a time.
  8153. 6:30:33And so we described its running time as this picture
  8154. 6:30:36there, though I didn't use that expression at the time, running times.
  8155. 6:30:39But indeed, time to solve might be measured just
  8156. 6:30:42abstractly in some unit of measure--
  8157. 6:30:44seconds, milliseconds, minutes, pages--
  8158. 6:30:47via this y-axis here.
  8159. 6:30:49So let's now slap some numbers on this.
  8160. 6:30:52If we had n pages in that phone book, n just representing
  8161. 6:30:55a generic number, the first algorithm here
  8162. 6:30:57we might describe as taking n steps.
  8163. 6:30:59Second algorithm we might describe as taking n divided by 2 steps,
  8164. 6:31:03maybe give or take one if we have to double back but generally
  8165. 6:31:05n divided by 2.
  8166. 6:31:06And then this thing, if you remember your logarithms,
  8167. 6:31:09was sort of a fundamentally different formula--
  8168. 6:31:11log base 2 of n or just log of n for short.
  8169. 6:31:14So this is of a fundamentally different formula.
  8170. 6:31:17But what's noteworthy is that these first two algorithms,
  8171. 6:31:20even though, yes, the second algorithm was hands down faster--
  8172. 6:31:24I mean, literally twice as fast--
  8173. 6:31:26when you start to zoom out and if I increase my y-axis and x-axis,
  8174. 6:31:30these first two start to look awfully similar to one another.
  8175. 6:31:36And if we keep zooming out and zooming out and zooming
  8176. 6:31:39out as n gets really large--
  8177. 6:31:41that is, the x-axis gets really long--
  8178. 6:31:43these first two algorithms start to become essentially the same.
  8179. 6:31:47And so this is where computer scientists use big O notation.
  8180. 6:31:50Instead of saying specifically, this algorithm takes any steps.
  8181. 6:31:54And this one n divided by 2, a computer scientist would say,
  8182. 6:31:57eh, each of those algorithms takes on the order of n steps
  8183. 6:32:01or on the order of n over 2.
  8184. 6:32:03But you know what?
  8185. 6:32:04On the order of n over 2 is pretty much the same
  8186. 6:32:07when n gets really large as being equivalent to big O of n itself.
  8187. 6:32:13So yes, in practice, it's obviously fewer steps to move twice as fast.
  8188. 6:32:18But in the big picture, when n becomes a million, a billion,
  8189. 6:32:22the numbers are already so darn big at that point
  8190. 6:32:24that these are as, the shapes of these curves imply,
  8191. 6:32:28pretty much functionally equivalent.
  8192. 6:32:30But this one still looks better and better
  8193. 6:32:33as n gets large because it's rising so much less quickly.
  8194. 6:32:36And so here, a computer scientist would say
  8195. 6:32:39that that third algorithm was on the order of-- that is, big O of-- log n.
  8196. 6:32:43And they don't have to bother with the base
  8197. 6:32:45because it's a smaller mathematical detail that is also just in some sense
  8198. 6:32:49a constant, multiplicative factor.
  8199. 6:32:52So in short, what are the takeaways here?
  8200. 6:32:54This is just a new vocabulary that we'll start
  8201. 6:32:56to use when we just want to describe the running time of an algorithm.
  8202. 6:33:00To make this more real, if any of you have implemented
  8203. 6:33:02a for loop at this point in any of your code and that for loop iterated n times
  8204. 6:33:08where maybe in was the height of your pyramid or maybe n
  8205. 6:33:11was something else that you wanted to do n times, you wrote code
  8206. 6:33:15or you implemented an algorithm that operated in big O of n time,
  8207. 6:33:20if you will.
  8208. 6:33:21So this is just a way now to retroactively start
  8209. 6:33:23describing with somewhat mathematical notation what we've
  8210. 6:33:27been doing in practice for a while now.
  8211. 6:33:30So here's a list of commonly seen running times in the real world.
  8212. 6:33:35This is not a thorough list because you could come up
  8213. 6:33:39with an infinite number of mathematical formulas, certainly.
  8214. 6:33:42But the common ones we'll discuss and you will see in your own code
  8215. 6:33:45probably reduce to this list here.
  8216. 6:33:48And if you were to study more computer science theory,
  8217. 6:33:50this list would get longer and longer.
  8218. 6:33:52But for now, these are sort of the most familiar ones that we'll soon see.
  8219. 6:33:56All right, two other pieces of vocabulary, if you will,
  8220. 6:33:59before we start to use this stuff--
  8221. 6:34:00so this, a big omega, capital omega symbol,
  8222. 6:34:03is used now to describe a lower bound on the running time of an algorithm.
  8223. 6:34:09So to be clear, big O is on the order of-- that
  8224. 6:34:12is, an upper bound-- on how many steps an algorithm might
  8225. 6:34:16take, on the order of so many steps.
  8226. 6:34:19If you want to talk, though, from the other perspective, well,
  8227. 6:34:21how few steps my algorithm take?
  8228. 6:34:24Maybe in the so-called best case, it'd be nice
  8229. 6:34:26if we had a notation to just describe what a lower
  8230. 6:34:29bound is because some algorithms might be super fast
  8231. 6:34:32in these so-called best cases.
  8232. 6:34:34So the symbology is almost the same, but we replace the big O
  8233. 6:34:38with the big omega.
  8234. 6:34:39So to be clear, big O describes an upper bound and omega
  8235. 6:34:42describes a lower bound.
  8236. 6:34:44And we'll see examples of this before long.
  8237. 6:34:46And then lastly, last one here, big theta, is used by a computer scientist
  8238. 6:34:52when you have a case where both the upper bound on an algorithm's
  8239. 6:34:57running time is the same as the lower bound.
  8240. 6:35:00You can then describe it in one breath as being in theta of such and such
  8241. 6:35:03instead of saying it's in big O and in omega of something else.
  8242. 6:35:08All right, so out of context, sort of just seemingly cryptic symbols,
  8243. 6:35:12but all they refer to is upper bounds, lower bounds, or when
  8244. 6:35:15they happen to be one in the same.
  8245. 6:35:17And we'll now introduce over time examples of how we might actually
  8246. 6:35:20apply these to concrete problems.
  8247. 6:35:23But first, let me pause to see if there's any questions.
  8248. 6:35:27Any questions here?
  8249. 6:35:30Any questions?
  8250. 6:35:32I see pointing somewhere.
  8251. 6:35:35Where are you pointing to?
  8252. 6:35:37Over here-- there we go.
  8253. 6:35:39OK, sorry-- very bright.
  8254. 6:35:40AUDIENCE: So, um, smaller--
  8255. 6:35:43DAVID J. MALAN: Smaller n functions move faster.
  8256. 6:35:45So yes, if you have something like n, that takes only steps.
  8257. 6:35:50If you have a formula like n squared, just by nature of the math,
  8258. 6:35:53that take more steps and therefore be slower.
  8259. 6:35:56So the larger the mathematical expression,
  8260. 6:35:58the slower your algorithm is because the more time or more steps that it takes.
  8261. 6:36:05AUDIENCE: So you want your n function to be small?
  8262. 6:36:07DAVID J. MALAN: You want your n function, so to speak, to be small, yes.
  8263. 6:36:10And in fact, the Holy Grail, so to speak,
  8264. 6:36:12would be this last one here either in big O notation or even theta,
  8265. 6:36:16when an algorithm is on the order of a single step.
  8266. 6:36:19That means it literally takes constant time, one step, or maybe 10 steps,
  8267. 6:36:23100 steps, but a fixed, constant number of steps.
  8268. 6:36:26That's the best because even as the phone book gets bigger,
  8269. 6:36:30even as the data set you're searching gets larger and larger,
  8270. 6:36:34if something only takes a finite number of steps constantly,
  8271. 6:36:37then it doesn't matter how big the data set actually gets.
  8272. 6:36:42Questions as well on these notations-- yep, thank you for the pointing.
  8273. 6:36:46This is actually very helpful.
  8274. 6:36:47I'm seeing pointing this way?
  8275. 6:36:49AUDIENCE: [INAUDIBLE]
  8276. 6:36:52DAVID J. MALAN: What is the input to each of these functions?
  8277. 6:36:54It is an expression of how many steps an algorithm takes.
  8278. 6:36:58So in fact, let me go ahead and make this
  8279. 6:37:00more concrete with an actual example here if we could.
  8280. 6:37:03So on stage here, we have seven lockers which represent,
  8281. 6:37:06if you will, an array of memory.
  8282. 6:37:08And this array of memory is maybe storing
  8283. 6:37:10seven integers, seven integers that we might actually want to search for.
  8284. 6:37:14And if we want to search for these values, how might
  8285. 6:37:17we go about doing this?
  8286. 6:37:18Well, for this, why don't we make things interesting?
  8287. 6:37:20Would a volunteer like to come on up?
  8288. 6:37:22Have to be masked and on the internet if you are comfortable.
  8289. 6:37:25Both of-- oh, there's someone putting their friend's hand up and back?
  8290. 6:37:28Yes, OK.
  8291. 6:37:29Come on down.
  8292. 6:37:34And in just a moment, our brave volunteer
  8293. 6:37:37is going to help me find a specific number in the data set
  8294. 6:37:41that we have here on the screen.
  8295. 6:37:42So come on down, and I'll get things ready for you in advance here.
  8296. 6:37:46Come on down nice to meet.
  8297. 6:37:53And what is your name?
  8298. 6:37:54AUDIENCE: [? Nomira. ?]
  8299. 6:37:54DAVID J. MALAN: Minera?
  8300. 6:37:55AUDIENCE: [? Nomira. ?]
  8301. 6:37:55DAVID J. MALAN: [? Nomira. ?] Nice to meet.
  8302. 6:37:57Come on over.
  8303. 6:37:58So here we have for Nomira seven lockers or an array of memory.
  8304. 6:38:02And behind each of these doors is a number.
  8305. 6:38:03And the goal, quite simply, is, given this array of memory
  8306. 6:38:06as input, to return, true or false, is the number I care about actually there?
  8307. 6:38:12So suppose I care about the number 0.
  8308. 6:38:14What would be the simplest, most correct algorithm you could
  8309. 6:38:18apply in order to find us the number 0?
  8310. 6:38:22OK, try opening the first one.
  8311. 6:38:25All right, and maybe just step aside so the audience can see.
  8312. 6:38:28I think you have not found 0 yet.
  8313. 6:38:30OK, so keep the door open.
  8314. 6:38:31Let's move on to your next choice.
  8315. 6:38:34Second door, sure.
  8316. 6:38:35AUDIENCE: [INAUDIBLE]
  8317. 6:38:36DAVID J. MALAN: Oh, go ahead, second door.
  8318. 6:38:37Let's keep it simple.
  8319. 6:38:38Let's just move from left to right, sort of searching our way.
  8320. 6:38:41And what do you see there?
  8321. 6:38:43Oh, 6, not 0.
  8322. 6:38:44How about the next door?
  8323. 6:38:48All right, also not working out so well yet, but that's OK.
  8324. 6:38:51If you want to go on to the next, we're still looking for 0.
  8325. 6:38:55All right, I see a 2.
  8326. 6:38:57All right, it's not so good yet.
  8327. 6:38:58Let's keep going.
  8328. 6:38:59Next door.
  8329. 6:39:012, 7-- no.
  8330. 6:39:02OK, next door.
  8331. 6:39:04No, that's a-- all right, very well done.
  8332. 6:39:10Oh.
  8333. 6:39:13All right, so I kind of set you up for a fairly slow algorithm,
  8334. 6:39:16but let me just ask you to describe what is it
  8335. 6:39:18you did by following the steps I gave you.
  8336. 6:39:21AUDIENCE: I just went one by one to each character.
  8337. 6:39:24DAVID J. MALAN: You went one by one to each character
  8338. 6:39:26if you want to talk into here.
  8339. 6:39:27So you went one by one by each character.
  8340. 6:39:29And would you say that algorithm left or right is correct?
  8341. 6:39:32AUDIENCE: No.
  8342. 6:39:34DAVID J. MALAN: No?
  8343. 6:39:35AUDIENCE: Or, yes, in the scenario.
  8344. 6:39:37DAVID J. MALAN: OK, yes in this scenario.
  8345. 6:39:38Why are you hesitating?
  8346. 6:39:39What's going through your mind?
  8347. 6:39:40AUDIENCE: Because it's not the most efficient way to do it.
  8348. 6:39:42DAVID J. MALAN: OK, good.
  8349. 6:39:43So we see a contrast here between correctness and design.
  8350. 6:39:45I mean, I do think it was correct because even though it was slow,
  8351. 6:39:48you eventually found zero.
  8352. 6:39:50But it took some number of steps.
  8353. 6:39:52So in fact, this would be an algorithm.
  8354. 6:39:54It has a name, called linear search.
  8355. 6:39:56And, [? Nomira, ?] as you did, you kind of walked along
  8356. 6:39:59a line going from left to right.
  8357. 6:40:01Now let me ask.
  8358. 6:40:01If you had gone from right to left, would the algorithm
  8359. 6:40:04have been fundamentally better?
  8360. 6:40:07AUDIENCE: Yes.
  8361. 6:40:08DAVID J. MALAN: OK, and why?
  8362. 6:40:09AUDIENCE: Because the zero is here in the first scenario.
  8363. 6:40:11But if it was like, the zero is in the middle, it wouldn't have been.
  8364. 6:40:15DAVID J. MALAN: Yeah, and so here is where the right way to do things
  8365. 6:40:19becomes a little less obvious.
  8366. 6:40:20You would absolutely have given yourself a better result
  8367. 6:40:23if you would just happened to start from the right
  8368. 6:40:25or if I had pointed you to start over there.
  8369. 6:40:27But the catch is if I asked her to find another number, like the number 8,
  8370. 6:40:30well, that would have backfired.
  8371. 6:40:31And this time, it would have taken longer
  8372. 6:40:33to find that number because it's way over here instead.
  8373. 6:40:35And so in the general case, going left to right or, heck, right to left
  8374. 6:40:40is probably as correct as you can get because if you know nothing
  8375. 6:40:43about the order of these numbers-- and indeed, they seem to be fairly random.
  8376. 6:40:47Some of them are smaller, some of them are bigger.
  8377. 6:40:49There doesn't seem to be rhyme or reason.
  8378. 6:40:51Linear search is about as good as you can do when you don't know anything
  8379. 6:40:55a priori about the numbers.
  8380. 6:40:57So I have a little thank you gift here, a little CS stress ball.
  8381. 6:41:00Round of applause for our first volunteer.
  8382. 6:41:03Thank you so much.
  8383. 6:41:08Let's try to formalize what I just described as linear search
  8384. 6:41:12because indeed, no matter which end [? Nomira ?] had started on,
  8385. 6:41:15I could have kind of changed up the problem
  8386. 6:41:17to make sure that it appears to be running slow.
  8387. 6:41:19But it is correct.
  8388. 6:41:20If zero were among those doors, she absolutely would have found it
  8389. 6:41:23and indeed did.
  8390. 6:41:24So let's now try to translate what we did into what we might call again
  8391. 6:41:30pseudo code as from week zero.
  8392. 6:41:32So with pseudo code, we just need a terse English
  8393. 6:41:35like, or any language, syntax to describe what we did.
  8394. 6:41:38So here might be one formulation of what [? Nomira ?] did.
  8395. 6:41:40For each door, from left to right, if the number is behind the door,
  8396. 6:41:45return true.
  8397. 6:41:46Else, at the very end of the program, you would return false by default.
  8398. 6:41:51And now you got lucky.
  8399. 6:41:53And by the seventh door, [? Nomira ?] had indeed
  8400. 6:41:55returned true by saying, well, there is the zero.
  8401. 6:41:58But let's consider if this pseudo code is now correct,
  8402. 6:42:01an accurate translation.
  8403. 6:42:02First of all, normally, when we've seen ifs, we might see an if else.
  8404. 6:42:06And yet down here, return false is aligned with the for.
  8405. 6:42:10Why did I not indent the return false, or put another way,
  8406. 6:42:14why did I not do if number is behind door, return true, else return false?
  8407. 6:42:21Why would that version of this code have been problematic?
  8408. 6:42:24Way in back.
  8409. 6:42:25AUDIENCE: [INAUDIBLE]
  8410. 6:42:34DAVID J. MALAN: OK, I'm not sure it's because of redundancy.
  8411. 6:42:37Let me go ahead and just make this explicit.
  8412. 6:42:39If I had instead done else return false, I
  8413. 6:42:42don't think it's so much redundancy that I'd be worried about.
  8414. 6:42:47Let me bounce somewhere else.
  8415. 6:42:48Yeah, in front?
  8416. 6:42:49AUDIENCE: Um, maybe [INAUDIBLE] for the entire list
  8417. 6:42:52after just checking one number.
  8418. 6:42:54DAVID J. MALAN: Yeah, it would be returning falls for--
  8419. 6:42:56even though I'd only looked at-- [? Nomira ?]
  8420. 6:42:58had only looked at one element.
  8421. 6:42:59And it would have been as though if all of these doors were still closed,
  8422. 6:43:02she opens this up and says, nope, this is not zero, return false.
  8423. 6:43:05That would give me an incorrect result because obviously,
  8424. 6:43:09at that stage in the algorithm, she wouldn't have even looked
  8425. 6:43:11through any of the other doors.
  8426. 6:43:13So just the original indentation of this, if you will,
  8427. 6:43:16without the [? else, ?] is correct because only
  8428. 6:43:19if I get to the bottom of this algorithm or the pseudo code does
  8429. 6:43:23it make sense to conclude at that point, once she's
  8430. 6:43:26gone through all of the doors, that nope, there's in fact--
  8431. 6:43:29the number I'm looking for is, in fact, not actually there.
  8432. 6:43:32So how might we consider now the running time of this algorithm?
  8433. 6:43:37We have a few different types of vocabulary now.
  8434. 6:43:40And if we consider now how we might think about this,
  8435. 6:43:43let's start to translate it from sort of higher level pseudo code
  8436. 6:43:46to something a little lower level.
  8437. 6:43:48We've been writing code using n and loops and the like.
  8438. 6:43:52So let's take this higher level pseudo code and now just kind of
  8439. 6:43:56get a middle ground between English and C.
  8440. 6:43:59Let me propose that we think about this version of the same algorithm
  8441. 6:44:03as being a little more pedantic.
  8442. 6:44:05For i from 0 to n minus 1, if number behind doors bracket i return true.
  8443. 6:44:13Otherwise, at the end of the program, return false.
  8444. 6:44:15Now I'm kind of mixing English and C here,
  8445. 6:44:17but that's reasonable if the reader is familiar with C
  8446. 6:44:20or some similar language.
  8447. 6:44:21And notice this pattern here.
  8448. 6:44:23This is a way of just saying in pseudo code, give myself a variable called i.
  8449. 6:44:29Start at 0 and then just count up to n minus 1.
  8450. 6:44:33And recall n minus 1 is not one shy of the end of the array.
  8451. 6:44:37N minus 1 is the end of the array because again, we
  8452. 6:44:40started counting at 0.
  8453. 6:44:41So this is a very common way of expressing this kind of loop
  8454. 6:44:45from the left all the way to the right of an array.
  8455. 6:44:48Doors I'm kind of implicitly treating as the name of this array,
  8456. 6:44:51like it's a variable from last week that I defined as being
  8457. 6:44:54an array of integers in this case.
  8458. 6:44:56So doors bracket i means that when i is 0, it's this location.
  8459. 6:45:01When i is 1, it's this.
  8460. 6:45:02When i is 7 or, more generally n minus--
  8461. 6:45:06sorry, 6 or, more generally, n minus 1, that's this location here.
  8462. 6:45:10So same idea but a translation of it.
  8463. 6:45:13So now let's consider what the running time of this algorithm is.
  8464. 6:45:17If we have this menu of possible answers to this question,
  8465. 6:45:20how efficient or inefficient is this algorithm,
  8466. 6:45:23let's take a look in the context of this pseudo code.
  8467. 6:45:26We don't even have to bother going all the way to C.
  8468. 6:45:28How do we go about analyzing each of these steps?
  8469. 6:45:32Well, let's consider this.
  8470. 6:45:33This outermost loop here for i from 0 to n minus 1, that line of code
  8471. 6:45:39is going to execute how many times?
  8472. 6:45:42How many times will that loop execute?
  8473. 6:45:45Let me give folks this moment to think on it.
  8474. 6:45:48How many times is that going to loop here?
  8475. 6:45:51Yeah, over there.
  8476. 6:45:52AUDIENCE: [INAUDIBLE]
  8477. 6:45:54DAVID J. MALAN: n times, right?
  8478. 6:45:55Because it's from 0 to n minus 1.
  8479. 6:45:58And if it's a little weird to think in from 0 to n minus 1,
  8480. 6:46:00this is essentially the same mathematically as from 1 to n.
  8481. 6:46:04And that's perhaps a little more obviously more
  8482. 6:46:06intuitively n total steps.
  8483. 6:46:08So I might just make a note to myself this loop is going to operate n times.
  8484. 6:46:12What about these inner steps?
  8485. 6:46:14Well, how many steps or seconds does it take to ask a question?
  8486. 6:46:17If the number behind--
  8487. 6:46:19if the number you're looking for is behind doors bracket i,
  8488. 6:46:23well, as [? Nomira ?] did, that's kind of like one step.
  8489. 6:46:25So you open the door and boom.
  8490. 6:46:27All right, maybe it's two steps, but it's a constant number of steps.
  8491. 6:46:30So this is some constant number of steps.
  8492. 6:46:32Let's just call it one for simplicity.
  8493. 6:46:34How many steps or seconds does it take to return true?
  8494. 6:46:37I don't know exactly in the computer's memory
  8495. 6:46:40but that feels like a single step.
  8496. 6:46:41Just return true.
  8497. 6:46:43So if this takes one step, this takes one step
  8498. 6:46:46but only if the condition is true, it looks
  8499. 6:46:49like you're doing a constant number of things n times.
  8500. 6:46:53Or maybe you're doing one additional step.
  8501. 6:46:56So in short, the only thing that really matters here
  8502. 6:46:59in terms of the efficiency or inefficiency of the algorithm
  8503. 6:47:02is what are you doing again and again and again because that's obviously
  8504. 6:47:05the thing that's going to add up.
  8505. 6:47:07Doing one thing or two things a constant number of times?
  8506. 6:47:10Not a big deal.
  8507. 6:47:11But looping, that's going to add up over time because the more doors there are,
  8508. 6:47:16the bigger n is going to be and the more steps that's going to take,
  8509. 6:47:19which is all to say if you were to describe roughly
  8510. 6:47:22how many steps does this algorithm take in big O notation,
  8511. 6:47:27what might your instincts say?
  8512. 6:47:30How many steps is this algorithm on the order of given n doors or n integers?
  8513. 6:47:35Yeah?
  8514. 6:47:36AUDIENCE: [INAUDIBLE]
  8515. 6:47:37DAVID J. MALAN: Say again?
  8516. 6:47:38AUDIENCE: O n.
  8517. 6:47:39DAVID J. MALAN: Big O of n.
  8518. 6:47:40And indeed, that's going to be the case here.
  8519. 6:47:42Why?
  8520. 6:47:42Because you're essentially, at the end of the day,
  8521. 6:47:44doing n things as an upper bound on running time.
  8522. 6:47:48And that's, in fact, what exactly what happened
  8523. 6:47:50with [? Nomira. ?] She had to look at all n lockers
  8524. 6:47:52before finally getting to the right answer.
  8525. 6:47:55But what if she got lucky and the number we
  8526. 6:47:58were looking for was not at the end of the array
  8527. 6:48:01but was at the beginning of the array?
  8528. 6:48:04How might we think about that?
  8529. 6:48:06Well, have a nomenclature for this too, of course-- omega notation.
  8530. 6:48:09Remember, omega notation is a lower bound.
  8531. 6:48:12So given this menu of possible running times for lower bounds on an algorithm,
  8532. 6:48:18what might the omega notation be for [? Nomira's ?] linear search?
  8533. 6:48:23AUDIENCE: Omega 1.
  8534. 6:48:24DAVID J. MALAN: Omega of 1, and why that?
  8535. 6:48:26AUDIENCE: [INAUDIBLE]
  8536. 6:48:28DAVID J. MALAN: Right, because if just by chance she gets lucky
  8537. 6:48:30and the number she's looking for is right there where
  8538. 6:48:33she begins the algorithm, that's it.
  8539. 6:48:35It's one step.
  8540. 6:48:36Maybe it's two steps if you have to unlock the door and open it,
  8541. 6:48:39but it's a constant number of steps.
  8542. 6:48:41And the way we describe constant number of steps
  8543. 6:48:43is just with a single number like 1.
  8544. 6:48:45So the omega notation for linear search might be omega of 1
  8545. 6:48:49because in the best case, she might just get the number right from the get go.
  8546. 6:48:53But in the worst case, we need to talk about the upper bound, which
  8547. 6:48:56might indeed be big O of n.
  8548. 6:48:58So again there's this way now of talking symbolically
  8549. 6:49:01about best cases and worst cases or lower bounds and upper bounds.
  8550. 6:49:06Theta notation, just as a little trivia now,
  8551. 6:49:09is it applicable based on the definition I gave earlier?
  8552. 6:49:12AUDIENCE: [INAUDIBLE]
  8553. 6:49:13DAVID J. MALAN: OK, no, because you only take out the theta notation
  8554. 6:49:15when those two bounds, upper and lower, happen
  8555. 6:49:18to be the same for shorthand notation, if you will.
  8556. 6:49:21So it suffices here to talk about just big O and omega notation.
  8557. 6:49:25Well, what if we are a little smarter about this?
  8558. 6:49:28Let me go ahead and sort of semi-secretly here
  8559. 6:49:31rearrange these numbers.
  8560. 6:49:32But first, how about one other volunteer?
  8561. 6:49:34One other volunteer-- you have to be comfortable with your mask
  8562. 6:49:37and your being on the internet.
  8563. 6:49:39How about over here?
  8564. 6:49:42Yes, you want to come on down?
  8565. 6:49:44All right, come on down.
  8566. 6:49:45And don't look at what I'm doing because I'm going to--
  8567. 6:49:52take your time and don't look up this way
  8568. 6:49:55because I need a moment to rearrange all of the numbers.
  8569. 6:49:58And actually, if you could stay right there before coming up,
  8570. 6:50:01just an awkward few seconds while I finish hiding the numbers
  8571. 6:50:05behind these doors for you.
  8572. 6:50:06AUDIENCE: [INAUDIBLE]
  8573. 6:50:08DAVID J. MALAN: I will be right with you.
  8574. 6:50:10Actually, if-- do you want to warm up the crowd for a moment
  8575. 6:50:15and I'll be right back?
  8576. 6:50:16So you want to introduce yourself?
  8577. 6:50:18AUDIENCE: Yeah, hi, guys.
  8578. 6:50:19I'm Rave.
  8579. 6:50:22Yeah!
  8580. 6:50:27DAVID J. MALAN: All right, I think I am ready.
  8581. 6:50:30Thank you for stalling there.
  8582. 6:50:32AUDIENCE: Of course.
  8583. 6:50:33DAVID J. MALAN: And I didn't catch your name.
  8584. 6:50:34What was your name?
  8585. 6:50:34AUDIENCE: I'm Rave.
  8586. 6:50:35DAVID J. MALAN: I'm sorry?
  8587. 6:50:35AUDIENCE: Rave, like a party.
  8588. 6:50:36DAVID J. MALAN: Rave, OK.
  8589. 6:50:37Nice to meet.
  8590. 6:50:38Come on over.
  8591. 6:50:39So Rave has kindly volunteered now.
  8592. 6:50:41And I'm going to give you an additional advantage this time.
  8593. 6:50:43AUDIENCE: OK.
  8594. 6:50:43DAVID J. MALAN: Unbeknownst to you, I now took numbers behind the doors,
  8595. 6:50:47but I sorted them for you.
  8596. 6:50:48So they're not in the same random order like they
  8597. 6:50:50were for [? Nomira. ?] You now have the advantage
  8598. 6:50:52to know that the numbers are sorted from small to big.
  8599. 6:50:55AUDIENCE: OK.
  8600. 6:50:55DAVID J. MALAN: Given that, and given perhaps what we talked about in week zero
  8601. 6:50:59with the phone book, where might you propose we begin the story this time?
  8602. 6:51:03With which locker?
  8603. 6:51:05AUDIENCE: To find zero?
  8604. 6:51:06DAVID J. MALAN: Let's find number six this time.
  8605. 6:51:07Let's make things interesting.
  8606. 6:51:09AUDIENCE: OK.
  8607. 6:51:10I'll start in the middle.
  8608. 6:51:11DAVID J. MALAN: OK, so the middle.
  8609. 6:51:12There's seven total.
  8610. 6:51:13So--
  8611. 6:51:13AUDIENCE: OK.
  8612. 6:51:14DAVID J. MALAN: --that would be right here.
  8613. 6:51:14Go ahead.
  8614. 6:51:15Open that up.
  8615. 6:51:16And you find, sadly, the number five.
  8616. 6:51:18So what do you know now?
  8617. 6:51:20AUDIENCE: I know to go up.
  8618. 6:51:21DAVID J. MALAN: OK.
  8619. 6:51:22AUDIENCE: OK.
  8620. 6:51:22DAVID J. MALAN: All right, and just to keep it uniform,
  8621. 6:51:24just like I did, I opened to the right half of the phone book.
  8622. 6:51:27AUDIENCE: Yes.
  8623. 6:51:27DAVID J. MALAN: Let's keep it similar.
  8624. 6:51:29Yeah.
  8625. 6:51:29AUDIENCE: All right.
  8626. 6:51:30DAVID J. MALAN: All right, and, uh, a little too far
  8627. 6:51:32even though I know you wanted to go one over.
  8628. 6:51:34AUDIENCE: All good, all good.
  8629. 6:51:35DAVID J. MALAN: And now we're going to go which direction?
  8630. 6:51:37AUDIENCE: Over here in the middle.
  8631. 6:51:38DAVID J. MALAN: Right, and voila, the number six.
  8632. 6:51:40All right, so very nicely done.
  8633. 6:51:44A little stressful for you as well.
  8634. 6:51:46Thank you again.
  8635. 6:51:47So here we see by nature of the locker door
  8636. 6:51:50still being open sort of an artifact of the greater efficiency,
  8637. 6:51:54it would seem, of this algorithm because now that Rave
  8638. 6:51:57was given the assumption that these numbers are sorted from small
  8639. 6:52:00on the left to large on the right, she was able to apply that same divide
  8640. 6:52:04and conquer algorithm from week zero which we're now going to give a name--
  8641. 6:52:07binary search.
  8642. 6:52:09And simply by starting in the middle and realizing,
  8643. 6:52:13OK, too small, then by going to the right half and realizing, oh,
  8644. 6:52:17went a little too far, then by going to the left half, which,
  8645. 6:52:20Rave able to find in just three steps instead of seven
  8646. 6:52:24the number six in this case that we were actually searching for.
  8647. 6:52:28So you can see that this would seem to be more efficient.
  8648. 6:52:32Let's consider for just a moment is it correct.
  8649. 6:52:35If I had used different numbers but still sorted them from left to right,
  8650. 6:52:40would it still have worked this algorithm?
  8651. 6:52:43You're nodding your head.
  8652. 6:52:44Can I call on you?
  8653. 6:52:45Like, why would it still have worked, do you think?
  8654. 6:52:48AUDIENCE: [INAUDIBLE]
  8655. 6:52:51DAVID J. MALAN: Yeah, so so long as the numbers
  8656. 6:52:52are always in the same order from left to right
  8657. 6:52:55or, heck, they could even be in reverse order, so long as it's consistent,
  8658. 6:52:58the decisions that Rave was making-- if greater than, else, if less than--
  8659. 6:53:02would guide us to the solution no matter what.
  8660. 6:53:05And it would seem to take fewer steps.
  8661. 6:53:07So if we consider now the pseudo code for this algorithm,
  8662. 6:53:10let's take a look how we might describe binary search.
  8663. 6:53:12So binary search we might describe with something like this.
  8664. 6:53:15If the number is behind the middle door, which is where Rave began,
  8665. 6:53:19then we can just return true.
  8666. 6:53:21Else if the number is less than the middle door,
  8667. 6:53:24so if six is less than whatever is behind the middle door,
  8668. 6:53:27then Rave would have searched the left half.
  8669. 6:53:29Else if the number is greater than the middle door,
  8670. 6:53:32Rave would have searched the right half.
  8671. 6:53:34Else, if there are no doors-- and we'll see in a moment why I put
  8672. 6:53:38this up top just to keep things clean.
  8673. 6:53:40If there's no doors, what should Rave have presumably returned immediately
  8674. 6:53:43if I gave her no lockers to work with?
  8675. 6:53:47Just returned false.
  8676. 6:53:48But this is an important case to consider
  8677. 6:53:50because if in the process of searching by locker by locker,
  8678. 6:53:54we might have whittled down the problem from seven doors to three doors
  8679. 6:53:58to one door to zero doors-- and at that point,
  8680. 6:54:01we might have had no doors left to search.
  8681. 6:54:03So we have to naturally have a scenario for just considering
  8682. 6:54:06if there were no doors.
  8683. 6:54:07So it's not to say that maybe I don't give Rave any doors to begin with.
  8684. 6:54:11But as she divides and divides and divides,
  8685. 6:54:13if she runs out of lockers to ask those questions of-- or a few weeks ago,
  8686. 6:54:17if I ran out of phone book pages to tear in half,
  8687. 6:54:20I too might have had to return false as in this case.
  8688. 6:54:23So how can we now describe this a little more like C
  8689. 6:54:26just to give ourselves a variable to start thinking and talking about?
  8690. 6:54:30Well, I might talk about doors as being an array.
  8691. 6:54:33And so if I want to express the middle door, I could just, in pseudo code,
  8692. 6:54:36say doors bracket middle.
  8693. 6:54:38I'm assuming that someone has done the math
  8694. 6:54:40to figure out what the middle door is, but that's easy enough to do.
  8695. 6:54:43And then doors, if the number we're looking for
  8696. 6:54:46is less than doors bracket middle, then search door
  8697. 6:54:49zero through doors middle minus 1.
  8698. 6:54:53So again, this is a more pedantic way of taking what's a pretty intuitive idea--
  8699. 6:54:57search the left half, search the right half--
  8700. 6:55:00but start to now describe it in terms of actual indices or indexes
  8701. 6:55:07like we did with our array notation.
  8702. 6:55:08The last scenario, of course, is if the number
  8703. 6:55:10is greater than the door's bracket middle,
  8704. 6:55:13then Rave would have wanted to search the middle door plus 1--
  8705. 6:55:16so 1 over-- through doors n minus 1--
  8706. 6:55:21through n minus 1.
  8707. 6:55:22So again, just a way of sort of describing a little more syntactically
  8708. 6:55:25what it is that's going on.
  8709. 6:55:27So how might we translate this now into big O notation?
  8710. 6:55:31Well, in the worst case, how many steps total might Rave's binary search
  8711. 6:55:38algorithm have taken?
  8712. 6:55:39Given seven doors or given more generically n doors,
  8713. 6:55:43how many times could she go left or go right before finding herself with one
  8714. 6:55:47or no doors left?
  8715. 6:55:50What's the way to think about that?
  8716. 6:55:53Yeah, in the middle?
  8717. 6:55:53AUDIENCE: Log n.
  8718. 6:55:55DAVID J. MALAN: Log n.
  8719. 6:55:56So there's log n again.
  8720. 6:55:57And even if you're not feeling wholly comfortable with your logarithm
  8721. 6:56:00still, pretty much in programming and in computer science more generally,
  8722. 6:56:03any time we talk about some algorithm that's dividing and conquering
  8723. 6:56:06in half, in half, in half, or any other multiple,
  8724. 6:56:10it's probably involving logarithms in some sense.
  8725. 6:56:12And log base n essentially refers to the number
  8726. 6:56:15of times you can divide n by 2 until you bottom out at just a single door
  8727. 6:56:21or equivalently zero doors left.
  8728. 6:56:23So log n.
  8729. 6:56:24So we might say that indeed, binary search is in big O of log n
  8730. 6:56:28because the door that Rave opened last, this one,
  8731. 6:56:32happened to be three doors away.
  8732. 6:56:34And actually, if you do the math here, that roughly
  8733. 6:56:37works out to be exactly that case.
  8734. 6:56:38If we add one, that's sort of out of seven doors or roughly eight,
  8735. 6:56:43we were able to search it in just three total steps.
  8736. 6:56:46What about omega notation, though?
  8737. 6:56:48Like, in the best case, Rave might have gotten lucky.
  8738. 6:56:51She opened the door, and there it is.
  8739. 6:56:53So how might we describe a lower bound on the running time of binary search.
  8740. 6:56:59Yeah.
  8741. 6:56:59AUDIENCE: 1.
  8742. 6:57:00DAVID J. MALAN: Say again?
  8743. 6:57:01AUDIENCE: 1.
  8744. 6:57:02DAVID J. MALAN: Omega of 1.
  8745. 6:57:03So here too, we see that in some cases binary search and linear search, eh,
  8746. 6:57:08like, they're pretty equivalent.
  8747. 6:57:10And so this is why sometimes compelling to consider both the best
  8748. 6:57:15case in the worst case because honestly, in general,
  8749. 6:57:17who really cares if you just get lucky once in a while
  8750. 6:57:19and your algorithm is super fast?
  8751. 6:57:21What you probably care about is what's the worst case.
  8752. 6:57:24How long are my users--
  8753. 6:57:25how long am I going to be sitting there watching some spinning hourglass
  8754. 6:57:29or beach ball trying to give myself an answer to a pretty big problem?
  8755. 6:57:35Well, odds are, you're going to generally care about big O notation.
  8756. 6:57:38So indeed, moving forward, will generally
  8757. 6:57:39talk about the running time of algorithms often in terms of big O,
  8758. 6:57:43a little less so in terms of omega.
  8759. 6:57:45But understanding the range can be important
  8760. 6:57:47depending on the nature of the data that you're going to actually be given here.
  8761. 6:57:53All right let me pause and see if there is any questions.
  8762. 6:57:58Any questions here?
  8763. 6:58:00Yes, thank you.
  8764. 6:58:03AUDIENCE: So this method is clearly more efficient,
  8765. 6:58:05but it requires that the information is all compiled in a certain order.
  8766. 6:58:10How do you ensure that you can compile information
  8767. 6:58:14in a particular order at scale?
  8768. 6:58:15DAVID J. MALAN: Yeah, it's a really good question.
  8769. 6:58:17And if I can generalize it, how do you guarantee that you can do this
  8770. 6:58:20at scale, which algorithm is better?
  8771. 6:58:22I've sort of led us down this road of implying
  8772. 6:58:25that Rave's second algorithm, binary search,
  8773. 6:58:27is better because it's so much faster.
  8774. 6:58:29It's log of n in the worst case instead of big O of n.
  8775. 6:58:33But Rave was given an advantage when she came up here in that the doors were
  8776. 6:58:37already sorted.
  8777. 6:58:38And so that sort of invites the question,
  8778. 6:58:40well, given a whole bunch of random data,
  8779. 6:58:42either a small data set or, heck, something Google sized with millions,
  8780. 6:58:45billions of pieces of data, should you sort it first
  8781. 6:58:48from smallest to largest and then search?
  8782. 6:58:51Or should you just dive right in and search it linearly?
  8783. 6:58:56Like, how might you think about that?
  8784. 6:58:58If you are Google, for instance, and you've
  8785. 6:58:59got millions, billions of web pages, should they just go with linear search
  8786. 6:59:03because it's always going to work even though it might be slow?
  8787. 6:59:06Or should they invest the time in sorting all of that data--
  8788. 6:59:09we'll see how in a bit--
  8789. 6:59:10and then search it more efficiently?
  8790. 6:59:13Like, how do you decide between those options?
  8791. 6:59:15AUDIENCE: If you're sorting the data, then wouldn't you
  8792. 6:59:18have to go through all of the data?
  8793. 6:59:20DAVID J. MALAN: Yeah, if you had to sort the data first--
  8794. 6:59:23and we don't yet formally know how to do this.
  8795. 6:59:25But obviously, as humans, we could probably figure it out.
  8796. 6:59:27You do have to look at all of the data anyway.
  8797. 6:59:29And so you're sort of wasting your time if you're sorting it only
  8798. 6:59:33then to go in search it.
  8799. 6:59:35But maybe it depends a bit more.
  8800. 6:59:37Like, that's absolutely right, and if you're just
  8801. 6:59:39searching for one thing in life, then that's probably a waste of time
  8802. 6:59:42to sort it and then search it because you're just adding to the process.
  8803. 6:59:46But what's another scenario in which you might not
  8804. 6:59:48worry about that whereby it might make sense to sort it and then search?
  8805. 6:59:53Yeah.
  8806. 6:59:54AUDIENCE: [INAUDIBLE] you can go and use the other values as a way
  8807. 7:00:00to find out what's happening.
  8808. 7:00:02DAVID J. MALAN: Yeah, exactly.
  8809. 7:00:03So if your problem is a Google-like problem where
  8810. 7:00:05you have more than just one user who's searching for more than just one
  8811. 7:00:08website page, probably you should incur the cost up front
  8812. 7:00:11and sort the whole thing because every subsequent request thereafter
  8813. 7:00:14is going to be faster, faster, faster because it's
  8814. 7:00:17going to [INAUDIBLE] algorithm of binary search, binary search, binary search
  8815. 7:00:20that's going to add up to be way fewer steps
  8816. 7:00:23than doing linear search multiple times.
  8817. 7:00:25So again, kind of depends on the use case
  8818. 7:00:27and kind of depends on how important it is.
  8819. 7:00:29And this happens even in real world contexts.
  8820. 7:00:32I think back always to graduate school, when I was writing some code
  8821. 7:00:35to analyze some large data set.
  8822. 7:00:36And honestly, it was actually easier at the time for me
  8823. 7:00:39to write pretty inefficient but hopefully correct
  8824. 7:00:42code because you know what?
  8825. 7:00:43I could just go to sleep for eight hours and let it analyze this really big data
  8826. 7:00:47set.
  8827. 7:00:47I didn't have to bother writing more complex code to sort it just
  8828. 7:00:50to run it more efficiently.
  8829. 7:00:51Why?
  8830. 7:00:52Because I was the only user, and I only needed to run these queries once.
  8831. 7:00:55And so this was kind of a reasonable approach,
  8832. 7:00:58reasonable until I woke up eight hours later and my code was incorrect.
  8833. 7:01:01And now I had to spend another eight hours rerunning it after fixing it.
  8834. 7:01:05But even there, you see an example where,
  8835. 7:01:07what is your most precious resource?
  8836. 7:01:09Is it time to run the code?
  8837. 7:01:11Is it time to write the code?
  8838. 7:01:13Is it the amount of memory the computer is using?
  8839. 7:01:15These are all resources we'll start to talk about because it really
  8840. 7:01:18depends on what your goals are.
  8841. 7:01:20Any questions, then, on upper bounds, lower bounds,
  8842. 7:01:23or each of these two searches, linear or binary?
  8843. 7:01:26Yeah.
  8844. 7:01:27AUDIENCE: So just, when you're calculating running time,
  8845. 7:01:29does the sorting step count for that time?
  8846. 7:01:34DAVID J. MALAN: When analyzing running time, does the sorting step count?
  8847. 7:01:37If you want it to if you actually do it.
  8848. 7:01:39At the moment, it did not apply.
  8849. 7:01:41I just gave Rave the luxury of knowing that the data was sorted.
  8850. 7:01:45But if I really wanted to charge her for the amount of time
  8851. 7:01:48it took to find that number six, I should have added the time
  8852. 7:01:52to sort plus the time to search.
  8853. 7:01:54And in fact, that's a road we'll go down.
  8854. 7:01:55Why don't we go ahead and pace ourselves as before?
  8855. 7:01:57Let's take a 10 minute break here.
  8856. 7:01:58And when we come back, we'll write some actual code.
  8857. 7:02:01So we've seen a couple of searches-- linear search and binary search, which,
  8858. 7:02:05to be fair, we saw back in week zero.
  8859. 7:02:06But let's actually translate at least one of those now to some code
  8860. 7:02:10using this building block from last week where we can actually
  8861. 7:02:13define an array if we want, like an array of integers called numbers.
  8862. 7:02:17So let me switch over to VS Code here.
  8863. 7:02:18Let me go ahead and start a program called numbers.c.
  8864. 7:02:22And in numbers.c, let me go ahead here.
  8865. 7:02:25And how about let's include our familiar header files?
  8866. 7:02:29So css50.h.
  8867. 7:02:31I'll include standardio.h that we can get input and print input if we want.
  8868. 7:02:35And now I'm going to go ahead and give myself int main void.
  8869. 7:02:38No command line arguments today.
  8870. 7:02:40So I'll leave that as void.
  8871. 7:02:41And I'm going to go ahead and give myself
  8872. 7:02:43an array of how about seven numbers?
  8873. 7:02:45So I'll call it int number 7.
  8874. 7:02:48And then I can fill this array with numbers.
  8875. 7:02:50Like, numbers brackets 0 can be the number 4, and numbers bracket 1
  8876. 7:02:54could be the number 6, and numbers bracket 2 can be the number 8.
  8877. 7:02:58And this is the same list that we saw with [? Nomira ?] a bit
  8878. 7:03:01ago where it was 4, then 6, then 8.
  8879. 7:03:03But you know what?
  8880. 7:03:04There's actually another syntax I can show you here.
  8881. 7:03:06If you know in advance in a C program that you
  8882. 7:03:09want an array of certain values and you know therefore how many of those values
  8883. 7:03:14you want, you can actually do this little trick using curly braces.
  8884. 7:03:17You can say, don't worry about how big this is.
  8885. 7:03:20It's going to be implicit by way of these curly braces.
  8886. 7:03:23Here, I can do 4, 6, 8, 2, 7, 5, 0, close curly brace.
  8887. 7:03:28So it's a somewhat new use of curly braces.
  8888. 7:03:31But this has the effect of giving me an array called numbers inside
  8889. 7:03:35of which are a whole bunch of integers.
  8890. 7:03:36How many?
  8891. 7:03:37The compiler can infer it from what's ever inside these curly braces.
  8892. 7:03:41And it seems to be of size 1, 2, 3, 4, 5, 6, 7.
  8893. 7:03:44And all seven elements will be initialized with 4, 6, 8, 2, 7, 5, 0
  8894. 7:03:49respectively.
  8895. 7:03:50So just a minor optimization code wise to tighten up
  8896. 7:03:53what would have otherwise been like eight separate lines of code.
  8897. 7:03:56Now let's go ahead and implement linear search, as we called it.
  8898. 7:03:59And you can do this in a bunch of ways, but I'm going to do it like this.
  8899. 7:04:02For int i get 0, i is less than 7 i plus plus.
  8900. 7:04:09Then inside of my loop, I'm going to ask the question, well,
  8901. 7:04:12if the numbers at location i equals equals, as we asked of
  8902. 7:04:17[? Nomira, ?] the number 0, then I'm going to go ahead and do something
  8903. 7:04:21like printf found backslash n.
  8904. 7:04:25And then I'm going to return 0.
  8905. 7:04:27Just because of last week's discussion of returning
  8906. 7:04:30a value for main when all is well, I'm going to return 0 by convention
  8907. 7:04:34just to signal that indeed, I found what I'm looking for.
  8908. 7:04:37Otherwise, on what line do I want to go and add a printf, like, not found
  8909. 7:04:44and return something other than 0?
  8910. 7:04:46Right, I don't think I want an else here per our pseudo code earlier.
  8911. 7:04:51So on what line would you prefer I sort of insert a default scenario
  8912. 7:04:55of not found and I'll return an error?
  8913. 7:04:58Yeah, over here?
  8914. 7:05:00[INTERPOSING VOICES]
  8915. 7:05:03DAVID J. MALAN: Nice.
  8916. 7:05:04So at the end of the for loop because you
  8917. 7:05:06want to give the program or our volunteer
  8918. 7:05:07earlier a chance to go through all of the doors, all of the numbers.
  8919. 7:05:11But if you go through the whole thing, through the whole loop,
  8920. 7:05:14at the very end, you probably just want to conclude not found backslash n
  8921. 7:05:17and then return something like positive 1
  8922. 7:05:20just to signify that an error happened.
  8923. 7:05:22And again, this was a minor detail last week.
  8924. 7:05:24Any time main is successful, the programming convention is to return 0.
  8925. 7:05:28That means all as well.
  8926. 7:05:30And if something goes wrong, like you didn't find what you're looking for,
  8927. 7:05:33you might return something other than 0, like positive 1, maybe positive 2,
  8928. 7:05:37or even negative numbers if you want.
  8929. 7:05:39All right, well, let me go ahead and save this.
  8930. 7:05:41Let me do make numbers.
  8931. 7:05:43Hopefully no syntax errors.
  8932. 7:05:45All good so far.
  8933. 7:05:46dot slash numbers, enter.
  8934. 7:05:49All right, and it's found, as I would hope it would be.
  8935. 7:05:51And just as a little check, let's search for something that's definitely
  8936. 7:05:55not there, like the number negative 1.
  8937. 7:05:59Let me go ahead and recompile the code with make numbers.
  8938. 7:06:02Let me rerun the code with dot slash numbers
  8939. 7:06:04and hopefully-- whew, OK, not found.
  8940. 7:06:06So proof by example seems to be working correctly.
  8941. 7:06:08But let's make things a little more interesting now.
  8942. 7:06:11Right now, I'm using just an array of integers.
  8943. 7:06:14Let me go ahead and introduce maybe an array of strings instead.
  8944. 7:06:18And maybe this time, I'll store a bunch of names and not just integers
  8945. 7:06:21but actual strings of names.
  8946. 7:06:23So how might I do this?
  8947. 7:06:24Well, let me go back to my code here.
  8948. 7:06:26I'm going to switch us over to maybe a file called names.c.
  8949. 7:06:30And in here, I'll go ahead and include cs50.h.
  8950. 7:06:34I'll include standardio.h.
  8951. 7:06:37And I'm going to go ahead and for now include a new friend
  8952. 7:06:41from last week, string.h, which gives me some string-related functionality.
  8953. 7:06:44Int main void because I'm not going to bother with any command line
  8954. 7:06:47arguments for now.
  8955. 7:06:48And now if I want an array of strings, I could do something like this--
  8956. 7:06:53string names bracket 7.
  8957. 7:06:56And then I could start doing like before.
  8958. 7:06:58Names bracket 0 could be someone like Bill, and names bracket 1
  8959. 7:07:01could be someone like Charlie and so forth.
  8960. 7:07:05But there's this new improvement I can make.
  8961. 7:07:08Let me just let the compiler figure out how many names there are.
  8962. 7:07:11And using curly braces, I'll do Bill and then Charlie and then Fred and then
  8963. 7:07:16George and then Ginny and then Percy and then Ron if there's the pattern there.
  8964. 7:07:24All right, so now I have these seven names as strings.
  8965. 7:07:27Let's do something similar.
  8966. 7:07:28So for int, i get 0.
  8967. 7:07:32i is less than 7 as before, i plus plus as before.
  8968. 7:07:35And inside of the, loop lets this time check for the string in question,
  8969. 7:07:39and suppose we're searching for Ron arbitrarily.
  8970. 7:07:41He is there, so we should eventually find him.
  8971. 7:07:44Let me go ahead and say if names bracket i equals quote unquote Ron, then inside
  8972. 7:07:51of my if condition, I'm going to say printf found just like before.
  8973. 7:07:55And I'm going to return 0 just because all is well.
  8974. 7:07:57And I'm going to take your advice from the get go this time
  8975. 7:08:00and, at the end of the loop, print out not found because if I get this far,
  8976. 7:08:04I have not printed found, and I have not returned already.
  8977. 7:08:08So I'm just going to go ahead and return 1 after printing not found.
  8978. 7:08:12All right, let me go ahead and cross my fingers as always.
  8979. 7:08:14Make names this time.
  8980. 7:08:17And it doesn't seem to like my code here.
  8981. 7:08:20This is perhaps a new error that you might not
  8982. 7:08:22have seen yet in names.c line 11.
  8983. 7:08:25So that's this line here, my if condition.
  8984. 7:08:28Result of comparison against a string literal is unspecified.
  8985. 7:08:32Use an explicit string comparison function instead.
  8986. 7:08:34I mean, that's kind of a mouthful, and the first time you see it,
  8987. 7:08:37you're probably not going to know how to make sense of that.
  8988. 7:08:39But it does kind of draw our attention to something being awry
  8989. 7:08:43with the equality checking here, with equal equals and Ron.
  8990. 7:08:48And here's where again we've been telling
  8991. 7:08:50sort of a white lie for the past couple of weeks.
  8992. 7:08:53Strings are a thing in C. Strings are a thing in programming.
  8993. 7:08:57But recall from last week, I did disclaim
  8994. 7:08:59there's no such thing as a string data type
  8995. 7:09:01technically because it's not a primitive in the way an int
  8996. 7:09:05and a float and a bool are that are sort of built into the language.
  8997. 7:09:08You can't just use equation equals to compare two strings.
  8998. 7:09:12You actually have to use a special function that's
  8999. 7:09:15in this header file we talked briefly about last week.
  9000. 7:09:18In that header file was string length or strlen.
  9001. 7:09:21But there's other functions instead as well.
  9002. 7:09:23Let me, in fact, go ahead and open up the manual pages.
  9003. 7:09:27And if we go to string.h--
  9004. 7:09:30let me scroll down a bit.
  9005. 7:09:32In string.h you can perhaps infer what function will probably take
  9006. 7:09:37the place of equals equals for today.
  9007. 7:09:40What do we want to use?
  9008. 7:09:41Yeah.
  9009. 7:09:42AUDIENCE: Strcmp?
  9010. 7:09:43DAVID J. MALAN: So strcmp, S-T-R-C-M-P, which apparently compares two strings.
  9011. 7:09:47And if I click on that, we'll see more information.
  9012. 7:09:49And indeed, if I click on strcmp, we'll see under the synopsis
  9013. 7:09:53that, OK, I need to use the CS50 header file and string.h, as I already have.
  9014. 7:09:58Here is its prototype, which is telling me
  9015. 7:10:02that strcmp takes two strings, S1 and S2, that
  9016. 7:10:05are presumably going to be compared.
  9017. 7:10:07And it returns an integer, which is interesting.
  9018. 7:10:09So let's read on.
  9019. 7:10:10The description of this function is that it compares two strings case
  9020. 7:10:14sensitively.
  9021. 7:10:15So uppercase or lowercase matters, just FYI.
  9022. 7:10:18And then let's look it the return value here.
  9023. 7:10:20The return value of this function returns an int less than 0
  9024. 7:10:25if S1 comes before S2, 0 if S1 is the same as S2, or an int greater than 0
  9025. 7:10:32if S1 comes after S2.
  9026. 7:10:35So the reason that this function returns an integer and not just a
  9027. 7:10:39bool, true or false, is that it actually will
  9028. 7:10:41allow us to sort these things eventually because if you can tell me
  9029. 7:10:45if two strings come in this order or in this order or they're the same,
  9030. 7:10:49you need three possible return values.
  9031. 7:10:51And a bool, of course, only gives you two,
  9032. 7:10:53but an int gives you like 4 billion even though we just need the 3.
  9033. 7:10:56So 0 or a positive number or a negative number is what this function returns.
  9034. 7:11:01And the documentation goes on to explain what we mean by ASCIIbetical order.
  9035. 7:11:06Recall that capital A is 65, capital B is 66,
  9036. 7:11:09and it's those underlying ASCII or Unicode
  9037. 7:11:12numbers that a computer uses to figure out whether something comes before it
  9038. 7:11:15or after it like in the dictionary.
  9039. 7:11:17But for our purposes now, we only care about equality.
  9040. 7:11:20So I'm going to go ahead and do this.
  9041. 7:11:22If I want to compare names bracket i against Ron,
  9042. 7:11:26I use stir compare or strcmp, names bracket i comma, quote unquote, Ron.
  9043. 7:11:33So it's a little more involved than actually
  9044. 7:11:35using equals equals, which does work for integers, longs,
  9045. 7:11:40and certain other values.
  9046. 7:11:41But for strings, it turns out we need to use a more powerful function.
  9047. 7:11:45Why?
  9048. 7:11:45Well, last week, recall what a string really is.
  9049. 7:11:47It's an array of characters.
  9050. 7:11:50And so whereas you can use equals equals for single characters,
  9051. 7:11:54strcmp, as we'll eventually see, is going
  9052. 7:11:56to compare multiple characters for us.
  9053. 7:11:58There's more logic there.
  9054. 7:11:59There's a loop needed, and that's why it comes with the string library.
  9055. 7:12:03But it doesn't just work out of the box with equals equals alone.
  9056. 7:12:06That would literally be comparing two things, not two arrays of things.
  9057. 7:12:10And we'll come back to this next week as to what's
  9058. 7:12:12really going on under the hood.
  9059. 7:12:14So let me go ahead and fix one bug that I just realized I made.
  9060. 7:12:18I want to check if the return value of str compare is equal to 0
  9061. 7:12:23because per the documentation, that meant they're the same.
  9062. 7:12:27All right, let me go ahead and make names this time.
  9063. 7:12:30Now it compiles.
  9064. 7:12:31Dot slash names, Enter, found.
  9065. 7:12:34And just as a sanity check, let's check someone outside the family.
  9066. 7:12:39Searching now for Hermione after recompiling the code,
  9067. 7:12:43after rerunning the code.
  9068. 7:12:44And she's not, in fact, found.
  9069. 7:12:46So here's just a similar implementation of linear search
  9070. 7:12:49not for integers this time but instead for strings,
  9071. 7:12:53the subtlety really being we need a helper function, str compare,
  9072. 7:12:57to actually do the legwork for us of comparing two arrays of characters.
  9073. 7:13:02All right, questions on either of these implementations-- yeah, in the middle?
  9074. 7:13:05AUDIENCE: So, if I do [INAUDIBLE]
  9075. 7:13:07DAVID J. MALAN: Ah, good question.
  9076. 7:13:08If I had not fixed what I claimed was a mistake earlier and I did this--
  9077. 7:13:12and we saw an example of this last week, actually.
  9078. 7:13:15If a function returns an integer, be it negative or positive or 0,
  9079. 7:13:21when you get back 0, the expression, the Boolean expression,
  9080. 7:13:25will be considered false.
  9081. 7:13:26So 0 equals false always.
  9082. 7:13:29If a function returns any positive number, or any negative number,
  9083. 7:13:33that's going to be interpreted as true even
  9084. 7:13:37if it's positive or negative, whether it's 1, negative 1, 2, negative 2.
  9085. 7:13:41And so if I did this, this would be saying the opposite.
  9086. 7:13:45So if I were to say this, if str compare of names bracket i and Hermione, that's
  9087. 7:13:51implicitly like saying this does not equal 0, or it means sort of is true,
  9088. 7:13:57but you don't want to check for true because, again, we're
  9089. 7:14:00comparing integers here.
  9090. 7:14:01So the reason I did 0 here in this case is
  9091. 7:14:05that it explicitly checks for the return value that means they're the same.
  9092. 7:14:08And yeah.
  9093. 7:14:09Follow up?
  9094. 7:14:10AUDIENCE: [INAUDIBLE]
  9095. 7:14:15DAVID J. MALAN: Yes, you might not have seen this yet,
  9096. 7:14:17but you can express the equivalent because if you
  9097. 7:14:20want to check if this is false, you can actually
  9098. 7:14:24use an exclamation point, known as a bang in programming,
  9099. 7:14:27that inverts the meaning.
  9100. 7:14:29So false becomes true, true becomes false.
  9101. 7:14:32So this would be another way of expressing it.
  9102. 7:14:34This is arguably a worse design, though, because the documentation explicitly
  9103. 7:14:39says you should be checking for 0 or a positive value
  9104. 7:14:43or a negative value, and this little trick, while correct,
  9105. 7:14:46and I think you can make a reasonable case for it, sort of hides that detail.
  9106. 7:14:49And I would argue instead for the first way,
  9107. 7:14:51checking for equals equals 0 instead.
  9108. 7:14:53And if that's a little subtle, not to worry.
  9109. 7:14:55We'll come back to little syntactic tricks like that before long.
  9110. 7:15:00Other questions on linear search in these two forms.
  9111. 7:15:05Is there another hand or hands?
  9112. 7:15:06Two hands?
  9113. 7:15:08No?
  9114. 7:15:08OK, just holler if I missed.
  9115. 7:15:10So let's now actually take this one step further.
  9116. 7:15:12Suppose that we want to write a program that maybe implements something
  9117. 7:15:15a little more like a phone book that has both names and numbers and not
  9118. 7:15:19just integers but actual phone numbers.
  9119. 7:15:21Well, we could escalate things like this.
  9120. 7:15:23We could now have two arrays-- one called names, one called numbers.
  9121. 7:15:27And I'm going to use strings for the numbers now,
  9122. 7:15:29the phone numbers, because in most communities,
  9123. 7:15:32phone numbers might have dashes, pluses, parentheses, so something
  9124. 7:15:36that really looks more like a string even though we call it a phone number.
  9125. 7:15:39Probably don't want to use an int lest we throw away those kinds of details.
  9126. 7:15:42So let me switch back to VS Code here, and let's do one more program, this one
  9127. 7:15:47in a file called phonebook.c.
  9128. 7:15:49And now let me go ahead and do the same.
  9129. 7:15:51Let me include cs50.h.
  9130. 7:15:52Let me include standardio.h, and let me include string.h.
  9131. 7:15:58I'm going to again do int main void.
  9132. 7:16:01And then inside of my program, I'm going to give myself two arrays--
  9133. 7:16:05the efficient way this time.
  9134. 7:16:06String names will be just two of us this time.
  9135. 7:16:09How about Carter and me?
  9136. 7:16:12And then I'll give myself-- oops, typo already.
  9137. 7:16:15If I want this to be an array, I don't have to specify the number.
  9138. 7:16:18The compiler can count for me.
  9139. 7:16:19But I do need the square brackets.
  9140. 7:16:21Then for numbers, I'm again going to use a string array specifying with
  9141. 7:16:28the curly braces that how about Carter can be at 1-617-495-1000.
  9142. 7:16:33And how about my own number here--
  9143. 7:16:351-949-468-- oh pattern appearing--
  9144. 7:16:392750 will be mine.
  9145. 7:16:42Why mine?
  9146. 7:16:42Well, I'm just kind of lined things up.
  9147. 7:16:44So Carter's number is apparently first in this array,
  9148. 7:16:47and I'm claiming that he'll be first in this array, respectively.
  9149. 7:16:51I, David, will be the first-- the second in the names array
  9150. 7:16:53and second in the numbers array.
  9151. 7:16:56If you want to have a little fun with programming, feel free to text
  9152. 7:16:59or call me some time at that number.
  9153. 7:17:01So now let's actually use this data in some way.
  9154. 7:17:05Let's go ahead and actually search for my own name and number here.
  9155. 7:17:08So let me do.
  9156. 7:17:09For int i, get 0.
  9157. 7:17:11There's two of us this time-- so i less than 2 and then i plus plus as before.
  9158. 7:17:16And now I'm going to practice what I preached earlier,
  9159. 7:17:18and I'm going to use str compare to find my name in this case.
  9160. 7:17:22And I'm going to say if strcmp of names bracket i equals quote unquote David
  9161. 7:17:29and that equals 0, meaning they're the same,
  9162. 7:17:33then just as before, I'm going to go ahead and print something out.
  9163. 7:17:35But this time, I'm going to make the program more useful
  9164. 7:17:37and not just say found or not found.
  9165. 7:17:39Now I'm implementing a phone book, like the contacts app on iOS or Android.
  9166. 7:17:43So I'm going to say something like, quote unquote, found percent
  9167. 7:17:46s backslash n and then actually plug in numbers bracket i
  9168. 7:17:53to correspond to the current name bracket i.
  9169. 7:17:56And then I'll return 0 as before.
  9170. 7:17:58And then down here if we get all the way through the loop
  9171. 7:18:00and David's not there for some reason, I'm going to print as before not found
  9172. 7:18:04and then return 1.
  9173. 7:18:05So let me go ahead and compile this with make phone dot slash phonebook,
  9174. 7:18:10and it seems to have found the number.
  9175. 7:18:13So this code I'm going to claim is correct.
  9176. 7:18:17It's kind of stupid because I've just made a phone book or a contacts
  9177. 7:18:20app that only supports two people.
  9178. 7:18:22They're only going to be me and Carter.
  9179. 7:18:23This would be like downloading the contacts app on a phone
  9180. 7:18:26and you can only call two people in the world.
  9181. 7:18:28There's no ability to add names or edit things.
  9182. 7:18:30That, of course, could come later using get string or something else.
  9183. 7:18:33But for now for the sake of discussion, I've
  9184. 7:18:35just hardcoded two names and two numbers.
  9185. 7:18:37But for what it does, I claim this is correct.
  9186. 7:18:40It's going to find me and print out my number.
  9187. 7:18:43But is it well-designed?
  9188. 7:18:45Let's start to now consider if we're not just using arrays,
  9189. 7:18:49but are we using them, well?
  9190. 7:18:52We started to use them last week, but are we using them well this week?
  9191. 7:18:55And what might I even mean by using an array well or designing
  9192. 7:18:59this program well?
  9193. 7:19:01Any critiques or concerns with why this might not
  9194. 7:19:06be the best road for us to be going down when
  9195. 7:19:08I want to implement something like a phone book with pieces of information?
  9196. 7:19:12It seems all too vulnerable to just mistakes.
  9197. 7:19:15For instance, if I screw up the actual number of names in the names array
  9198. 7:19:19such that it's now more or less than is in the numbers array or vise versa,
  9199. 7:19:24it feels like there's not a tight relationship between those pieces
  9200. 7:19:27of data, and it's just sort of is trusting on the honor system
  9201. 7:19:31that any time I use names bracket i that it lines up with numbers bracket i.
  9202. 7:19:37And that's fine.
  9203. 7:19:38If you're the one writing the code, you're probably
  9204. 7:19:40not going to really screw this up.
  9205. 7:19:42But if you start collaborating with someone else or the program
  9206. 7:19:44is getting much, much longer, the odds that you or your colleagues
  9207. 7:19:48remember that you're sort of just trusting that names and numbers line up
  9208. 7:19:52like this is going to fail eventually.
  9209. 7:19:54Someone's not going to realize that, and just, the code is going to break.
  9210. 7:19:57And you're going to start out putting the wrong numbers for names, which
  9211. 7:20:00is to say it'd be much nicer if we could somehow couple these two
  9212. 7:20:05pieces of data, names and numbers, a little more tightly together so
  9213. 7:20:09that you're not just trusting that these two independent variables, names
  9214. 7:20:13and numbers, have this kind of relationship with themselves.
  9215. 7:20:16So let's consider how we might solve this.
  9216. 7:20:19A new feature today that we'll introduce is generally known as a data structure.
  9217. 7:20:23In C, we have the ability to invent our own data types,
  9218. 7:20:27if you will-- data types that the authors of C decades
  9219. 7:20:30ago just didn't envision or just didn't think
  9220. 7:20:32were necessary because we can implement them ourselves-- similar to Scratch
  9221. 7:20:36just as you could create custom puzzle pieces,
  9222. 7:20:38or in C, you can create custom functions.
  9223. 7:20:40So in C, can you create your own types of data
  9224. 7:20:45that go beyond the built in ints and floats and even strings?
  9225. 7:20:49You can make, for instance, a person data type or a candidate data
  9226. 7:20:54type in the context of elections or a person data type
  9227. 7:20:57more generically that might have a name and a number.
  9228. 7:21:00So how might we do this?
  9229. 7:21:02Well, let me go here and propose that if we want to define a person,
  9230. 7:21:07wouldn't it be nice if we could have a person data type,
  9231. 7:21:11and then we could have an array called people?
  9232. 7:21:13And maybe that array is our only array with two things
  9233. 7:21:17in it, two persons in it.
  9234. 7:21:19But somehow, those data types, these persons,
  9235. 7:21:22would have both a name and a number associated with them.
  9236. 7:21:25So we don't need two separate arrays.
  9237. 7:21:27We need one array of persons, a brand new data type.
  9238. 7:21:31So how might we do this?
  9239. 7:21:33Well, if we want every person in the world
  9240. 7:21:35or in this program to have a name and a number,
  9241. 7:21:37we literally right out first those two data types.
  9242. 7:21:40Give me a string called name.
  9243. 7:21:42Give me a string called number semicolon, after each.
  9244. 7:21:45And then we wrap that, those two lines of code,
  9245. 7:21:48with this syntax, which at first glance is a little cryptic.
  9246. 7:21:51It's a lot of words all of a sudden.
  9247. 7:21:52But typedef is a new keyword today that defines a new data type.
  9248. 7:21:57This is the C key word that lets you create your own data
  9249. 7:22:00type for the very first time.
  9250. 7:22:02Struct is another related key word that tells the compiler that this isn't just
  9251. 7:22:07a simple data type, like an int or a float renamed or something like that.
  9252. 7:22:11It actually is a structure.
  9253. 7:22:13It's got some dimensions to it, like two things in it or three things in it
  9254. 7:22:17or even 50 things inside of it.
  9255. 7:22:19The last word down here is the name that you want to give your data type,
  9256. 7:22:23and it weirdly goes after the curly braces.
  9257. 7:22:26But this is how you invent a data type called person.
  9258. 7:22:30And what this code is implying is that henceforth,
  9259. 7:22:33the compiler clang will know that a person is composed of a name that's
  9260. 7:22:38a string and a number that's a string.
  9261. 7:22:41And you don't have to worry about having multiple arrays now.
  9262. 7:22:44You can just have an array of people moving forward.
  9263. 7:22:48So how can we go about using this?
  9264. 7:22:50Well, let me go back to my code from before where
  9265. 7:22:52I was implementing a phone book.
  9266. 7:22:53And why don't we enhance the phone book code a little bit
  9267. 7:22:56by borrowing some of that new syntax?
  9268. 7:22:58Let me go to the top of my program above main
  9269. 7:23:01and define a type that's a structure or a data
  9270. 7:23:04structure that has a name inside of it and that has a number inside of it.
  9271. 7:23:08And the name of this new structure again is going to be called person.
  9272. 7:23:12Inside of my code now, let me go ahead and delete this old stuff temporarily.
  9273. 7:23:17Let me give myself an array called people of size 2.
  9274. 7:23:21And I'm going to use the non-terse way to do this.
  9275. 7:23:25I'm not going to use the curly braces.
  9276. 7:23:26I'm going to more pedantic spell out what I want in this array of size 2
  9277. 7:23:31at location 0, which is the first person in an array
  9278. 7:23:35because you always start counting at 0.
  9279. 7:23:37I'm going to give that person a name of quote unquote Carter.
  9280. 7:23:40And the dot is admittedly one new piece of syntax today too.
  9281. 7:23:44The dot means go inside of that structure
  9282. 7:23:46and access the variable called name and give it this value Carter.
  9283. 7:23:50Similarly, if I'm going to give Carter a number,
  9284. 7:23:52I can go into people bracket 0 dot number and give that the same thing
  9285. 7:23:57as before plus 1-617-495-1000.
  9286. 7:24:02And then I can do the same for myself here--
  9287. 7:24:04people bracket-- where should I go?
  9288. 7:24:08OK, one because again, two elements.
  9289. 7:24:10But we started counting at zero.
  9290. 7:24:11Bracket name equals quote unquote David.
  9291. 7:24:13And then lastly, people bracket 1 dot number equals quote unquote plus
  9292. 7:24:181-949-468-2750.
  9293. 7:24:24So now if I scroll down here to my logic,
  9294. 7:24:27I don't think this part needs to change too much.
  9295. 7:24:30I'm still, for the sake of discussion, going to iterate 2 times from i
  9296. 7:24:35is 0 on up to but not through 2.
  9297. 7:24:37But I think this line of code needs to change.
  9298. 7:24:41How should I now refer to the i-th person's name as I iterate?
  9299. 7:24:49What should I compare quote unquote David to this time?
  9300. 7:24:52Let me see.
  9301. 7:24:53On the end here?
  9302. 7:24:54AUDIENCE: People bracket i dot name.
  9303. 7:24:57DAVID J. MALAN: Yeah, people bracket i dot name.
  9304. 7:24:59Why?
  9305. 7:24:59Because people is the name of the array.
  9306. 7:25:01Bracket i is the i-th person that we're iterating over in the current loop--
  9307. 7:25:04first zero, then one, maybe higher if it had more people.
  9308. 7:25:07Then dot is our new syntax for going inside of a data structure
  9309. 7:25:10and accessing a variable therein which in this case is name.
  9310. 7:25:14And so I can compare David just as before.
  9311. 7:25:16So it's a little more verbose, but now arguably this is a better program
  9312. 7:25:21because now these people are full fledged data types unto themselves.
  9313. 7:25:26There's no more honor system inside of my loop
  9314. 7:25:29that this is going to line up because in just a moment,
  9315. 7:25:31I'm going to fix this one last remnant of the previous version.
  9316. 7:25:34And if I can call back on you again, what should I
  9317. 7:25:36change numbers bracket i to this time?
  9318. 7:25:39AUDIENCE: [INAUDIBLE] dot number.
  9319. 7:25:45DAVID J. MALAN: Dot number, exactly.
  9320. 7:25:46So gone is the honor system that just assumes
  9321. 7:25:49that bracket i in this array lines up with bracket i in this other array.
  9322. 7:25:52Now why?
  9323. 7:25:53There's only one array.
  9324. 7:25:54It's an array called people.
  9325. 7:25:56The things it stores are persons.
  9326. 7:25:58A person has a name and a number.
  9327. 7:26:00And so even though it's kind of marginal admittedly given
  9328. 7:26:02that this is a short program and given that this kind of made things
  9329. 7:26:05look more complicated at first glance, we're
  9330. 7:26:07now laying the foundation for just a better design because you really
  9331. 7:26:10can't screw up now the association of names
  9332. 7:26:13with numbers because every person's name and number is, so to speak,
  9333. 7:26:17encapsulated inside of the same data type.
  9334. 7:26:21And that's a term of art in CS.
  9335. 7:26:22Encapsulation means to encapsulate-- that is, contain--
  9336. 7:26:26related pieces of information.
  9337. 7:26:28And thus, we have a person that encapsulates two other data types, name
  9338. 7:26:34and number.
  9339. 7:26:34And this just sets the foundation for all
  9340. 7:26:36of the cool stuff we've talked about and you use every day.
  9341. 7:26:39What is an image?
  9342. 7:26:40Well, recall that an image is a bunch of pixels or dots on the screen.
  9343. 7:26:43Every one of those dots has RGB values associated
  9344. 7:26:46with it-- red, green, and blue.
  9345. 7:26:48You could imagine now creating a structure in C probably where
  9346. 7:26:52maybe you have three values, three variables-- one called red,
  9347. 7:26:55one called green, one called blue.
  9348. 7:26:57And then you could name the thing not person but pixel.
  9349. 7:27:00And now you could store in C three different colors-- some amount of red,
  9350. 7:27:04some green, some blue-- and collectively treat it as the color of a pixel.
  9351. 7:27:08And you could imagine doing something similar perhaps for video or music.
  9352. 7:27:11Music, you might have three variables-- one for the musical note,
  9353. 7:27:14the duration, the loudness of it.
  9354. 7:27:17And you can imagine coming up with your own data type for music as well.
  9355. 7:27:20So this is a little low level.
  9356. 7:27:21We're just using like a familiar contacts application.
  9357. 7:27:24But we now have the way in code to express most any type of data
  9358. 7:27:28that we might want to implement or discuss ultimately.
  9359. 7:27:32So any questions now on struct or defining our own types,
  9360. 7:27:37the purposes for which are to use arrays but use them more responsibly
  9361. 7:27:42now in a better design but also to lay the foundation
  9362. 7:27:45for implementing cooler and cooler stuff per our week zero discussion?
  9363. 7:27:50Yeah.
  9364. 7:27:50AUDIENCE: What's the [INAUDIBLE]
  9365. 7:27:52DAVID J. MALAN: What's the difference between this and an object in an object
  9366. 7:27:55oriented language?
  9367. 7:27:55So slight side note, C is not object-oriented.
  9368. 7:27:58Languages like Java and C++ and others which you might have heard
  9369. 7:28:02of, programmed yourself, had friends program in, are object oriented
  9370. 7:28:05languages in those languages they have things called classes or objects which
  9371. 7:28:09are interrelated.
  9372. 7:28:10And objects can store not just data, like variables.
  9373. 7:28:14Objects can also store functions, and you can kind of sort of do this in C.
  9374. 7:28:18But it's not sort of conventional.
  9375. 7:28:20In C, you have data structures that store data.
  9376. 7:28:24In languages like Java and C+, you have objects that store data and functions
  9377. 7:28:29together.
  9378. 7:28:29Python is an object-oriented language as well.
  9379. 7:28:32So we'll see this issue in a few weeks, but let me wave my hands at it for now.
  9380. 7:28:35Yeah.
  9381. 7:28:36AUDIENCE: Could you use this [INAUDIBLE]??
  9382. 7:28:38DAVID J. MALAN: Yes.
  9383. 7:28:38Could you use this struct to redefine how an int is defined?
  9384. 7:28:41Short answer, yes.
  9385. 7:28:42We talked a couple of times now about integer overflow.
  9386. 7:28:46And most recently, you might have seen me mention the bug in iOS and Mac OS
  9387. 7:28:50that was literally related to an int overflow.
  9388. 7:28:52That's the result of ints only storing 4 bytes or 32 bits
  9389. 7:28:57or even as long as 64 bits or 8 bytes.
  9390. 7:29:00But it's finite.
  9391. 7:29:01But if you want to implement some financial software
  9392. 7:29:03or some scientific or mathematical software that
  9393. 7:29:06allows you to count way bigger than a typical int or a long,
  9394. 7:29:10you could imagine John coming up with your own structure.
  9395. 7:29:13And in fact, in some languages there is a structure
  9396. 7:29:15called big int, which allows you to express even bigger numbers.
  9397. 7:29:19How?
  9398. 7:29:20Well, maybe you store inside of a big ant an array of values.
  9399. 7:29:24And you somehow allow yourself to store more and more bits
  9400. 7:29:27based on how high you want to be able to count.
  9401. 7:29:29So in short, yes.
  9402. 7:29:30We now have the ability now to do most anything we want in the language
  9403. 7:29:34even if it's not built in for us.
  9404. 7:29:36Other questions.
  9405. 7:29:37AUDIENCE: [INAUDIBLE]
  9406. 7:29:43DAVID J. MALAN: Could you define a name and a number in the same line?
  9407. 7:29:45Sort of.
  9408. 7:29:46It starts to get syntactically a little messy,
  9409. 7:29:48so I did it a little more pedantic line by line.
  9410. 7:29:51Good question.
  9411. 7:29:52Over here.
  9412. 7:29:52AUDIENCE: [INAUDIBLE] function you use for the function
  9413. 7:29:57at the bottom of the [INAUDIBLE].
  9414. 7:29:59Could you do something like that [INAUDIBLE]??
  9415. 7:30:03DAVID J. MALAN: Prototypes-- you have to do A and C. You
  9416. 7:30:05have to define anything you're going to use or declare anything you're going
  9417. 7:30:09to use before you actually use it.
  9418. 7:30:11So it is deliberate that I put it at the top of my code in this file.
  9419. 7:30:15Otherwise, the compiler would not know what I mean by person when I first
  9420. 7:30:19use it here on what's line 14.
  9421. 7:30:22So it has to come first, or it has to be put into something like a header file
  9422. 7:30:25so that you include it at the very top of your code.
  9423. 7:30:29Other questions over here.
  9424. 7:30:31Yeah.
  9425. 7:30:32AUDIENCE: [INAUDIBLE]
  9426. 7:30:37DAVID J. MALAN: Yeah, good question, and we'll
  9427. 7:30:39come back to this later in the term when we talk about SQL, a database language,
  9428. 7:30:42and storing things in actual databases.
  9429. 7:30:44Generally speaking, even though we humans call things phone numbers,
  9430. 7:30:48or in the US, we have social security numbers, those types of numbers
  9431. 7:30:52often have other punctuation in it, like dashes, parentheses, pluses,
  9432. 7:30:56and so forth.
  9433. 7:30:57You could not store any of that syntax or that punctuation inside of an int.
  9434. 7:31:01You could only store numbers.
  9435. 7:31:03So one motivation for using a string is just
  9436. 7:31:05I can store whatever the human wanted me to store, including parentheses
  9437. 7:31:08and so forth.
  9438. 7:31:10Another reason for storing things as strings,
  9439. 7:31:13even if they look like numbers, is in the context
  9440. 7:31:15of zip codes in the United States.
  9441. 7:31:17Again, we'll come back to this.
  9442. 7:31:18But long story short-- years ago, actually--
  9443. 7:31:21I was using Microsoft Outlook for my email client.
  9444. 7:31:24And eventually I switched to Gmail.
  9445. 7:31:25And this is like 10 plus years ago now.
  9446. 7:31:27And Outlook at the time lets you export all of your contacts as a CSV file--
  9447. 7:31:31Comma Separated Values.
  9448. 7:31:33More on that in the weeks to come too.
  9449. 7:31:34And that just means I could download a text
  9450. 7:31:36file with all of my friends and family and their numbers inside of it.
  9451. 7:31:40Unfortunately, I open that same CSV file with Excel, I think, at the time
  9452. 7:31:44just to kind of spot check it and see if what's
  9453. 7:31:46in there was what it was expected.
  9454. 7:31:47And I must have instinctively hit, like, Command or Control-S to save it.
  9455. 7:31:51And Excel at least has this habit of sort of reformatting your data.
  9456. 7:31:54If things look like numbers, it treats them as numbers.
  9457. 7:31:56And Apple Numbers does this too.
  9458. 7:31:58Google Spreadsheets does this to nowadays.
  9459. 7:32:00But long story short, I then imported my mildly saved CSV file into Gmail.
  9460. 7:32:07And now 10 plus years later, I'm still occasionally finding friends and family
  9461. 7:32:11members whose zip codes are in Cambridge, Massachusetts 2138,
  9462. 7:32:17which is missing the 0 because we here in Cambridge are 02138.
  9463. 7:32:20And that's because I treated or I let Excel
  9464. 7:32:23treat what looks like a number as an actual number or int,
  9465. 7:32:26and now leading zeros become a problem because mathematically, they
  9466. 7:32:29mean nothing, but in the mail system, they do--
  9467. 7:32:33sending envelopes and such.
  9468. 7:32:34All right, other final questions here.
  9469. 7:32:36AUDIENCE: [INAUDIBLE]
  9470. 7:32:39DAVID J. MALAN: Yeah, so could I have used a 2D or two dimensional
  9471. 7:32:42array to solve the problem earlier of having just one array?
  9472. 7:32:47Yes, but one, I would argue it's less readable, especially
  9473. 7:32:51as I get lots of names and numbers.
  9474. 7:32:53And two, that too is also kind of relying on the honor system.
  9475. 7:32:56It would be all too easy to omit some of the square brackets in the two
  9476. 7:32:59dimensional array.
  9477. 7:33:00So I would argue it too is not as good as introducing a struct.
  9478. 7:33:04More on that down the road.
  9479. 7:33:05Two dimensional arrays just means arrays of arrays, as you might infer.
  9480. 7:33:10All right, so now that we have this ability
  9481. 7:33:12to store different types of data like contacts in a phone book,
  9482. 7:33:16having names and addresses, let's actually
  9483. 7:33:18take a step back and consider how we might now
  9484. 7:33:21solve one of the original problems by actually sorting the information we're
  9485. 7:33:26given in advance and considering, per our discussion earlier, just how
  9486. 7:33:30costly, how time consuming is that because that might tip
  9487. 7:33:33the scales in favor of sorting, then searching, or maybe just
  9488. 7:33:37not sorting and only searching.
  9489. 7:33:39It'll give us a sense of just how expensive, so to speak,
  9490. 7:33:42sorting something actually is.
  9491. 7:33:44Well, what's the formulation of this problem?
  9492. 7:33:46It's the same thing as week zero.
  9493. 7:33:48We've got input to sort.
  9494. 7:33:49We want it to be output as sorted.
  9495. 7:33:51So for instance, if we're taking unsorted input as input,
  9496. 7:33:54we want the sorted output as the result. More concretely,
  9497. 7:33:58if we've got numbers like these--
  9498. 7:33:5963852741, which are just randomly arranged numbers--
  9499. 7:34:04we want to get back out 12345678.
  9500. 7:34:08So we just want those things to be sorted.
  9501. 7:34:10So again, inside of the black box here is
  9502. 7:34:12going to be one or more algorithms that actually gets this job done.
  9503. 7:34:17So how might we go about doing this?
  9504. 7:34:20Well, just to vary things a bit more, I think we have a chance here
  9505. 7:34:23for a bit more audience participation.
  9506. 7:34:25But this time, we need eight people if we may.
  9507. 7:34:28All of you have to be comfortable appearing on the internet.
  9508. 7:34:30OK, so this is actually quite convenient that you're all quite close.
  9509. 7:34:33How about 1, 2, 3, 4, 5, 6, 7--
  9510. 7:34:37oh, OK, and someone volunteering their friend-- number eight.
  9511. 7:34:41Come on down.
  9512. 7:34:42Come on down.
  9513. 7:34:43And if you could, I'm going to set things up.
  9514. 7:34:45If you all could join Valerie, my colleague over there,
  9515. 7:34:47to give you a prop to use here, we'll go ahead in just a moment
  9516. 7:34:53and try to find some numbers at hand.
  9517. 7:34:59In just a moment, each of our volunteers is going to be representing an integer.
  9518. 7:35:05And that integer is initially going to be in unsorted order.
  9519. 7:35:09And I claim that using an algorithm, step by step instructions,
  9520. 7:35:13we can probably sort these folks in at least a couple of different ways.
  9521. 7:35:18So they're in wardrobe right now just getting their very own Harvard T-shirts
  9522. 7:35:22with a Jersey number on it, which will then represent an element of our array.
  9523. 7:35:31Give us just a moment to finish getting the attire ready.
  9524. 7:35:35They're being handed a shirt and a number.
  9525. 7:35:40And let me ask the audience for just a moment.
  9526. 7:35:42As we have these numbers up here on the screen, these numbers too are unsorted.
  9527. 7:35:47They're just in random order.
  9528. 7:35:48And let me ask the audience.
  9529. 7:35:49How would you go about sorting these eight numbers on the screen?
  9530. 7:35:55How would you go about sorting these?
  9531. 7:35:57Yeah, what are your thoughts?
  9532. 7:35:58AUDIENCE: [INAUDIBLE] the number at the end, the following number.
  9533. 7:36:04DAVID J. MALAN: OK.
  9534. 7:36:05AUDIENCE: The following number is bigger, then I keep it as it is.
  9535. 7:36:08DAVID J. MALAN: OK.
  9536. 7:36:09AUDIENCE: If not, then [INAUDIBLE].
  9537. 7:36:11DAVID J. MALAN: OK, so just to recap, you would start
  9538. 7:36:13with one of the numbers on the end.
  9539. 7:36:15You would look to the number to the right or to the left of it,
  9540. 7:36:17depending on which end you start at.
  9541. 7:36:18And if it's out of order, you would just start to swap things.
  9542. 7:36:21And that seems reasonable.
  9543. 7:36:22There's a whole bunch of mistakes to fix here
  9544. 7:36:24because things are pretty out of order.
  9545. 7:36:26But probably, if you start to solve small problems at a time,
  9546. 7:36:29you can achieve the end result of getting the whole thing sorted.
  9547. 7:36:32Other instincts, if you were just handed these numbers, how
  9548. 7:36:35you might go about sorting them?
  9549. 7:36:38How might you?
  9550. 7:36:39Yeah, in the back.
  9551. 7:36:40AUDIENCE: [INAUDIBLE]
  9552. 7:36:44DAVID J. MALAN: OK, I like that.
  9553. 7:36:46So to recap there, find the smallest one first and put it at the beginning,
  9554. 7:36:50if I heard you correctly.
  9555. 7:36:51And then presumably, you could do that again and again and again.
  9556. 7:36:54And that would seem to give you a couple of different algorithms.
  9557. 7:36:57And if you all are attired here--
  9558. 7:37:00do you want to come on up if you're ready?
  9559. 7:37:03We had some [? felt ?] volunteers too.
  9560. 7:37:05Come on over.
  9561. 7:37:07So if you all would like to line yourselves up
  9562. 7:37:09facing the audience in exactly this order-- so
  9563. 7:37:12whoever is number zero should be way over here,
  9564. 7:37:14and whoever is number five should be way over there.
  9565. 7:37:18Feel free to distance as much as you'd like and scooch a little with this way
  9566. 7:37:21if you could.
  9567. 7:37:22OK, all right.
  9568. 7:37:24And make a little more room.
  9569. 7:37:25So seven-- let's see.
  9570. 7:37:265, 2, 7, 4--
  9571. 7:37:28AUDIENCE: [INAUDIBLE]
  9572. 7:37:29DAVID J. MALAN: 4, hopefully 1.
  9573. 7:37:31Yeah, keep them to the side.
  9574. 7:37:32OK, 1, 6, and there we go--
  9575. 7:37:353.
  9576. 7:37:36Come on over, three.
  9577. 7:37:36I was looking for you.
  9578. 7:37:38All right, so here, we have an array of eight numbers--
  9579. 7:37:41eight integers if you will.
  9580. 7:37:42And do you want to each say a quick hello to the group?
  9581. 7:37:45AUDIENCE: Hello, I'm Quinn.
  9582. 7:37:47Go [INAUDIBLE].
  9583. 7:37:49AUDIENCE: Hi, everyone.
  9584. 7:37:50I'm [INAUDIBLE].
  9585. 7:37:52AUDIENCE: Hey, I'm Mitchell.
  9586. 7:37:53AUDIENCE: Hi, I'm Brett.
  9587. 7:37:54And also, go [INAUDIBLE].
  9588. 7:37:57AUDIENCE: I'm Hannah.
  9589. 7:37:57Go [INAUDIBLE].
  9590. 7:37:59AUDIENCE: Hi, I'm Matthew.
  9591. 7:38:00Go [INAUDIBLE]
  9592. 7:38:02AUDIENCE: Hi, I'm Miriam.
  9593. 7:38:03Go Winthrop.
  9594. 7:38:05AUDIENCE: Hi, I'm Celeste, and go Strauss.
  9595. 7:38:07DAVID J. MALAN: Wonderful.
  9596. 7:38:08Well, welcome all to the stage, and let's just visualize,
  9597. 7:38:11perhaps organically, how you eight would solve this problem.
  9598. 7:38:13So we currently have the numbers 0 through 7 quite out of order.
  9599. 7:38:16Could you go ahead and just yourselves from 0 through 7?
  9600. 7:38:20AUDIENCE: Thank you.
  9601. 7:38:25DAVID J. MALAN: OK, so what did they just do?
  9602. 7:38:28OK, yes.
  9603. 7:38:29First of all, yes, very well done.
  9604. 7:38:34How would you describe what they just did?
  9605. 7:38:37Well, let's do this.
  9606. 7:38:38Could you go back into that order on the screen--
  9607. 7:38:4052741630?
  9608. 7:38:44And could you do exactly what you just did again?
  9609. 7:38:47Sort yourselves.
  9610. 7:38:52All right, what did--
  9611. 7:38:53OK, yes.
  9612. 7:38:53Well done again.
  9613. 7:38:58All right, so admittedly, there's kind of a lot going on because each of you,
  9614. 7:39:01except number four, are doing something in parallel all at the same time.
  9615. 7:39:05And that's not really how a computer typically works.
  9616. 7:39:07Just like a computer can only look at one memory location, at one locker,
  9617. 7:39:11at a time, so can a computer only move one number at a time-- sort of opening
  9618. 7:39:15a locker, checking what's there, moving it as needed.
  9619. 7:39:18So let's try this more methodically based on the two audience suggestions.
  9620. 7:39:21If you all could randomize yourself again to 52741630,
  9621. 7:39:26let's take the second of those approaches first.
  9622. 7:39:29I'm going to look at these numbers.
  9623. 7:39:30And even though I as the human can obviously see all the numbers
  9624. 7:39:33and I just kind of have the intuition for how to fix this,
  9625. 7:39:35we got to be more methodical because eventually, we've
  9626. 7:39:37got to translate this to pseudo code and then code.
  9627. 7:39:39So let me see.
  9628. 7:39:40I'm going to search for, as you proposed, the smallest number.
  9629. 7:39:43And I'm going to start from left to right.
  9630. 7:39:45I could do it right to left, but left to right just tends to be convention.
  9631. 7:39:48All right, 5 at this moment is the smallest number I've seen.
  9632. 7:39:51So I'm going to remember that in a variable, if you will.
  9633. 7:39:54Now I'm going to take one more step--
  9634. 7:39:552.
  9635. 7:39:56OK, 2 I'm going to compare to the variable in mind, obviously smaller.
  9636. 7:39:59I'm going to forget about 5 and only now remember 2 as the now smallest
  9637. 7:40:03elements.
  9638. 7:40:047, nope-- I'm going to ignore that because it's not smaller than the 2
  9639. 7:40:07I have in mind.
  9640. 7:40:084, 1-- OK, I'm going to update the variable in mind
  9641. 7:40:11because that's indeed smaller.
  9642. 7:40:12Now obviously, we the humans know that's getting pretty small.
  9643. 7:40:15Maybe it's the end.
  9644. 7:40:16I have to check all values to see if there's something even smaller
  9645. 7:40:19because 6 is not, 3 is not, but 0 is.
  9646. 7:40:22And what's your name again?
  9647. 7:40:23AUDIENCE: Celeste.
  9648. 7:40:24DAVID J. MALAN: Celeste.
  9649. 7:40:25Where should Celeste or number 0 go according to this proposed algorithm?
  9650. 7:40:32All right, I'm seeing a lot of this.
  9651. 7:40:33So at the beginning of the array, so before doing this for real,
  9652. 7:40:37let's have you pop out in front.
  9653. 7:40:38And could you all shift and make room for Celeste?
  9654. 7:40:42Is this a good idea to have all of them move or equivalently
  9655. 7:40:46move everything in the array to make room for Celeste
  9656. 7:40:48and number 0 over there?
  9657. 7:40:51No, probably not.
  9658. 7:40:52That felt like a lot of work.
  9659. 7:40:53And even though it happened pretty quickly, that's like seven steps
  9660. 7:40:56to happen just to move her in place.
  9661. 7:40:58So what would be marginally smarter perhaps--
  9662. 7:41:00a little more efficient, perhaps?
  9663. 7:41:03What's that?
  9664. 7:41:03AUDIENCE: Swapping.
  9665. 7:41:04DAVID J. MALAN: Swapping.
  9666. 7:41:04What do you mean by swap?
  9667. 7:41:05AUDIENCE: Replacing swaps.
  9668. 7:41:07DAVID J. MALAN: OK, replace two values.
  9669. 7:41:08So if you want to go back to where you were, one step Over, number 5,
  9670. 7:41:12he's not in the right place.
  9671. 7:41:13He's got to move eventually.
  9672. 7:41:15So you know what?
  9673. 7:41:15If that's where Celeste belongs, why don't we just swap 5 and 0?
  9674. 7:41:18So if you want to go ahead and exchange places with each other.
  9675. 7:41:21Notice what's just happened.
  9676. 7:41:22The problem I'm trying to solve has gotten smaller.
  9677. 7:41:25Instead of being size 8, now it's size 7.
  9678. 7:41:28Now granted, I moved 5 to another wrong location.
  9679. 7:41:31But if these numbers started off randomly,
  9680. 7:41:33it doesn't really matter where 5 goes until we get him into the right place.
  9681. 7:41:37So I think we've improved.
  9682. 7:41:38And now if I go back, my loop is sort of coming back around.
  9683. 7:41:41I can ignore Celeste and make this a seven step problem and not eight
  9684. 7:41:46because I know she's in the right place.
  9685. 7:41:472 seems to be the smallest.
  9686. 7:41:49I'll remember that.
  9687. 7:41:50Not 7, not 4--
  9688. 7:41:511 seems to be the smallest.
  9689. 7:41:53Now I know as a human this should be my next smallest.
  9690. 7:41:57But why, intuitively, should I keep going, do you think?
  9691. 7:42:02I can't sort of optimize as a human and just say, number 1,
  9692. 7:42:05let's get you into the right place.
  9693. 7:42:07I still want to check the whole array.
  9694. 7:42:08Why?
  9695. 7:42:09Yeah.
  9696. 7:42:10AUDIENCE: Perhaps there's another 1.
  9697. 7:42:12DAVID J. MALAN: Maybe there's another 1, and that
  9698. 7:42:14could be another problem altogether.
  9699. 7:42:16Other thoughts?
  9700. 7:42:17Yeah.
  9701. 7:42:17AUDIENCE: Could be another 0
  9702. 7:42:18DAVID J. MALAN: There could be another 0 indeed,
  9703. 7:42:20but I did go through the list once, right?
  9704. 7:42:22And I kind of know there isn't.
  9705. 7:42:24Your thoughts?
  9706. 7:42:24AUDIENCE: You don't know that every value is represented.
  9707. 7:42:27So maybe there's a [INAUDIBLE] You just don't know what kind of data
  9708. 7:42:31you're working with.
  9709. 7:42:32DAVID J. MALAN: Yeah, I don't necessarily know what is there.
  9710. 7:42:34And honestly, I only stipulated earlier that I'm using one variable in my mind.
  9711. 7:42:39I could use two and remember the two smallest elements I've seen.
  9712. 7:42:42I could use three variables, four.
  9713. 7:42:44But then I'm going to start to use a lot of space in addition to time.
  9714. 7:42:47So if I've stipulated that I only have one variable to solve this problem,
  9715. 7:42:51I don't know anything more about these elements
  9716. 7:42:53because the only thing I'm remembering at this moment
  9717. 7:42:55is number 1 is the smallest element I've seen.
  9718. 7:42:57So I'm going to keep going.
  9719. 7:42:586?
  9720. 7:42:59Nope.
  9721. 7:42:593?
  9722. 7:42:59Nope.
  9723. 7:43:005?
  9724. 7:43:00Nope.
  9725. 7:43:01OK, I know that number 1, and your name was--
  9726. 7:43:03AUDIENCE: Hannah.
  9727. 7:43:03DAVID J. MALAN: --Hannah is the next smallest element.
  9728. 7:43:06I could have everyone move over to make room, but nope.
  9729. 7:43:082?
  9730. 7:43:09You know, even though you're so close to where I want you,
  9731. 7:43:11I'm just going to keep it simple and swap you two.
  9732. 7:43:13So granted, I've made the problem a little worse.
  9733. 7:43:15But on average, I could get lucky too and just pop number 2
  9734. 7:43:19into the right place.
  9735. 7:43:20Now let me just accelerate this.
  9736. 7:43:22I can now ignore Hannah and Celeste, making the problem size 6 instead of 8.
  9737. 7:43:26So it's getting smaller.
  9738. 7:43:287 is the smallest.
  9739. 7:43:29Nope, now 4 is--
  9740. 7:43:302 is the smallest.
  9741. 7:43:32Still 2, still 2, still 2.
  9742. 7:43:34So let's go ahead and swap 2 and 7.
  9743. 7:43:37And now I'll just kind of orchestrate it verbally.
  9744. 7:43:404, you're about to have to do something.
  9745. 7:43:42So we now have 4, 7, 6 3, 5.
  9746. 7:43:46OK, 3-- could you swap with 4?
  9747. 7:43:48All right, now we have 7, 6, 4, 5.
  9748. 7:43:52OK, 4, could you swap with 7?
  9749. 7:43:54Now we have 6, 7, 5.
  9750. 7:43:575, could you swap with 6?
  9751. 7:43:59And now we have 7, 6.
  9752. 7:44:016, would you swap at 7?
  9753. 7:44:02And now perhaps round of applause.
  9754. 7:44:04They've sorted themselves.
  9755. 7:44:05OK, hang on there one minute.
  9756. 7:44:09So we'll do this one other approach.
  9757. 7:44:11And my God, that felt so much slower than the first approach,
  9758. 7:44:14but that's, one, because I was kind of providing a long voiceover.
  9759. 7:44:17But two, we were doing one thing at a time whereas the first time, you guys
  9760. 7:44:22had the luxury of moving like eight different CPUs--
  9761. 7:44:25brains, if you will-- were all operating at the same time.
  9762. 7:44:28And computers like that exist.
  9763. 7:44:29If you have a computer with multiple cores, so to speak,
  9764. 7:44:32that's like having a computer that technically
  9765. 7:44:34can do multiple things at once.
  9766. 7:44:35But software typically, at least as we've written it thus far,
  9767. 7:44:38can only do one thing at a time.
  9768. 7:44:40So in a bit, we'll add up all of these steps.
  9769. 7:44:42But for now, let's take one other approach.
  9770. 7:44:44If you all could reorder yourselves like that--
  9771. 7:44:4652741630-- let's take the other approach that
  9772. 7:44:51was recommended by just fixing small problems and see where this gets us.
  9773. 7:44:54So we're back in the original order.
  9774. 7:44:575 and 2 are clearly out of order.
  9775. 7:44:59So you know what?
  9776. 7:44:59Let's just bite this problem off now.
  9777. 7:45:015 and 2, could you swap?
  9778. 7:45:03Now let me take a next step.
  9779. 7:45:045 and 7, I think you're OK.
  9780. 7:45:06There's a gap, yes, but that might not be a big deal.
  9781. 7:45:097 and 4-- problem.
  9782. 7:45:10Let's have you swap.
  9783. 7:45:12OK, 7 and 1, let's have you swap.
  9784. 7:45:157 and 6, let's have you swap.
  9785. 7:45:187 and 3, you swap.
  9786. 7:45:207 and 0, you swap.
  9787. 7:45:22Now let me pause for just a moment.
  9788. 7:45:23Still not sorted.
  9789. 7:45:25So I'm clearly not done.
  9790. 7:45:26But have I improved the problem?
  9791. 7:45:29Right, I can't see-- like before, I can't optimize like
  9792. 7:45:32before because 0 is obviously not here.
  9793. 7:45:34So unless they're still way back there, so it's not like I've gone from 8 steps
  9794. 7:45:38to 7 to 6 just yet.
  9795. 7:45:40But have I made any improvements?
  9796. 7:45:42AUDIENCE: Yes.
  9797. 7:45:42DAVID J. MALAN: Yes.
  9798. 7:45:43In what sense is this improved?
  9799. 7:45:45What's a concrete thing you could point to is better?
  9800. 7:45:50Yeah.
  9801. 7:45:50AUDIENCE: Sorted the highest number.
  9802. 7:45:52DAVID J. MALAN: I've sorted the highest number, which is indeed 7.
  9803. 7:45:55And conversely, if you prefer, Celeste is one step closer to the beginning.
  9804. 7:45:59Now worst case, Celeste is going to have to move one step on each iteration.
  9805. 7:46:04So I might need to do this thing like n total times
  9806. 7:46:06to move her all the way over.
  9807. 7:46:08But that might work out OK.
  9808. 7:46:09Let me see.
  9809. 7:46:102 and 5, you're good.
  9810. 7:46:125 and 4, swap you.
  9811. 7:46:135 and 1, let's swap you.
  9812. 7:46:155 and 6, you're good.
  9813. 7:46:166 and 3, let's swap you.
  9814. 7:46:186 and 0, let's swap you.
  9815. 7:46:216 and 7, you're good.
  9816. 7:46:22And I think now--
  9817. 7:46:23notice that the high values, as you noted,
  9818. 7:46:25are sort of bubbling up, if you will, to the end of the list.
  9819. 7:46:282 and 4, you're good.
  9820. 7:46:294 and 1, let's swap.
  9821. 7:46:314 and 5, good.
  9822. 7:46:325 and 3, swap.
  9823. 7:46:335 and 0, swap.
  9824. 7:46:365, 6, 7, of course, are good.
  9825. 7:46:37So now you can sort of see the problem resolving itself.
  9826. 7:46:40And let's just do this part now faster.
  9827. 7:46:422 and 1, 2 and 4.
  9828. 7:46:44OK, 4 and 3, 4 and 0.
  9829. 7:46:48All right, now 1 and 2, 2, and 3, and 0, and good.
  9830. 7:46:53So we do have some optimization there.
  9831. 7:46:54We don't need to keep going because those all are sorted.
  9832. 7:46:571 and 2, you're good.
  9833. 7:46:582 and 0, all right, done.
  9834. 7:47:011 and 0-- and big round of applause in closing.
  9835. 7:47:04OK, so thank you all.
  9836. 7:47:09We need the puppets back, but you can keep the shirts.
  9837. 7:47:11Thank you for volunteering here.
  9838. 7:47:13Feel free to make your way exits left or right.
  9839. 7:47:16And let's see if, thanks to our volunteers
  9840. 7:47:18here, we can't now formalize a little bit what we did on both passes here.
  9841. 7:47:24I claim that the first algorithm our volunteers kindly acted out
  9842. 7:47:28is what's called selection sort.
  9843. 7:47:30And as the name implied, we selected the smallest elements again and again
  9844. 7:47:35and again, working our way from left to right,
  9845. 7:47:37putting Celeste into the right place, and then continuing with everyone else.
  9846. 7:47:42So selection sort, as it's formally called,
  9847. 7:47:45can be described, for instance, with this pseudo code here--
  9848. 7:47:484i from 0 to n minus 1.
  9849. 7:47:51And again, why this?
  9850. 7:47:52This is just how talk about arrays.
  9851. 7:47:54The left end is 0, the right end is n minus 1 where in this case,
  9852. 7:47:59n happened to be eight people.
  9853. 7:48:01So that's 0 through 7.
  9854. 7:48:03So for i from 0 to n minus 1, what did I do?
  9855. 7:48:06I found the smallest number between numbers bracket i and numbers bracket
  9856. 7:48:11n minus 1.
  9857. 7:48:13It's a little cryptic at first glance, but this
  9858. 7:48:15is just a very pseudo code-like way of saying
  9859. 7:48:18find the smallest element among all eight volunteers
  9860. 7:48:22because if i starts at 0 and n minus 1 never changes because there's always
  9861. 7:48:278, 8 people, so 8 minus 1 is 7, this first
  9862. 7:48:31says find the smallest number between numbers bracket 0
  9863. 7:48:34and numbers bracket 7, if you will.
  9864. 7:48:37Then what do I do?
  9865. 7:48:38Swap the smallest number with numbers bracket i.
  9866. 7:48:42So that's how we got Celeste from over here all the way over there.
  9867. 7:48:45We just swapped those two values.
  9868. 7:48:47What then happens next in this pseudo code?
  9869. 7:48:50i, of course, goes from 0 to 1.
  9870. 7:48:52And that's the technical way of saying now
  9871. 7:48:54find the smallest element among the 7 remaining volunteers,
  9872. 7:48:58ignoring Celeste this time because she was already in the correct location.
  9873. 7:49:01So the problem went from size 8 to size 7.
  9874. 7:49:04And if we repeat, size 6, 5, 4, 3, 2, 1, until boom,
  9875. 7:49:07it's all done at the very end.
  9876. 7:49:10So this is just one way of expressing in pseudo code what
  9877. 7:49:13we did a little more organically and a formalization of what someone
  9878. 7:49:17volunteered out in the audience.
  9879. 7:49:19So if we consider, then, the efficiency of this algorithm,
  9880. 7:49:24maybe abstracting it away now as a bunch of doors
  9881. 7:49:27where the left most again is always 0, the right most is always n minus 1,
  9882. 7:49:31or equivalently, the second to last is n minus 2, the third to last
  9883. 7:49:34is n minus 3 where n might be 8 or anything else,
  9884. 7:49:38how do we think about or quantify the running time of selection sort?
  9885. 7:49:43Big O of what?
  9886. 7:49:46I mean, that was a lot of steps to be adding up.
  9887. 7:49:49It's probably more than n, right, because I went through the list
  9888. 7:49:53again and again.
  9889. 7:49:54It was like n plus n minus 1 plus n minus 2.
  9890. 7:49:59Any instincts here?
  9891. 7:50:01We got like the whole team in the orchestra now.
  9892. 7:50:04Let me propose we think about it this way with just a bit of formula, say.
  9893. 7:50:09So the first time, I had to look at n different volunteers.
  9894. 7:50:13n was 8 in this case, but generically, I looked at all eight numbers
  9895. 7:50:17in order to decide who was the smallest.
  9896. 7:50:19And sure enough, Celeste was at the very end.
  9897. 7:50:21She happened to be all the way to the right.
  9898. 7:50:23But I only knew that once I looked at all 8 or all n volunteers.
  9899. 7:50:27So that took me n steps first.
  9900. 7:50:30But once the list was swapped into the right place, then
  9901. 7:50:33my problem with size n minus 1, and I had n minus 1 other people
  9902. 7:50:37to look through.
  9903. 7:50:38So that's n minus 1 steps.
  9904. 7:50:40Then after that, it's n minus 2 plus n minus 3 plus n minus 4 plus dot dot
  9905. 7:50:44dot until I had one final step.
  9906. 7:50:45And it's obvious that I only have one human left to consider.
  9907. 7:50:48So we might wave our hands at this with a little ellipsis
  9908. 7:50:51and just say dot dot dot plus 1 for the final step.
  9909. 7:50:54Now what does this actually equal?
  9910. 7:50:56Well, this is where you might think back on, like,
  9911. 7:50:57your high school math or physics textbook that
  9912. 7:50:59has a little cheat sheet at the end that shows these kinds of recurrences.
  9913. 7:51:03That happens to work out mathematically to be
  9914. 7:51:05n times n plus 1 all divided by 2.
  9915. 7:51:09That's just what that recurrence, that series, actually adds up to.
  9916. 7:51:13So if you take on faith that that math is correct, let's
  9917. 7:51:15just now multiply this out mathematically.
  9918. 7:51:19That's n squared plus n divided by 2 or n squared divided by 2 plus n over 2.
  9919. 7:51:26And here's where we're starting to get annoyingly into the weeds.
  9920. 7:51:29Like, honestly, as n gets really large, like a million doors or integers
  9921. 7:51:34or a billion web pages in Google search engine, honestly, which of these terms
  9922. 7:51:39is going to matter the most mathematically
  9923. 7:51:41if n is a really big number?
  9924. 7:51:43Is n squared divided by 2 the dominant factor,
  9925. 7:51:46or is n divided by 2 the dominant factor?
  9926. 7:51:48AUDIENCE: n squared.
  9927. 7:51:50DAVID J. MALAN: Yeah, n squared.
  9928. 7:51:51I mean, no matter what n is-- and the bigger it is,
  9929. 7:51:53the bigger raising it to the power 2 is going to be.
  9930. 7:51:56So you know what?
  9931. 7:51:57Let's just wave our hands at this because at the end of the day,
  9932. 7:52:00as n gets really large, the dominant factor is indeed that first one.
  9933. 7:52:04And you know what?
  9934. 7:52:04Even the divided 2, as I claimed earlier with our two phone book examples, where
  9935. 7:52:08the two straight lines if you keep zooming out essentially
  9936. 7:52:11looked the same when n is large enough, let's just call this on the order of n
  9937. 7:52:16squared.
  9938. 7:52:16So that is to say a computer scientist would describe bubble sort as taking
  9939. 7:52:21on the order of n squared steps.
  9940. 7:52:24That's an oversimplification.
  9941. 7:52:25If we really added it up, it's actually this many steps-- n
  9942. 7:52:28squared divided by 2 plus n over 2.
  9943. 7:52:30But again, if we want to just be able to generally compare two algorithms'
  9944. 7:52:34performance, I think it's going to suffice if we look at that highest
  9945. 7:52:38order term to get a sense of what the algorithm feels like, if you will,
  9946. 7:52:44or what it even looks like graphically.
  9947. 7:52:46All right, so with that said, we might describe bubble sort
  9948. 7:52:50as being in big O--
  9949. 7:52:52sorry, selection sort as being in big O of n squared.
  9950. 7:52:56But what if we consider now the best case scenario-- an opportunity
  9951. 7:53:01to talk about a lower bound?
  9952. 7:53:03In the best case, how many steps does selection sort take?
  9953. 7:53:07Well, here, we need some context.
  9954. 7:53:09Like, what does it mean to be the best case or the worst case
  9955. 7:53:11when it comes to sorting?
  9956. 7:53:13Like, what could you imagine meaning the best possible scenario when you're
  9957. 7:53:16trying to sort a bunch of numbers?
  9958. 7:53:20I got the whole crew here again.
  9959. 7:53:21Yeah.
  9960. 7:53:21AUDIENCE: They would already be sorted.
  9961. 7:53:23DAVID J. MALAN: All right, they're already sorted, right?
  9962. 7:53:24I can't really imagine a better scenario than I have to sort some numbers,
  9963. 7:53:28but they're already sorted for me.
  9964. 7:53:30But does this algorithm leverage that fact in practice?
  9965. 7:53:35Even if all of our humans had lined up from 0 to 7,
  9966. 7:53:38I'm pretty sure I would have pretty naively started here.
  9967. 7:53:41And yes, Celeste happens to be here.
  9968. 7:53:43But I only know she needs to be here once I've looked at all eight people.
  9969. 7:53:47And then I would have realized, well, that was a waste of time.
  9970. 7:53:50I can leave Celeste be.
  9971. 7:53:51But then what would I have done?
  9972. 7:53:53I would have ignored her position because we've solved one problem.
  9973. 7:53:57I would have done the same thing now for seven people, then six people.
  9974. 7:54:00So every time I walk through, I'm not doing much useful work.
  9975. 7:54:03But I am doing those comparisons because I
  9976. 7:54:06don't know until I do the work that the people were in the right order.
  9977. 7:54:09So this would seem to imply that the omega notation, the best case
  9978. 7:54:14scenario, even, a lower bound on the running time would be what, then?
  9979. 7:54:18AUDIENCE: [INAUDIBLE]
  9980. 7:54:20DAVID J. MALAN: A little louder?
  9981. 7:54:21AUDIENCE: N squared.
  9982. 7:54:22DAVID J. MALAN: It's still going to be n squared,
  9983. 7:54:24in fact, because the code I'm giving myself doesn't leverage or benefit
  9984. 7:54:30from any of that scenario because it just mindlessly continues
  9985. 7:54:34to do this again and again.
  9986. 7:54:36So in this case, yes, I would claim that the omega notation for selection sort
  9987. 7:54:41is also big O of n squared.
  9988. 7:54:43So those are the kinds of numbers to beat.
  9989. 7:54:44It seems like the upper bound and lower bound of selection
  9990. 7:54:48sort are indeed n squared.
  9991. 7:54:50And so we can also describe selection sort, therefore,
  9992. 7:54:52as being in theta of n squared.
  9993. 7:54:54That's the first algorithm we've had the chance to describe that in,
  9994. 7:54:56which is to say that it's kind of slow.
  9995. 7:54:59I mean, maybe other algorithms are slower,
  9996. 7:55:00but this isn't the best starting point.
  9997. 7:55:02Can we do better?
  9998. 7:55:03Well, there's a reason that I guided us to doing the second algorithm second.
  9999. 7:55:07Even though you verbally proposed them in a different order,
  10000. 7:55:09this second algorithm we did is generally known as bubble sort.
  10001. 7:55:12And I deliberately used that word a bit ago,
  10002. 7:55:15saying the big values are bubbling their way up to the right
  10003. 7:55:19to kind of capture the fact that, indeed, this algorithm works
  10004. 7:55:22differently.
  10005. 7:55:22But let's consider if it's better or worse.
  10006. 7:55:25So here, we have pseudo code for bubble sort.
  10007. 7:55:28You could write this too in different ways.
  10008. 7:55:30But let's consider what we did on the stage.
  10009. 7:55:32We repeated the following n minus 1 times.
  10010. 7:55:36We initialized at least, even though I didn't verbalize it this way,
  10011. 7:55:39a variable like i from 0 to n minus 2, n minus 2.
  10012. 7:55:44And then I asked this question.
  10013. 7:55:46If numbers bracket i and numbers bracket i plus 1 are out of order,
  10014. 7:55:52then swap them.
  10015. 7:55:54So again, I just did it more intuitively by pointing,
  10016. 7:55:56but this would be a way, with a bit of pseudo code,
  10017. 7:55:59to describe what's going on.
  10018. 7:56:00But notice that I'm doing something a little differently here.
  10019. 7:56:03I'm iterating from if equals 0 to n minus 2.
  10020. 7:56:07Why?
  10021. 7:56:07Well, if I'm comparing two things, left hand and right hand,
  10022. 7:56:11I'd still want to start at 0.
  10023. 7:56:13But I don't want to go all the way to n minus 1
  10024. 7:56:15because then, I'd be going past the boundary of my array, which
  10025. 7:56:19would be bad.
  10026. 7:56:19I want to make sure that my left hand-- i, if you will--
  10027. 7:56:22stops at n minus 2 so that when I plus 1 in my pseudo code,
  10028. 7:56:27I'm looking at the last two elements, not the last element
  10029. 7:56:29and then pass the boundary.
  10030. 7:56:31That's actually a common programming mistake
  10031. 7:56:33that we'll undoubtedly soon make by going
  10032. 7:56:34beyond the boundaries of your array.
  10033. 7:56:37So this pseudo code, then, allows me to say compare every one again and again
  10034. 7:56:43and swap them if they're out of order.
  10035. 7:56:46Why do I repeat the whole thing n minus 1 times?
  10036. 7:56:50Like, why does it not suffice just to do this loop here?
  10037. 7:56:55Think what happened with Celeste.
  10038. 7:56:59Why do I repeat this whole thing n minus 1 times?
  10039. 7:57:03Yeah, in the back?
  10040. 7:57:04AUDIENCE: [INAUDIBLE]
  10041. 7:57:12DAVID J. MALAN: Indeed, and I think if I can recap accurately,
  10042. 7:57:14think back to Celeste again.
  10043. 7:57:16And I'm sorry to keep calling on you as our number 0.
  10044. 7:57:18Each time through bubble sort, she only moved one step.
  10045. 7:57:22And so in total, if there's n locations, at the end of the day,
  10046. 7:57:25she needs to move n minus 1 steps to get 0 all the way to where it needs to be.
  10047. 7:57:30And so this inner loop, if you will, where we're iterating using i,
  10048. 7:57:34that just fixes some of the problems.
  10049. 7:57:37But it doesn't fix all of the problems until we do that same logic again
  10050. 7:57:40and again and again.
  10051. 7:57:42And so how might we quantify the running time of this algorithm?
  10052. 7:57:45Well, one way to see it is to just literally look at the pseudo code.
  10053. 7:57:49The outer loop repeats n minus 1 times by definition.
  10054. 7:57:53It literally says that.
  10055. 7:57:54The inner loop, the for loop, also iterates n minus 1 times.
  10056. 7:58:00Why?
  10057. 7:58:00Because it's going from 0 to n minus 2.
  10058. 7:58:02And if that's hard to think about, that's the same thing is 1 to n minus 1
  10059. 7:58:06if you just add 1 to both ends of the formula.
  10060. 7:58:09So that means you're doing n minus 1 things n minus 1 times.
  10061. 7:58:14So I literally multiply how many times the outer loop
  10062. 7:58:16is running by how many times the inner loop is running, which gives me
  10063. 7:58:20sort of FOIL method n minus 1 squared.
  10064. 7:58:23And I could multiply that whole thing out.
  10065. 7:58:25Well, let's consider this just a little more methodically here.
  10066. 7:58:28If I have n minus 1 on the outer, n minus 1 on the inner--
  10067. 7:58:32let's go ahead and FOIL this.
  10068. 7:58:33So n squared minus n minus n plus 1, combine
  10069. 7:58:37like terms-- n squared minus 2n plus 1.
  10070. 7:58:40And now which of these terms is clearly going to be dominant, so to speak?
  10071. 7:58:45The--
  10072. 7:58:46AUDIENCE: N squared.
  10073. 7:58:46DAVID J. MALAN: --the n squared.
  10074. 7:58:48So yes, even though minus 2n is a good thing
  10075. 7:58:50because it's subtracting off some of the time required,
  10076. 7:58:53plus 1 is not that big a thing, there's such drops in the bucket when
  10077. 7:58:56n gets really large, like in the millions or billions,
  10078. 7:58:58certainly, that bubble sort 2 is on the order of n squared.
  10079. 7:59:02It's not the same exactly as selection sort.
  10080. 7:59:05But as n gets big, honestly, we're barely
  10081. 7:59:07going to be able to notice the difference most likely.
  10082. 7:59:09And so it too might be said to be on the order of n squared.
  10083. 7:59:13And if we consider now the lower bound on bubble sort's running time,
  10084. 7:59:18here's where things get potentially interesting.
  10085. 7:59:23What might you claim is the running time of bubble sort in the best case?
  10086. 7:59:28And the best case, I claim, is when the numbers are already sorted.
  10087. 7:59:32Is our pseudo code going to take that into account?
  10088. 7:59:35AUDIENCE: N
  10089. 7:59:36DAVID J. MALAN: OK, n.
  10090. 7:59:37Why do you propose n?
  10091. 7:59:38AUDIENCE: [INAUDIBLE]
  10092. 7:59:43DAVID J. MALAN: Yes, and that's the key word.
  10093. 7:59:45To summarize, in bubble sort, I do have to minimally make one pass because if I
  10094. 7:59:49don't look at all n elements, that I'm theoretically
  10095. 7:59:52just guessing if it's sorted or not.
  10096. 7:59:53Like, I obviously intuitively have to look
  10097. 7:59:55at every element to decide yay or nay, it's in the right order.
  10098. 7:59:58And my original pseudo code, though, is pretty naive.
  10099. 8:00:01It's just going to blindly go back and forth n minus 1 times again and again,
  10100. 8:00:07and that's going to add up.
  10101. 8:00:08But what if I add a bit of an optimization
  10102. 8:00:10that you might have glimpsed on the slide a moment ago
  10103. 8:00:12where if I compare two people and I don't swap them, compare two people,
  10104. 8:00:15don't swap them, and I go all the way through the list comparing
  10105. 8:00:18every pair of adjacent people, and I make no swaps,
  10106. 8:00:22it would be kind of not just naive but stupid
  10107. 8:00:25to do that same process again because if the humans have not moved,
  10108. 8:00:28I'm not going to make any different decisions.
  10109. 8:00:31I'm going to do nothing again, nothing again.
  10110. 8:00:34So at that point, it would be stupid, very inefficient, to go back and forth
  10111. 8:00:37and back and forth.
  10112. 8:00:38So if I modify our pseudo code with just an additional if condition,
  10113. 8:00:42I bet we can speed this up.
  10114. 8:00:44Inside of that same pseudo code, what if I say, hey, if no swaps, quit?
  10115. 8:00:50Like quit, prematurely before the loops are finished running.
  10116. 8:00:54One of the loops has gone through per the indentation here.
  10117. 8:00:57But if I do a loop from left to right and I
  10118. 8:01:00have made no swaps, which you can think of as just being
  10119. 8:01:03one other variable that's plus plusing as I go keeping, track of how many
  10120. 8:01:06swaps--
  10121. 8:01:07if I've made no swaps from left to right,
  10122. 8:01:09I'm not going to make any swaps the next time around either.
  10123. 8:01:11So let's just quit at that point.
  10124. 8:01:14And that is to say in the best case, if you will,
  10125. 8:01:16when the list is already sorted, the omega notation for bubble sort
  10126. 8:01:20might indeed be omega of n if you add that optimization
  10127. 8:01:25so as to short circuit all of that inefficient
  10128. 8:01:28looping to do it only as many times as is necessary.
  10129. 8:01:34Let me pause to see if there's any questions here.
  10130. 8:01:36Yeah.
  10131. 8:01:37AUDIENCE: [INAUDIBLE] to optimize the running time for all cases possible?
  10132. 8:01:46DAVID J. MALAN: Good question.
  10133. 8:01:47If the running time of selection sort and bubble sort are both in big O
  10134. 8:01:53of n squared but selection sort is in omega of n squared while bubble sort is
  10135. 8:01:58in omega of n, which sounds better--
  10136. 8:02:01I think if I may, should we just always use bubble sort?
  10137. 8:02:04Yes if we think that we might benefit over time
  10138. 8:02:09from a lot of good case scenarios or best case scenarios.
  10139. 8:02:13However, the goal at hand in just a bit is
  10140. 8:02:15going to be to do even better than both of these.
  10141. 8:02:17So hold that question further for a moment.
  10142. 8:02:19Yeah.
  10143. 8:02:20AUDIENCE: [INAUDIBLE] n minus 1?
  10144. 8:02:25DAVID J. MALAN: No.
  10145. 8:02:26So yes, good question.
  10146. 8:02:27So I say omega of n, but is it technically omega of n minus 1?
  10147. 8:02:31Maybe, but again, we're throwing away lower order terms.
  10148. 8:02:34And that's an advantage because we're not comparing things ever so precisely.
  10149. 8:02:38Just like I plotted with the green and yellow and red chart,
  10150. 8:02:41I just want to get a sense of the shape of these algorithms
  10151. 8:02:44so that when n gets really large, which of these choices
  10152. 8:02:47is going to matter the most?
  10153. 8:02:49At the end of the day, it's actually perfectly reasonable
  10154. 8:02:51to use selection sort or bubble sort if you
  10155. 8:02:53don't have that much data because they're going to be pretty fast.
  10156. 8:02:56My God, our computers nowadays are 1 gigahertz,
  10157. 8:02:582 gigahertz, 1 billion things per second, 2 billion things per second.
  10158. 8:03:02But if we have large data sets, as we will later in the term
  10159. 8:03:05and as you might in the real world, that the Googles of the world,
  10160. 8:03:07then you're going to want to be more thoughtful.
  10161. 8:03:09And that's where we're going today.
  10162. 8:03:11All right, so let's actually see this visualized a little bit.
  10163. 8:03:14In a moment, I'm going to change screens here
  10164. 8:03:16to open up what is a little visualization tool that will give us
  10165. 8:03:21a sense of how these things actually work and look at a faster rate
  10166. 8:03:25than our humans are able to do here on stage.
  10167. 8:03:27So here is another visualization of a bunch of numbers, an array of numbers.
  10168. 8:03:31Short bars mean small numbers, tall bars mean big numbers.
  10169. 8:03:35So instead of having the numbers on their torsos here,
  10170. 8:03:37we just have bars that are small or tall based on the magnitude of the number.
  10171. 8:03:42Let me go ahead, and I preconfigured this in advance
  10172. 8:03:44to operate somewhat quickly.
  10173. 8:03:46Let's go ahead and do selections sort by clicking this button.
  10174. 8:03:49And you'll see some pink bars flying by.
  10175. 8:03:52And that's like me walking left and right, left and right,
  10176. 8:03:56to select the next smallest number.
  10177. 8:03:58And so what you'll see happening on the left of this array of numbers
  10178. 8:04:01is Celeste, if you will, and all of the other smaller numbers
  10179. 8:04:04are appearing on the left while we continue to solve the remaining
  10180. 8:04:08problems to the right.
  10181. 8:04:10So again, we no longer have to touch the smaller numbers here.
  10182. 8:04:13So that's why the problem is getting smaller and smaller and smaller
  10183. 8:04:16over time.
  10184. 8:04:17But you can notice now visually, look at how many times
  10185. 8:04:20we're retracing our steps.
  10186. 8:04:22This is why things that are n squared tend
  10187. 8:04:25to be frowned upon if avoidable because I'm touching the same elements again
  10188. 8:04:29and again.
  10189. 8:04:29When I was walking through, I kept pointing at the same humans
  10190. 8:04:31again and again.
  10191. 8:04:32And that adds up.
  10192. 8:04:34So let's see if bubble sort looks or feels a little different.
  10193. 8:04:37Let me re-randomize the thing, and let me now click Bubble Sort at the top.
  10194. 8:04:40And as you might infer, there's other sorting algorithms out there,
  10195. 8:04:43not all of which we'll look at.
  10196. 8:04:44But here's bubble sort.
  10197. 8:04:46Same pink coloration, but it's doing something different.
  10198. 8:04:48It's two pink bars going through again and again comparing
  10199. 8:04:52the adjacent numbers.
  10200. 8:04:53And you'll see that the largest numbers are indeed bubbling the way up
  10201. 8:04:57to the right, but the smaller numbers, like our number 0 was,
  10202. 8:05:02is only slowly making its way over.
  10203. 8:05:04Here's a comparable.
  10204. 8:05:05Here's the number one.
  10205. 8:05:06And it's going to take a while to get all the way to the left.
  10206. 8:05:09And here too, notice how many times the same bars
  10207. 8:05:12are becoming pink, how many times the algorithm is retracing and retracing
  10208. 8:05:16its steps.
  10209. 8:05:17Why?
  10210. 8:05:17Because it's only solving one problem at a time on each pass.
  10211. 8:05:21And each time we do that, we're stepping through practically the whole array.
  10212. 8:05:25And now granted, I could speed this up even further if I really wanted to,
  10213. 8:05:28but my God, this is only, what, like 50 or 60 elements, something like that?
  10214. 8:05:32This is slow.
  10215. 8:05:33Like, this is what n squared looks like and feels like.
  10216. 8:05:36And now I'm just trying to come up with words to say
  10217. 8:05:38until we get to the finish line here.
  10218. 8:05:40Like, this would be annoying if this is the speed of sorting,
  10219. 8:05:43and this is why I sort of secretly sorted the numbers for Rave in advance
  10220. 8:05:47because it would have taken us an annoying number of steps
  10221. 8:05:49to get that in place for her.
  10222. 8:05:51So those two algorithms are n squared.
  10223. 8:05:54Can we do, in fact, better?
  10224. 8:05:56Well, to save the best algorithm for last, let's take a shorter five minute
  10225. 8:05:59break here.
  10226. 8:06:00And when we come back, we'll do even better than n squared.
  10227. 8:06:04All right.
  10228. 8:06:06So the challenge at hand is to do better than selection sort
  10229. 8:06:11and better than bubble sort and ideally not just marginally
  10230. 8:06:14better but fundamentally better.
  10231. 8:06:16Just like in week zero, that third and final divide and conquer algorithm
  10232. 8:06:20was sort of fundamentally faster than the other two.
  10233. 8:06:23So can we do better than something on the order of n squared?
  10234. 8:06:26Well, I bet we can if we start to approach
  10235. 8:06:28the problem a little differently.
  10236. 8:06:30The sorts we've done thus far, generally known
  10237. 8:06:32as comparison sorts-- and that kind of captures
  10238. 8:06:34the reality that we were doing a huge number of comparisons again and again.
  10239. 8:06:38And you kind of saw that in the vertical bars that were going pink as everything
  10240. 8:06:41was being compared again and again.
  10241. 8:06:43But there's this programming technique, and it's actually
  10242. 8:06:45a mathematical technique known as recursion
  10243. 8:06:48that we've actually seen before.
  10244. 8:06:50And this is a building block or a mental model
  10245. 8:06:53we can bring to bear on the problem to solve the sorting problem
  10246. 8:06:56sort of fundamentally differently.
  10247. 8:06:58But first, let's look at it in a more familiar context.
  10248. 8:07:00A little bit ago, I proposed this pseudo code for the binary search algorithm.
  10249. 8:07:07And notice that what was interesting about this code,
  10250. 8:07:10even though I didn't call it out at the time, it's kind of cyclically defined.
  10251. 8:07:14Like, I claim this is an algorithm for search,
  10252. 8:07:17and yet it seems a little unfair that I'm using the verb search
  10253. 8:07:21inside of the algorithm for search.
  10254. 8:07:23It's like an English sort of defining a word by using the word.
  10255. 8:07:26Normally, you shouldn't really get away with that.
  10256. 8:07:28But there's something interesting about this technique
  10257. 8:07:30here because even though this whole thing is a search algorithm
  10258. 8:07:35and I'm using my own algorithm to search the left half or the right half,
  10259. 8:07:40the key feature here that doesn't normally
  10260. 8:07:42happen in English when you define a word in terms of a word
  10261. 8:07:46is that when I search the left half or search the right half, yes,
  10262. 8:07:49I'm doing the same thing.
  10263. 8:07:51I'm using the same algorithm.
  10264. 8:07:52But the problem is, by definition, half as large.
  10265. 8:07:55So this isn't going to be a cyclical argument in the same way.
  10266. 8:07:58This approach, by using search within search
  10267. 8:08:02is going to whittle the problem down and down and down until hopefully,
  10268. 8:08:05one door or no doors remains.
  10269. 8:08:08And so recursion is a programming technique
  10270. 8:08:11whereby a function calls itself.
  10271. 8:08:14And we haven't seen this yet in C, and we haven't seen this really in Scratch.
  10272. 8:08:18But in C, you can have a function call itself.
  10273. 8:08:22And the form that takes is like literally
  10274. 8:08:24using the function's name inside of the function's implementation itself.
  10275. 8:08:28We've actually seen an opportunity for this once before too.
  10276. 8:08:32Think back to week zero.
  10277. 8:08:33Here's that same pseudo code for searching for someone
  10278. 8:08:35in an actual, physical phone book.
  10279. 8:08:37And notice these yellow lines here.
  10280. 8:08:40We described those in week zero as inducing a loop, a cycle.
  10281. 8:08:44And this is a very procedural approach, if you will, because lines 8 and 11
  10282. 8:08:48are very mechanically, if you will, telling
  10283. 8:08:50me to go back to line three to do this kind of looping thing.
  10284. 8:08:54But really, what that's doing in the binary search algorithm for the phone
  10285. 8:08:59book is it's just telling me to search the left half or search the right half.
  10286. 8:09:04I'm doing it more mechanically again by sort of telling myself
  10287. 8:09:08what line number to go back to.
  10288. 8:09:09But that's equivalent to just telling myself go search the left half,
  10289. 8:09:12search the right half, the key thing being the left
  10290. 8:09:15have and the right half are smaller than the original problem.
  10291. 8:09:18It would be a bug if I just said search the phone book, search the phone book,
  10292. 8:09:21because obviously, you never get anywhere.
  10293. 8:09:23But if you search the half, the half, the half,
  10294. 8:09:25problem gets smaller and smaller.
  10295. 8:09:27So let's reformulate week zero's phone book code to be not procedural as here
  10296. 8:09:34but recursive whereby in this search algorithm,
  10297. 8:09:39AKA binary search, formerly called divide and conquer, I'm
  10298. 8:09:42going to literally use also the keyword search here.
  10299. 8:09:46Notice among the benefits of doing this is it
  10300. 8:09:48kind of tightens the code up, makes it a little more succinct,
  10301. 8:09:51even though that's kind of a fringe benefit here.
  10302. 8:09:53But it's an elegant way too of describing
  10303. 8:09:56a problem by just having a function use itself
  10304. 8:10:01to solve a smaller puzzle at hand.
  10305. 8:10:05So let's now consider a familiar problem, a smaller
  10306. 8:10:08version than the one you've dabbled with-- this sort of pyramid,
  10307. 8:10:11this half pyramid from Mario.
  10308. 8:10:12And let's throw away the parts that aren't that interesting
  10309. 8:10:15and just consider how we might, up until now, implement this in C code,
  10310. 8:10:19this left aligned pyramid, if you will.
  10311. 8:10:21Let me go over here, and let me create a file called-- how about iteration.c?
  10312. 8:10:28And in this file, I'm going to go ahead and include cs50.h.
  10313. 8:10:32And I'm going to include stdio.h.
  10314. 8:10:36And the goal at hand is to implement in C a little program that just prints out
  10315. 8:10:41this and exactly this pyramid.
  10316. 8:10:43So no get string or any of that-- we're just going to keep it simple
  10317. 8:10:46and print exactly this pyramid of height 4 here.
  10318. 8:10:49So how might I do this?
  10319. 8:10:50Well, let me go ahead, and in main, let me first ask the user for--
  10320. 8:10:55well, we'll go ahead and generalize it.
  10321. 8:10:56Let's go ahead and ask the user for heights.
  10322. 8:10:58We're using getint as before.
  10323. 8:11:00And I'll store that in a variable called height.
  10324. 8:11:02And then let me go ahead and simply call the function
  10325. 8:11:05draw passing in that height.
  10326. 8:11:06So for the moment, let me assume that someone somewhere
  10327. 8:11:09has implemented a draw function.
  10328. 8:11:10And this, then, is the entirety of my program.
  10329. 8:11:14All right, unfortunately, C does not come with a draw function.
  10330. 8:11:17So let me go ahead and invent one.
  10331. 8:11:19It doesn't need to return a value.
  10332. 8:11:20It just needs to print something-- so-called side effect.
  10333. 8:11:23So I'm going to define a function called draw that takes as input an int.
  10334. 8:11:27I'll call it n for number, but I could call it anything I want.
  10335. 8:11:30And inside of this.
  10336. 8:11:32I'm going to go ahead and print out a left aligned pyramid like this from top
  10337. 8:11:37to bottom.
  10338. 8:11:38The salient features here are that this is a pyramid, at least in this example,
  10339. 8:11:42of height four.
  10340. 8:11:43And now in height four, the first row has one brick.
  10341. 8:11:46The second row has two.
  10342. 8:11:47The third has three.
  10343. 8:11:48The fourth has four.
  10344. 8:11:49That's a nice pattern that I can probably represent in code.
  10345. 8:11:52So how might I do this?
  10346. 8:11:53Well, how about 4 int i gets--
  10347. 8:11:55let me do it the old school way--
  10348. 8:11:571.
  10349. 8:11:58And then i is less than or equal to n.
  10350. 8:12:02And then i plus plus--
  10351. 8:12:04so I'm going from 1 to 4 just to keep myself sane here.
  10352. 8:12:08And then inside of this loop, what do I want to do?
  10353. 8:12:11Well, let me keep it conventional, in fact.
  10354. 8:12:12Let me just change this to be the more conventional 0
  10355. 8:12:16to n even though it might not be as intuitive because now on row 0,
  10356. 8:12:20I want one brick.
  10357. 8:12:21On row 1, I want two bricks, dot dot dot.
  10358. 8:12:24On row 3, I want four.
  10359. 8:12:25So it's kind of offset now.
  10360. 8:12:26But I'm being more conventional.
  10361. 8:12:28So on each row, how many bricks do I want to print?
  10362. 8:12:32Well, I think I want to do this.
  10363. 8:12:34For int j, for instance, common to use j after if you have a nested loop,
  10364. 8:12:40let's start j at 0 and do this so long as is less than i plus 1
  10365. 8:12:47and then do j plus plus.
  10366. 8:12:48So why i plus 1?
  10367. 8:12:50Well, again, when I equals 0, that's the first row, and I want one brick.
  10368. 8:12:55When i equals 1, that's the second row.
  10369. 8:12:57I want two bricks.
  10370. 8:12:57And dot dot dot, when i is 3, I want four bricks.
  10371. 8:13:00So again, I have to add 1 to i to get the total number of bricks
  10372. 8:13:03that I want to print to the screen.
  10373. 8:13:05So inside of this nested for loop, I'm going to do printf of a hash
  10374. 8:13:10with no new line.
  10375. 8:13:13I'm going to save the new line for about here instead.
  10376. 8:13:17All right, the last thing I'm going to do
  10377. 8:13:19is copy and paste the prototype at the top of the file.
  10378. 8:13:22So that I can call this.
  10379. 8:13:23And again, this is of now week one, week two.
  10380. 8:13:27Wouldn't necessarily come to your mind as quickly as it
  10381. 8:13:29might to mine after all this practice, but this is something reminiscent
  10382. 8:13:32of what you yourself did already for Mario-- printing out
  10383. 8:13:35a pyramid that hopefully in a moment is going to look like this.
  10384. 8:13:38So let me go back to my code.
  10385. 8:13:40Let me run make iteration, and let me do dot slash iteration.
  10386. 8:13:44I'll type in 4, and voila.
  10387. 8:13:46Seems to be correct, and let's assume it's going to work for other inputs
  10388. 8:13:50as well.
  10389. 8:13:50Oh, thank you.
  10390. 8:13:56So this is indeed an example of iteration-- doing something
  10391. 8:13:59again and again.
  10392. 8:14:01And it's very procedural.
  10393. 8:14:02Like, I literally have a function called draw that does this thing.
  10394. 8:14:05But I can think about implementing draw in a somewhat different way that's
  10395. 8:14:09kind of clever.
  10396. 8:14:11And it's not strictly necessary for this problem
  10397. 8:14:13because this problem honestly is not that complicated
  10398. 8:14:15to solve once you have practice under your belt.
  10399. 8:14:17Certainly the first time around, probably significantly challenging.
  10400. 8:14:20But now that you kind of associate, OK, row one
  10401. 8:14:23with one brick, row two with two bricks, it kind of comes together
  10402. 8:14:26with these for loops.
  10403. 8:14:27But how else could we think about this problem?
  10404. 8:14:30Well, this physical structure, these bricks, in some sense
  10405. 8:14:33is a recursive structure, a structure that's defined in terms of itself.
  10406. 8:14:39Now what do I mean by that?
  10407. 8:14:40Well, if I were to ask you the question, what does a pyramid of height 4
  10408. 8:14:45look like, you would point, of course, to this picture.
  10409. 8:14:49But you could also kind of cleverly say to me, well,
  10410. 8:14:55it's actually a pyramid of height 3 plus 1 additional row.
  10411. 8:15:00And here's that cyclical argument, right?
  10412. 8:15:02Kind of obnoxious to do typically in English or in a spoken language
  10413. 8:15:05because you're defining one thing in terms of itself.
  10414. 8:15:07What's a pyramid of height 4?
  10415. 8:15:08Well, it's a pyramid of height 3 plus 1 more row.
  10416. 8:15:12But we can kind of leverage this logic in code.
  10417. 8:15:15Well, what's a pyramid of height 3?
  10418. 8:15:16Well, it's a pyramid of height 2 plus 1 more row.
  10419. 8:15:19Fine, what's a pyramid of height 2?
  10420. 8:15:21Well, it's a pyramid of height 1 plus 1 more row.
  10421. 8:15:23And then hopefully, this process ends, and it does because notice,
  10422. 8:15:26the pyramid is getting smaller and smaller.
  10423. 8:15:29So you're not going to have this sort of silly back and forth with me
  10424. 8:15:32infinitely many times because when we finally get to the base case,
  10425. 8:15:36the end of the pyramid, fine.
  10426. 8:15:38What is a pyramid of height 1?
  10427. 8:15:39Well, it's a pyramid of no height plus one more row.
  10428. 8:15:42And at that point, things just get negative--
  10429. 8:15:45no pun intended.
  10430. 8:15:46Things just would otherwise go negative.
  10431. 8:15:48And so you can just kind of stop.
  10432. 8:15:49The base case is when there is no more pyramid.
  10433. 8:15:52So there's a way to draw a line in the sand and say, stop, no more arguments.
  10434. 8:15:56But this idea of defining a physical structure in terms of itself
  10435. 8:16:00or code in terms of itself actually lets us do some interesting new algorithms.
  10436. 8:16:06Let me go back to my code here.
  10437. 8:16:08Let me go ahead and create one final file here called recursion.c
  10438. 8:16:14that leverages this idea of this built-in self-referential nature.
  10439. 8:16:20Let me include cs50.h.
  10440. 8:16:22Let me go ahead and include standardio.h, int main void.
  10441. 8:16:26And then inside of main, I'm going to do the exact same thing-- int
  10442. 8:16:30height equals get int, asking the user for height.
  10443. 8:16:34And then I'm going to go ahead and call draw passing in height.
  10444. 8:16:38So that's going to stay the same.
  10445. 8:16:39I even am going to make my prototype the same-- void draw int n semicolon.
  10446. 8:16:45And now I'm going to implement void down here
  10447. 8:16:48with that same prototype, of course.
  10448. 8:16:49But the code now is going to be a little different.
  10449. 8:16:52What am I going to do here?
  10450. 8:16:54Well, first of all, if you ask me to draw a pyramid of height n,
  10451. 8:16:59I'm going to be kind of a wise ass here and say, well, just
  10452. 8:17:02draw a pyramid of n minus 1--
  10453. 8:17:05done.
  10454. 8:17:06All right, but there's still a little more work to be done.
  10455. 8:17:08What happens after I print or draw a pyramid of height n minus 1
  10456. 8:17:13according to our structural definition a moment ago?
  10457. 8:17:17What remains after drawing a pyramid of height n minus 1 or 3, specifically?
  10458. 8:17:22AUDIENCE: [INAUDIBLE]
  10459. 8:17:25We need one more row of hashes.
  10460. 8:17:26OK, so I can do that, right?
  10461. 8:17:28I'm OK with the single loops.
  10462. 8:17:29There's no nesting necessary here.
  10463. 8:17:30I'm just going to do this-- for int i get 0, i is less than n,
  10464. 8:17:35which is the height that's passed in, i plus plus.
  10465. 8:17:37And then inside of this loop, I'm very simply
  10466. 8:17:39going to print out a single hash.
  10467. 8:17:41And then down here, I'm going to print out a new line at the very end.
  10468. 8:17:45So that's good, right?
  10469. 8:17:45I might not be as comfortable with nested loops.
  10470. 8:17:48This is nice and simple.
  10471. 8:17:49What does this loop do here on line 17 through 20?
  10472. 8:17:52It literally prints n hashes by counting from i equals 0 on up to
  10473. 8:17:57but not through n.
  10474. 8:17:59So that's sort of week one style syntax.
  10475. 8:18:02But this is kind of trippy now because I've somehow
  10476. 8:18:05boiled down the implementation of draw into printing a row after just
  10477. 8:18:09drawing the thing above it.
  10478. 8:18:11But this is problematic as is because in this case,
  10479. 8:18:15my drawer function, notice, is always going to call the draw function forever
  10480. 8:18:22in some sense.
  10481. 8:18:23But ideally, when do I want this cyclical process to stop?
  10482. 8:18:28When do I want to not call draw anymore?
  10483. 8:18:32Yeah, when n is 1, right?
  10484. 8:18:35When I get to the top of the pyramid, when n is 1,
  10485. 8:18:37or heck, when the pyramids all gone and n equals 0.
  10486. 8:18:40I can pick any line in the sand, so long as it's
  10487. 8:18:42sort of at the end of the process.
  10488. 8:18:44Then I don't want to call draw anymore.
  10489. 8:18:45So maybe what I should do is this.
  10490. 8:18:48If n equals equals 0, there's really nothing to draw.
  10491. 8:18:54So I'm just going to go ahead and return like this.
  10492. 8:18:58Otherwise, I'm going to go ahead and draw
  10493. 8:19:01n minus 1 rows and then one more row.
  10494. 8:19:04And I could express this differently.
  10495. 8:19:06I could do something like this, which would be equivalent.
  10496. 8:19:08I could say something like if n is greater than or equal to 0,
  10497. 8:19:13then go ahead and draw the row.
  10498. 8:19:15But I like it this way first.
  10499. 8:19:17For now, I'm going to go with the original way
  10500. 8:19:18just to ask a simple question and then just bail out of the function
  10501. 8:19:22if n equals 0.
  10502. 8:19:23And heck, just to be super safe, just in case
  10503. 8:19:26the user types in a negative number, let me also
  10504. 8:19:28just check if n is a negative number, also, just return immediately.
  10505. 8:19:31Don't do anything.
  10506. 8:19:32I'm not returning a value because again, the function is void.
  10507. 8:19:35It doesn't need or have a return value.
  10508. 8:19:38So just saying return suffices.
  10509. 8:19:40But if n equals 1 or 2 or 3 or anything higher,
  10510. 8:19:45it is reasonable to draw a pyramid of slightly shorter height like, instead
  10511. 8:19:50of 4, 3, and then go ahead and print one more row.
  10512. 8:19:55So this is an example now of code that calls itself within itself.
  10513. 8:20:00Draw is calling draw.
  10514. 8:20:02But this so-called base case ensures, this conditional ensures,
  10515. 8:20:07that we're not going to do this forever.
  10516. 8:20:09Otherwise, we literally would do this infinitely many times,
  10517. 8:20:11and something bad is probably going to happen.
  10518. 8:20:14All right, let me go ahead and compile this code-- make recursion.
  10519. 8:20:18OK, no syntax errors-- dot slash recursion, Enter, height of 4,
  10520. 8:20:22and voila.
  10521. 8:20:24If only because some of you have run into this issue accidentally already,
  10522. 8:20:28let me get rid of the base case here, and let me recompile the code.
  10523. 8:20:32Make recursion.
  10524. 8:20:34Oh, and actually, now it's actually catching it.
  10525. 8:20:36So the compiler is smart enough here to realize
  10526. 8:20:39that all paths through this function will call itself.
  10527. 8:20:42AKA, It's going to loop forever.
  10528. 8:20:45So let me do the first thing.
  10529. 8:20:47Suppose I only check for n equaling 0.
  10530. 8:20:49Let me go ahead and recompile this code with make recursion.
  10531. 8:20:53And now let me just be kind of uncooperative.
  10532. 8:20:56When I run this program, still works for 4, still works for 0.
  10533. 8:21:00What if I do like negative 100?
  10534. 8:21:03Have any of you experienced a segmentation fault or core dump?
  10535. 8:21:07OK, so no shame in this.
  10536. 8:21:08Like, this means I have somehow touched memory that I shouldn't have.
  10537. 8:21:13And in short, I actually called this function thousands of times
  10538. 8:21:17accidentally, it would seem now, until the program just
  10539. 8:21:19bailed on me because I eventually touched memory in the computer
  10540. 8:21:22that I shouldn't have.
  10541. 8:21:23That'll make even more sense next week.
  10542. 8:21:25But for now, it's simply a bug.
  10543. 8:21:27And I can avoid that bug in this context,
  10544. 8:21:28probably not your own pset context, by just making sure we don't even
  10545. 8:21:33allow for negative numbers at all.
  10546. 8:21:35So with this building block in place, what
  10547. 8:21:38can we now do in terms of those same numbers to sort?
  10548. 8:21:41Well, it turns out there's a sorting algorithm called merge sort.
  10549. 8:21:44And there's bunches of others too.
  10550. 8:21:46But merge sort is a nice one to discuss because it fundamentally, we hope,
  10551. 8:21:51is going to do better than selection sort and bubble
  10552. 8:21:53sort that is better than n squared.
  10553. 8:21:55But the catch is it's a little harder to think about.
  10554. 8:21:58In fact, I'll act it out myself with just these numbers on the shelf here
  10555. 8:22:01rather than humans because recursion in general takes a little bit of effort
  10556. 8:22:05to wrap your mind around, typically a bit of practice.
  10557. 8:22:08But I'll see if we can't walk through it methodically
  10558. 8:22:10enough such that this comes to light.
  10559. 8:22:12So here's the pseudo code I propose for this algorithm called merge sort.
  10560. 8:22:16In the spirit of recursion, this sorting algorithm
  10561. 8:22:20literally calls itself by using the verb sort in its pseudo code.
  10562. 8:22:25So how does merge sort work?
  10563. 8:22:26It sort of obnoxiously says, well, if you want to sort all of these things,
  10564. 8:22:30go sort the left half, then go sort the right half,
  10565. 8:22:33and then merge the two together.
  10566. 8:22:34Now obnoxious in what sense?
  10567. 8:22:36Well, if I just asked you to sort something and you just tell me,
  10568. 8:22:38well, go sort that thing and then go sort
  10569. 8:22:40that thing, what was the point of asking you in the first place?
  10570. 8:22:43But the key is that each of these lines is
  10571. 8:22:45sorting a smaller piece of the problem.
  10572. 8:22:48So eventually, we'll be able to pare this down
  10573. 8:22:50into something that doesn't go on forever because in fact, in merge sort,
  10574. 8:22:54there's a base case too.
  10575. 8:22:56There's a scenario where we just check, wait a minute,
  10576. 8:22:59if there's only one number to sort, that's it.
  10577. 8:23:01Quit then because you're all done.
  10578. 8:23:03So there has to be this base case in any use of recursion
  10579. 8:23:06to make sure that you don't mindlessly call yourself forever.
  10580. 8:23:11You've got to stop at some point.
  10581. 8:23:13So let's focus on the third of these steps.
  10582. 8:23:16What does it mean to merge two lists, two halves of a list,
  10583. 8:23:21just because this is apparently going to be
  10584. 8:23:23a key ingredient-- so here, for instance,
  10585. 8:23:25are two halves of a list of size 8.
  10586. 8:23:28We have the numbers 2-- and I'll call it out if you're at a bad angle--
  10587. 8:23:312457 and 0136.
  10588. 8:23:36Notice that the left half at the moment, 2457, is already sorted,
  10589. 8:23:41and the right half, 0136, is also sorted as well.
  10590. 8:23:45So that's a good thing because it means that theoretically, I've
  10591. 8:23:48sorted the left half already.
  10592. 8:23:49I've sorted the right half already before we began.
  10593. 8:23:51I just need to merge these two halves.
  10594. 8:23:54What does it mean to sort two halves?
  10595. 8:23:56Well, for the sake of discussion, I'm just
  10596. 8:23:57going to turn over most of the numbers except for the first numbers in each
  10597. 8:24:03of these halves.
  10598. 8:24:04There's two halves here, left and right.
  10599. 8:24:07At the moment, I'm only going to consider
  10600. 8:24:09the leftmost element of each half-- that is, the one on the left here
  10601. 8:24:13and the one on the left here.
  10602. 8:24:15How do I merge these two lists together?
  10603. 8:24:18Well, if I look at 2 and I look at 0, which one should presumably come first?
  10604. 8:24:22The smaller one.
  10605. 8:24:23So I'm going to grab the 0, and I'm going
  10606. 8:24:25to put it into its own place on this new shelf here.
  10607. 8:24:28And now I'm going to consider, as part of my iteration,
  10608. 8:24:34the beginning of this list and the new beginning of this list.
  10609. 8:24:37So I'm now comparing 2 and 1.
  10610. 8:24:39Which one's smaller?
  10611. 8:24:40I'm going to go ahead and grab the 1.
  10612. 8:24:42Now I'm going to compare the beginning of the left list
  10613. 8:24:45and the new beginning of the right list, 2 and 3.
  10614. 8:24:47Of course, it's 2.
  10615. 8:24:49Now I'm going to compare the beginning of the left list
  10616. 8:24:51and the beginning of the right list, 4 and 3.
  10617. 8:24:53It's of course 3.
  10618. 8:24:55Now I'm going to compare the 4 against the beginning and end,
  10619. 8:24:58it turns out, of the second list--
  10620. 8:25:004, of course.
  10621. 8:25:01Now I'm going to compare the beginning of the left list
  10622. 8:25:03and the beginning of the right list--
  10623. 8:25:055, of course.
  10624. 8:25:06I'm realizing this is not going to end well because I left
  10625. 8:25:09too much distance between the numbers.
  10626. 8:25:10But that has nothing to do with the algorithm.
  10627. 8:25:127 is the beginning of the left list.
  10628. 8:25:146 is the beginning of the right list.
  10629. 8:25:15It's, of course, 6.
  10630. 8:25:17And at the risk of knocking all of these over,
  10631. 8:25:20if I now make room for this element, we have hopefully
  10632. 8:25:27sorted the whole thing by having merged together the two halves of the list.
  10633. 8:25:34So in short-- thank you.
  10634. 8:25:40I'm a little worried that's just getting sarcastic now,
  10635. 8:25:43but we now have merged two half lists.
  10636. 8:25:48We haven't done the guts of the algorithm yet-- sort the left half
  10637. 8:25:51and sort the right half.
  10638. 8:25:52But I claim that that is how mechanically you
  10639. 8:25:55merge two sorted halves.
  10640. 8:25:57You keep looking at the beginning of each list,
  10641. 8:25:59and you just kind of weave them together based
  10642. 8:26:02on which one belongs first based on its size.
  10643. 8:26:05So if you agree that that was a reasonable way
  10644. 8:26:07to merge two lists together, let's go ahead and focus lastly
  10645. 8:26:12on what it means to actually sort the left half
  10646. 8:26:15and sort the right half of a whole bunch of numbers.
  10647. 8:26:17And for this, I'm going to go ahead and order them
  10648. 8:26:19in this seemingly random order.
  10649. 8:26:21And I just have a little cheat sheet above so that I don't mess up.
  10650. 8:26:24And I'm going to start at the very top this time.
  10651. 8:26:26And hopefully, these will not fall down at any point.
  10652. 8:26:29But I'm just deliberately putting them in this random order, 5274.
  10653. 8:26:35And then we have 1630--
  10654. 8:26:381630.
  10655. 8:26:41Hopefully this won't fall over.
  10656. 8:26:43Here is now an array of size 8 with eight integers.
  10657. 8:26:48And I want to sort this.
  10658. 8:26:49I could use selection sort and just go back and forth and back and forth.
  10659. 8:26:52I could use bubble sort and just compare pairs, pairs, pairs.
  10660. 8:26:55But those are going to be on the order of big O of n squared.
  10661. 8:26:58My hope is to do fundamentally better here.
  10662. 8:27:00So let's see if we can do better.
  10663. 8:27:02All right, so let me look now at my code.
  10664. 8:27:04I'll keep it on the screen.
  10665. 8:27:05How do I implement merge sort?
  10666. 8:27:07Well, if there's only one number, I quit.
  10667. 8:27:09There's obviously not.
  10668. 8:27:10There's eight numbers, so that's not applicable.
  10669. 8:27:12I'm going to go ahead and sort the left half of numbers.
  10670. 8:27:14All right, here's the left half--
  10671. 8:27:165274.
  10672. 8:27:18Do I sort an array of size 4?
  10673. 8:27:21Well, here's where the recursion kicks in.
  10674. 8:27:24How do you sort a list of size 4?
  10675. 8:27:26Well, there's the pseudo code on the board.
  10676. 8:27:28I sort the left half of the list of size 4.
  10677. 8:27:31So here we go.
  10678. 8:27:33I have a list of size 4.
  10679. 8:27:34How do I sort it?
  10680. 8:27:35I sort the left half.
  10681. 8:27:37All right, now I have a list of size 2.
  10682. 8:27:38How do I sort this?
  10683. 8:27:41Well, sort the left half.
  10684. 8:27:42So here we go.
  10685. 8:27:43Here's a list of size 1.
  10686. 8:27:45How do I sort this?
  10687. 8:27:48I think it's done, right?
  10688. 8:27:50That's quit, right?
  10689. 8:27:50If only one number, I'm done.
  10690. 8:27:52The 5 is sorted.
  10691. 8:27:53All right, what was the next step?
  10692. 8:27:55You have to now rewind in time.
  10693. 8:27:56I just sorted the left half of the left half of the left half.
  10694. 8:28:00What do I now sort?
  10695. 8:28:02The right half, which is 2.
  10696. 8:28:05This is one element.
  10697. 8:28:06So I'm done.
  10698. 8:28:07So now at this point in the story, I have sorted, sort of idiotically--
  10699. 8:28:11the 5 assorted, and the 2 is sorted.
  10700. 8:28:14But what's the third and final step of this phase of the algorithm?
  10701. 8:28:18Merge the two together.
  10702. 8:28:20So here's the left, here's the right list.
  10703. 8:28:21How do I merge these together?
  10704. 8:28:23I compare the lists, and I put the two there.
  10705. 8:28:25I only have the [? 5 ?] left, and I do that.
  10706. 8:28:27So now we see some visible progress.
  10707. 8:28:30But again, let's rewind.
  10708. 8:28:31How did we get here?
  10709. 8:28:32We started to sort the left half of the left half of the left half, then
  10710. 8:28:37the right half.
  10711. 8:28:38And now where are we?
  10712. 8:28:39We've just sorted the left half of the left half.
  10713. 8:28:42So what comes after sorting the left half of anything?
  10714. 8:28:45Right half.
  10715. 8:28:46All right, here's the sort of same nonsensical thing.
  10716. 8:28:48Here's a list of size 2.
  10717. 8:28:49Let's sort the left half.
  10718. 8:28:51Done.
  10719. 8:28:51Let's sort the right half.
  10720. 8:28:52Done.
  10721. 8:28:53What's the third step?
  10722. 8:28:54Merge them together.
  10723. 8:28:55So that's the 4, and that's the 7.
  10724. 8:28:59What have I now done?
  10725. 8:29:00In total, I've now sorted the left half of the original thing.
  10726. 8:29:05So what happens next?
  10727. 8:29:07Wait a minute, wait a minute.
  10728. 8:29:08I have not done that.
  10729. 8:29:09What have I done?
  10730. 8:29:10I have sorted the left half of the left half,
  10731. 8:29:13and I've sorted the right half of the left half.
  10732. 8:29:16What do I now need to do lastly?
  10733. 8:29:19Merge those two lists together.
  10734. 8:29:21So again, I put my finger on the beginning
  10735. 8:29:22of this list, the beginning of this list.
  10736. 8:29:24And if you want, I'll do the same thing when I merged last time
  10737. 8:29:26to be clear what I'm comparing.
  10738. 8:29:282 and 4-- the 2 obviously comes first.
  10739. 8:29:30What comes next?
  10740. 8:29:32Well, the 4 comes next.
  10741. 8:29:34What comes next?
  10742. 8:29:36The 5 comes next and then lastly, of course, the 7.
  10743. 8:29:40Notice that the 2457 are now sorted.
  10744. 8:29:44So the original left half is sorted.
  10745. 8:29:47And I'll do the rest a little faster because, my God,
  10746. 8:29:49this feels like it takes forever.
  10747. 8:29:50But I bet we're on to something here.
  10748. 8:29:52What step remains next?
  10749. 8:29:54I've just sorted the left half of the original.
  10750. 8:29:56Sort the right half of the original.
  10751. 8:29:58How do I sort this?
  10752. 8:29:59I sort the left half of the right half.
  10753. 8:30:02How do I sort this?
  10754. 8:30:03I sort the left half of the left half.
  10755. 8:30:05Done.
  10756. 8:30:06I sort the right half of the left half.
  10757. 8:30:08Done.
  10758. 8:30:09Now I merge the two together.
  10759. 8:30:11The 1 comes first, the 6 comes next.
  10760. 8:30:14Now I sort the right half of the right half.
  10761. 8:30:18What do I do?
  10762. 8:30:19Sort the left half.
  10763. 8:30:20Done.
  10764. 8:30:21Sort the right half.
  10765. 8:30:22Done.
  10766. 8:30:23What do I do?
  10767. 8:30:23Merge them together.
  10768. 8:30:25So that's the third step of that phase.
  10769. 8:30:27Now where are we in the stor-- oh my God, where are we in the story?
  10770. 8:30:32We have sorted the left half of the right half
  10771. 8:30:36and the right half of the right half.
  10772. 8:30:38What comes next?
  10773. 8:30:40Merge.
  10774. 8:30:40So I'm going to compare, and I'm going to move those
  10775. 8:30:42down just to make clear what I'm comparing,
  10776. 8:30:44the beginning of both sublists.
  10777. 8:30:46What comes first?
  10778. 8:30:47Of course, the 0.
  10779. 8:30:48What comes next?
  10780. 8:30:51What comes next?
  10781. 8:30:52The 1.
  10782. 8:30:54What comes next?
  10783. 8:30:56The 3.
  10784. 8:30:57And then lastly comes the 6.
  10785. 8:30:59All right, where are we in the story?
  10786. 8:31:01We've now sorted the left half of the original
  10787. 8:31:03and the right half of the original.
  10788. 8:31:05What step remains?
  10789. 8:31:06Merge.
  10790. 8:31:07All right, so I'm going to make the same point.
  10791. 8:31:09And this is actually literally what we did earlier
  10792. 8:31:12because I deliberately demoed those original numbers in this order, 2
  10793. 8:31:16and a 0.
  10794. 8:31:16This comes out first.
  10795. 8:31:18What comes next?
  10796. 8:31:192 and 1.
  10797. 8:31:20The 1 comes out next.
  10798. 8:31:22What comes next?
  10799. 8:31:23The 2 comes next.
  10800. 8:31:25What comes next?
  10801. 8:31:26The 3 comes next.
  10802. 8:31:27What comes next?
  10803. 8:31:28The 4.
  10804. 8:31:31What comes after that?
  10805. 8:31:32The 5.
  10806. 8:31:35What comes after that?
  10807. 8:31:36The 6.
  10808. 8:31:37And lastly-- this is when we run out of memory--
  10809. 8:31:41the 7 over there is actually in place.
  10810. 8:31:45OK.
  10811. 8:31:47OK, so admittedly, a little harder to explain,
  10812. 8:31:50and honestly, it gets a little trippy because it's
  10813. 8:31:52so easy to forget about where you are in the story
  10814. 8:31:55because we're constantly diving into the algorithm
  10815. 8:31:58and then backing back out of it.
  10816. 8:31:59But in code, we could express this pretty correctly
  10817. 8:32:02and, it turns out, pretty efficiently because what
  10818. 8:32:05I was doing, even though it's longer when I do it verbally,
  10819. 8:32:09I was touching these elements a minimal amount of times, right?
  10820. 8:32:12I wasn't going back and forth, back and forth in front of the shelf
  10821. 8:32:15again and again.
  10822. 8:32:16I was deliberately only ever merging the smallest elements in each list.
  10823. 8:32:21So every time we merge, even though I was doing it quickly,
  10824. 8:32:24my fingers were only touching each of the elements once.
  10825. 8:32:28And how many times did we divide, divide, divide in half the list?
  10826. 8:32:34Well, we started with all of the elements here,
  10827. 8:32:36and there were eight of them.
  10828. 8:32:37And then we moved them 1, 2, 3 positions.
  10829. 8:32:41So the height of this visualization, if you will, is actually log n, right?
  10830. 8:32:47If I started with 8, turns out if you do the arithmetic,
  10831. 8:32:50this is log n height because 2 to the 3 is 8.
  10832. 8:32:54But for now, just trust that this is a log n height.
  10833. 8:32:57And how wide is the shelf?
  10834. 8:32:58Well, it's of width n because there's n elements any time
  10835. 8:33:02they were on the shelf.
  10836. 8:33:03So technically, I was kind of cheating this algorithm because this
  10837. 8:33:08is the first time I've needed shelves.
  10838. 8:33:09With the human examples, we just had the humans, and that's it, and only eight
  10839. 8:33:13of them.
  10840. 8:33:13Here, I was sort of using more and more memory.
  10841. 8:33:16In fact, I was using like four times as much memory
  10842. 8:33:19even though that was just for visualization's sake.
  10843. 8:33:21Merge sort actually requires that you have some spare space, an empty array
  10844. 8:33:25to move the elements into when you're merging them together.
  10845. 8:33:28But if I really wanted and if I didn't have this shelf or this shelf,
  10846. 8:33:31honestly, I could have just gone back and forth between the two shelves.
  10847. 8:33:33That would have been sufficient.
  10848. 8:33:35So merge sort uses more memory for this merging process,
  10849. 8:33:40but the advantage of using more memory is
  10850. 8:33:43that the total running time, if you can perhaps infer from that math, is what?
  10851. 8:33:49The big O notation for merge sort, it turns out,
  10852. 8:33:51is actually going to be n times log n.
  10853. 8:33:54And even if you're a little rusty still on your logarithms,
  10854. 8:33:57we saw in week zero and again today that log n is smaller than n.
  10855. 8:34:02That's a good thing.
  10856. 8:34:04Binary search was log n.
  10857. 8:34:05That's faster than linear search, which was n.
  10858. 8:34:07So n times log n is, of course, smaller than n times n or n squared.
  10859. 8:34:13So it's sort of lower on this little cheat sheet that I've been drawing,
  10860. 8:34:16which is to suggest that it's running time is indeed better or faster.
  10861. 8:34:19And in fact, if we consider the best case running time,
  10862. 8:34:22turns out it's not quite as good as bubble sort with omega of n,
  10863. 8:34:27where you can just sort of abort if you realize, wait a minute,
  10864. 8:34:29I've done no work.
  10865. 8:34:30Merge sort, you actually have to do that work to get to the finish line anyway.
  10866. 8:34:35So it's actually in omega and ultimately theta of n log n as well.
  10867. 8:34:40So again, a trade off there because if you
  10868. 8:34:42happen to have a data set that is very often sorted,
  10869. 8:34:44honestly, you might want to stick with bubble sort.
  10870. 8:34:47But in the general case, where the data is unsorted,
  10871. 8:34:49n log n as sounding better than n squared.
  10872. 8:34:53Well, what does it actually look or feel like?
  10873. 8:34:55Give me a moment to just change over to our visualization here.
  10874. 8:34:58And we'll see with this example what merge sort looks like
  10875. 8:35:02depicted with now these vertical bars.
  10876. 8:35:04So same algorithm, but instead of my numbers on shelves,
  10877. 8:35:07here is a random array of numbers being sorted.
  10878. 8:35:12And you can see it being done half at a time.
  10879. 8:35:14And you see sort of remnants of the previous bars.
  10880. 8:35:18Actually, that was unfair.
  10881. 8:35:19Let me zoom out here.
  10882. 8:35:21Let me zoom out so you can actually see the height here.
  10883. 8:35:26Let me go ahead and randomize this again and run merge sort.
  10884. 8:35:29There we go.
  10885. 8:35:29Now you can see the second array and where the values are going temporarily.
  10886. 8:35:34And even though this one looks way more cryptic visualization-wise,
  10887. 8:35:38it does seem to be moving faster.
  10888. 8:35:40And it seems to be merging halves together, and boom, it's done.
  10889. 8:35:44So let's actually see, in conclusion, what these algorithms compare to
  10890. 8:35:48and consider that moving forward as we write more and more code,
  10891. 8:35:51the goal is, again, not just to be correct but to be well-designed.
  10892. 8:35:54And one measure of design is going to indeed be efficiency.
  10893. 8:35:58So here we have, in final, a visualization of three algorithms--
  10894. 8:36:02selection sort, bubble sort, and merge sort--
  10895. 8:36:05from top to bottom.
  10896. 8:36:06And let's see what these algorithms might look or sound like here.
  10897. 8:36:09Oh, if we can dim the lights for dramatic effect--
  10898. 8:36:16selection's on top, bubble on bottom, merge in the middle.
  10899. 8:36:20[MUSIC PLAYING]
  10900. 8:37:17[MUSIC PLAYING]
  10901. 8:37:55[MUSIC PLAYING]
  10902. 8:39:13DAVID J. MALAN: Well, this is CS50, and already this is week four,
  10903. 8:39:18and recall that last week, week three, we
  10904. 8:39:19began to explore the inside of a computer's memory a bit more.
  10905. 8:39:22We talked about arrays, which were just chunks of memory
  10906. 8:39:25back to back to back that really lay things out left to right, top
  10907. 8:39:28to bottom, and this is actually a pretty common paradigm, even if you're
  10908. 8:39:32new to programming, and certainly new to C.
  10909. 8:39:34You've seen this approach of just using memory in some way to lay things out,
  10910. 8:39:39like images, for instance.
  10911. 8:39:40So for instance, here is a photo taken of last week's front row, for instance,
  10912. 8:39:45and this is an opportunity to explore exactly what happens
  10913. 8:39:49if we start to zoom in and zoom in and zoom in, because it seems like most
  10914. 8:39:52any TV show like CSI, or whatever, or any movie that
  10915. 8:39:56explores forensic information might have the investigators zoom in
  10916. 8:40:01on an image like this to see what the glint in someone's eye
  10917. 8:40:05is because that reveals the license plate number of someone that
  10918. 8:40:08just drove past.
  10919. 8:40:08Something that's a little over the top there,
  10920. 8:40:10but there's an opportunity here to speak to why that is so unrealistic.
  10921. 8:40:14For instance, let's zoom on this puppet here's eye and let's
  10922. 8:40:17zoom in a little more to see what might be reflected.
  10923. 8:40:19Let's zoom in a little more, and that's it.
  10924. 8:40:21There's only finite amount of information
  10925. 8:40:24if you have an image represented in this way.
  10926. 8:40:26We're using pixels-- these dots on the screen as rows and columns--
  10927. 8:40:29because if you're only using a finite amount of memory
  10928. 8:40:32then at the end of the day, you can only store a finite amount of information.
  10929. 8:40:35At least I don't really see in this grid here any glint of a license plate
  10930. 8:40:39or something like that that you might otherwise see in Hollywood.
  10931. 8:40:42So today we'll explore these kinds of representations
  10932. 8:40:45of how you might use memory in new and interesting ways
  10933. 8:40:47to represent now, very familiar things, but also
  10934. 8:40:51start to explore what some of the limitations are of this representation.
  10935. 8:40:54But consider after all that this doesn't need to be even as high resolution,
  10936. 8:40:58as many pixels as something like this other image,
  10937. 8:41:00you can imagine just doing something silly with Post-It notes, like this.
  10938. 8:41:04And if you think of an image as just having rows and columns,
  10939. 8:41:07these rows otherwise known as scan lines-- something
  10940. 8:41:09we'll explore in the coming week-- you could make this fun smiley face
  10941. 8:41:13by just using two different values, maybe a zero and a one.
  10942. 8:41:17Or yellow and purple, or vice versa, just to make something come to life.
  10943. 8:41:21Now in practice, recall we talked about storing not just a zero or one,
  10944. 8:41:25but maybe an R, a G, and a B value-- like 24 bits, or three bytes in total--
  10945. 8:41:32but we'll come back to that.
  10946. 8:41:33That would just be a more involved image.
  10947. 8:41:35But for fun, if today you want to tackle something passively in the background,
  10948. 8:41:41if you go to this URL here, we've put together an opportunity
  10949. 8:41:44to do a bit of pixel art.
  10950. 8:41:47If you go to this URL here, that'll redirect you to a Google Spreadsheet.
  10951. 8:41:51If you have a laptop with you today that'll
  10952. 8:41:53look a little something like this, which we've organized in rows and columns.
  10953. 8:41:56So if you'd like to go ahead and use Google Spreadsheet's colorization
  10954. 8:42:01feature to color in those individual squares if you'd like,
  10955. 8:42:04see if you can't make something a little creative and then email it to Carter
  10956. 8:42:08and we'll exhibit some of the best or favorites on the website thereafter.
  10957. 8:42:12So let's transition then to something a little more familiar-- images.
  10958. 8:42:15And not all of you have used, presumably, Photoshop,
  10959. 8:42:17but you're probably generally familiar with Photoshop as a program for editing
  10960. 8:42:20and creating images or photos or the like.
  10961. 8:42:23And here is a screenshot of p's color picker,
  10962. 8:42:25via which you can change what color you're
  10963. 8:42:27going to draw with the paint brush, or what color you're
  10964. 8:42:30going to fill in with the paint bucket.
  10965. 8:42:32It's representative of any kind of graphical tool.
  10966. 8:42:34And there's a lot of information in here,
  10967. 8:42:36but there's perhaps some familiar terms now--
  10968. 8:42:39R, G, and B. In fact, right now this is Photoshop's way
  10969. 8:42:43of saying you're about to fill in your background or foreground
  10970. 8:42:45with the color black, and that appears to be
  10971. 8:42:48represented with an R, a G, and a B value of zero, zero, zero.
  10972. 8:42:51Or alternatively, using a hash symbol and then 000000.
  10973. 8:42:57And if some of you have already made web pages before
  10974. 8:42:59and you know a little bit of HTML and CSS,
  10975. 8:43:01you probably are familiar with this kind of syntax--
  10976. 8:43:04a hash symbol and then six, or sometimes three digits thereafter.
  10977. 8:43:07And if we look at a few different colors here, for instance,
  10978. 8:43:10here might be the representation of white.
  10979. 8:43:12Now the R, the G, and the B values went way up from 0 to 255, 255, 255.
  10980. 8:43:18Or alternatively, it looks like Photoshop, and in turn web browsers,
  10981. 8:43:23could represent that same color white with FFFFFF.
  10982. 8:43:26And let's just do a few others.
  10983. 8:43:28Here is red, and it turns out that red is a whole lot of red, 255,
  10984. 8:43:32but no green, no blue.
  10985. 8:43:34Or, a.k.a.
  10986. 8:43:35FF0000.
  10987. 8:43:37So there's perhaps a pattern here emerging.
  10988. 8:43:39Here is green, zero, 255, zero, a.k.a.
  10989. 8:43:4300FF00, or lastly, here blue, which is no red,
  10990. 8:43:48no green but apparently a lot of blue, 255 again, a.k.a.
  10991. 8:43:510000FF.
  10992. 8:43:53Now some of you, again, might have seen this notation before,
  10993. 8:43:57these zeros and these F's and all of the numbers and letters in between,
  10994. 8:44:00but this is another form of notation.
  10995. 8:44:02And in fact, we'll explore this today-- really
  10996. 8:44:04is just a precondition for talking about some other concepts.
  10997. 8:44:06But the ideas, ultimately, are really no different.
  10998. 8:44:10What we're about to see is a different base system--
  10999. 8:44:13not just binary, not just decimal, but something
  11000. 8:44:15we're about to call hexadecimal.
  11001. 8:44:17But first, recall that with RGB we previously did the following.
  11002. 8:44:21Any RGB value-- red, green, blue-- just combine
  11003. 8:44:23some amount of red or green or blue.
  11004. 8:44:26So here we have 72, 73, 33, which in the context of an email or text, of course,
  11005. 8:44:30said what--
  11006. 8:44:32a couple of weeks back?
  11007. 8:44:33Just hi with an exclamation point, but in the context
  11008. 8:44:36of a Photoshop-like program, this might instead be representing,
  11009. 8:44:40collectively, this shade of yellow, for instance,
  11010. 8:44:42when you combine that much red that much green that much blue.
  11011. 8:44:45So here is the same idea.
  11012. 8:44:46If you've got a lot of red, no green, no blue,
  11013. 8:44:49together that's going to give us red.
  11014. 8:44:50If you've got no red, a lot of green, no blue,
  11015. 8:44:53that's going to give us, of course, green.
  11016. 8:44:55If you've got no red, no green, a lot of blue, that of course,
  11017. 8:44:58is going to give us blue.
  11018. 8:44:59So there's a pattern emerging here where apparently 00 is none, as always,
  11019. 8:45:03and FF is apparently a lot.
  11020. 8:45:05And it's maybe somehow equated with 255, at least per that Photoshop screenshot.
  11021. 8:45:12Meanwhile, if we combine one last one, a lot of red, a lot of green,
  11022. 8:45:15a lot of blue--
  11023. 8:45:16that's actually going to give us a single white pixel like this.
  11024. 8:45:20All right, so think back.
  11025. 8:45:21Here was binary-- in the world of binary you had just two digits, zero and one.
  11026. 8:45:25Could have been anything else--
  11027. 8:45:26A or B, X or Y, but the world standardized on these numerals
  11028. 8:45:31zero and one.
  11029. 8:45:32In our world's decimal system, of course, you have zero through nine.
  11030. 8:45:35As of today though, we're going to start using hexadecimal sometimes
  11031. 8:45:39in the context of images and also files just because it's a convention
  11032. 8:45:43and there's some conveniences to it.
  11033. 8:45:45Where now, you're going to be able to count up
  11034. 8:45:47to F in a notation called hexadecimal.
  11035. 8:45:49From zero through nine, then you keep going to A to B to C to D to E to F,
  11036. 8:45:55the idea being each of these, even though it's weirdly
  11037. 8:45:58a letter of the English alphabet, it's still just a single symbol.
  11038. 8:46:02It's not one zero for 10, or 1 1 for eleven-- all 16 of these values,
  11039. 8:46:07these digits, so to speak, are indeed still just single symbols,
  11040. 8:46:10and that's a characteristic of just using this other notational system.
  11041. 8:46:14So how do we get from 00 and FF to something like 0 and 255, respectively?
  11042. 8:46:20Well, this hexadecimal system, a.k.a.
  11043. 8:46:22Base 16, just does the math from week zero and really,
  11044. 8:46:25grade school, a little bit differently.
  11045. 8:46:27For instance, if you have a number that's got two digits,
  11046. 8:46:30or hexadecimal digits as of today, the columns are just a little different.
  11047. 8:46:34Instead of powers of two or powers of 10, which we saw for binary and decimal
  11048. 8:46:37respectively, it's powers of 16.
  11049. 8:46:40So if we just do the math out, that's the ones column,
  11050. 8:46:43this is the 16s column, and so forth.
  11051. 8:46:46Things get actually pretty big pretty quickly in this system.
  11052. 8:46:49But now let's just consider how we would represent familiar numbers.
  11053. 8:46:52If you've got two hexadecimal digits for which these hashes are
  11054. 8:46:54just placeholders, zero, zero is going to mathematically
  11055. 8:46:57equal the decimal number you and I know, of course, as zero.
  11056. 8:47:00Why?
  11057. 8:47:00Same thing as week zero--
  11058. 8:47:0216 times zero plus one times zero is the number you and I know as zero.
  11059. 8:47:06And we can count up from here.
  11060. 8:47:07This, in hexadecimal, would be how a computer
  11061. 8:47:10represents the number we know as one.
  11062. 8:47:12It would be zero one in this case.
  11063. 8:47:14This would be two, three, four, five, six, seven, eight, nine--
  11064. 8:47:19in decimal, we're about to go to 10.
  11065. 8:47:21But in hexadecimal, to be clear, what comes next?
  11066. 8:47:24So, apparently A, so 0A, 0B, which is now 10, or 11, or 12, 13, 14, 15.
  11067. 8:47:33So using hexadecimal is just an interesting way
  11068. 8:47:36of using single symbols now, zero through F,
  11069. 8:47:40to count from zero through 15.
  11070. 8:47:43And we'll see why it's 15 in a moment, but as soon as we get to F,
  11071. 8:47:46anyone want to conjecture how in hexadecimal, a.k.a. hex,
  11072. 8:47:50do we now count up one position higher?
  11073. 8:47:53What comes after 0F in hexadecimal?
  11074. 8:47:56So, one zero-- it's the same kind of thing--
  11075. 8:47:59once you're at the highest digit possible, F--
  11076. 8:48:01or in our decimal world that would have been nine--
  11077. 8:48:03you add one more, nine wraps around to zero, or in this case,
  11078. 8:48:06F wraps around to zero.
  11079. 8:48:08You carry the one and voila-- now we're representing
  11080. 8:48:11the number you and I know as 16.
  11081. 8:48:12And we could keep going forever, literally.
  11082. 8:48:14This could be 17, 18, 19, 20, and decimal--
  11083. 8:48:18but let's just wave our hands at it and count
  11084. 8:48:20as high as we can-- dot, dot, dot-- the highest
  11085. 8:48:23we could count in hexadecimal with two digits, just logically,
  11086. 8:48:26would be what, in hexadecimal?
  11087. 8:48:28Something, something.
  11088. 8:48:30FF, I heard.
  11089. 8:48:31So yes, that's the biggest digit possible, so FF is what we have.
  11090. 8:48:34So how high can you count in hexadecimal if you've got just two of these digits?
  11091. 8:48:38Well, it's the same math as always.
  11092. 8:48:3916 times F, a.k.a.
  11093. 8:48:4115, so that's 16 times 15 plus one times F, or one times 15--
  11094. 8:48:48that gives us 240 plus 15 in decimal, the result of which, of course, now
  11095. 8:48:52is 255.
  11096. 8:48:54So this hexadecimal system-- you may have seen in the world of web pages,
  11097. 8:48:57and if you haven't we'll get to that in this class in a few weeks,
  11098. 8:49:00or we just saw in the context of Photoshop-- just
  11099. 8:49:03has this shorthand notation of counting as high as 255 but just calling it FF.
  11100. 8:49:09Now it's marginal, but that's like 50% savings of how many digits
  11101. 8:49:13you need in order to count as high as 255 because in decimal, of course,
  11102. 8:49:16255 is three digits.
  11103. 8:49:18In hexadecimal you can count as high using just two,
  11104. 8:49:22and that difference is going to get magnified the bigger our numbers get.
  11105. 8:49:25Let me stipulate for now, you're going to get more and more savings
  11106. 8:49:28in terms of just how many symbols you need on the screen to represent
  11107. 8:49:31bigger and bigger numbers than that.
  11108. 8:49:35All right, let me pause here just to see if there's any questions thus far
  11109. 8:49:38on what we've called hexadecimal, which again, just gives us zero through nine
  11110. 8:49:42as well as A through F. Any questions or confusion?
  11111. 8:49:48And if it feels like we're lingering a bit much on arithmetic,
  11112. 8:49:51we're not really going to see other notations besides this moving forward.
  11113. 8:49:54These are the go-to three in a programmer's world, typically.
  11114. 8:49:58But there are some others.
  11115. 8:50:00Yeah.
  11116. 8:50:01AUDIENCE: Does the hexadecimal symbol take more storage
  11117. 8:50:03than the decimal system?
  11118. 8:50:06DAVID J. MALAN: Good question.
  11119. 8:50:07Does hexadecimal require more storage or less storage than the decimal system?
  11120. 8:50:11Theoretically no, because this is just a way of representing information
  11121. 8:50:16and we'll see in a concrete example in a moment.
  11122. 8:50:19But inside of the computer, at the end of the day, you're still storing bits.
  11123. 8:50:22And using hexadecimal is not using more or fewer bits,
  11124. 8:50:25think of this as how you might write it down
  11125. 8:50:27on a piece of paper, just how many digits you're going to write
  11126. 8:50:30or on a computer screen, how many digits you're going to see at once,
  11127. 8:50:33but it doesn't change how the computer is representing information
  11128. 8:50:36because all they're representing at the end of the day is zeros and ones.
  11129. 8:50:39So in fact, let's go there.
  11130. 8:50:40If this-- a moment ago FF I claimed was 255--
  11131. 8:50:45let's just rewind to week zero and if we wanted
  11132. 8:50:47to count to 255 in binary, that's as high as you can count, recall,
  11133. 8:50:51with eight bits.
  11134. 8:50:52And there's only a few of these numbers that
  11135. 8:50:54are useful to memorize, like 255 is as high as you can count with eight bits
  11136. 8:50:58if you start at zero, because two to the eighth is 256, but if you start at zero
  11137. 8:51:02it's zero through 255.
  11138. 8:51:04So in binary, recall if you have eight bits, all of which were ones,
  11139. 8:51:09and I won't do out the math pedantically here,
  11140. 8:51:11but if I do do this plus this plus this, dot, dot,
  11141. 8:51:13dot-- that's also going to give me 255.
  11142. 8:51:16So this is what's interesting here about hexadecimal.
  11143. 8:51:19It turns out that an upside of storing values in hexadecimal
  11144. 8:51:24is that we're going to see the first F represents
  11145. 8:51:27the left half of all these bits, and the second F in this case
  11146. 8:51:31represents the rightmost four of these bits.
  11147. 8:51:33So it turns out hexadecimal is very useful when you
  11148. 8:51:36want to treat data in units of four.
  11149. 8:51:39It's not quite eight, but units of four, and that's not bad.
  11150. 8:51:42Which is why-- if you use two digits like I have thus far,
  11151. 8:51:4500 or FF or anything in between--
  11152. 8:51:48that's actually a convenient way of representing eight bits in total.
  11153. 8:51:53One hex digit for the first four bits, one hex digit for the second.
  11154. 8:51:57And again, there's nothing new intellectually here per se,
  11155. 8:52:00it's just a different way of representing the same story as before--
  11156. 8:52:03zeros and ones.
  11157. 8:52:05So in what context do we see this?
  11158. 8:52:06Well, we talked about memory last week, and we're
  11159. 8:52:08going to talk more about it this week.
  11160. 8:52:09If this is my computer's RAM-- random access memory--
  11161. 8:52:12you can again think of each byte as having a number associated with it--
  11162. 8:52:16its address or location.
  11163. 8:52:18This might be zero, this might be 2 billion, and so in the past
  11164. 8:52:22I've described these as just this, using decimal numbers.
  11165. 8:52:25Here's byte zero, one, two, three, four, five, six, seven, 15, 16
  11166. 8:52:29would be here, and so forth.
  11167. 8:52:30But it turns out in the world of memory, and thus today, programming, people
  11168. 8:52:35tend to count memory bytes using hexadecimal.
  11169. 8:52:40Partly just by convention, but also partly
  11170. 8:52:42because it's a little more succinct and again, each digit
  11171. 8:52:44represents four bits, typically.
  11172. 8:52:48So what comes after F here?
  11173. 8:52:49Well, if I think about the computer's memory,
  11174. 8:52:51I normally might do after F, which is 15, 16.
  11175. 8:52:56But instead, one zero, one one, one two, one three-- this
  11176. 8:53:01is not 10, 11, 12, 13, because I claim I'm in the context of hexadecimal now.
  11177. 8:53:05As per the previous slide, we already started
  11178. 8:53:07going into A's through F's, so you immediately
  11179. 8:53:10see here a possible problem.
  11180. 8:53:13Why is this now worrisome, if all of a sudden you're
  11181. 8:53:16seeing seemingly familiar numbers like 10, 11, 12, 13?
  11182. 8:53:22We didn't really stumble across this problem
  11183. 8:53:24when it was all zeros and ones before.
  11184. 8:53:25Yeah.
  11185. 8:53:26AUDIENCE: Try to do math [INAUDIBLE].
  11186. 8:53:30DAVID J. MALAN: Yeah, so if you're writing some code in C that's
  11187. 8:53:33doing some math, you might accidentally--
  11188. 8:53:35or the computer might accidentally confuse hexadecimal with decimal
  11189. 8:53:37if they look in some context the same.
  11190. 8:53:40Any number on the board that doesn't have a letter
  11191. 8:53:42is ambiguously hexadecimal or decimal at this point,
  11192. 8:53:46and so how might we resolve this?
  11193. 8:53:48Well, it turns out that what computers typically do is this.
  11194. 8:53:51By convention, any time you see 0x and then a number,
  11195. 8:53:55that's a human convention of saying--
  11196. 8:53:58signaling to the reader that this is in fact a hexadecimal number.
  11197. 8:54:01So if it's 0x10, that is not the number 10,
  11198. 8:54:05that is the hexadecimal number one zero, which recall we said earlier,
  11199. 8:54:10is how you count up to 16.
  11200. 8:54:13And again, these are not the kinds of things to memorize,
  11201. 8:54:16it's really just the system for how you think about these things.
  11202. 8:54:19So henceforth today, we're going to start seeing hexadecimal
  11203. 8:54:22in a bunch of contexts.
  11204. 8:54:23When you write code, you might even write code using some hexadecimal
  11205. 8:54:26but again, it's just a different way of representing numbers
  11206. 8:54:29and humans have different conventions for different contexts.
  11207. 8:54:32All right, so with that said, any questions now on this building block?
  11208. 8:54:36But here on out, we'll start using it in some actual code.
  11209. 8:54:41Any questions?
  11210. 8:54:43Nothing so far?
  11211. 8:54:44All right.
  11212. 8:54:45So, let's go ahead and consider maybe a familiar example.
  11213. 8:54:49Something where involving code, where I initialize a variable like n
  11214. 8:54:52to a value like 50, in this case.
  11215. 8:54:54And then let's start to tinker around with what's going
  11216. 8:54:57on inside of the computer's memory.
  11217. 8:54:58In a moment I'm going to load up VS Code on my computer
  11218. 8:55:01and I'm going to go ahead and whip up a program that very simply assigns
  11219. 8:55:04a value like the number 50 to a variable called n,
  11220. 8:55:08but today, keep in mind that that variable n and that value 50
  11221. 8:55:14is going to be stored somewhere in my computer's memory,
  11222. 8:55:16and it turns out today we'll introduce a bit more syntax so you can actually
  11223. 8:55:19see where things are being stored.
  11224. 8:55:22So let me click over to VS Code here.
  11225. 8:55:24I'm going to create a program called address.c just
  11226. 8:55:27to explore computer's addresses today, and I'm
  11227. 8:55:29going to do an include stdio.h, int main(void), as usual.
  11228. 8:55:34No command line arguments for now.
  11229. 8:55:35I'm going to declare that variable n equals 50,
  11230. 8:55:38and then I'm just going to go ahead and print it out.
  11231. 8:55:40So nothing very interesting but I'll use %i backslash n and then comma n
  11232. 8:55:46to print out that value.
  11233. 8:55:47Nothing here should be very interesting to compile or run,
  11234. 8:55:50but I'll do it just to make sure I didn't make any mistakes.
  11235. 8:55:53Looks like as expected, it simply prints out the number 50, like this.
  11236. 8:55:58But let's consider then, what this code is doing underneath the hood
  11237. 8:56:02when it's actually run on your machine.
  11238. 8:56:04So here we have that grid of memory.
  11239. 8:56:06That variable n is an int, and if you think back,
  11240. 8:56:10how many bytes typically do we use for an int?
  11241. 8:56:14Yeah.
  11242. 8:56:15Four, so four bytes, or 32 bits.
  11243. 8:56:18So if each of these squares represents one byte, then my computer, somewhere
  11244. 8:56:21in my memory, or RAM, is using four of these squares.
  11245. 8:56:25Maybe it ends up over here just because there's other stuff being
  11246. 8:56:27used elsewhere, for instance.
  11247. 8:56:29Though I don't really know, and frankly, I
  11248. 8:56:30don't really care where it ends up, just that it ends up somewhere.
  11249. 8:56:33So the variable-- the value 50 is stored here in a variable called n.
  11250. 8:56:37Even though I've written it as decimal, just like in my code--
  11251. 8:56:40let me again remind that this is 32 zeros and ones representing that 50--
  11252. 8:56:45it's just going to be very tedious if we start writing everything in binary,
  11253. 8:56:48so I'll use the more comfortable human decimal system.
  11254. 8:56:51So that's what's going on inside of the computer's memory.
  11255. 8:56:54So what if I actually wanted to start tinkering with its location,
  11256. 8:56:58or maybe just knowing its location?
  11257. 8:57:01Well, this variable n indeed has a name, n--
  11258. 8:57:05that's a label of sorts for it-- but at the end of the day that 50 is
  11259. 8:57:09technically at a specific address, and I'm going to make one up--
  11260. 8:57:110x123, and it's 123 because I really don't
  11261. 8:57:14care what it is, I just want an address for the sake of discussion.
  11262. 8:57:17So way over here off screen might be byte zero, way down here is byte 0x123.
  11263. 8:57:24It's in hexadecimal notation just by convention.
  11264. 8:57:28So how can I actually see where my variables are ending up
  11265. 8:57:32in memory if I'm curious to do so?
  11266. 8:57:33Well, let me go back to my code here and let me actually
  11267. 8:57:37change this just a little bit.
  11268. 8:57:39Let me go ahead and introduce, for instance, another symbol
  11269. 8:57:44here and another topic altogether, namely pointers.
  11270. 8:57:48So a pointer is a variable that stores the address of some value--
  11271. 8:57:54the location of some value or more specifically,
  11272. 8:57:57the specific byte in which that value is stored.
  11273. 8:58:01So again, if you think of your memory as being a whole bunch of bytes--
  11274. 8:58:04zero at top left, 2 billion or whatever at bottom right,
  11275. 8:58:07depending on how much RAM you have--
  11276. 8:58:08each of those things has a location, or an address.
  11277. 8:58:10A pointer is just a variable storing one such address.
  11278. 8:58:14So it turns out that in the world of C, there's a couple of new symbols
  11279. 8:58:20we can use if we want to see what it is we're talking about here,
  11280. 8:58:24and those two operators, as of today, are these.
  11281. 8:58:27You can use the ampersand operator in C in a couple of ways.
  11282. 8:58:31We already saw it very briefly to do ampersand ampersand--
  11283. 8:58:34it's kind of and two Boolean expressions together
  11284. 8:58:37in the context of a conditional.
  11285. 8:58:39This is different.
  11286. 8:58:40A single ampersand is the address of operator.
  11287. 8:58:43So literally, in your code, if you've got a variable like n or anything else
  11288. 8:58:48and you write &n, C is going to figure out for you what is the address of that
  11289. 8:58:53variable n in the computer's memory.
  11290. 8:58:55And it's going to give you a number, otherwise known as the address of that.
  11291. 8:59:01If you want to store that address in a variable
  11292. 8:59:05even though yes, it's a number like 0x123, you have to tell C in advance
  11293. 8:59:11that you want to store not an int per se, but the address of an int.
  11294. 8:59:17And the syntax for doing that-- somewhat nonobviously-- is
  11295. 8:59:20to use an asterisk here, a star operator, and you
  11296. 8:59:24say this when creating the variable.
  11297. 8:59:26If you want p to be a pointer, that is the address of some other variable,
  11298. 8:59:30you do int star p.
  11299. 8:59:32And the star just tells the computer, this is not an integer per se,
  11300. 8:59:36this is the address of something that yes, is an int,
  11301. 8:59:40but we're just being more precise.
  11302. 8:59:41So on the right hand side you have the address of operator.
  11303. 8:59:44As always with the equal sign, you copy from right to left.
  11304. 8:59:47Because &n is by definition the address of something you have to store it
  11305. 8:59:51in a pointer, and the way to declare a pointer is to specify the type of value
  11306. 8:59:57whose address you're storing, and then use the star to indicate that this is
  11307. 9:00:01indeed a pointer and not just a regular old int.
  11308. 9:00:04So let's see this in practice.
  11309. 9:00:06Let me go back to my own source code here and let
  11310. 9:00:09me make just a couple of tweaks.
  11311. 9:00:11I'm going to leave n alone here but I'm going
  11312. 9:00:13to go ahead and initially just do this.
  11313. 9:00:18Let me say int star p equals ampersand n,
  11314. 9:00:22and then down here, I'm going to print out not n this time, but p--
  11315. 9:00:27the variable p.
  11316. 9:00:28And then even though yes, it's just a number and therefore I could use %i
  11317. 9:00:33for integers, there's actually a special format code in printf for printing
  11318. 9:00:37pointers or addresses, and that's %p.
  11319. 9:00:40So now let's go ahead and recompile this, make address--
  11320. 9:00:44so far so good-- ./address, Enter, and a little weirdly,
  11321. 9:00:49but perhaps understandably now, the address in my computer's memory
  11322. 9:00:53at which the variable n happened to be stored was not quite as simple
  11323. 9:00:57as 0x123.
  11324. 9:00:59This computer has a lot more memory so technically,
  11325. 9:01:01it was stored at 0x7FFCB4578E5C.
  11326. 9:01:07Now that has no special significance to me.
  11327. 9:01:10It could have ended up somewhere else altogether,
  11328. 9:01:12but this is just where, in my computer-- or technically the cloud
  11329. 9:01:15server to which I'm connected using VS Code here--
  11330. 9:01:18that just happens to be where n ended up.
  11331. 9:01:20And strictly speaking, I don't even need to introduce this variable.
  11332. 9:01:23I could get rid of p and I could just say
  11333. 9:01:26print not just n, but the address of n and achieve the same thing.
  11334. 9:01:30You don't need to temporarily store it in a variable.
  11335. 9:01:32Let me just do make address again, ./address,
  11336. 9:01:35and now I see this address here.
  11337. 9:01:38And notice if I keep running the program, it's actually moving around.
  11338. 9:01:41There's other stuff presumably going on inside of the computer.
  11339. 9:01:44Maybe it's actually randomizing it so it's not always at the same location.
  11340. 9:01:47That can actually be a security feature underneath the hood,
  11341. 9:01:50but this happens to be at that moment in time where that value is in memory,
  11342. 9:01:55quite like our picture a moment ago.
  11343. 9:01:58All right, so let me pause here to see if there's now
  11344. 9:02:02any questions on what we just did.
  11345. 9:02:03Yeah?
  11346. 9:02:05AUDIENCE: Is there any way to control where
  11347. 9:02:07you are storing something in memory?
  11348. 9:02:10Does it even matter if it works, or does it just
  11349. 9:02:14matter that you could go in and locate where something is?
  11350. 9:02:16DAVID J. MALAN: Really good question.
  11351. 9:02:18Is there any way to control where something is in memory?
  11352. 9:02:20Short answer is yes, and this is both the power in the danger of C,
  11353. 9:02:23and we're going to do this today and make a few deliberate mistakes,
  11354. 9:02:26because with this power of going to or getting the address of any variable,
  11355. 9:02:31I could just arbitrarily right now write code
  11356. 9:02:33that stores a value at byte 2 billion, or zero, or anything in between.
  11357. 9:02:37But that also means potentially, I could start creepily looking
  11358. 9:02:42around at all of the computer's memory, even at things that I didn't put there.
  11359. 9:02:46Maybe other programs, maybe other parts of programs
  11360. 9:02:48and indeed, this is a potential security threat,
  11361. 9:02:50if suddenly you're able to just look anywhere
  11362. 9:02:53you want in the computer's memory.
  11363. 9:02:54Now, I'm overselling it a little bit because nowadays, in this decade,
  11364. 9:02:59there are some defenses in place in compilers
  11365. 9:03:01and in our operating systems that do hedge against this a little bit.
  11366. 9:03:05But this is still a very frequent source of problems,
  11367. 9:03:07and later today we'll talk briefly about things
  11368. 9:03:10called stack overflow, which is not just a website,
  11369. 9:03:13it is a problem that you can encounter.
  11370. 9:03:15Heap overflow, and more generally buffer overflows--
  11371. 9:03:17there's just so many things that can go wrong using this language called C,
  11372. 9:03:21and if any of you have encountered a segmentation fault yet?
  11373. 9:03:24I think we saw a few hands for that already.
  11374. 9:03:26You touched memory that you shouldn't have
  11375. 9:03:29and odds are you did it most recently by going too far in an array.
  11376. 9:03:33Going to the left, or negative in an array, or somehow looking at memory
  11377. 9:03:37you shouldn't have.
  11378. 9:03:38And we'll explain today why it is you were able to do that.
  11379. 9:03:42Other questions on these primitives so far?
  11380. 9:03:44Yeah, from Carter?
  11381. 9:03:46AUDIENCE: [INAUDIBLE] pointer star p, but then we used p later in the code.
  11382. 9:03:50Is it called star p or p?
  11383. 9:03:51DAVID J. MALAN: Good question.
  11384. 9:03:52Earlier, we used star p.
  11385. 9:03:53Let me rewind in time to the previous version of this code,
  11386. 9:03:56where I actually had a variable called p.
  11387. 9:03:58Just like with variable declarations in the past,
  11388. 9:04:02once you've declared a variable to be an int, a char, a bool, or an int
  11389. 9:04:07star, a.k.a. a pointer, you don't thereafter
  11390. 9:04:11keep using the word int or now, the star.
  11391. 9:04:14Once you've declared it, that's it.
  11392. 9:04:15You only refer to it by name.
  11393. 9:04:17And so it's very deliberate what I did here,
  11394. 9:04:21saying that the type here is int star--
  11395. 9:04:24that is a pointer to an int--
  11396. 9:04:26but here I just said the name of the variable, as always.
  11397. 9:04:28I didn't repeat int, and I also didn't repeat star.
  11398. 9:04:31But at the risk of bending one's minds a little bit there
  11399. 9:04:34is unfortunately one other use for the star operator, and that's as follows.
  11400. 9:04:40If you want to print out not the address of something,
  11401. 9:04:44but what is at a specific address, you can actually do this.
  11402. 9:04:49If I want to print out the integer via %i, that is at that address,
  11403. 9:04:54I can actually use the star here, which technically contradicts what I just
  11404. 9:04:59said but it has a different function here-- a different purpose.
  11405. 9:05:02So let me go ahead and do this in two different ways.
  11406. 9:05:04I'm going to leave this line of code as is,
  11407. 9:05:06but I'm going to add another line of code now
  11408. 9:05:08that prints out what apparently will be an integer, in a moment.
  11409. 9:05:12So %i backslash n, and I could see-- and let me just do n for now.
  11410. 9:05:16So there's really nothing special happening now, I'm
  11411. 9:05:18just adding a sort of mindless printing of n.
  11412. 9:05:20So make address, ./address--
  11413. 9:05:23there's the current address of n and there's the value of n.
  11414. 9:05:26But what's kind of cool about C here, too,
  11415. 9:05:29is if you know that a value is at a specific address like p,
  11416. 9:05:34there's one other use for this star operator, the asterisk.
  11417. 9:05:37You can use it as the so-called dereference operator,
  11418. 9:05:41which means go to that address.
  11419. 9:05:44And so here what we actually have is an example of a pointer p,
  11420. 9:05:50which is an address like 0x123 or 0x7FF and so forth.
  11421. 9:05:54But if you say star p now, you're not redeclaring the variable
  11422. 9:05:58because I didn't mention int--
  11423. 9:05:59you're going to that address in p.
  11424. 9:06:02So let me recompile this now.
  11425. 9:06:04Make address, ./address, and just to be clear--
  11426. 9:06:10what should I see?
  11427. 9:06:12I'm first going to see the pointer itself, 0x something.
  11428. 9:06:15What's the second line of output I should presumably see now?
  11429. 9:06:21Shout a little louder.
  11430. 9:06:22So I'm hearing 50, and that's true because if you figure out the address
  11431. 9:06:27of n and print it in line seven, but then go to the address of n, a.k.a. p,
  11432. 9:06:33that's indeed going to just show you the number n--
  11433. 9:06:36the value of n again.
  11434. 9:06:39All right, any questions now on this syntax-- and I will concede,
  11435. 9:06:42I think this is confusing-- the fact that we
  11436. 9:06:44use the star for multiplication, the fact
  11437. 9:06:46that we use the star to declare a pointer,
  11438. 9:06:48but then we use a star in a third way to dereference the pointer
  11439. 9:06:51and go to the pointer.
  11440. 9:06:53It's just too confusing, honestly, but with practice comes comfort.
  11441. 9:06:56Yeah.
  11442. 9:06:58AUDIENCE: [INAUDIBLE]
  11443. 9:07:07DAVID J. MALAN: Good question.
  11444. 9:07:09Do you-- when you are using the ampersand operator
  11445. 9:07:12to get the address of something, the onus
  11446. 9:07:14is on you at the moment to know what you are getting the address of.
  11447. 9:07:18Is it a string?
  11448. 9:07:19Is it a char?
  11449. 9:07:20Is it a bool?
  11450. 9:07:21Is it an int?
  11451. 9:07:22I wrote this code so I know in line six that I'm
  11452. 9:07:25trying to get the address of what is an integer.
  11453. 9:07:28AUDIENCE: What about line eight?
  11454. 9:07:30DAVID J. MALAN: In line eight you don't have
  11455. 9:07:34to worry about that-- good question.
  11456. 9:07:36Notice in line eight, I didn't tell the computer, other than the %i,
  11457. 9:07:40what kind of address I'm going to, but I did already in line six.
  11458. 9:07:44I told the compiler that p, now and forever,
  11459. 9:07:47is going to be the address of an int.
  11460. 9:07:50That's enough information in advance so that printf, or really the language C,
  11461. 9:07:55still knows on line eight that p is a pointer to an int,
  11462. 9:07:59and that way it will print out all four bytes at that address,
  11463. 9:08:02not just part of it, and not more than those four bytes.
  11464. 9:08:06Good question.
  11465. 9:08:07Yeah, next to you.
  11466. 9:08:09AUDIENCE: Do pointers have pointers?
  11467. 9:08:10DAVID J. MALAN: Do pointers have pointers?
  11468. 9:08:11Yes.
  11469. 9:08:12We won't do this today by having pointers to pointers,
  11470. 9:08:16but yes, you can use star star, and then things get--
  11471. 9:08:19I'm sorry.
  11472. 9:08:21We won't do that today and we won't do that often.
  11473. 9:08:23In fact Python, another language, is just a couple of weeks
  11474. 9:08:26away, so hang in there.
  11475. 9:08:27Almost there.
  11476. 9:08:28A question back here?
  11477. 9:08:29Was there?
  11478. 9:08:31That was-- more verbal feedback like that
  11479. 9:08:33is helpful as we forge into the more complicated stuff.
  11480. 9:08:36Other questions?
  11481. 9:08:36Yeah.
  11482. 9:08:38AUDIENCE: What's the point of [INAUDIBLE]??
  11483. 9:08:43DAVID J. MALAN: What's the point of printing the address?
  11484. 9:08:46AUDIENCE: Like, using the address to [INAUDIBLE]..
  11485. 9:08:49DAVID J. MALAN: Sure.
  11486. 9:08:50What's the point of doing this?
  11487. 9:08:51If you don't mind, let me-- let's get there in a moment.
  11488. 9:08:54This is not the common use case, just printing out the address--
  11489. 9:08:56who really cares?
  11490. 9:08:58At the moment we care only for the sake of discussion.
  11491. 9:09:00We're soon going to start using these addresses.
  11492. 9:09:02So hang in there just a little bit for that one, too,
  11493. 9:09:05but it will solve some problems for us before long.
  11494. 9:09:08So let's actually just now depict what was going on inside of the computer's
  11495. 9:09:12memory just a moment ago.
  11496. 9:09:15So if I toggle back here, let me redraw my computer's memory,
  11497. 9:09:19now let me plop into the memory n, which is storing in this program
  11498. 9:09:22the number 50.
  11499. 9:09:23Where is p in my computer's memory?
  11500. 9:09:25Specifically, I don't know and apparently it moves around each time I
  11501. 9:09:29run the program so for the sake of discussion,
  11502. 9:09:31let's just propose that if 50 ended up at address 0x123, I don't know--
  11503. 9:09:36p ends up over here, at address--
  11504. 9:09:38whoops-- at whatever address this is here.
  11505. 9:09:42But notice a couple of curiosities now.
  11506. 9:09:44If p is a pointer, it's the address of something.
  11507. 9:09:47So the value in p should be an address, and I've indeed written it as such--
  11508. 9:09:530x123, and technically there's not an x there, there's not a zero there,
  11509. 9:09:57there's not even a 123 there per se-- there's
  11510. 9:09:59a pattern of bits that represents the address 0x123.
  11511. 9:10:03But again, that's weak zero-- don't care about binary day-to-day.
  11512. 9:10:07So if this is p, and this I claimed was n, why is p so much bigger?
  11513. 9:10:13Can someone conjecture here?
  11514. 9:10:15Because it turns out whether n is an int or a char or a bool,
  11515. 9:10:20which are different types-- heck, even a long--
  11516. 9:10:23it turns out that p is always going to take up eight squares on the board,
  11517. 9:10:27but why might that be?
  11518. 9:10:29What might explain that?
  11519. 9:10:34Yeah, thoughts?
  11520. 9:10:36AUDIENCE: Perhaps it allocates eight bytes,
  11521. 9:10:40but it doesn't know the type of the data [INAUDIBLE]..
  11522. 9:10:44DAVID J. MALAN: OK, fair.
  11523. 9:10:45Maybe it's allocating eight bytes because it doesn't know the type.
  11524. 9:10:47Turns out that's OK because an address is an address.
  11525. 9:10:50It's really up to the programmer to use it as a string or a char or a bool.
  11526. 9:10:53Other thoughts?
  11527. 9:10:55AUDIENCE: Maybe the first four for the actual number and the last four
  11528. 9:11:00is some null that [INAUDIBLE] where the pointer ends.
  11529. 9:11:06DAVID J. MALAN: OK, possibly.
  11530. 9:11:07It could be that pointers have some complexity like a backslash n
  11531. 9:11:10or something curious like that, like we talked about for strings.
  11532. 9:11:13Turns out that's not the case.
  11533. 9:11:15It turns out that pointers nowadays typically are, but not
  11534. 9:11:18always are eight bytes, a.k.a.
  11535. 9:11:2164 bits, because you and I-- our Macs, our PCs,
  11536. 9:11:24heck-- even our phones have a lot more memory than they did years ago.
  11537. 9:11:28Back in the day, a pointer might have only
  11538. 9:11:30been 32 bits, or even only eight bits way back in the day.
  11539. 9:11:34It's considered 32 bits, because that was the norm for some time.
  11540. 9:11:36How high can you count, roughly, if you've got 32 bits?
  11541. 9:11:40What's the number we keep rattling off?
  11542. 9:11:4332 bits is roughly 2 to the 32, so it's 4 billion,
  11543. 9:11:48and I keep saying it's 2 billion if you do negative, but in the world of memory
  11544. 9:11:52there's a reason I keep saying 2 billion bytes, two gigabytes,
  11545. 9:11:55because for a very long time that was the maximum amount of memory
  11546. 9:11:58a computer could have.
  11547. 9:11:59Why?
  11548. 9:12:00Because the pointers that the computers were using
  11549. 9:12:02were only, for instance, 32 bits.
  11550. 9:12:04And with 32 bits, depending on whether you allow for negatives or not,
  11551. 9:12:07you can count as high as 2 billion, roughly, or maybe 4 billion
  11552. 9:12:10but you know what-- your Mac, your PC, your phone
  11553. 9:12:13could not have had five gigabytes of memory, or 5 billion bytes of memory.
  11554. 9:12:17You certainly couldn't have had what computers nowadays come with,
  11555. 9:12:20which might be 8 gigabytes of memory--
  11556. 9:12:2216 gigabytes of memory.
  11557. 9:12:23Why?
  11558. 9:12:24Because with 4 bytes, or 32 bits, you literally, physically,
  11559. 9:12:28can't count that high, which means if I drew a picture of all of the memory we
  11560. 9:12:32would run out of numbers to describe them, which means most of my memory
  11561. 9:12:36would just be unusable.
  11562. 9:12:37So pointers nowadays are 64 bits, or eight bytes.
  11563. 9:12:41That's really big.
  11564. 9:12:41I can't even pronounce how big that number is,
  11565. 9:12:43but it's plenty for the next many years, and so
  11566. 9:12:46we've drawn it that way on the board here.
  11567. 9:12:48Now let's just abstract this away.
  11568. 9:12:49Let's get rid of all the other bytes that
  11569. 9:12:51are storing something or nothing else, and let's now
  11570. 9:12:54start to abstract away this complexity because the reality is,
  11571. 9:12:57to your question earlier--
  11572. 9:12:59what is this useful for, or what do we-- do we actually
  11573. 9:13:01care about these addresses?
  11574. 9:13:03Generally, no.
  11575. 9:13:04We're doing this so that you see there's no magic.
  11576. 9:13:06We're just moving things around and poking around in memory.
  11577. 9:13:09But what a person would typically do when talking about pointers
  11578. 9:13:12would literally be to just point at something.
  11579. 9:13:14I really don't care what address n is at,
  11580. 9:13:17so it suffices when general, when drawing pictures on a whiteboard,
  11581. 9:13:20having a discussion with another programmer,
  11582. 9:13:22you just draw an arrow from the pointer to the value in question,
  11583. 9:13:26because neither you nor I probably care about the specifics of 0x whatever.
  11584. 9:13:31There's your pointer-- it's literally an arrow, and we can see this.
  11585. 9:13:35So it turns out that these pointers, these addresses,
  11586. 9:13:37are not that dissimilar to what we've done for hundreds of years
  11587. 9:13:41in the form of a postal system.
  11588. 9:13:43For instance, here is a post office--
  11589. 9:13:45here, no-- here is a mailbox, and suppose
  11590. 9:13:48that this is a mailbox labeled p.
  11591. 9:13:50It's a pointer, and suppose there's another mailbox
  11592. 9:13:53way over there, which is just another bite of my computer's memory.
  11593. 9:13:57What are we really talking about?
  11594. 9:13:59Well, you store in a computer's memory values like the number 50,
  11595. 9:14:03or the word "hi" inside of your computer's memory at some location.
  11596. 9:14:07But today we can also use those same memory locations
  11597. 9:14:11to store the address of things.
  11598. 9:14:12For instance, if I open this up here and I
  11599. 9:14:16see OK, the value inside of this mailbox is not a number like 50,
  11600. 9:14:20it's actually an address--
  11601. 9:14:210x123-- that's like a pointer, a breadcrumb leading
  11602. 9:14:26from one location in memory to another.
  11603. 9:14:28And in fact, would someone who's seated roughly over there--
  11604. 9:14:30do you mind getting the mail over there?
  11605. 9:14:33Any volunteers over in this section?
  11606. 9:14:35Just need you to get to the mailbox before I do.
  11607. 9:14:38Who's being volunteered?
  11608. 9:14:40Oh yes, please.
  11609. 9:14:40Whoever is gesturing most wildly, come on down.
  11610. 9:14:46Sure.
  11611. 9:14:53What's your name?
  11612. 9:14:54AUDIENCE: Anfoo.
  11613. 9:14:55DAVID J. MALAN: Say again?
  11614. 9:14:56AUDIENCE: Anfoo.
  11615. 9:14:57DAVID J. MALAN: Anfoo?
  11616. 9:14:58OK, come on up to the edge of the stage there and just to be clear--
  11617. 9:15:01if this is p, that is apparently n, but to make clear
  11618. 9:15:05what we're talking about when we're storing 0x whatever values--
  11619. 9:15:07like 0x123, that's essentially equivalent to my
  11620. 9:15:11maybe pulling out something like this and just
  11621. 9:15:13abstractly pointing to your mailbox there,
  11622. 9:15:16or if you prefer, pointing to the mailbox--
  11623. 9:15:20OK, all right.
  11624. 9:15:24Thank you.
  11625. 9:15:24All right.
  11626. 9:15:28This is akin to me pointing at your mailbox,
  11627. 9:15:30and if you want to go ahead and open your mailbox
  11628. 9:15:32and reveal to the crowd what's inside your mailbox labeled n.
  11629. 9:15:38All right.
  11630. 9:15:41Thank you.
  11631. 9:15:43We have a little CS50 stress ball for your trouble.
  11632. 9:15:46Thank you for coming up.
  11633. 9:15:47So that's just to put a visual on what it is we're talking about,
  11634. 9:15:50because it can get very abstract, very cryptic quickly when we're
  11635. 9:15:53talking about addresses and memory and drawing it like these little squares.
  11636. 9:15:56But if you think about just walking into a post office or an apartment
  11637. 9:15:59complex that's got a lot of mailboxes, those mailboxes
  11638. 9:16:02essentially are a big chunk of memory and each
  11639. 9:16:05of those mailboxes has an address--
  11640. 9:16:07this is apartment one, two, three-- apartment 2 billion.
  11641. 9:16:10And inside of those mailboxes can go anything
  11642. 9:16:13that can be represented as information.
  11643. 9:16:15It could be a number like n, or 50, or if you
  11644. 9:16:18prefer it could be a number that represents
  11645. 9:16:21the address of another mailbox.
  11646. 9:16:22And this is akin, really, if you've ever had an apartment or you
  11647. 9:16:26and your parents have moved, to having a forwarding address.
  11648. 9:16:28It's like having the Post Office in the US
  11649. 9:16:31put some kind of piece of paper in your old mailbox saying,
  11650. 9:16:34actually forward it to that other mailbox.
  11651. 9:16:37That really is all a pointer is doing.
  11652. 9:16:39At the end of the day, it's just a number
  11653. 9:16:41but it's a number being used in a different way
  11654. 9:16:43and it's the syntax that we've introduced,
  11655. 9:16:45not just int but int star, that tells the computer how
  11656. 9:16:49to treat that number in this slightly different way.
  11657. 9:16:54Are there any questions then, on this?
  11658. 9:16:57Yeah, in back.
  11659. 9:16:59AUDIENCE: If you had a variable, like int c, [INAUDIBLE]..
  11660. 9:17:06DAVID J. MALAN: If I did int c and--
  11661. 9:17:08say the code again?
  11662. 9:17:10Once more?
  11663. 9:17:12Equal to n, so let me actually type it out.
  11664. 9:17:14If I give myself another line of code, tell me
  11665. 9:17:16one last time what to type. int is equal to n, like this?
  11666. 9:17:22So this is OK, and I can't draw it quite quickly enough on the board here,
  11667. 9:17:27but this would be like creating another four bytes somewhere in memory, maybe
  11668. 9:17:31down here, that stores an identical copy of 50
  11669. 9:17:35because the assignment operator from right to left copies one value
  11670. 9:17:38to another.
  11671. 9:17:39So that would just add one more rectangle of size four
  11672. 9:17:43to this particular picture.
  11673. 9:17:45If I'm answering your question as intended.
  11674. 9:17:47OK, so that is week one style use of assignment operators before pointers.
  11675. 9:17:52I could, though, start copying pointers but again, we'll
  11676. 9:17:55come back to some of that complexity.
  11677. 9:17:57Any other questions here?
  11678. 9:17:58AUDIENCE: That was a great question.
  11679. 9:18:00Does the pointer point--
  11680. 9:18:02does the same pointer point to the new replica as well?
  11681. 9:18:05DAVID J. MALAN: Ah, good question.
  11682. 9:18:06Short answer, no.
  11683. 9:18:07And to repeat for the camera, if I create a second variable like this,
  11684. 9:18:12int c equals n, and I claim without actually drawing it on the board
  11685. 9:18:16that this gives me another rectangle, the value of which is also 50,
  11686. 9:18:20p does not get touched.
  11687. 9:18:22And this is what's important and really characteristic
  11688. 9:18:24of C. Nothing happens automatically for you.
  11689. 9:18:28p is not going to be updated unless you update p in some way,
  11690. 9:18:31so creating a third variable called c-- even
  11691. 9:18:34if you're copying its value from right to left,
  11692. 9:18:36that has no effect on anything else in the program.
  11693. 9:18:40A good question.
  11694. 9:18:41So what have we seen that's perhaps now a little more explainable?
  11695. 9:18:47Well, recall that we talked quite a bit last week about strings, and just
  11696. 9:18:51to recap in layperson's terms, what is this string as you now understand it?
  11697. 9:18:57So say-- well, let me take a specific hand here.
  11698. 9:18:59What's a string?
  11699. 9:19:00How about over here.
  11700. 9:19:02AUDIENCE: An array of characters.
  11701. 9:19:03DAVID J. MALAN: OK, sure.
  11702. 9:19:04Both of you are right.
  11703. 9:19:05An array of characters.
  11704. 9:19:06An array of characters, and we--
  11705. 9:19:09I claimed-- or revealed last week that string is not technically
  11706. 9:19:12a feature built into C. It's not an official data type
  11707. 9:19:15but every programmer in most any language
  11708. 9:19:17refers to sequences of characters-- words, letters,
  11709. 9:19:21paragraphs-- as strings.
  11710. 9:19:22So the vernacular exists but the data type doesn't typically
  11711. 9:19:26exist per se in C. So what we're about to do, if you will,
  11712. 9:19:29for dramatic effect, is take off some training wheels today.
  11713. 9:19:32The CS50 library implemented in the form of the header file cs50.h--
  11714. 9:19:36we claim has had a bunch of things in it.
  11715. 9:19:38Prototypes for GetString, prototypes for GetInt,
  11716. 9:19:42and all of those other functions, but it turns out
  11717. 9:19:44it also is what defines the word "string" in such a way
  11718. 9:19:48that you all can use it these past several weeks.
  11719. 9:19:51So let's take a look at an example of a string in use.
  11720. 9:19:54Here, for instance, is a tiny bit of code
  11721. 9:19:56that uses the word "string," creating a variable called s
  11722. 9:20:00and then storing quote unquote, hi, exclamation point.
  11723. 9:20:03Let's consider what this looks like now in the computer's memory.
  11724. 9:20:06I don't care about all the other bytes, let's just focus on these,
  11725. 9:20:08and this per last week is how "hi" might be stored.
  11726. 9:20:11h-i exclamation point and then one more, as someone already
  11727. 9:20:14observed, that sentinel value-- that null character which
  11728. 9:20:18just means eight zero bits to demarcate the end of that string
  11729. 9:20:21just in case there's something to the right of it,
  11730. 9:20:24the computer can now distinguish one string from another.
  11731. 9:20:27So last week we introduced this new syntax.
  11732. 9:20:30Well, if strings are just arrays of characters
  11733. 9:20:32you can then very cleverly use that square bracket notation
  11734. 9:20:35and go to location zero or one or two, which are like addresses,
  11735. 9:20:39but they're relative to the string.
  11736. 9:20:41This could be at 0x123 or 0x456, but with this bracket notation
  11737. 9:20:46zero is always the beginning of the string, one is the next,
  11738. 9:20:49two is the next, and so forth.
  11739. 9:20:51So that was our array syntax for indexing into an array.
  11740. 9:20:55But technically speaking, we can go a little deeper today--
  11741. 9:20:58technically speaking, if hi is starting at the address 0x123 then
  11742. 9:21:05it stands to reason that i is at 0x124, exclamation point's at 0x125,
  11743. 9:21:11and the null is that 0x126.
  11744. 9:21:14Now, I don't care about 123 per se, but even though this is hexadecimal,
  11745. 9:21:18this is correct math.
  11746. 9:21:19Even in hex, if you just add one when you start at 0x123,
  11747. 9:21:23the next number is four, five, six at the end.
  11748. 9:21:25I don't have to worry about A's, B's, and C's
  11749. 9:21:27because I'm not counting that high in this example.
  11750. 9:21:30So if that's the case, and my computer is actually
  11751. 9:21:34laying out the word hi in memory like that, well, what exactly is s?
  11752. 9:21:42What exactly is s if, at the end of the day,
  11753. 9:21:45H-I exclamation point null is storing-- or is or stored at these addresses?
  11754. 9:21:51Where is s?
  11755. 9:21:52Now that I've taken off those training wheels
  11756. 9:21:54and showed you where H-I exclamation point null actually are,
  11757. 9:21:57what happened to s?
  11758. 9:21:59Well s, as always, is actually a variable.
  11759. 9:22:03Even in the code I proposed a moment ago,
  11760. 9:22:05s is apparently a data type that yes, doesn't come with C,
  11761. 9:22:08but CS50's library makes it exist.
  11762. 9:22:11s is a variable of type string, so where is s in this picture?
  11763. 9:22:16Well, it turns out that s might be up here.
  11764. 9:22:20Again, I'm just drawing it anywhere for the sake of discussion,
  11765. 9:22:24but s is a variable per that line of code.
  11766. 9:22:28What s is storing, apparently, I claim, is 0x123.
  11767. 9:22:32I actually don't really care about these addresses, so let's abstract that away.
  11768. 9:22:35s is apparently, as of now, today, one week later, just a pointer
  11769. 9:22:40to a character.
  11770. 9:22:42Specifically, the first character in s.
  11771. 9:22:44And this is the last piece of the puzzle.
  11772. 9:22:46Last week we had this clever way of demarcating the end of a string.
  11773. 9:22:50Well, it turns out that strings are represented in the computer's memory
  11774. 9:22:55as a variable that is a pointer, inside of which
  11775. 9:22:59is the address of the first character in the string.
  11776. 9:23:02So if s points at the first character and you
  11777. 9:23:05can trust that backslash zero is at the end of the string,
  11778. 9:23:07that's literally all you need to figure out where a string begins and ends.
  11779. 9:23:13So what do I mean by this?
  11780. 9:23:14Well, let's be a little more concrete.
  11781. 9:23:16In terms of this picture, if I've started with this line of code here,
  11782. 9:23:20it turns out all this time since week 1, that the word string has just
  11783. 9:23:25semi-secretly been an alias for char star.
  11784. 9:23:32I know, so char star.
  11785. 9:23:34So why does this make sense?
  11786. 9:23:36It's a little weird still, but if in our previous example
  11787. 9:23:39we were able to store the address of an integer by declaring a variable
  11788. 9:23:43called p, as int star p--
  11789. 9:23:45well, if as of now strings are just the address
  11790. 9:23:48of the first character in a string, then probably a string is just a char star
  11791. 9:23:53because that means s is the address of a character, the very
  11792. 9:23:57first character in the string.
  11793. 9:23:58Now, the string might have three letters like it did, or four, or even a hundred
  11794. 9:24:02if it's a long paragraph, but that's fine
  11795. 9:24:04because you can trust that there's going to be
  11796. 9:24:06that null character at the very end.
  11797. 9:24:08So this is a general purpose way of representing strings
  11798. 9:24:12using this new mechanism in C.
  11799. 9:24:15So in fact, let me go ahead here and introduce maybe
  11800. 9:24:18a couple of manipulations of this.
  11801. 9:24:20Let me go back to my code here, and let's get rid of this integer stuff,
  11802. 9:24:24and let's instead now do, for instance, this.
  11803. 9:24:27Let me add in the CS50 library, so we'll include CS50.H for now.
  11804. 9:24:32I'm going to go ahead and inside of main,
  11805. 9:24:34give myself a string s equals hi exclamation point.
  11806. 9:24:37I don't type the backslash zero.
  11807. 9:24:38C does that for me automatically by using my double quotes like this.
  11808. 9:24:43Now let me just go ahead and print it.
  11809. 9:24:45So this again is week 1 style stuff where I'm just printing a string.
  11810. 9:24:48No pointers yet.
  11811. 9:24:49So let me do make address, Enter, ./address, and hopefully I see hi,
  11812. 9:24:55so nothing new there.
  11813. 9:24:56But let's start to peel back some of these layers here.
  11814. 9:25:00Let me first of all, get rid of the CS50 library for a moment
  11815. 9:25:04and let me change string to char star.
  11816. 9:25:09And it's a little bit weird but yes, the convention
  11817. 9:25:11is to say char, a space, then the star, and then immediately thereafter
  11818. 9:25:15the name of the variable.
  11819. 9:25:16Strictly speaking though, you might see textbooks or websites that
  11820. 9:25:19do it like this or like this, but the canonical way
  11821. 9:25:22is typically to do it like that.
  11822. 9:25:23So now no more CS50 library, no more training wheels, if you will.
  11823. 9:25:26I'm just treating strings for what they really are.
  11824. 9:25:29Let me go ahead and do make address, Enter--
  11825. 9:25:32so far so good-- ./address--
  11826. 9:25:34and that, too, still works.
  11827. 9:25:36So %s is a thing that comes with printf because the word string is programmer
  11828. 9:25:40terminology but strictly speaking C doesn't have a string data type.
  11829. 9:25:44It's always been char star, so what this means now is I
  11830. 9:25:48can start to have some fun with these basic ideas,
  11831. 9:25:52even though this is not purposeful other than for the sake of discussion.
  11832. 9:25:55But if s is this-- let me go back and give myself the CS50 library.
  11833. 9:25:59Let's put those training wheels back on for just a moment
  11834. 9:26:01so that I can do one manipulation at a time.
  11835. 9:26:04Here's my string s, as before.
  11836. 9:26:07Well, let me go ahead and declare a char called c,
  11837. 9:26:10and let me store the first character in the string there, which is
  11838. 9:26:15s bracket zero, and that should give me h.
  11839. 9:26:18And then just for kicks, let me go ahead and do char star--
  11840. 9:26:21whoops-- let me go ahead and do char star p equals ampersand c,
  11841. 9:26:28and see what this actually prints for me.
  11842. 9:26:30Let me go ahead and print out what p is here.
  11843. 9:26:34So we're just playing around.
  11844. 9:26:35So make address-- so far so good-- ./address.
  11845. 9:26:39All right, so what have I just done?
  11846. 9:26:41I've just created a char c and stored in it the letter H, which
  11847. 9:26:46is the same thing as s bracket I, then I'm saying, what's the address of c,
  11848. 9:26:50and that's apparently 0x7FF whatever.
  11849. 9:26:53So that's the address.
  11850. 9:26:55But I technically didn't have to do that.
  11851. 9:26:57Let me go ahead and do two things now.
  11852. 9:26:59Instead of just printing p, let me go ahead and print out maybe s itself.
  11853. 9:27:07Let me go ahead and do make address, Enter--
  11854. 9:27:09so far so good-- ./address and--
  11855. 9:27:12damn it, what did I do wrong.
  11856. 9:27:15Oh shoot, I didn't want to do that.
  11857. 9:27:17Oh, I really made a mess of this.
  11858. 9:27:21What did I want to do here?
  11859. 9:27:23That was supposed to be impressive but it was the opposite.
  11860. 9:27:27So let me turn it around.
  11861. 9:27:30So if I intended to do this, why are lines nine and 10
  11862. 9:27:34printing different values?
  11863. 9:27:36Didn't really intend to go here, but let me try to save this.
  11864. 9:27:40Why are we seeing different addresses, namely this address 402004 for s,
  11865. 9:27:47and then 0x7FF for p?
  11866. 9:27:52Any thoughts?
  11867. 9:27:53Yeah, over here.
  11868. 9:27:55AUDIENCE: [INAUDIBLE] is the character c is
  11869. 9:27:57its own sort of location of the [INAUDIBLE],,
  11870. 9:28:02and it's taking off just the values [INAUDIBLE]..
  11871. 9:28:04DAVID J. MALAN: Correct.
  11872. 9:28:05So if I really wanted to weasel my way out of this,
  11873. 9:28:08this is a great answer to the previous question which was about,
  11874. 9:28:10what if I introduce another variable, c, that's a copy of the value,
  11875. 9:28:15and not in this case an int, but an actual char.
  11876. 9:28:18Here, I've made c be a copy of the character that's at the beginning of s,
  11877. 9:28:23but that's indeed a copy.
  11878. 9:28:24So if I were to draw it on the screen that
  11879. 9:28:26would give me a different rectangle in which this copy of h
  11880. 9:28:30would actually be stored.
  11881. 9:28:32So I didn't intend to do this, but what you're
  11882. 9:28:33seeing is yes, the address of s--
  11883. 9:28:35and apparently that's at a pretty low address by default
  11884. 9:28:38here-- then you're seeing the address of c.
  11885. 9:28:40But even though each of them is h, I claim
  11886. 9:28:43one is at a different address in memory.
  11887. 9:28:45And this has always been happening.
  11888. 9:28:46Any time you created one variable or another it was ending up here,
  11889. 9:28:49or here, or here, or somewhere else in memory.
  11890. 9:28:51Now for the first time all we're doing is actually just poking around
  11891. 9:28:54the computer's memory to see what is actually there.
  11892. 9:28:57So let me actually back this up a little bit
  11893. 9:29:01and do what I intended to do here, which was something like this.
  11894. 9:29:04So if string s equals quote unquote, hi, let's go ahead
  11895. 9:29:08and give myself a pointer, called p, to the first character in s.
  11896. 9:29:18All right, so now let me go ahead and print out the value of this pointer,
  11897. 9:29:22%p, printing out p.
  11898. 9:29:24So we're just going to do one thing at a time.
  11899. 9:29:26So make address, Enter, ./address.
  11900. 9:29:29There, at the moment, is the address of the first character in s.
  11901. 9:29:34What I meant to do now, was this.
  11902. 9:29:36If I want to print out two things this time,
  11903. 9:29:39let me print out not only what p is, but also what s itself originally is.
  11904. 9:29:44Because if I claim that everyone from last week should be comfortable with
  11905. 9:29:48s bracket zero just representing the first character in s
  11906. 9:29:51by definition of strings being arrays of characters.
  11907. 9:29:54Then s, as of today, is itself the address of a character,
  11908. 9:30:01the first one in s.
  11909. 9:30:02So if I now do make address, and do ./address,
  11910. 9:30:06this time I see the same exact things.
  11911. 9:30:08Thank you.
  11912. 9:30:13This is really the lamest sort of thing to be applauding over,
  11913. 9:30:16but what we're demonstrating here is that s is by definition the address
  11914. 9:30:21of the first character in c.
  11915. 9:30:23So if we borrow some of our mental model from last week--
  11916. 9:30:26well, if s bracket zero is the first character in c, doing the ampersand on
  11917. 9:30:31that expression should be the same as s.
  11918. 9:30:33Now this isn't to say that we would jump through these hoops
  11919. 9:30:36all the time with this much syntax, but this is just to do proof by example
  11920. 9:30:40that s is in fact, as I claimed a moment ago, just the address of a character.
  11921. 9:30:46Not even multiple characters, it's the address of a single character,
  11922. 9:30:50but the key thing is it's the address of the first character in the string,
  11923. 9:30:53and per last week we trust that C is going
  11924. 9:30:57to look for that null character at the very end just
  11925. 9:31:00to make sure it knows where the string actually ends.
  11926. 9:31:04All right, a question came up over here.
  11927. 9:31:07AUDIENCE: [INAUDIBLE]
  11928. 9:31:20DAVID J. MALAN: Correct.
  11929. 9:31:21To summarize, on line eight, when I am using %p--
  11930. 9:31:25that just means print a pointer value, so 0x something--
  11931. 9:31:28I'm passing it s.
  11932. 9:31:30Previously, when we used %s, printf knew to print not just the first character
  11933. 9:31:36of s, but h, i, exclamation point, and then stop when it hits the backslash
  11934. 9:31:40zero.
  11935. 9:31:41p is different. %p tells the computer to go to that address--
  11936. 9:31:47sorry, tells the computer to print that address on the screen.
  11937. 9:31:52So this is where %s all this time has been powerful.
  11938. 9:31:55The reason printf worked in week 1 and 2 and 3
  11939. 9:31:59was because printf was designed by some human years ago
  11940. 9:32:02to go to the address that's being passed in-- for instance,
  11941. 9:32:05s-- and print out character after character
  11942. 9:32:07after character until it sees the null character backslash zero,
  11943. 9:32:11and then stop printing it.
  11944. 9:32:13So that's-- you're getting a lot of functionality for free from %s.
  11945. 9:32:16Today we're using something much simpler, %p,
  11946. 9:32:19which just literally prints what s is.
  11947. 9:32:22And the reason we don't do this in week 1
  11948. 9:32:24is just because this is like way too much
  11949. 9:32:26to be interesting when all you want to print out
  11950. 9:32:28is hi or hello, world, or the like.
  11951. 9:32:29But now what we're really doing is revealing
  11952. 9:32:31what's been going on this whole time.
  11953. 9:32:34And let me make one other example here.
  11954. 9:32:36Let me go ahead and get rid of this variable
  11955. 9:32:37here and let me just print out a few things to make the same point.
  11956. 9:32:41I'm going to print out not just s like I did here, but let's go ahead
  11957. 9:32:45and print out every--
  11958. 9:32:46the address of every character in s.
  11959. 9:32:48So let's get the first letter in s and get its address,
  11960. 9:32:52and I'm going to do copy paste for time's sake,
  11961. 9:32:54but not something I would do frequently.
  11962. 9:32:57So let me print out the address of the first character, the second character,
  11963. 9:33:01the third, and actually even the fourth, which
  11964. 9:33:03is the backslash zero, by doing this.
  11965. 9:33:06So when I compiled this program-- make address, ./address--
  11966. 9:33:11I should see two identical values and then
  11967. 9:33:14additional values that are one byte away.
  11968. 9:33:17In my diagram a moment ago, my addresses were arbitrarily 0x123, 124, 125, 126.
  11969. 9:33:22Now it starts at, by chance, 0x402004, which is s.
  11970. 9:33:290x402004 is the same thing as s because I'm just
  11971. 9:33:32saying go to the first character and then get its address.
  11972. 9:33:35Those are one in the same now.
  11973. 9:33:36And then after that is 0x402005, 006, 007,
  11974. 9:33:42because that is just like the diagram.
  11975. 9:33:44Go to the i, to the exclamation point, and to the null character.
  11976. 9:33:48So all I'm doing now is using my newfound understanding of what
  11977. 9:33:51ampersand does and what the star does, is I'm just playing around.
  11978. 9:33:54I'm poking around in the computer's memory.
  11979. 9:33:57Just to demonstrate there's no magic.
  11980. 9:33:59It's all there very deliberately because I or printf or someone
  11981. 9:34:02else put it there.
  11982. 9:34:02Yeah.
  11983. 9:34:04AUDIENCE: [INAUDIBLE]
  11984. 9:34:11DAVID J. MALAN: Really good observation.
  11985. 9:34:12So it's indeed the case that hi, unlike 50,
  11986. 9:34:16is ending up at a very low address, not the 0x7FF wherever it was.
  11987. 9:34:21That's actually because, long story short, strings
  11988. 9:34:24are often stored in a different part of the computer's memory--
  11989. 9:34:27more on that later today-- for efficiency.
  11990. 9:34:29There's actually only going to be one copy of the word "hi" and exclamation
  11991. 9:34:32point, and the computer is going to tuck it at the beginning of my memory,
  11992. 9:34:36but other values like ints and floats and the
  11993. 9:34:39like-- they end up lower in memory by convention.
  11994. 9:34:41But a good observation, because that is consistent here.
  11995. 9:34:45All right, so a couple final details then, on what's been going on here.
  11996. 9:34:48Let me go ahead and claim that we implemented char star--
  11997. 9:34:54or rather, string as a char star as follows.
  11998. 9:34:56As of last week we were writing this code.
  11999. 9:34:59As of this week, we can now start writing this code because char star
  12000. 9:35:03specifically, we invented in the CS50 library.
  12001. 9:35:06But it turns out you've seen a way of inventing your own data types.
  12002. 9:35:10Recall this thing here.
  12003. 9:35:11We played around last time with data structures, or the struct keyword in C,
  12004. 9:35:16and briefly the typedef keyword, which defines a type for you.
  12005. 9:35:20And if I highlight what's interesting here,
  12006. 9:35:22the way we invented a person data type last time
  12007. 9:35:25was to define a person as having two variables inside of it--
  12008. 9:35:28a structure that encapsulates a name and encapsulates a number.
  12009. 9:35:33Now even though the syntax is a little different today because of the star
  12010. 9:35:37thing, notice that this could be a similar application of that idea.
  12011. 9:35:43If I want to create a type called string, highlighted in yellow here,
  12012. 9:35:47then I use typedef to make it defined to be char star.
  12013. 9:35:51So this is literally all that has ever been in CS50.h,
  12014. 9:35:55in addition to those prototypes of functions we've talked about.
  12015. 9:35:58typedef char star string is a one-line code
  12016. 9:36:01that brings the word string as a data type into existence,
  12017. 9:36:05and that's all that's ever been there.
  12018. 9:36:07But the star, the char star, is just too much in week 1.
  12019. 9:36:10We wait until this point to peel back that layer.
  12020. 9:36:14are any questions, then, on what a string is?
  12021. 9:36:16What star or the ampersand are doing?
  12022. 9:36:19Yeah.
  12023. 9:36:20AUDIENCE: [INAUDIBLE]
  12024. 9:36:23DAVID J. MALAN: Oh my God.
  12025. 9:36:25Massive spoiler, but yes.
  12026. 9:36:26If that is-- is that why when you compare two strings as I briefly
  12027. 9:36:30did, or almost did, problems arise.
  12028. 9:36:34And in fact yes, last week we use str compare--
  12029. 9:36:36STRCMP-- for a very deliberate reason because yes, the spoiler is I
  12030. 9:36:40accidentally would have compared two addresses in memory, not the strings
  12031. 9:36:45at those addresses.
  12032. 9:36:47Other questions here.
  12033. 9:36:50All right, well, before we give ourselves maybe a 10 minute break here,
  12034. 9:36:53we have lots of pieces of paper.
  12035. 9:36:54If anyone wants to come on up and play with this big stack of Post-Its,
  12036. 9:36:57if you want to make your own eight by eight grid of something
  12037. 9:36:59to share with the class if you're artistically inclined, come on up.
  12038. 9:37:02Otherwise, let's take 10 minutes and will return after 10.
  12039. 9:37:05All right, so let's come back to this question of how
  12040. 9:37:10we can start to use these pointers and these addresses, ultimately
  12041. 9:37:13in an interesting way.
  12042. 9:37:14The goal ultimately next week is going to be
  12043. 9:37:16to use these addresses to really stitch together more complicated data
  12044. 9:37:20structures than just persons, like last week, or candidates
  12045. 9:37:23in the context of an electoral algorithm,
  12046. 9:37:25if you will, and actually really use our memory in the most versatile way
  12047. 9:37:28to represent not just images but maybe videos
  12048. 9:37:32and other two-dimensional structures as well.
  12049. 9:37:34But for now, let's come back to this address example,
  12050. 9:37:36whittle it down to just a hi initially, and see what's going on again, here
  12051. 9:37:41underneath the hood.
  12052. 9:37:42So let me re-add the CS50 library just so we
  12053. 9:37:45use our synonym for a moment, that is the word string,
  12054. 9:37:49and I'll redefine s as a string.
  12055. 9:37:51And what I didn't mention before is that these double quotes
  12056. 9:37:54that you've been using for some time are actually a little special.
  12057. 9:37:57The double quotes are a clue to the compiler
  12058. 9:38:00that what is between them is in fact a string as we now know it,
  12059. 9:38:04which means the compiler will do all the work of figuring out
  12060. 9:38:07where to put the h, the i, the exclamation point,
  12061. 9:38:10and even adding for you automatically a backslash zero.
  12062. 9:38:13And what the compiler will do for you, too,
  12063. 9:38:15is figure out what address all four of those chars
  12064. 9:38:18ended up at and store it for you in the variable s.
  12065. 9:38:22So that's why it just happens with strings without using ampersands
  12066. 9:38:26or even stars explicitly, but the star at least has been there because again,
  12067. 9:38:31string is just synonymous now with char star.
  12068. 9:38:33It's not really as readable, but it is now the same idea.
  12069. 9:38:37So I'll leave string in place just to do something week
  12070. 9:38:401 style here for a moment, and let's go ahead and print out a few characters.
  12071. 9:38:43So I'm going to use %c this time, and I'm going to print out s bracket zero
  12072. 9:38:49and then I'm going to print out s bracket one and s bracket two,
  12073. 9:38:54literally doing week three style from last week--
  12074. 9:38:58a printing of every character in s as though it were an array.
  12075. 9:39:03So ./address should give me h-i exclamation point.
  12076. 9:39:06And if I really want to get curious, technically speaking,
  12077. 9:39:09I could print out one more location, and let me go ahead and recompile,
  12078. 9:39:14make address ./address and there is, it would seem, the backslash zero.
  12079. 9:39:19I'm not seeing zero because I didn't type literally the zero char in ASCII,
  12080. 9:39:25it's literally eight zero bits which are technically unprintable,
  12081. 9:39:28if you will, in printf speak.
  12082. 9:39:30And so what I'm seeing here is like a blank symbol.
  12083. 9:39:32That just means there is something else there--
  12084. 9:39:34it's apparently all eight zero bits, but they are there
  12085. 9:39:39even though we're not seeing them literally right now.
  12086. 9:39:41Well, let's go ahead and peel back one of these layers
  12087. 9:39:44and let me go ahead and get rid of the CS50 library and get rid of,
  12088. 9:39:48therefore, the word string because again, henceforth it's just char star.
  12089. 9:39:51Nothing else is different.
  12090. 9:39:53I'm going to now do make address, ./address,
  12091. 9:39:56and it's the same exact thing.
  12092. 9:39:57And now, let's just focus on the hi rather than even worry about that.
  12093. 9:40:00So I'm going to recompile one last time and now I have h-i exclamation point.
  12094. 9:40:05Well, it turns out that the array notation we used last week
  12095. 9:40:10was technically some of this syntactic sugar.
  12096. 9:40:12Sort of a neat way to use syntax in a useful way,
  12097. 9:40:16but we can see more explicitly today what the square brackets for a string
  12098. 9:40:21is actually doing.
  12099. 9:40:23Let me go ahead and do this.
  12100. 9:40:25Let me adventurously say I want to print out not s bracket
  12101. 9:40:30zero, but I want to print out whatever the first character of s is.
  12102. 9:40:36So to be clear, what is s now?
  12103. 9:40:38It's the address of a string.
  12104. 9:40:39OK, but what is s, really?
  12105. 9:40:41s is the address of the first char in a string
  12106. 9:40:44and again, that's sufficient for defining a string because eventually
  12107. 9:40:47the computer will see that there's a backslash n at the end of it.
  12108. 9:40:50So s is specifically the address of the first character in a string.
  12109. 9:40:56So that means, using my new syntax, if I want
  12110. 9:40:59to print out that first character I can print out star
  12111. 9:41:02s, because recall that star is the dereference operator when you don't
  12112. 9:41:06repeat the word char, you don't repeat the word int--
  12113. 9:41:09you just use the star here.
  12114. 9:41:10That means go to that address.
  12115. 9:41:13Similarly, if I, in my newfound knowledge of how strings work,
  12116. 9:41:18know that the h comes first, then the i right after it,
  12117. 9:41:21then the exclamation point, then the backslash zero, contiguously
  12118. 9:41:25one byte apart, I could start to do some arithmetic.
  12119. 9:41:29I could go to s plus 1 byte and print out the second character,
  12120. 9:41:34and I could print out whatever is at s plus 2--
  12121. 9:41:38in fact, doing what's generally known as pointer arithmetic.
  12122. 9:41:41Literally treating pointers as the numbers they are--
  12123. 9:41:44hexadecimal or decimal, doesn't really matter-- it's still just numbers.
  12124. 9:41:48And go ahead and add one byte or two bytes
  12125. 9:41:51to them to start at the beginning of a string
  12126. 9:41:53and just poke around from left to right.
  12127. 9:41:56So this now is equivalent to what we did last week using square bracket
  12128. 9:42:00notation, but now I'm re implementing that same idea with this lower level
  12129. 9:42:05plumbing, understanding ampersand and stars now a little bit more,
  12130. 9:42:09so if I remake this program and do ./address,
  12131. 9:42:11I should still see h-i exclamation point.
  12132. 9:42:14But what I'm really doing is just kind of demonstrating,
  12133. 9:42:16hopefully, my understanding of what really
  12134. 9:42:20is going on in the computer's memory.
  12135. 9:42:22Now, programmers who are maybe trying to show off
  12136. 9:42:24might actually write this syntax.
  12137. 9:42:25I think the more common syntax would be what we did last week--
  12138. 9:42:28s bracket zero, s bracket one.
  12139. 9:42:30Why?
  12140. 9:42:30It's just a little more readable and we don't
  12141. 9:42:32need to brag about or care about this underlying representation.
  12142. 9:42:36The square brackets last week we're an abstraction, if you will,
  12143. 9:42:39on top of what is lower level math.
  12144. 9:42:42But that's all that's going on underneath the hood.
  12145. 9:42:44We're poking around from byte to byte to byte.
  12146. 9:42:48All right, let me pause here, see if there's any questions on that one.
  12147. 9:42:53Any questions on this?
  12148. 9:42:56Let's do one more then, just to demonstrate that this is not
  12149. 9:42:59even specific to strings.
  12150. 9:43:00Let me go ahead and get rid of all of this
  12151. 9:43:02and let me give myself an array of numbers like I did last week.
  12152. 9:43:06So if I'm going to declare all the numbers
  12153. 9:43:09at once using this funky curly brace notation,
  12154. 9:43:11I can do like 4, 6, 8, 2, 7, 5, 0.
  12155. 9:43:15So seven different numbers inside of an array that's automatically
  12156. 9:43:19initialized like this.
  12157. 9:43:20I don't, strictly speaking, need to say seven.
  12158. 9:43:22The compiler is smart enough to figure out
  12159. 9:43:24how many numbers I put with commas between them,
  12160. 9:43:26and that just gives me an array containing 4, 6, 8, 2, 7, 5, 0.
  12161. 9:43:31So it turns out I can print each of these numbers in the familiar way.
  12162. 9:43:34I can do a printf of %i backslash n, and I can print numbers bracket zero,
  12163. 9:43:40and let me just do some quick copy/paste just to print the first three of these.
  12164. 9:43:44Theoretically, that should print out 4, 6, 8, and so forth.
  12165. 9:43:49But I can do the same sort of manipulation understanding
  12166. 9:43:52what pointers now are, using pointer arithmetic.
  12167. 9:43:55So let me actually unwind this and just go back to one printf,
  12168. 9:43:59and instead of printing numbers bracket zero like I might have last week,
  12169. 9:44:02let me just go and print out whatever is at that address--
  12170. 9:44:06so asterisk numbers.
  12171. 9:44:08Let me then print out the second digit, which
  12172. 9:44:11is going to be whatever is at numbers plus 1, and then let me do this further
  12173. 9:44:16and do whatever is at numbers plus 2, and if I really want to repeat this,
  12174. 9:44:20let me do it four more times and do what's
  12175. 9:44:22at location three, four, five, and six.
  12176. 9:44:27And that's seven total numbers because I started counting at zero.
  12177. 9:44:30So let me just quickly run this.
  12178. 9:44:32Make address, ./address.
  12179. 9:44:35There are those seven digits being printed.
  12180. 9:44:37But there's something subtle but also useful here.
  12181. 9:44:41Each of these digits--
  12182. 9:44:424, 6, 8, 2,7,5, 0--
  12183. 9:44:44is an int.
  12184. 9:44:45Why?
  12185. 9:44:45Because I made an array of integers.
  12186. 9:44:47But think back-- how big is a typical integer, have we claimed?
  12187. 9:44:52Four bytes, or 32 bits, so it's worth noting that I don't really
  12188. 9:44:58need to worry about that detail.
  12189. 9:45:00Notice that I did not do plus 4, plus 8, plus 12, plus 16, plus 20.
  12190. 9:45:05I, the programmer, strictly speaking, don't
  12191. 9:45:07need to worry about how big the data type is.
  12192. 9:45:09This is the power of pointer arithmetic.
  12193. 9:45:11The compiler is smart enough to know that if you add 1 to this pointer,
  12194. 9:45:17that is the same as saying go one more piece of data--
  12195. 9:45:21not just one byte--
  12196. 9:45:22so if it's an int, move four.
  12197. 9:45:24If it's a second int, move eight.
  12198. 9:45:26If it's a third int, move 12.
  12199. 9:45:27Pointer arithmetic handles that annoying arithmetic for you
  12200. 9:45:31so you can just think of this as a number after a number
  12201. 9:45:33after a number that are back to back to back but not one byte apart,
  12202. 9:45:37but four bytes apart.
  12203. 9:45:38Which is only to say plus 1, plus 2, plus 3 works no matter the data type.
  12204. 9:45:42Why?
  12205. 9:45:43Because the compiler knows what type of data you're talking about.
  12206. 9:45:48Now, there's one other detail I should reveal here
  12207. 9:45:51that I've taken for granted.
  12208. 9:45:54In the past I was using double quotes to represent strings,
  12209. 9:45:57and I claim that the compiler's smart enough to realize that oh,
  12210. 9:45:59if I have double quote hi, that means it's an array of h-i exclamation point,
  12211. 9:46:04and then the backslash zero.
  12212. 9:46:05Notice this usefulness.
  12213. 9:46:08It turns out that you can actually treat arrays as though the name of the array
  12214. 9:46:13is itself a pointer, and this is actually
  12215. 9:46:16going to be something useful in upcoming problems
  12216. 9:46:18when we want to pass arrays around in the computer's memory.
  12217. 9:46:22Notice that strictly speaking on line five, there's no pointers going on.
  12218. 9:46:25There's no star, there's no ampersand-- there's
  12219. 9:46:27nothing new there, and yet instantly on line seven
  12220. 9:46:31I'm pretending that it is the address, and this is actually OK.
  12221. 9:46:35It turns out that an array really can be treated
  12222. 9:46:39as the address of the first element in that array.
  12223. 9:46:43The difference is that there's no secret backslash zero anywhere.
  12224. 9:46:47This is just part of the phone number here,
  12225. 9:46:49the ending in zero-- that's not like a special backslash zero.
  12226. 9:46:52So this is something we're going to take advantage of too, before long.
  12227. 9:46:55There's this interrelationship between addresses and arrays
  12228. 9:46:58that just generally allows you to treat one as though it is the other,
  12229. 9:47:03but the math is taken care of for you.
  12230. 9:47:05Are any questions then on this before we start to solve some bigger problems?
  12231. 9:47:10Yeah.
  12232. 9:47:12AUDIENCE: [INAUDIBLE]
  12233. 9:47:19DAVID J. MALAN: Potentially.
  12234. 9:47:20If you go beyond the end of an array, you might get a segmentation fault.
  12235. 9:47:24The problem is that that symptom is sometimes nondeterministic,
  12236. 9:47:27which means that sometimes it will happen, sometimes it won't.
  12237. 9:47:30It often depends on how far off the end of the array you actually go.
  12238. 9:47:34You'll often not induce the segmentation fault
  12239. 9:47:36if you just poke a little too far, but if you go way too far
  12240. 9:47:39it quite likely will.
  12241. 9:47:41But we'll give you a tool today actually for detecting and solving
  12242. 9:47:44exactly that kind of situation.
  12243. 9:47:46So let's go ahead now and do something a little different in code,
  12244. 9:47:49but that actually comes back to that spoiler from earlier.
  12245. 9:47:51Let me go ahead and create a program called compare.c, and in this program
  12246. 9:47:56I'm going to go ahead and allow myself the CS50 library,
  12247. 9:48:00not so much for string but so that I can actually use GetInt still,
  12248. 9:48:03which is way easier than the way we'll see that C normally lets you get input.
  12249. 9:48:07Let me give myself stdio.h, do an int main(void),
  12250. 9:48:10not worrying about command line arguments today, and let me go ahead
  12251. 9:48:13and get an int i using get int, and ask the human for the value of i,
  12252. 9:48:18then let me give myself an int j, ask the user for another int, calling it j,
  12253. 9:48:23and then let me go ahead and kind of naively, but to your point earlier,
  12254. 9:48:27if i equals equals j, then let's go ahead
  12255. 9:48:31and print out something like "same," backslash n, else let's go ahead
  12256. 9:48:36and print out "different" if they are not, in fact, the same.
  12257. 9:48:40So that would seem to be a program that compares the value of two integers.
  12258. 9:48:44All right, so let's go ahead and run make compare--
  12259. 9:48:46so far so good-- ./compare.
  12260. 9:48:48OK, i will be 50, j will be 50--
  12261. 9:48:52they're the same.
  12262. 9:48:53Let's do it once more.
  12263. 9:48:54i will be 50, j will be 42.
  12264. 9:48:57They are different.
  12265. 9:48:58So so far, so good in this first version of comparison.
  12266. 9:49:02But as you might see where I'm going with this,
  12267. 9:49:05let's move away from integers and let's actually change these things to char--
  12268. 9:49:09to strings.
  12269. 9:49:10So I could do string s over here--
  12270. 9:49:13GetString s over here.
  12271. 9:49:15Then I could do string t over here, and GetString over here,
  12272. 9:49:22asking the user for t this time, here.
  12273. 9:49:25And then I can compare the two.
  12274. 9:49:26If s equals equals t--
  12275. 9:49:28and this is a common convention.
  12276. 9:49:30If you've used s for string already you can use t for the next one, at least
  12277. 9:49:33for simple demonstrations like this.
  12278. 9:49:34I'm going to compare the two, just like I did for ints, which worked great.
  12279. 9:49:37Make compare-- so far so good-- ./address--
  12280. 9:49:41oh, sorry.
  12281. 9:49:42Wrong program-- ./compare.
  12282. 9:49:44Let me go ahead and type in something like
  12283. 9:49:47hi, exclamation point and bye, exclamation point, which of course
  12284. 9:49:52should definitely be different.
  12285. 9:49:54Let me run it again with hi, exclamation point and hi, exclamation point.
  12286. 9:50:00Different-- maybe I messed up.
  12287. 9:50:02Let's maybe do it lowercase, maybe that'll fix.
  12288. 9:50:05But no, those two are different.
  12289. 9:50:07So to come back to what I described as a spoiler earlier, what's
  12290. 9:50:11the fundamental issue here, to be clear?
  12291. 9:50:16Why is it saying different even though I'm pretty
  12292. 9:50:18sure I typed the same thing twice.
  12293. 9:50:19Yeah.
  12294. 9:50:21Yeah, this is where it's now useful to know that string has been
  12295. 9:50:24an abstraction-- a training wheel, if you will-- and if we take that away--
  12296. 9:50:28still use GetString because that's convenient still--
  12297. 9:50:30but if I change string to be char star, it's
  12298. 9:50:33a little more explicit as to what s and what t are. s is a pointer to a char,
  12299. 9:50:39that is the address of a char. t is a pointer
  12300. 9:50:42to a char, that is the address of a char.
  12301. 9:50:44Specifically, the first character in s and the first character
  12302. 9:50:47in t, respectively.
  12303. 9:50:49So if I'm comparing these two it should stand
  12304. 9:50:51to reason that they're going to be different.
  12305. 9:50:53Why?
  12306. 9:50:53Because s might end up here in memory and t might end up here in memory.
  12307. 9:50:57Each time I call GetString, it is not smart enough or advanced enough
  12308. 9:51:00to know that, wait a minute-- you typed the same thing.
  12309. 9:51:02I'm just going to hand you back the same address.
  12310. 9:51:04That doesn't happen because we did not design GetString that way.
  12311. 9:51:06Each time I call GetString, it returns, apparently,
  12312. 9:51:10a different copy of the string that was typed in.
  12313. 9:51:13A hi over here and a hi over here.
  12314. 9:51:15They might look the same to the human but to the computer
  12315. 9:51:18they are different chunks of memory, and therefore at different addresses.
  12316. 9:51:22And here, too, we can reveal what is GetString returning?
  12317. 9:51:25Well, up until today it was returning a string, so to speak.
  12318. 9:51:29That's not really a thing.
  12319. 9:51:31Technically, what GetString has always been
  12320. 9:51:33doing is returning the address of the first char in a string
  12321. 9:51:38and trusting that we put a backslash zero at the end of whatever the human
  12322. 9:51:42typed in, and that's enough now for printf, for strlen, for you
  12323. 9:51:46to know where a string begins and ends.
  12324. 9:51:49So GetString has actually always returned a pointer.
  12325. 9:51:53It has not returned a quote unquote string per se,
  12326. 9:51:56but there are functions that can solve this comparison for us.
  12327. 9:51:59Recall that I could do something like this.
  12328. 9:52:02I could actually go in here and I could--
  12329. 9:52:05let's see, where was it?
  12330. 9:52:07So if I include str compare here and use it to pass in two values, s and t,
  12331. 9:52:14let's see now what happens when I make compare.
  12332. 9:52:18Implicitly declaring library function str compare with type int--
  12333. 9:52:21and well, there's a star.
  12334. 9:52:22So you might have seen this error before and you might have ignored most of it,
  12335. 9:52:26but there's some evidence of stars or pointers going on here.
  12336. 9:52:30It looks like I didn't include the string.h header file,
  12337. 9:52:33so that's an easy fix.
  12338. 9:52:34Include string.h which, despite its name, does not create a data type
  12339. 9:52:38called string, it just has string-related functions in it
  12340. 9:52:41like str compare.
  12341. 9:52:42Let's make compare again.
  12342. 9:52:44Now it compiles, ./compare.
  12343. 9:52:46Now let's type in hi, exclamation point and even the same thing again.
  12344. 9:52:50These are now-- oh, I used it wrong.
  12345. 9:52:54OK, user error.
  12346. 9:52:55That was supposed to be impressive, but it's the opposite.
  12347. 9:52:58What did I do wrong?
  12348. 9:53:00What did I do wrong here?
  12349. 9:53:01Yeah.
  12350. 9:53:02Yeah.
  12351. 9:53:04AUDIENCE: [INAUDIBLE]
  12352. 9:53:07DAVID J. MALAN: Yeah, it returns three different values.
  12353. 9:53:09Zero if they're the same, positive 1 becomes before the other,
  12354. 9:53:13negative if the opposite is true.
  12355. 9:53:15I just forgot that, so like I did last week correctly,
  12356. 9:53:18if I want to compare them for equality per the manual page,
  12357. 9:53:22I should be checking for zero as the return value.
  12358. 9:53:24Now make compare, ./compare, Enter.
  12359. 9:53:27Let's try it one last time-- hi and hi.
  12360. 9:53:30OK now, they're in fact the same.
  12361. 9:53:32And Justin, thank you.
  12362. 9:53:37And indeed, not that it's returning same all the time.
  12363. 9:53:40If I type in hi and then bye, it's indeed
  12364. 9:53:42noticing that difference as well.
  12365. 9:53:44Well, let me go ahead and do one other thing here.
  12366. 9:53:48Let's do one other thing.
  12367. 9:53:50Let me go ahead now and just reveal more pictorially what's going on.
  12368. 9:53:54Let's get rid of the string comparison and let's just print these things out.
  12369. 9:53:57The simple way to print this out would be with %s and again, %s is special--
  12370. 9:54:01printf knows--
  12371. 9:54:02taking an address and start there, print every character up
  12372. 9:54:05until the backslash n, so let's just hand it s and do that.
  12373. 9:54:09And then let's do one more, %s,t.
  12374. 9:54:12This is, again, sort of a mix of week 1 and this week
  12375. 9:54:17because I got rid of the word string.
  12376. 9:54:18I'm using char star, but I'm still using printf and %s in the same way.
  12377. 9:54:24Let me go ahead and run compare now, and if I type hi and hi,
  12378. 9:54:27I should see the same thing twice.
  12379. 9:54:29So they look the same, but here now we have the syntax today
  12380. 9:54:33to print out the actual addresses of these things.
  12381. 9:54:35So let me just change the s to a p, because p means don't go to the address
  12382. 9:54:40and print it, it means just print the address as a pointer.
  12383. 9:54:44So make compare, ./compare, and now let's type in hi, and once more,
  12384. 9:54:48and I should see, indeed, two slightly different addresses given
  12385. 9:54:53in hexadecimal.
  12386. 9:54:54One's got a B at the end, one's got an F at the end,
  12387. 9:54:56and they are indeed a few bytes apart.
  12388. 9:54:58So this is just confirming what our suspicions have actually been.
  12389. 9:55:02So what does this mean, perhaps in the computer's memory?
  12390. 9:55:04Well, let's take a look.
  12391. 9:55:05I've zoomed out so I have a little more squares to look at at once.
  12392. 9:55:09Here might be s in memory when I do string s equals, or char star s equals.
  12393. 9:55:16I get a variable that's of size 1, 2, 3, 4, 5, 6, 7, 8, because I
  12394. 9:55:19claimed earlier that on modern systems, pointers are generally eight bytes
  12395. 9:55:23nowadays so they can count even higher.
  12396. 9:55:25And inside of the computer's memory, also, might be hi.
  12397. 9:55:28And I don't know where it ends up so for the sake of discussion
  12398. 9:55:31it ended up down here.
  12399. 9:55:32That's what was free when I ran the program.
  12400. 9:55:35h-i exclamation point, backslash zero.
  12401. 9:55:36Maybe it ended up, for the sake of discussion, at 0x123, 4, 5, and 6.
  12402. 9:55:42So to be clear, what is s storing once the assignment
  12403. 9:55:47operator copies from right to left?
  12404. 9:55:50What is s storing if I advance one more slide?
  12405. 9:55:54Yeah.
  12406. 9:55:560x123, the presumption being that if a string is
  12407. 9:56:00defined by the address of its first char and that address of its first char
  12408. 9:56:04is 0x123, then that's indeed what should be in the variable s.
  12409. 9:56:09And so technically, that's what's been happening with that assignment
  12410. 9:56:12operator from right to left.
  12411. 9:56:13GetString indeed returns a string, so to speak,
  12412. 9:56:16but more properly it returns the address of a char.
  12413. 9:56:20What's been then copied from right to left using that assignment operator
  12414. 9:56:24all these weeks is indeed that address.
  12415. 9:56:26Now technically, we don't really need to care about where these addresses are.
  12416. 9:56:31It suffices to just think about them referentially, but let's
  12417. 9:56:34first consider where t might be. t is just another variable that I
  12418. 9:56:38created on my second line of code.
  12419. 9:56:39Maybe it ends up there, maybe somewhere else.
  12420. 9:56:41For the sake of discussion I'll draw it left and right.
  12421. 9:56:43Where did the second word end up that I typed in?
  12422. 9:56:47Well, suppose the second copy of hi ended up at 0x456457458459.
  12423. 9:56:53What ended up in t?
  12424. 9:56:54I'll pluck this one off myself.
  12425. 9:56:550x456, presumably.
  12426. 9:56:57And so this is now a pictorial representation of why,
  12427. 9:57:01and let's abstract away everything else.
  12428. 9:57:03When I compared s against t using equal equals, based on the picture
  12429. 9:57:08they're obviously not the same.
  12430. 9:57:09One is over here, one is over here.
  12431. 9:57:12And per a moment ago, one is 0x123, the other is 0x456.
  12432. 9:57:16Yes, technically they're pointing at something that's the same,
  12433. 9:57:19but that just reveals how str compare works.
  12434. 9:57:23str compare is apparently a function that
  12435. 9:57:26takes in the address of a string as its argument
  12436. 9:57:29and the address of another string as its argument,
  12437. 9:57:31it goes to the first character in each of those strings, respectively,
  12438. 9:57:36and probably has a for loop or a while loop
  12439. 9:57:38and just goes from left to right, comparing, looking
  12440. 9:57:41for the same chars left and right, and if it doesn't notice any differences,
  12441. 9:57:45boom-- it returns zero.
  12442. 9:57:47If it does notice a difference it returns a positive or a negative value.
  12443. 9:57:51And that's very similar, recall, to how we implemented string length ourselves
  12444. 9:57:55last week.
  12445. 9:57:56I used a for loop, I was looking for a backslash zero.
  12446. 9:57:59str compare is probably a little similar in spirit, looping from left to right
  12447. 9:58:04but comparing, this time not just counting.
  12448. 9:58:08Are any questions then, on string comparison
  12449. 9:58:11and why it is that we use str compare and not equals equals?
  12450. 9:58:14Yeah.
  12451. 9:58:15AUDIENCE: Do pointers have addresses?
  12452. 9:58:17DAVID J. MALAN: Do pointers have addresses?
  12453. 9:58:19Yes.
  12454. 9:58:19So we won't do that today, but I could actually use the ampersand operator
  12455. 9:58:24on s or on t.
  12456. 9:58:26That would give me the equivalent of a char star star
  12457. 9:58:29that itself could be stored elsewhere in memory.
  12458. 9:58:31That's where it ends.
  12459. 9:58:32We don't do that recursively forever.
  12460. 9:58:35There's star and there's star star, but yes, that is a thing
  12461. 9:58:37and it's very often useful in the context of two dimensional arrays,
  12462. 9:58:41which we haven't really talked about, but that is a feature of the language,
  12463. 9:58:44too.
  12464. 9:58:45But not today.
  12465. 9:58:46Good question.
  12466. 9:58:47All right, so what might we now do to take things up a notch?
  12467. 9:58:50Well let's go ahead and implement a different program here
  12468. 9:58:53that maybe tries copying some values, just to demonstrate this.
  12469. 9:58:56Let me open up a file called, how about copy.c,
  12470. 9:59:00and I'm going to start off with a few includes.
  12471. 9:59:02So let's include the CS50 library just so we have a way of getting user input.
  12472. 9:59:06Let's include-- how about stdio as always, let's preemptively
  12473. 9:59:11include string.h and maybe one other in a moment.
  12474. 9:59:14Let's do int main(void) as before.
  12475. 9:59:17And then in here, let's get a string from the user and just
  12476. 9:59:20call it s for simplicity.
  12477. 9:59:23And heck, we can actually just call this char star if we want,
  12478. 9:59:26or string, since we're using the RS50 library.
  12479. 9:59:28But we'll come back to that.
  12480. 9:59:30Let's now make a copy of s and do s equals t,
  12481. 9:59:33using a single assignment operator and then let's check something like this.
  12482. 9:59:38Let's go into the first character of t, which is t bracket zero,
  12483. 9:59:43and then let's uppercase it using that function
  12484. 9:59:45that we've used in the past of toupper t bracket zero, semicolon.
  12485. 9:59:50And actually, I should go back up here.
  12486. 9:59:52If I'm using toupper or if you use tolower or isupper or islower--
  12487. 9:59:56I might not remember this offhand, but it was in another header file
  12488. 9:59:59called C type dot h.
  12489. 10:00:01There was a bunch of helpful functions in that library as well.
  12490. 10:00:04Now at the very last line of the program let's just print out what both s and t
  12491. 10:00:09are by simply printing out %s for each of them, and t is %s also, not %t,
  12492. 10:00:16of course, and let's see what happens here.
  12493. 10:00:20So let me make copy--
  12494. 10:00:21oh my God, so many mistakes.
  12495. 10:00:23What did I do wrong?
  12496. 10:00:24Oh.
  12497. 10:00:25OK, that was unintended.
  12498. 10:00:26String t equals s, sorry, so I'm creating two variables,
  12499. 10:00:30s and t respectively, and I'm copying s into t.
  12500. 10:00:33Make copy, Enter.
  12501. 10:00:34There we go. ./copy, and let's now type in, for instance,
  12502. 10:00:40how about hi exclamation point in all lowercase this time,
  12503. 10:00:43and now what gets printed?
  12504. 10:00:47I don't think that's what I intended, so to speak, here.
  12505. 10:00:51Because notice that I got s from the user, so that checks out.
  12506. 10:00:55I then copied t into s, which looks correct.
  12507. 10:00:59That's what we always use assignment for.
  12508. 10:01:00Then I uppercase the first letter in t, but not s--
  12509. 10:01:04at least in my code--
  12510. 10:01:05then I printed s and t and then noticed, apparently, both s
  12511. 10:01:09and t got capitalized.
  12512. 10:01:13So if you're starting to get a little comfortable with what's
  12513. 10:01:15going on underneath the hood, what's the fundamental problem here?
  12514. 10:01:19Why did both get capitalized?
  12515. 10:01:23Why did both get capitalized?
  12516. 10:01:24Yeah, over here.
  12517. 10:01:25AUDIENCE: Could it be they're referencing the same address?
  12518. 10:01:27DAVID J. MALAN: Yeah, they're representing the same address.
  12519. 10:01:29So C is really literal.
  12520. 10:01:31If you create another variable called t and you assign it the value of s,
  12521. 10:01:34you are literally assigning it the value in s,
  12522. 10:01:37which is 0x123 or something like that.
  12523. 10:01:40And so at that point in the story both s and t presumably
  12524. 10:01:43have a value of 0x123, which means they technically
  12525. 10:01:47point to the same h-i exclamation point in memory.
  12526. 10:01:51Nowhere did I tell the computer to give me a copy of a h-i exclamation point
  12527. 10:01:56per se, I literally said just copy s.
  12528. 10:01:59So here's where an understanding of what s literally is explains the situation.
  12529. 10:02:03I'm only copying the pointers.
  12530. 10:02:06So what actually went on in memory?
  12531. 10:02:07Let's take a look here at this grid.
  12532. 10:02:09If I created s initially, maybe it ends up here.
  12533. 10:02:12And I created hi in lowercase, and it ended up down here.
  12534. 10:02:15Then the address was, again, like 0x123456, 0x123 is what's in s.
  12535. 10:02:22If then I create a second variable called t,
  12536. 10:02:24and I call it a string, a.k.a. char star, maybe it again ends up here.
  12537. 10:02:29But when I copy s into t by doing t equals s semicolon,
  12538. 10:02:34that literally just copies s into t, which puts the value 0x123 there.
  12539. 10:02:40So if we now abstract away all these numbers and just think about a picture
  12540. 10:02:43with arrows, what we've drawn in the computer's memory is this.
  12541. 10:02:47Two different pointers but storing the same address, which means
  12542. 10:02:52the breadcrumbs lead to the same place.
  12543. 10:02:55And so if you follow the t breadcrumb and capitalize the first letter,
  12544. 10:02:58it is functionally the same as copying the--
  12545. 10:03:02changing the first letter in the version s as well.
  12546. 10:03:07So what's the solution, then, to this kind of problem?
  12547. 10:03:12Even if you have no idea how to do it in code,
  12548. 10:03:14what's the gist of what I really intended, which is,
  12549. 10:03:17I want a genuine copy of s, called t.
  12550. 10:03:21I want a new h-i exclamation point backslash zero.
  12551. 10:03:25What do I need to do to make that happen?
  12552. 10:03:27Thoughts?
  12553. 10:03:28AUDIENCE: I think there's a function called str copy.
  12554. 10:03:30DAVID J. MALAN: So there is a function called str copy, strcpy,
  12555. 10:03:34which is a possible answer to this question.
  12556. 10:03:36The catch with stir copy is that you have to tell it in advance not only
  12557. 10:03:41what the source string is-- the one you want to copy--
  12558. 10:03:43you also need to pass in the address of a chunk of memory
  12559. 10:03:46into which you can copy the string, and here's one thing we haven't seen yet,
  12560. 10:03:50and we need one more building block today, if you will.
  12561. 10:03:53We haven't yet seen a way to create new chunks of memory
  12562. 10:03:57and then let some other function copy into them.
  12563. 10:04:00And for this, we're going to introduce something called dynamic memory
  12564. 10:04:04allocation.
  12565. 10:04:04And this is the last and most powerful feature perhaps, today,
  12566. 10:04:07whereby we're going to introduce two functions, malloc and free, where
  12567. 10:04:11malloc means memory allocate, which literally does just that.
  12568. 10:04:14It's a function that takes a number as input-- how many bytes of memory
  12569. 10:04:18do you want the operating system to find for you somewhere in that big grid?
  12570. 10:04:21It's going to find it and it's going to return
  12571. 10:04:23to you the address of the first byte of contiguous memory back to back to back,
  12572. 10:04:26and then you can do anything you want with that chunk of memory.
  12573. 10:04:29free is going to do the opposite.
  12574. 10:04:31When you're done using a chunk of memory that malloc has given you,
  12575. 10:04:33you can say free it, and that means you hand it back to the operating system
  12576. 10:04:37and then the operating system can use it for something else later.
  12577. 10:04:40So this is actually evidence of a common problem in programming.
  12578. 10:04:44If your Mac your PC has ever been in the habit of starting to get really,
  12579. 10:04:48really slow, or it's slowing to a crawl-- heck, maybe it even freezes--
  12580. 10:04:53one of the possible explanations could be
  12581. 10:04:56that the program you're running by Apple or Microsoft
  12582. 10:04:59or whoever, maybe they're using malloc or some equivalent,
  12583. 10:05:02asking the operating system--
  12584. 10:05:03Mac OS or Windows-- for, give me more memory.
  12585. 10:05:05I need more memory.
  12586. 10:05:06The user is creating more images.
  12587. 10:05:07The user is typing a longer essay.
  12588. 10:05:09Give me more memory, more memory.
  12589. 10:05:10If the program has a bug and never actually frees any of that memory,
  12590. 10:05:15your computer might end up using all of the available memory
  12591. 10:05:18and honestly, humans are not very good at handling corner cases like that.
  12592. 10:05:21Very often programs, computers just freeze at that point
  12593. 10:05:24or get really, really slow because they start trying to be creative
  12594. 10:05:28when there's not enough memory left.
  12595. 10:05:31So one of the reasons for a computer really slowing down
  12596. 10:05:33might be calling for malloc a lot, or some equivalent, but never freeing it.
  12597. 10:05:38Which is to say, you should always use these two functions
  12598. 10:05:40in concert and free memory once you are done with it.
  12599. 10:05:43So let me go ahead and do this in code and solve this problem properly.
  12600. 10:05:48Let me go ahead and do this.
  12601. 10:05:50Before I copy s into t using something like str copy,
  12602. 10:05:53I first need to get a bunch of memory from the computer.
  12603. 10:05:56So to do that, let's make this super clear that we're dealing with pointer,
  12604. 10:05:59so I'm going to change my strings to char stars for both s and t,
  12605. 10:06:03and what I technically am going to store in t
  12606. 10:06:05is the address of an available chunk of memory.
  12607. 10:06:09To do that, I can ask the computer to allocate memory for me,
  12608. 10:06:13and how many bytes.
  12609. 10:06:15If I want to create a copy of h-i exclamation point,
  12610. 10:06:18I need how many bytes?
  12611. 10:06:21Good!
  12612. 10:06:22Four!
  12613. 10:06:22Because I need the h, the i, the exclamation point, and additional space
  12614. 10:06:27for the backslash zero.
  12615. 10:06:28It's up to me to understand that and ask for it.
  12616. 10:06:30It's not going to happen magically.
  12617. 10:06:32Nothing does in C. So I could just naively type four there,
  12618. 10:06:35and that would be correct if I type in h-i exclamation
  12619. 10:06:38point or any other three letter word or phrase, but to do this dynamically
  12620. 10:06:42I should probably do something like strlen of s
  12621. 10:06:46plus 1 for the additional null character.
  12622. 10:06:49Recall that string length does it in the English sense--
  12623. 10:06:52it returns the length of the string you see, plus 1 also takes into account
  12624. 10:06:56the fact that I'm going to need that backslash n.
  12625. 10:06:58Now let me do this old school style first.
  12626. 10:07:00Let me go ahead and manually copy the string s into t first.
  12627. 10:07:05So for int i equals 0, i is less than the string length of s, i plus plus.
  12628. 10:07:13Then inside my for loop, I'm going to do t bracket i equals s bracket
  12629. 10:07:18i, but actually I want the null character too,
  12630. 10:07:22so I want to do the length of the string plus 1 more,
  12631. 10:07:25and heck, I think I learned an optimization last time.
  12632. 10:07:28If I'm doing this again and again, I could really
  12633. 10:07:30do n equals strlen of s plus 1 and then do i is less than n,
  12634. 10:07:36just as a nice design optimization.
  12635. 10:07:38I think this for loop will actually handle the process, then,
  12636. 10:07:41of copying every character from s into every available byte of memory in t.
  12637. 10:07:48Or I could get rid of all of that and take your suggestion, which
  12638. 10:07:52is to use str copy, which takes as its first argument the destination
  12639. 10:07:56and its second argument the source.
  12640. 10:07:58So copy from right to left in this case, too, that's going to do all of that
  12641. 10:08:03automatically for me as well.
  12642. 10:08:06Now I think I'm good.
  12643. 10:08:08I can now capitalize safely.
  12644. 10:08:10The first character in t, which is now a different chunk of memory
  12645. 10:08:14than s, and then I can print them both out to see that one has not changed
  12646. 10:08:18but the other has.
  12647. 10:08:19So make copy-- all right, what did I do wrong?
  12648. 10:08:22Implicitly declaring library function malloc dot, dot, dot.
  12649. 10:08:25So we've seen this kind of error before.
  12650. 10:08:28What is-- even if you don't know quite how to solve it,
  12651. 10:08:31what's the essence of the solution?
  12652. 10:08:33What do I need to do to fix this kind of problem involving implicitly
  12653. 10:08:36declaring a library function?
  12654. 10:08:38What did I forget?
  12655. 10:08:39Yeah.
  12656. 10:08:41I need to include the library.
  12657. 10:08:42And I could look this up in the manual, or I know it off the top of my head,
  12658. 10:08:46I just forgot it.
  12659. 10:08:47There's another library we'll occasionally
  12660. 10:08:49need now called standard lib--
  12661. 10:08:51standard library-- that contains malloc and free prototypes
  12662. 10:08:56and some other stuff, too.
  12663. 10:08:57All right, let me just clear this away and do make copy one more time.
  12664. 10:09:00Now I'm good. ./copy, Enter, All right. s, I'm going to type in hi, lowercase.
  12665. 10:09:06t and s now come back as intended.
  12666. 10:09:10s is untouched, it would seem, but t is now capitalized.
  12667. 10:09:15Are any questions, then, on what we just did in code?
  12668. 10:09:18Yeah.
  12669. 10:09:20AUDIENCE: You said that malloc and free go together.
  12670. 10:09:23[INAUDIBLE]
  12671. 10:09:27DAVID J. MALAN: Indeed.
  12672. 10:09:28There's a few improvements I want to make, so let
  12673. 10:09:30me actually do those right now.
  12674. 10:09:32Technically, I should practice what I preached and I should indeed,
  12675. 10:09:35when I'm done with t, free t.
  12676. 10:09:37Fortunately, I don't have to worry about how big t
  12677. 10:09:39was-- the computer remembers how many bytes it gave me and it will go free
  12678. 10:09:43all of them, not just the first.
  12679. 10:09:44I should do free t.
  12680. 10:09:46I don't need to do free s, and I shouldn't,
  12681. 10:09:49because that is handled automatically by the CS50 library.
  12682. 10:09:52s, recall, came from GetString, and we actually
  12683. 10:09:54have some fancy code in place that makes sure
  12684. 10:09:56that at the end of your program's execution
  12685. 10:09:58we free any memory that we allocated so we don't actually
  12686. 10:10:01waste memory like I described earlier.
  12687. 10:10:03But there's actually a couple of other things
  12688. 10:10:05if I really want to be pedantic I should put in here.
  12689. 10:10:07It turns out that sometimes malloc can fail,
  12690. 10:10:11and sometimes malloc doesn't have enough memory available
  12691. 10:10:14because maybe your computer's doing so much
  12692. 10:10:15stuff there's just no more RAM available.
  12693. 10:10:18So technically, I should do something like this--
  12694. 10:10:20if t equals equals null, with two L's today,
  12695. 10:10:24then I should just return 1 or something to say that there was a problem.
  12696. 10:10:28I should probably print an error message too,
  12697. 10:10:29but for now I'm going to keep it simple.
  12698. 10:10:31I should also probably check this.
  12699. 10:10:33This is a little risky of me.
  12700. 10:10:36If I'm doing t bracket zero, this is assuming that there is a letter there.
  12701. 10:10:40But what if the human just hit Enter at the prompt
  12702. 10:10:43and didn't even type h, let alone h-i exclamation point?
  12703. 10:10:46What if there is no t bracket zero?
  12704. 10:10:48So technically, what I should probably do here is, if the length of t
  12705. 10:10:54is at least greater than zero, then go ahead and safely capitalize
  12706. 10:11:00the first letter of it.
  12707. 10:11:01And then at the very end if all goes well,
  12708. 10:11:04I can return zero, thereby signifying that indeed, this thing was successful.
  12709. 10:11:08So yes, these two functions, malloc and free, should be in concert.
  12710. 10:11:12And so if you call malloc you should call free eventually.
  12711. 10:11:17But you did not call malloc for s, so you should not call free for s.
  12712. 10:11:22Yeah, other question.
  12713. 10:11:23AUDIENCE: Here's a question.
  12714. 10:11:24Why do we do malloc plus 1?
  12715. 10:11:26DAVID J. MALAN: Why did I do malloc plus 1?
  12716. 10:11:28So malloc-- sorry, malloc of string length of s
  12717. 10:11:31plus 1-- the string length is the literal length of the string as a human
  12718. 10:11:35would perceive it in English.
  12719. 10:11:36So h-i exclamation point-- strlen gives me 3,
  12720. 10:11:39but I know now as of last week and this week what a string technically is
  12721. 10:11:43and a string always has an extra byte.
  12722. 10:11:45The onus is on me to understand and apply
  12723. 10:11:47that lesson learned so that I actually give str copy enough room for that
  12724. 10:11:52trailing null character.
  12725. 10:11:53And here's just an annoying thing when we called the backslash zero N-U-L last
  12726. 10:11:59week, it turns out that N-U-L-L is the same idea.
  12727. 10:12:03It's also zero, but it's zero in the context of pointer.
  12728. 10:12:06So long story short, you never really write N-U-L, I've just said it
  12729. 10:12:11and we saw it on the screen.
  12730. 10:12:12You will start writing N-U-L-L when you want to check whether or not a pointer
  12731. 10:12:17is valid or not.
  12732. 10:12:19And what I mean by that is this.
  12733. 10:12:20If malloc fails and there's just not enough memory left inside
  12734. 10:12:23of the computer for you, it's got to return a special value,
  12735. 10:12:26and that special value is N-U-L-L in all capital letters.
  12736. 10:12:30That signifies something went wrong.
  12737. 10:12:32Do not trust that I'm giving you a useful return value.
  12738. 10:12:37Other questions on these copies thus far?
  12739. 10:12:40Yeah, over there.
  12740. 10:12:42AUDIENCE: [INAUDIBLE]
  12741. 10:12:46DAVID J. MALAN: Good question.
  12742. 10:12:48Will str copy not work without malloc?
  12743. 10:12:49You kind of need both in this case because str copy,
  12744. 10:12:53by definition-- if I pull up its manual page-- needs a destination
  12745. 10:12:56to put the copied characters.
  12746. 10:12:58It's not sufficient just to say char star t semicolon.
  12747. 10:13:01That only gives you a pointer.
  12748. 10:13:03But I need another chunk of memory that's
  12749. 10:13:06just as big as h-i exclamation point backslash zero,
  12750. 10:13:10so malloc gives me a whole bunch of memory
  12751. 10:13:12and then str copy fills it with h-i exclamation point backslash zero.
  12752. 10:13:16So again, that's why we're going down to this lower level,
  12753. 10:13:19because once you understand what needs to be done
  12754. 10:13:21you now have the functions to do it.
  12755. 10:13:23So let's actually consider what we just solved.
  12756. 10:13:25So in this next version of the program where I actually introduced malloc,
  12757. 10:13:29t was initialized for the return value of malloc,
  12758. 10:13:32and maybe the memory that I got back was here--
  12759. 10:13:340x456457458459.
  12760. 10:13:38I've left it blank initially because nothing
  12761. 10:13:40is put there automatically by malloc.
  12762. 10:13:42I just get a chunk of memory that is now mine to use as I see fit.
  12763. 10:13:46I then assign t to that return value, which points t at the first address.
  12764. 10:13:51Notice there's no backslash zero.
  12765. 10:13:53This is not yet a string it's just a chunk of memory--
  12766. 10:13:56four bytes-- an array of four bytes.
  12767. 10:13:58What str copy eventually did for me was it copied the h over,
  12768. 10:14:01the i over, the exclamation point over, and the backslash zero.
  12769. 10:14:06And if I didn't want to use str copy or I forgot that it existed, my for loop
  12770. 10:14:09would have done exactly the same thing.
  12771. 10:14:14Are any questions, then, on these examples here.
  12772. 10:14:19Any questions?
  12773. 10:14:19Yeah.
  12774. 10:14:21AUDIENCE: [INAUDIBLE]
  12775. 10:14:28DAVID J. MALAN: Good question.
  12776. 10:14:29After malloc, if I had then still done just t equals s,
  12777. 10:14:34it actually would have recreated the same original problem
  12778. 10:14:37by just copying 0x123 from s into t.
  12779. 10:14:40So then I would have been left with a picture that looked like this a few
  12780. 10:14:44steps ago, I would have-- and I can't quite do it live--
  12781. 10:14:48this arrow, if I did what you just described,
  12782. 10:14:50would now be pointing over here and so I wouldn't have fundamentally solved
  12783. 10:14:54the problem, I would have just additionally wasted
  12784. 10:14:56four bytes temporarily that I'm not actually using.
  12785. 10:14:59Yeah.
  12786. 10:15:01AUDIENCE: [INAUDIBLE]
  12787. 10:15:05DAVID J. MALAN: You can--
  12788. 10:15:06do you always use malloc and str copy together?
  12789. 10:15:08Not necessarily.
  12790. 10:15:08These are both solving two different problems.
  12791. 10:15:10malloc's giving me enough memory to make a copy, str copy is doing the copy.
  12792. 10:15:15However, you could actually use an array, if you wanted, of characters,
  12793. 10:15:18and you could use str copy on that, and there's other use cases for str copy.
  12794. 10:15:22But thus far, it's a reasonable mental model
  12795. 10:15:24to have that if you want to copy strings,
  12796. 10:15:26you use malloc and then str copy, or your own homegrown loop.
  12797. 10:15:30Yeah.
  12798. 10:15:32AUDIENCE: [INAUDIBLE]
  12799. 10:15:42DAVID J. MALAN: Say that once more.
  12800. 10:15:44AUDIENCE: [INAUDIBLE]
  12801. 10:15:49DAVID J. MALAN: No.
  12802. 10:15:50It will-- good question.
  12803. 10:15:52If I had a--
  12804. 10:15:55str copy, per its documentation, will copy the whole string
  12805. 10:15:58plus the null character at the end.
  12806. 10:16:01It just assumes there will be one there.
  12807. 10:16:03It's therefore up to you to pass str copy a long enough chunk of memory
  12808. 10:16:07to have room for that.
  12809. 10:16:08If I only ask malloc for three bytes, that
  12810. 10:16:10could have potentially created a memory problem
  12811. 10:16:12whereby str copy would just still blindly copy one, two, three,
  12812. 10:16:16four bytes, but technically it should have only touched three of those.
  12813. 10:16:19You do not yet have access to the fourth one, or the rights to it,
  12814. 10:16:22because you never asked malloc for it.
  12815. 10:16:24Yeah.
  12816. 10:16:26AUDIENCE: So the number inside malloc would be the number of bytes.
  12817. 10:16:29DAVID J. MALAN: Correct.
  12818. 10:16:30The number inside malloc-- it's one argument.
  12819. 10:16:32It's the number of bytes you want back.
  12820. 10:16:35AUDIENCE: Does that mean you have to remember [INAUDIBLE]??
  12821. 10:16:41DAVID J. MALAN: Yes, the onus is on you, the programmer,
  12822. 10:16:43to remember or frankly, use a function to figure out
  12823. 10:16:45how many bytes you actually need.
  12824. 10:16:47That's why I did not ultimately type in four manually,
  12825. 10:16:50I used str length plus 1.
  12826. 10:16:51So the plus 1 is necessary if you understand how strings are represented,
  12827. 10:16:55but using strlen means that I can actually
  12828. 10:16:57play around with any types of inputs and it will dynamically
  12829. 10:17:01figure out the length.
  12830. 10:17:02So suffice it to say, there's so many ways
  12831. 10:17:05already where you can start to break programs.
  12832. 10:17:07Let's give you at least one tool for finding mistakes that you might make.
  12833. 10:17:10And indeed, in upcoming problem sets you will
  12834. 10:17:12use this to find bugs in your own code.
  12835. 10:17:14Not just using printf, not just using the built-in debugger, but another tool
  12836. 10:17:18here as well.
  12837. 10:17:19So let me go ahead and deliberately write a program called memory.c
  12838. 10:17:22that has some memory-related errors.
  12839. 10:17:24Let me include stdio.h at the top and let me include stdlib.h at the top
  12840. 10:17:30so I have access to malloc now.
  12841. 10:17:31Let me do int main(void) and then inside of main, let me do this--
  12842. 10:17:36I want to allocate maybe how about three--
  12843. 10:17:39space for three integers.
  12844. 10:17:41Why?
  12845. 10:17:41Just for the sake of discussion.
  12846. 10:17:43So I'm going to go ahead and do malloc of three, but I don't want three bytes.
  12847. 10:17:48I want three integers and an integer is four bytes,
  12848. 10:17:51so technically I could do this--
  12849. 10:17:523 times 4, or I could do 12 but again, that's making certain assumptions
  12850. 10:17:57and if I run this program on a slightly different computer,
  12851. 10:17:59int might be a different size.
  12852. 10:18:01so the better way to do this would be 3 times whatever the size is of an int.
  12853. 10:18:05And this is just an operator you can use any time if you just want to find out
  12854. 10:18:08on this computer, how big is an int?
  12855. 10:18:10How big is a float, or something else?
  12856. 10:18:13So that's going to give me that many--
  12857. 10:18:15that much memory for three ints.
  12858. 10:18:18What do I want to assign this to?
  12859. 10:18:20Well, malloc returns an address.
  12860. 10:18:22Pointers are addresses, so I'm going to create a pointer to an int called
  12861. 10:18:27x and assign it the value.
  12862. 10:18:29So what am I doing here?
  12863. 10:18:31This is a little less obvious, but again go back to basics.
  12864. 10:18:33The right hand side here gives me a chunk of memory for three integers.
  12865. 10:18:38malloc returns the address of the first byte of that chunk.
  12866. 10:18:42How do I store the address of anything?
  12867. 10:18:44I need a pointer.
  12868. 10:18:45The syntax for today is type of data, star,
  12869. 10:18:48where the type of data in question is three ints, so I do int star x.
  12870. 10:18:53Again, it's kind of purposeless, only for sort of instructional purposes
  12871. 10:18:57here, but this is equivalent now to having a chunk of memory of size 12
  12872. 10:19:03in total, presumably, so I can technically now do this.
  12873. 10:19:06I can go into maybe the first location and assign it the number 72
  12874. 10:19:10like the other day.
  12875. 10:19:12Second location, the number 73, and the third location, maybe the number 33.
  12876. 10:19:20Now I've deliberately made two mistakes here
  12877. 10:19:22because I'm trying to trip over my newfound understanding,
  12878. 10:19:26or my greenness with understanding pointers.
  12879. 10:19:28One, I didn't remember that I should be treating chunks of memory
  12880. 10:19:32as zero indexed.
  12881. 10:19:33malloc essentially returns an array, if you want to think of it as that.
  12882. 10:19:36An array of three ints, or more technically,
  12883. 10:19:38the address of a chunk of memory that could fit three ints.
  12884. 10:19:42So I can use my square bracket notation, or I could be really cool
  12885. 10:19:46and use pointer arithmetic, but this is a little more user friendly.
  12886. 10:19:48But I have made two mistakes.
  12887. 10:19:50I did not start indexing at zero, so line seven
  12888. 10:19:54should have been x bracket zero.
  12889. 10:19:56Line eight should have been x bracket 1, and then line nine
  12890. 10:19:59should have been x bracket 2.
  12891. 10:20:00So first mistake.
  12892. 10:20:01The second mistake that I've made as a side effect,
  12893. 10:20:04is I'm also touching memory that I shouldn't.
  12894. 10:20:07x bracket 3 would mean go to the fourth int in the chunk of memory
  12895. 10:20:12that came back.
  12896. 10:20:13I only asked for enough memory for three ints,
  12897. 10:20:15not four, so this is what's called a buffer overflow.
  12898. 10:20:19I am accidentally, but deliberately at the moment,
  12899. 10:20:22going beyond the boundaries of this array, this chunk of memory.
  12900. 10:20:26So bad things happen, but not necessarily
  12901. 10:20:28by just running your program.
  12902. 10:20:30Let me go ahead and just try this.
  12903. 10:20:31Make memory, and you'll see here that it compiles OK. ./memory,
  12904. 10:20:37and it actually does not segmentation fault,
  12905. 10:20:39which comes back to that point of nondeterminism.
  12906. 10:20:41Sometimes it does, sometimes it doesn't-- it depends on how bad
  12907. 10:20:43of a mistake you made.
  12908. 10:20:45But there's a program that can spot these kinds of mistakes,
  12909. 10:20:48and I'm going to go ahead and expand my terminal window for a moment
  12910. 10:20:51and I'm going to run not just ./memory, but a program called Valgrind./memory.
  12911. 10:20:56This is a command that comes with a lot of computer systems
  12912. 10:20:59that's designed to find memory-related bugs in code.
  12913. 10:21:02So it's a new tool in your toolkit today,
  12914. 10:21:04and you'll use it with the coming problem sets.
  12915. 10:21:06I'm going to run this now.
  12916. 10:21:07It's output, honestly, it's hideous.
  12917. 10:21:09But there's a few things that will start to jump out
  12918. 10:21:13and will help you with tools and the problems
  12919. 10:21:15sets to see these kinds of things.
  12920. 10:21:17Here's the first mistake.
  12921. 10:21:18Invalid write of size four.
  12922. 10:21:21That's on memory.c line nine, per my highlights.
  12923. 10:21:25So let me go look at line nine.
  12924. 10:21:27In what sense is this an invalid write of size four?
  12925. 10:21:31Well, I'm touching memory that I shouldn't, and I'm
  12926. 10:21:33touching it as though it's an int.
  12927. 10:21:35And an int is four bytes-- size four.
  12928. 10:21:37So again, this takes some practice to get used to, the nomenclature here,
  12929. 10:21:41but this is now a clue for me, the programmer,
  12930. 10:21:44that not only did I screw up, but I screwed up related to memory
  12931. 10:21:47and so this is just a hint, if you will.
  12932. 10:21:50It's not going to necessarily tell you exactly how to fix it,
  12933. 10:21:52you have to wrestle with the semantics, but invalid
  12934. 10:21:56write of size four-- oh, OK.
  12935. 10:21:58So I should not have indexed past the boundary here.
  12936. 10:22:02All right, so I shouldn't have done that.
  12937. 10:22:05So let me go ahead then and change this to zero, one, and two, perhaps, here.
  12938. 10:22:11All right, so let me go ahead and recompile my code.
  12939. 10:22:13Make memory, ./memory, still doesn't seem to be broken but it is technically
  12940. 10:22:19buggy.
  12941. 10:22:20Let me go ahead and run Valgrind again, so Valgrind of ./memory, Enter.
  12942. 10:22:26And now there's fewer scary--
  12943. 10:22:28less scary output now, but there's still something in there.
  12944. 10:22:32Notice this-- 12 bytes in one blocks--
  12945. 10:22:35no regard for grammar there-- are definitely
  12946. 10:22:37lost in lost record one of one.
  12947. 10:22:39Super cryptic, but this is hinting at a so-called memory leak.
  12948. 10:22:42The blocks of memory are lost in the sense that I malloc'd them--
  12949. 10:22:46I asked for them but I never--
  12950. 10:22:48take a guess-- freed them.
  12951. 10:22:50I have a memory leak.
  12952. 10:22:51And this is the arcane way of saying, you've screwed up.
  12953. 10:22:53You have a memory leak.
  12954. 10:22:54So this is an easy fix, fortunately.
  12955. 10:22:57Once I'm done with this memory I just need to free it at the end.
  12956. 10:23:01So now let me go ahead and rerun make memory,
  12957. 10:23:03it's still runs fine so all the while I might have thought, incorrectly,
  12958. 10:23:07my code is correct.
  12959. 10:23:08But let me run Valgrind one more time.
  12960. 10:23:10Valgrin of ./memory, Enter.
  12961. 10:23:12Now, this is pretty good.
  12962. 10:23:14All heap blocks were freed, whatever that means.
  12963. 10:23:16No leaks are possible.
  12964. 10:23:18And even though it's still a little cryptic, there's no other error here
  12965. 10:23:21and in fact, it's pretty explicit-- error summary, zero errors from zero
  12966. 10:23:25contexts, dot, dot, dot.
  12967. 10:23:27So even though this is one of the most arcane tools we'll use,
  12968. 10:23:30it's also one of the most powerful because it can see things
  12969. 10:23:32that you, the human, might not, and maybe even that the debugger might not.
  12970. 10:23:36It does a much closer reading of your code
  12971. 10:23:38while it's running to figure out exactly what is going on.
  12972. 10:23:43Any questions, then, on this tool?
  12973. 10:23:46And we'll guide you after today with actually using this, too.
  12974. 10:23:50Just helps you find memory-related mistakes
  12975. 10:23:52that you might now be capable of making.
  12976. 10:23:55All right, let's do one other memory-related thing.
  12977. 10:23:57Let me shrink my terminal window here.
  12978. 10:23:59Let me create one other file here called garbage.c.
  12979. 10:24:03It turns out there's a term of ours called garbage values in programming
  12980. 10:24:06that we can reveal as follows.
  12981. 10:24:08Let me include stdio.h, and let me include--
  12982. 10:24:11how about stdlib.h, and then let me give myself int
  12983. 10:24:14main(void), and then in this relatively short program
  12984. 10:24:17let me give myself three ints using last week's
  12985. 10:24:20notation, just int scores bracket 3 for 3 quiz scores, or whatever.
  12986. 10:24:24Then let me go ahead and do for int i equals zero, i less than 3,
  12987. 10:24:28i plus plus, then let me go ahead and print out, %i backslash n,
  12988. 10:24:34scores bracket i semicolon.
  12989. 10:24:36That's it.
  12990. 10:24:38This code, pretty sure is going to compile and it's going to run,
  12991. 10:24:44but what is my logical bug?
  12992. 10:24:46I've forgotten a step even though the code that's written is not so wrong.
  12993. 10:24:51Yeah?
  12994. 10:24:53Yeah, I didn't provide the scores, so I didn't actually
  12995. 10:24:56initialize the array called scores to have any scores whatsoever.
  12996. 10:25:00What's curious about this, though, is that the computer technically
  12997. 10:25:03doesn't mind.
  12998. 10:25:04Let me go ahead and playfully make garbage, Enter,
  12999. 10:25:08and it's an apt description because what I'm about to see
  13000. 10:25:10are so-called garbage values.
  13001. 10:25:13When you, the programmer, do not initialize your codes variables to have
  13002. 10:25:18values, sometimes, who knows what's going to be there.
  13003. 10:25:21The computer's been doing some other things,
  13004. 10:25:23there's a bit of work that happens even before your code runs in the computer,
  13005. 10:25:26so there might be remnants of past ints, chars, strings,
  13006. 10:25:29floats-- anything else in there and what you're seeing
  13007. 10:25:32is those garbage values, which is to say you should never forget,
  13008. 10:25:38as I just did, to initialize the value of some variable.
  13009. 10:25:40And this is actually pretty dangerous, and there
  13010. 10:25:42have been many examples of software being compromised
  13011. 10:25:46because of one of these issues where a variable wasn't initialized
  13012. 10:25:49and all of a sudden users, maybe people on the internet in the context of web
  13013. 10:25:53applications, could suddenly see the contents of someone else's memory,
  13014. 10:25:57or remnants.
  13015. 10:25:58Maybe someone's password that had been previously typed in
  13016. 10:26:01or some other value like a credit card number
  13017. 10:26:03that had been previously typed in.
  13018. 10:26:04There are different defense mechanisms in place
  13019. 10:26:06to generally make this not so likely, but it's certainly
  13020. 10:26:10very possible, at least in this kind of context,
  13021. 10:26:13to see values that you probably shouldn't because they
  13022. 10:26:17might be remnants from something else that used them.
  13023. 10:26:20So this is to say again, you have this great power now to manipulate memory,
  13024. 10:26:25but also now you have this great hacking ability to poke around
  13025. 10:26:28the contents of memory, and this is exactly what hackers sometimes do when
  13026. 10:26:31trying to find ways to exploit systems.
  13027. 10:26:35Are any questions here?
  13028. 10:26:39No?
  13029. 10:26:40All right, let's go ahead and take a quick five minute break
  13030. 10:26:42and when we come back, we'll build on these final topics.
  13031. 10:26:44See you in five.
  13032. 10:26:45We are back.
  13033. 10:26:47First, just a little programmer humor from XKCD, which hopefully now
  13034. 10:26:50will make a little bit of sense to you.
  13035. 10:26:53And what we'll also do next to take a look at a short two minute video that
  13036. 10:26:57animates with claymation, if you will, from our friends at Stanford,
  13037. 10:27:00exactly what happens now if you have an understanding of what garbage
  13038. 10:27:03values are and how they get there, and what happens then if you misuse them.
  13039. 10:27:07It's one thing just to print them out as I just did,
  13040. 10:27:09it's another if you actually mistake a garbage value for a valid pointer,
  13041. 10:27:13because garbage values are just zeros and ones somewhere-- numbers, that is.
  13042. 10:27:17But if you use that new dereference operator, the star,
  13043. 10:27:20and try to go to a garbage value thinking incorrectly that it's
  13044. 10:27:24a valid pointer, bad things can happen.
  13045. 10:27:26Computers can crash or more familiarly, segmentation faults can happen.
  13046. 10:27:31So allow me to introduce, if we could dim the lights for two minutes,
  13047. 10:27:34our friend Binky from Stanford.
  13048. 10:27:40SPEAKER 1: Hey Binky, wake up.
  13049. 10:27:41It's time for pointer fun.
  13050. 10:27:44BINKY: What's that?
  13051. 10:27:45Learn about pointers?
  13052. 10:27:47Oh, goody!
  13053. 10:27:48SPEAKER 1: Well, to get started, I guess we're
  13054. 10:27:50going to need a couple of pointers.
  13055. 10:27:52BINKY: OK, this code allocates two pointers which can point to integers.
  13056. 10:27:56SPEAKER 1: OK.
  13057. 10:27:56Well, I see the two pointers, but they don't seem to be pointing to anything.
  13058. 10:28:00BINKY: That's right.
  13059. 10:28:01Initially, pointers don't point to anything.
  13060. 10:28:03The things they point to are called pointees, and setting them up
  13061. 10:28:06is a separate step.
  13062. 10:28:07SPEAKER 1: Oh, right, right.
  13063. 10:28:08I knew that.
  13064. 10:28:09The pointees are separate.
  13065. 10:28:11So how do you allocate a pointee?
  13066. 10:28:13BINKY: OK, well this code allocates a new integer pointee,
  13067. 10:28:17and this part sets x to point to it.
  13068. 10:28:20SPEAKER 1: Hey, that looks better.
  13069. 10:28:21So make it do something.
  13070. 10:28:23BINKY: OK, I'll dereference the pointer x to store the number
  13071. 10:28:2642 into its pointee.
  13072. 10:28:28For this trick, I'll need my magic wand of dereferencing.
  13073. 10:28:32SPEAKER 1: Your magic wand of dereferencing?
  13074. 10:28:35That great.
  13075. 10:28:37BINKY: This is what the code looks like.
  13076. 10:28:39I'll just set up the number and--
  13077. 10:28:42SPEAKER 1: Hey, look.
  13078. 10:28:43There it goes.
  13079. 10:28:44So doing a dereference on x follows the arrow to access its pointee,
  13080. 10:28:49in this case to store 42 in there.
  13081. 10:28:51Hey, try using it to store the number 13 through the other pointer, y.
  13082. 10:28:56BINKY: OK.
  13083. 10:28:57I'll just go over here to y and get the number 13 set up,
  13084. 10:29:01and then take the wand of dereferencing and just--
  13085. 10:29:06whoa!
  13086. 10:29:07SPEAKER 1: Oh hey, that didn't work.
  13087. 10:29:09Say, Binky, I don't think dereferencing y is a good idea
  13088. 10:29:13because setting up the pointee is a separate step
  13089. 10:29:16and I don't think we ever did it.
  13090. 10:29:18BINKY: Good point.
  13091. 10:29:19SPEAKER 1: Yeah, we allocated the pointer y,
  13092. 10:29:22but we never set it to point to a pointee.
  13093. 10:29:25BINKY: Very observant.
  13094. 10:29:26SPEAKER 1: Hey, you're looking good there, Binky.
  13095. 10:29:28Can you fix it so that y points to the same pointee as x?
  13096. 10:29:31BINKY: Sure, I'll use my magic wand of pointer assignment.
  13097. 10:29:35SPEAKER 1: Is that going to be a problem, like before?
  13098. 10:29:37BINKY: No, this doesn't touch the pointees,
  13099. 10:29:39it just changes one pointer to point to the same thing as another.
  13100. 10:29:42SPEAKER 1: Oh, I see.
  13101. 10:29:43Now y points to the same place as x.
  13102. 10:29:46So wait, now y is fixed.
  13103. 10:29:48It has a pointee so you can try the wand of dereferencing again
  13104. 10:29:51to send the 13 over.
  13105. 10:29:54BINKY: OK, here it goes.
  13106. 10:29:56SPEAKER 1: Hey, look at that.
  13107. 10:29:57Now dereferencing works on y.
  13108. 10:29:59And because the pointers are sharing that one pointee, they both see the 13.
  13109. 10:30:03BINKY: Yeah, sharing.
  13110. 10:30:04Whatever.
  13111. 10:30:05So are we going to switch places now?
  13112. 10:30:07SPEAKER 1: Oh look, we're out of time.
  13113. 10:30:09BINKY: But--
  13114. 10:30:10That's from our friend Nick Parlante at Stanford.
  13115. 10:30:12So let's consider what Nick did here as Binky.
  13116. 10:30:14So here is all the code together.
  13117. 10:30:16These first couple of lines were not bad, and notice that in Stanford's code
  13118. 10:30:20they move the stars to the left.
  13119. 10:30:21That's fine.
  13120. 10:30:22Again, more conventional might be this syntax here.
  13121. 10:30:25These two lines are fine.
  13122. 10:30:26It's OK to create variables, even pointers,
  13123. 10:30:30and not assign them a value initially so long as you eventually do.
  13124. 10:30:33So we eventually do here, with this line.
  13125. 10:30:36We assign to x the return value of malloc, which
  13126. 10:30:39is presumably the address of something.
  13127. 10:30:41To be fair, we should really be checking for null as well,
  13128. 10:30:44but that's not the biggest problem here.
  13129. 10:30:46The biggest problem is not even this next line,
  13130. 10:30:48which means go to the memory location in x and store the number 42 there.
  13131. 10:30:54That's fine, because again, malloc returns
  13132. 10:30:56the address of some chunk of memory.
  13133. 10:30:59This chunk of memory is big enough for an int.
  13134. 10:31:01x is therefore going to store the address of that chunk that's
  13135. 10:31:04big enough for an int.
  13136. 10:31:05Star x recalls the dereference operator, means go to that address
  13137. 10:31:08and put 42 in it.
  13138. 10:31:10It's like going to the mailbox and putting the number 42 in it
  13139. 10:31:13instead of taking the number 50 out, like we did before.
  13140. 10:31:16But why is this line bad?
  13141. 10:31:18This is where Binky lost his head, so to speak.
  13142. 10:31:21Why is this bad?
  13143. 10:31:23Yeah.
  13144. 10:31:24AUDIENCE: We haven't yet allocated space for it.
  13145. 10:31:26DAVID J. MALAN: Exactly.
  13146. 10:31:26We haven't yet allocated space for y.
  13147. 10:31:28There's no mention of malloc, there's no assignment of y,
  13148. 10:31:31even to that same memory.
  13149. 10:31:32So this would be, go to the address in y,
  13150. 10:31:35but if there is no known address in y, it is a so-called garbage value,
  13151. 10:31:39which means go to some random address that you have no control over,
  13152. 10:31:42and boom--
  13153. 10:31:42that might cause what we've seen in the past, perhaps as a segmentation fault.
  13154. 10:31:47Now this, fortunately, is the kind of thing
  13155. 10:31:49that if you don't quite have the eye for it yet, Valgrins, that new tool,
  13156. 10:31:53could help you find as well.
  13157. 10:31:55But it's just another example of again, the sort of upside and downside
  13158. 10:31:59of having control now over memory at this level.
  13159. 10:32:02All right.
  13160. 10:32:02Well, let's go ahead and do one other thing.
  13161. 10:32:04Considering from last week that this notion of swapping
  13162. 10:32:07was actually a really common operation.
  13163. 10:32:09We had all of our volunteers come up, we had to swap a lot of things
  13164. 10:32:12during bubble sorts and even selection sort,
  13165. 10:32:14and we just took for granted that the two
  13166. 10:32:17humans would swap themselves just fine.
  13167. 10:32:18But there needs to be code to do that if you actually
  13168. 10:32:21implement bubble sort, selection sort, or anything that involves swapping.
  13169. 10:32:25So let's consider some code like this.
  13170. 10:32:26We'll keep it simple like last week, and where
  13171. 10:32:28we wanted to swap some values like int A and int B, for instance, here.
  13172. 10:32:35Void because I'm not going to return a value, but I have a function
  13173. 10:32:38called swap.
  13174. 10:32:39So here, for instance, might be some code for this.
  13175. 10:32:44But why is it so complicated?
  13176. 10:32:45Here, let's actually take a step back.
  13177. 10:32:47Why don't we do this here.
  13178. 10:32:48I think we have time for one more volunteer.
  13179. 10:32:50Could we get someone to come on up?
  13180. 10:32:51You have to be comfy on camera and you're
  13181. 10:32:54being asked to help with your-- oh, I'll go with the friend, pointing.
  13182. 10:32:57So whoever has their friend doing this here--
  13183. 10:33:01no?
  13184. 10:33:01Now they're pointing it over here.
  13185. 10:33:03Now, literally an arm is being twisted.
  13186. 10:33:05OK.
  13187. 10:33:07Come on down.
  13188. 10:33:07That backfired.
  13189. 10:33:13Come on over.
  13190. 10:33:19And what is your name?
  13191. 10:33:21AUDIENCE: Marina.
  13192. 10:33:22DAVID J. MALAN: Marina.
  13193. 10:33:23Nice to meet you.
  13194. 10:33:25Who were you trying to volunteer?
  13195. 10:33:27AUDIENCE: My friend Jesse.
  13196. 10:33:28DAVID J. MALAN: OK.
  13197. 10:33:29So here we have for Marina two glasses of liquid, orange and purple,
  13198. 10:33:33just so that they're super obvious.
  13199. 10:33:35And suppose that the problem at hand, like last week,
  13200. 10:33:37it's just to swap two values, as though these two glasses represented
  13201. 10:33:40two people and we want to swap them.
  13202. 10:33:42But let's consider these glasses to be like variables, or location
  13203. 10:33:45in an array, and you know what?
  13204. 10:33:47I'd really like you to swap the values.
  13205. 10:33:50So orange has to go in there, and purple has to go in there.
  13206. 10:33:53How would you do it?
  13207. 10:33:54And we'll see if we can then translate that to code.
  13208. 10:33:56AUDIENCE: [INAUDIBLE]
  13209. 10:33:58DAVID J. MALAN: OK, what--
  13210. 10:33:59say it a little louder.
  13211. 10:34:01All right, yeah.
  13212. 10:34:02So presumably, you're struggling mentally
  13213. 10:34:04with how you would do this without having an extra cup, so good foresight
  13214. 10:34:08here.
  13215. 10:34:08Let me go ahead and we do have a temporary variable, if you will.
  13216. 10:34:11So if I hand you this, how would you now solve this problem?
  13217. 10:34:16AUDIENCE: I would go like that, but it's--
  13218. 10:34:18DAVID J. MALAN: No, that's--
  13219. 10:34:18Oh.
  13220. 10:34:19Well, OK.
  13221. 10:34:20Go do it-- go with your instincts.
  13222. 10:34:23OK.
  13223. 10:34:24Sure, go ahead.
  13224. 10:34:26Go to whatever your instincts are.
  13225. 10:34:34Yeah, so a little-- so strictly speaking, probably
  13226. 10:34:37shouldn't have moved the glasses just because that
  13227. 10:34:39would be like moving the array locations,
  13228. 10:34:41so let's actually do it one more time but the glasses now
  13229. 10:34:43have to go back where they originally are.
  13230. 10:34:45So how would you swap these now, using this temporary variable?
  13231. 10:34:50OK, good.
  13232. 10:34:51Otherwise we'd be completely uprooting the array, for instance,
  13233. 10:34:54by just physically moving it around.
  13234. 10:34:56So you moved the orange into this temporary variable,
  13235. 10:34:58then you copied the purple into where the orange was,
  13236. 10:35:01and now, presumably, excellent.
  13237. 10:35:03The orange is going to end up where the purple once was
  13238. 10:35:06and this temporary variable, it stored up some extra memory.
  13239. 10:35:08It was necessary at the time, but not necessary, ultimately.
  13240. 10:35:11But a round of applause if we could, and thank you for doing that so well.
  13241. 10:35:17So the fact that it instantly occurred to Mariana
  13242. 10:35:21that you need some temporary variable is a perfect translation to code,
  13243. 10:35:25and in fact this code here, that we might glimpse now,
  13244. 10:35:28is reminiscent of exactly that algorithm,
  13245. 10:35:30where A and B, at the end of the day, are the same chunks of memory.
  13246. 10:35:33Just like the second time, the two glasses
  13247. 10:35:35have to kind of stay put, even though we're physically lifting them,
  13248. 10:35:37but they're going back to where they were,
  13249. 10:35:39is kind of like having two values, A and B,
  13250. 10:35:41and you just have a temporary variable into which you copy A,
  13251. 10:35:44then you change A with B, then you go and change
  13252. 10:35:47B with whatever the original value of A was,
  13253. 10:35:50because you temporarily stored it in this temporary variable, tmp.
  13254. 10:35:55Unfortunately, this code doesn't necessarily work as intended.
  13255. 10:35:59So let me go over to my VS Code here and open up
  13256. 10:36:02a program called swap.c, and in swap.c, let
  13257. 10:36:06me whip up something really quickly here with, how about include stdio.h,
  13258. 10:36:11int main(void).
  13259. 10:36:12Inside of main let me do something like x gets 1 and y gets 2.
  13260. 10:36:18Let me just print out as a visual confirmation that x is %i,
  13261. 10:36:23y is %i backslash n, plugging in x and y, respectively.
  13262. 10:36:28Then let me call a swap function that we'll invent in just a moment.
  13263. 10:36:31Swap x and y And then let me print out again x is %i, y is %i backslash n,
  13264. 10:36:38just to print out again what they are, because presumably I should see 1,
  13265. 10:36:412 first, then 2, 1 the second time.
  13266. 10:36:44Now how is swap going to be implemented?
  13267. 10:36:46Let me implement it exactly as on the screen a moment ago.
  13268. 10:36:49So void swap int x--
  13269. 10:36:52or let's call it int A for consistency, int B.
  13270. 10:36:54But I could always call those anything I want.
  13271. 10:36:57Int tmp gets A, A gets B, B gets tmp.
  13272. 10:37:01So exactly as I proposed a moment ago, and exactly
  13273. 10:37:04as Mariana really implemented it using these glasses of water.
  13274. 10:37:08I need to now include my prototype, as always, so nothing new there.
  13275. 10:37:11And I'll just copy/paste that up here, and now let's go ahead and run this.
  13276. 10:37:15So make swap-- so far, so good-- swap--
  13277. 10:37:18x is now 1, y is 2, x is 1, y is 2.
  13278. 10:37:23So there seems to be a bit of a bug here, but why might this be?
  13279. 10:37:29This code does not in fact work, even though it obviously works in reality.
  13280. 10:37:33Yeah?
  13281. 10:37:35AUDIENCE: Because A and B have different addresses than x and y [INAUDIBLE]..
  13282. 10:37:41DAVID J. MALAN: Good, and let me summarize.
  13283. 10:37:43A and B do indeed have different addresses of x and y,
  13284. 10:37:46and in fact what happens when you call a function like this on line 11,
  13285. 10:37:50calling swap, passing in x and y, you are calling a function
  13286. 10:37:54by value, so to speak.
  13287. 10:37:56And this is a term of art that just means
  13288. 10:37:57you are passing in copies of x and y, respectively, and calling them
  13289. 10:38:02A and B in the context of this function, but they're indeed copies.
  13290. 10:38:06Now technically, these names are local only.
  13291. 10:38:10I could have called this x, I could have called this y,
  13292. 10:38:13I could have changed this to x, this to y, this to x, and this to y.
  13293. 10:38:17The problem would still remain.
  13294. 10:38:19Just because you use the same names in one function as you do elsewhere,
  13295. 10:38:23that doesn't mean they're the same.
  13296. 10:38:24They just look the same to you.
  13297. 10:38:26But indeed, swap is going to get copies of this x and y, and in this context,
  13298. 10:38:31this scope, so to speak--
  13299. 10:38:33x and y will be copies of the original.
  13300. 10:38:36So for clarity, let me revert this back to A and B
  13301. 10:38:38just to make super clear that they're indeed different, albeit copies,
  13302. 10:38:42but there's indeed a problem there.
  13303. 10:38:44This function actually works fine.
  13304. 10:38:46In fact, notice this.
  13305. 10:38:47Let me go ahead and print out inside of this. printf A is %i,
  13306. 10:38:52B is %i backslash n, and then I'll print A and B.
  13307. 10:38:56And let me do that same thing at the beginning of this function before it
  13308. 10:38:59does any work.
  13309. 10:39:00Let me go ahead and rerun.
  13310. 10:39:02Make swap, ./swap, and this is promising.
  13311. 10:39:06Initially, x is 1, y is 2, A is 1, B is 2, A is 2, B is 1,
  13312. 10:39:12but then nope-- x is 1, y is 2.
  13313. 10:39:14So if anything, I've confirmed that the logic is right--
  13314. 10:39:17Mariana's logic is right, but there's something about C.
  13315. 10:39:20There's something about using one function versus another that's actually
  13316. 10:39:24creating a problem here.
  13317. 10:39:26The fact that I'm passing in copies of these values is creating this problem.
  13318. 10:39:30So what in fact is going on?
  13319. 10:39:31Well again, inside of your computer's memory there is these little chips,
  13320. 10:39:34and we've been talking about them abstractly,
  13321. 10:39:36it's just this grid of memory locations.
  13322. 10:39:38It turns out that your computer uses this memory
  13323. 10:39:41in a pretty conventional way.
  13324. 10:39:42It's not just random, where it just puts stuff wherever is available,
  13325. 10:39:46it actually uses different parts of the memory for different purposes.
  13326. 10:39:50And you have control over a lot of it, but the computer uses some of it
  13327. 10:39:54for itself.
  13328. 10:39:55And let's go ahead and zoom out from this
  13329. 10:39:56and consider that within your computer's memory, what a computer will typically
  13330. 10:40:00do is actually store initially, all of the zeros and ones
  13331. 10:40:04that you compiled in the top of your computer's memory, so to speak.
  13332. 10:40:08So when you compile a program and then you run it with ./whatever,
  13333. 10:40:11or on a Mac or PC you double click on it, the computer first--
  13334. 10:40:15the operating system first-- loads all of your program zeros and ones, a.k.a.
  13335. 10:40:20Machine code, into just one big chunk of memory at the top, so to speak.
  13336. 10:40:24Below that it stores global variables-- any variables
  13337. 10:40:28you have created in your program that are outside of main and outside
  13338. 10:40:32of any functions.
  13339. 10:40:33Generally, the top of your file.
  13340. 10:40:35Globals tend to go at the top there.
  13341. 10:40:37Then there's this chunk of memory that's generally known as the heap--
  13342. 10:40:39and we saw that word briefly in Valgin's output,
  13343. 10:40:42and then there's this other chunk of memory called the stack.
  13344. 10:40:45And it turns out that up until this week you were using the stack heavily.
  13345. 10:40:51Any time you use local variables in a function they end up on the stack.
  13346. 10:40:56Any time you use malloc, that memory ends up on the heap.
  13347. 10:41:00Now as the arrow suggests, this actually looks
  13348. 10:41:02like a problem waiting to happen because if you use more and more and more
  13349. 10:41:05heap, and more and more and more stack, it's
  13350. 10:41:07like two things barreling down the tracks at one another-- this does not
  13351. 10:41:09end well.
  13352. 10:41:10And that's actually a problem.
  13353. 10:41:11If you've ever heard the phrase stack overflow, or use the website,
  13354. 10:41:14this is the origin of its name.
  13355. 10:41:16When you start to use more and more and more
  13356. 10:41:18memory by calling lots and lots of functions
  13357. 10:41:21or using lots and lots of local variables,
  13358. 10:41:23you use a lot of this stack memory.
  13359. 10:41:25Or if you use malloc a lot and keep calling malloc, malloc, malloc,
  13360. 10:41:29and never really, or rarely calling free, you just use more and more memory
  13361. 10:41:33and eventually these two things might overflow each other, at which point
  13362. 10:41:36you're just out of luck.
  13363. 10:41:37The program will crash or something bad will happen.
  13364. 10:41:40So the onus is on you just to don't do that.
  13365. 10:41:43But this is the design, generally, of what's
  13366. 10:41:45going on inside of your computer's memory.
  13367. 10:41:47Now within that memory, though, there are certain conventions
  13368. 10:41:51focusing on here, the stack.
  13369. 10:41:52And in fact, let me go over here with a marker
  13370. 10:41:55and say that this represents the bottom of my memory, ultimately.
  13371. 10:41:58And so here we have a whole bunch of wooden blocks and each of these squares
  13372. 10:42:03represents a byte of memory and this, for instance,
  13373. 10:42:05might represent four bytes altogether-- good enough for an int,
  13374. 10:42:08or something like that.
  13375. 10:42:09So in my original code that I wrote earlier, that is in fact, buggy,
  13376. 10:42:13what is in fact going on inside the swap function?
  13377. 10:42:16We can visualize it like this-- when you run ./swap or any program for that
  13378. 10:42:20matter, main is the first function to get called with a C program,
  13379. 10:42:23and so I'm just going to label this bottom row of memory as main.
  13380. 10:42:27And what were the two variables I had in main called in this code?
  13381. 10:42:31Yeah.
  13382. 10:42:32x and y.
  13383. 10:42:33And each of those was an int, so that's four bytes,
  13384. 10:42:35so it's deliberate that I reserved four--
  13385. 10:42:38a chunk of wood here that's four bytes.
  13386. 10:42:41So let me just call this x, and I'm just going to write the number 1 in this box
  13387. 10:42:45here.
  13388. 10:42:45And then I had my other variable y, and I'm going to put the number 2 there.
  13389. 10:42:49What happens when main calls swap like it does in this code here?
  13390. 10:42:54Well, it has two variables of its own, A and B, and A initially is 1
  13391. 10:43:00and B is initially 2, but it has a third variable, tmp,
  13392. 10:43:04which is a local variable in addition to the arguments A and B
  13393. 10:43:07that are passed in, so I'm going to call this tmp, tmp over here.
  13394. 10:43:12And what is the value of tmp?
  13395. 10:43:13Well, we have to look back at the code.
  13396. 10:43:15tmp initially gets the value of A. All right, the value of a was 1,
  13397. 10:43:19so tmp initially gets 1.
  13398. 10:43:21That's step one in my three line program.
  13399. 10:43:23OK, A equals B. So that is assigned from the right to the left of the B
  13400. 10:43:27into the A So B is 2, A is this, so let me go ahead
  13401. 10:43:31and erase this and just overwrite that.
  13402. 10:43:33So at this moment in the story you have two copies of two,
  13403. 10:43:37so that's OK though, because the third line of code
  13404. 10:43:40says tmp gets copied into B. So what's tmp--
  13405. 10:43:431, gets copied into B, so let me overwrite this 2 with a 1,
  13406. 10:43:48and now what happens?
  13407. 10:43:50Now unfortunately, the code ends.
  13408. 10:43:53swap doesn't actually do anything with the result, and the problem in C
  13409. 10:43:56is that I could have had a return value.
  13410. 10:43:58I could go in there and change void to int,
  13411. 10:44:01but which one am I going to return?
  13412. 10:44:02The A or the B?
  13413. 10:44:04The whole goal is to swap two values, and it
  13414. 10:44:06seems kind of lame if you can't write a function
  13415. 10:44:08to do something as common per last week sorting algorithms
  13416. 10:44:12as swapping two values.
  13417. 10:44:13But what really happens?
  13418. 10:44:14Well, even though when this program starts running,
  13419. 10:44:18main is using this chunk of memory at the bottom in the so-called stack,
  13420. 10:44:21and the stack is just like a cafeteria stack of trays--
  13421. 10:44:24it grows up, like this.
  13422. 10:44:25Here's main's memory on the stack.
  13423. 10:44:27Here's the swap function's memory on the stack.
  13424. 10:44:29It's using three ints instead of two--
  13425. 10:44:32instead of only two.
  13426. 10:44:34What happens when the function returns, whether it's void or not?
  13427. 10:44:37The sort of recollection that this is swap's memory goes away
  13428. 10:44:41and garbage values are left.
  13429. 10:44:42So, adorably, we get rid of these values here,
  13430. 10:44:46and there's still data there-- technically, the numbers 1, 1, and 2
  13431. 10:44:51are still there in the computer's memory but they no longer belong to us
  13432. 10:44:54because the function has now returned.
  13433. 10:44:56So they're still in there and this is kind of an example visually
  13434. 10:44:59of why there's other stuff in memory even though you didn't put it there,
  13435. 10:45:03necessarily.
  13436. 10:45:03Sometimes you did put it there, but now once
  13437. 10:45:06swap returns you only should be touching memory inside of main.
  13438. 10:45:10But we've never actually copied one value into main.
  13439. 10:45:14We haven't returned anything and we haven't solved this fundamentally.
  13440. 10:45:18So how could we do this?
  13441. 10:45:19Well, what if we instead passed into swap not copies of x and y,
  13442. 10:45:23calling them A and B. What if they passed in breadcrumbs to x and y,
  13443. 10:45:28sort of a treasure map that will lead swap to the actual x
  13444. 10:45:31and to the actual y?
  13445. 10:45:32Today we have that capability using pointers.
  13446. 10:45:36So suppose that we use this code instead.
  13447. 10:45:40There's a lot of stars going on here, which is a bit annoying,
  13448. 10:45:43but let's consider what it is we're trying to achieve.
  13449. 10:45:45What if we pass in not x and y, but the address of x and the address of y,
  13450. 10:45:50respectively-- breadcrumbs, if you will--
  13451. 10:45:52that will lead swap to the original values.
  13452. 10:45:55Then what we do is we still give ourselves a tmp variable,
  13453. 10:45:59like an empty glass.
  13454. 10:46:00It's still a glass, so we still call it an int,
  13455. 10:46:03but what do we want to put into that temporary variable?
  13456. 10:46:05We don't want to put A into it, because that's an address now.
  13457. 10:46:08We want to go to that address per the star
  13458. 10:46:10and put whatever's at that address.
  13459. 10:46:12What do we then want to do?
  13460. 10:46:13Well, we want to then copy into whatever's at location A,
  13461. 10:46:17we want to copy over to location A's contents
  13462. 10:46:20whatever is at location B's contents and then lastly, we
  13463. 10:46:24want to copy tmp into whatever's at location B.
  13464. 10:46:27So again, we're very deliberately introducing all of these stars
  13465. 10:46:31because we don't want to change any of these addresses,
  13466. 10:46:33we want to go to these addresses per the reference operator
  13467. 10:46:37and put values there, or get values from.
  13468. 10:46:41So what does this actually mean?
  13469. 10:46:43Well, if I kind of rewind in this story and I go back here, I still have tmp,
  13470. 10:46:47although I'm going to delete its value to begin with, I still have B
  13471. 10:46:53and I still have A, but what's going to be different
  13472. 10:46:56this time is how I use A and B. So let me finish erasing those.
  13473. 10:47:00That's A on the left, this is B on the right.
  13474. 10:47:02At this point in the story, we're rerunning swap
  13475. 10:47:05with this new and improved version, and let's see what happens.
  13476. 10:47:08Well, x is presumably at some address.
  13477. 10:47:12Maybe it's like 0x123, as always.
  13478. 10:47:15What then does A get when I'm using this code?
  13479. 10:47:18The value of A is 0x123.
  13480. 10:47:22What is the value of B?
  13481. 10:47:23Maybe y is that 0x456.
  13482. 10:47:27What goes in B?
  13483. 10:47:28Well, I'm going to put 0x456, and the what am I going to do?
  13484. 10:47:33Based on these three lines of code, I'm going
  13485. 10:47:35to store in tmp whatever is at the address in A. What is the address in A?
  13486. 10:47:40That's this thing here, so I'm going to put 1 in tmp.
  13487. 10:47:43Line two-- I'm going to go to B--
  13488. 10:47:45all right, B is 456, so I'm going to B and I'm
  13489. 10:47:48going to store 2 at whatever is at location A, and at location A
  13490. 10:47:53is 123, so that's this, so what am I going to do?
  13491. 10:47:56I'm going to change this 1 to a 2.
  13492. 10:47:59Last line of code-- get the value of tmp, which is 1,
  13493. 10:48:01and then put it at whatever the location B is, so B, 456, go there
  13494. 10:48:07and change it to be the value of tmp, tmp, which puts 1 here.
  13495. 10:48:11That's it for the code.
  13496. 10:48:12There's still no return value.
  13497. 10:48:14swap returns, which means these three temporary variables
  13498. 10:48:17are garbage values now.
  13499. 10:48:19They can be reused by subsequent function calls
  13500. 10:48:21but now, I've actually swapped the values of x and y.
  13501. 10:48:26Which is to say what came as naturally as the real world here for Mariana
  13502. 10:48:30is not quite as simply done in C because again,
  13503. 10:48:33functions are isolated from each other.
  13504. 10:48:36You can pass in values but you get copies of those values.
  13505. 10:48:39If you want one function to affect the value of a variable somewhere else,
  13506. 10:48:44you have to 1, understand what's going on but 2,
  13507. 10:48:47pass things in as by a pointer here.
  13508. 10:48:50So if I go back to my code here, I need to make a few changes now.
  13509. 10:48:53Let me get rid of these extra printf's.
  13510. 10:48:56Let me go in and add all these stars.
  13511. 10:48:58So I'm dereferencing these actual addresses here and here,
  13512. 10:49:02and I've got to make one more change.
  13513. 10:49:05How do I now call swap if swap is expecting an int star and an int star?
  13514. 10:49:11That is, the address of an int and the address of another int.
  13515. 10:49:14What do I change on line 11 here?
  13516. 10:49:17Yeah.
  13517. 10:49:19Sorry, a little louder.
  13518. 10:49:21AUDIENCE: [INAUDIBLE]
  13519. 10:49:25DAVID J. MALAN: Sorry, the address of operator.
  13520. 10:49:28So up here on line 11, we do ampersand x and ampersand y.
  13521. 10:49:33So that yes, we're technically passing in a copy of a value,
  13522. 10:49:36but this time the copy we're passing in is technically an address,
  13523. 10:49:39and as soon as we have an address, just like when I held up the fuzzy finger--
  13524. 10:49:42the foamy finger-- I can point at that address, I can go to that address
  13525. 10:49:45and actually get a value from the mailbox or put a value into the mailbox
  13526. 10:49:49if I even want.
  13527. 10:49:52So let's cross our fingers now and do make swap, Enter.
  13528. 10:49:56Oh my God, so many mistakes.
  13529. 10:49:58Oh, I didn't remember to change my prototype,
  13530. 10:50:00so let me go way up here and add two more stars because I
  13531. 10:50:03made that change already.
  13532. 10:50:05Make swap, ./swap, and viola-- now I have actually swapped.
  13533. 10:50:10Thank you.
  13534. 10:50:14Thank you.
  13535. 10:50:15The two values.
  13536. 10:50:17All right, so what more can we do here?
  13537. 10:50:19Well, let me consider that all this time we've
  13538. 10:50:24been deliberately using GetString and GetInt and GetFloat
  13539. 10:50:29and so forth, but for a reason.
  13540. 10:50:30These aren't just training wheels for the sake of making things easier,
  13541. 10:50:33they're actually in place to make your code safer.
  13542. 10:50:36And to illustrate this, let me go ahead and open up one other file here.
  13543. 10:50:40How about a file called scanf.c.
  13544. 10:50:45It turns out that the old school way-- the way in C,
  13545. 10:50:48really, of getting user input, is via functions like scanf,
  13546. 10:50:52and let me go ahead and include stdio.h, int main(void),
  13547. 10:50:56and without using the CS50 library at all for strings or for any of those
  13548. 10:50:59get functions.
  13549. 10:51:00Let me give myself an int called x.
  13550. 10:51:03Let me just print out what the value of x is, even though it's going to be a--
  13551. 10:51:07or rather, ask the user for the value by asking them for x.
  13552. 10:51:10And I'm going to use a function called scanf that's going to scan
  13553. 10:51:14in an integer using %i, and I'm going to store whatever the human types
  13554. 10:51:20in at this location.
  13555. 10:51:22And then I'm going to go ahead and, just so we can see what happened,
  13556. 10:51:25I'm going to print out with %i whatever the human typed in as follows.
  13557. 10:51:29All right, so line eight is week 1 style code.
  13558. 10:51:32Line five and six is week 1 style code.
  13559. 10:51:36So the curiosity today is this new line. scanf is another function in stdio.h,
  13560. 10:51:41and notice what I'm doing.
  13561. 10:51:43I'm using the same syntax that I use for printf,
  13562. 10:51:46which is kind of a little clue-- a format code to tell scanf what it is I
  13563. 10:51:49want to scan in, that is, read from the human's keyboard--
  13564. 10:51:52and I'm telling it where to put whatever the human typed in.
  13565. 10:51:55I can't just say x, because we run into the same darn problem as with swap.
  13566. 10:51:59I have to give a little breadcrumb to the variable
  13567. 10:52:02where I want scanf to put the human's integer.
  13568. 10:52:05And so this just tells the computer to get an int.
  13569. 10:52:08This is what you would have had to type, essentially,
  13570. 10:52:11in week 1 just to get an int from the user,
  13571. 10:52:14and there's a whole bunch of things that can go wrong still,
  13572. 10:52:16but that's the cryptic syntax we would have had to show you in week 1.
  13573. 10:52:20Let me go ahead and make scanf here--
  13574. 10:52:22oops-- user error.
  13575. 10:52:25Put the semicolon in the wrong place.
  13576. 10:52:27Make scanf, Enter.
  13577. 10:52:29Oh my God.
  13578. 10:52:30Non void doesn't return a value.
  13579. 10:52:35Oh, thank you.
  13580. 10:52:37Strike two.
  13581. 10:52:38OK.
  13582. 10:52:39Make scanf.
  13583. 10:52:40There we go.
  13584. 10:52:41OK, so scanf--
  13585. 10:52:42I'm going to type in a number like 50 and it just prints it back out.
  13586. 10:52:45So that is the traditional way of implementing something like GetInt.
  13587. 10:52:49The problem, though, is when you start to get into strings, things
  13588. 10:52:53get dangerous quickly.
  13589. 10:52:54Let me delete all of this and give myself
  13590. 10:52:56a string s, although wait a minute-- we don't call it strings
  13591. 10:52:59anymore-- char star to store a string.
  13592. 10:53:02Then let me go ahead and just prompt the user for a string, using just printf.
  13593. 10:53:06Then let me go ahead and use scanf, ask them for a string this time with %s,
  13594. 10:53:10and store it at that address.
  13595. 10:53:13Then let me go ahead and print out whatever the human typed
  13596. 10:53:16in just by using the same notation.
  13597. 10:53:19So here, line five is the same thing as string s, but we've taken back
  13598. 10:53:24that layer today so it's char star s.
  13599. 10:53:26This is just week one this is just week one, line seven is new.
  13600. 10:53:31scanf will also read from the human's keyboard a string and store it at s.
  13601. 10:53:37But that's OK, because s is an address.
  13602. 10:53:39It's correct not to do the ampersand.
  13603. 10:53:41It's not necessary.
  13604. 10:53:42A string is and has always been a char star, a.k.a string.
  13605. 10:53:47The problem, though, arises as follows--
  13606. 10:53:49if I do make scanf--
  13607. 10:53:51oh my God, what did I do wrong--
  13608. 10:53:53I can't-- OK, we have certain defenses in place with make.
  13609. 10:53:55Let me do clang of scanf.c, an output of program called scanf.
  13610. 10:54:02All right, so I'm overriding some of our pedagogical defenses
  13611. 10:54:05that we have in place with make.
  13612. 10:54:06Let me now run scanf of this version, Enter, and let me type in something
  13613. 10:54:11like, how about hi again.
  13614. 10:54:15So it didn't even store something and it weirdly printed out null.
  13615. 10:54:18This time it's in lowercase, but that is somewhat related.
  13616. 10:54:22What did I fundamentally do wrong though, here?
  13617. 10:54:26Why is this getting more and more dangerous?
  13618. 10:54:29And let me illustrate the point even more.
  13619. 10:54:30What if I type in not just something like hello, which also doesn't work.
  13620. 10:54:34What if I do like, hellooooo and make a really long string, Enter--
  13621. 10:54:39that still works.
  13622. 10:54:41Can I do this again?
  13623. 10:54:43Let's try again.
  13624. 10:54:45Right, a really long, unexpectedly long string.
  13625. 10:54:48This is the nondeterminism kicking in.
  13626. 10:54:50Enter.
  13627. 10:54:51All right, damn it.
  13628. 10:54:51I was trying to trigger a segmentation fault
  13629. 10:54:53but it wouldn't, but the point still remains.
  13630. 10:54:56It's still not working, but what's the essence of why this isn't working,
  13631. 10:55:01and it's not storing my actual input?
  13632. 10:55:03Yeah.
  13633. 10:55:04AUDIENCE: Do you have to make a space?
  13634. 10:55:06DAVID J. MALAN: We have to make space for it.
  13635. 10:55:07So what we're missing here is malloc, or something like that.
  13636. 10:55:11So I could do that, I could do something like this.
  13637. 10:55:14Well, let the human type in at least a three letter word
  13638. 10:55:16so I could do malloc of 3 plus 1 for the null character.
  13639. 10:55:20So let me give them four characters, and let me go ahead and do make scanf--
  13640. 10:55:25whoops.
  13641. 10:55:26Nope, sorry. clang, I have to--
  13642. 10:55:28nope.
  13643. 10:55:29Dammit.
  13644. 10:55:29Oh, include stdlib.h-- there we go.
  13645. 10:55:36That gives me malloc, now I'm going to recompile this with clang,
  13646. 10:55:39now I'm going to rerun it, and now I'm going to type in my first thing, hi.
  13647. 10:55:42That now works.
  13648. 10:55:43And let me get a little aggressive now and type in hello, which is too long.
  13649. 10:55:47Still works, but I'm getting lucky.
  13650. 10:55:49Let me try a hellooooooo.
  13651. 10:55:53Damn it, that still works, too.
  13652. 10:55:55Sort of.
  13653. 10:55:56But it actually-- not quite.
  13654. 10:55:58There's some weirdness going on there already.
  13655. 10:56:00It turns out I can also do this.
  13656. 10:56:02I could actually just say char star four and give myself
  13657. 10:56:05an array of four characters.
  13658. 10:56:07Let me try this one more time.
  13659. 10:56:08So let me rerun clang ./scanf.
  13660. 10:56:12Hellooooooo, clearly exceeding the four characters--
  13661. 10:56:16there we go.
  13662. 10:56:17Thank you, all right.
  13663. 10:56:22So the point here, though, is if we hadn't given you GetInt,
  13664. 10:56:24you would have had to use the scanf thing-- not a huge deal
  13665. 10:56:27because it seemed to work.
  13666. 10:56:28But if we hadn't given you GetString you would have had to do stuff like this,
  13667. 10:56:31knowing about malloc already or knowing about strings being erased,
  13668. 10:56:34and even now there's a danger.
  13669. 10:56:36If the human types in five letters, six letters, 100 letters-- this code,
  13670. 10:56:41like with the Hello input, will probably just crash, which is bad.
  13671. 10:56:44So GetString also has this functionality built
  13672. 10:56:46in where we have a fancy loop inside such
  13673. 10:56:49that we allocate using malloc as many bytes as you physically type in,
  13674. 10:56:53and we use malloc essentially every keystroke.
  13675. 10:56:55The moment you type in h-e-l-l-o, we're laying the tracks as we go and we keep
  13676. 10:57:00allocating more and more memory so that we theoretically will never crash with
  13677. 10:57:04GetString even though it's this easy to crack--
  13678. 10:57:07this easy to crash your code using scanf if you again
  13679. 10:57:10did it without the help of a library.
  13680. 10:57:13So where are we all going with this?
  13681. 10:57:15Well, let me show you a few final examples that'll
  13682. 10:57:17pave the way for what will be problem set four.
  13683. 10:57:19Let me go ahead and open up from today's code--
  13684. 10:57:23which is available on the course's website--
  13685. 10:57:25for instance, a program like this, called phonebook.c,
  13686. 10:57:32and I'm just going to give you a quick tour of it,
  13687. 10:57:34that you'll see more details on in the context of p-set four itself.
  13688. 10:57:37We're going to introduce a few new functions you're going to see.
  13689. 10:57:40You're going to see a function called fopen, which stands for file open,
  13690. 10:57:43and it takes two arguments-- the name of a file to open like a CSV
  13691. 10:57:47that you might manipulate in Excel or Google Spreadsheets or the like-- comma
  13692. 10:57:50separated values, and then something like A for append, R for read,
  13693. 10:57:55W for write, depending on whether you want to add to the file,
  13694. 10:57:58just open it up, or change it.
  13695. 10:58:00We're going to introduce you to a file pointer.
  13696. 10:58:03You'll see that capital file--
  13697. 10:58:05which is a little bit unconventional-- capital file is
  13698. 10:58:07a pointer to an actual file on the computer's hard drive
  13699. 10:58:10so that you can actually access something like a CSV file,
  13700. 10:58:13or heck, even images.
  13701. 10:58:14And we're going to see down below that you're also
  13702. 10:58:16going to have the ability to write files as well, or print to files.
  13703. 10:58:20You'll see functions like printf printf for file printf.
  13704. 10:58:24Or fwrite-- file write-- which now that you will begin to understand pointers,
  13705. 10:58:29you'll have the ability to actually not only read files--
  13706. 10:58:33text files, images, other things-- but also write them out.
  13707. 10:58:36In fact for instance, just as a teaser here, JPEGs will be one of the things
  13708. 10:58:42we focus on this week where we give you a forensic image
  13709. 10:58:44and your goal is to recover as many photographs
  13710. 10:58:47from this forensic image of a digital camera as you possibly can.
  13711. 10:58:51And the way you're going to do that is by knowing in advance
  13712. 10:58:54that every JPEG in the world starts with these three bytes, written
  13713. 10:58:58in hexadecimal, but these three numbers.
  13714. 10:59:01And so in fact, just as a teaser, let me open up
  13715. 10:59:03an example you'll see on the course's website for today.
  13716. 10:59:07If I scroll through here, you'll see a program
  13717. 10:59:09that does a little something like this.
  13718. 10:59:11And again, more on this--
  13719. 10:59:13if we could hit the button--
  13720. 10:59:15there we go.
  13721. 10:59:16So here we have the notion of a byte we're going to create for ourselves.
  13722. 10:59:21We'll see a data type called byte, which is a common convention.
  13723. 10:59:24This gives me three bytes.
  13724. 10:59:25And you're going to learn about a function called fread,
  13725. 10:59:28which reads from a file some number of bytes-- for instance, three bytes.
  13726. 10:59:31We might then use code like this.
  13727. 10:59:33If bytes bracket zero equals equals 0xFF and bytes
  13728. 10:59:37bracket 1 equals 0xD8 and bytes bracket 2 equals 0xFF, all three of those
  13729. 10:59:43bytes I just claimed represent a JPEG, you'll see an output like this.
  13730. 10:59:47Let me go ahead and run this program as follows.
  13731. 10:59:51Let me copy jpeg.c into my directory from today's distribution.
  13732. 10:59:55Let me do make jpeg, and let me run jpeg on a file which is available online
  13733. 11:00:03called lecture.jpeg, and I claim yes, it's possibly a JPEG.
  13734. 11:00:07Well, what is that file?
  13735. 11:00:08Let me open it up for us, called lecture.jpeg, and here, for instance,
  13736. 11:00:11is that same photo with which we began class, namely implemented as a JPEG.
  13737. 11:00:15But what we're also going to do this week
  13738. 11:00:18is start to implement our own sort of filters a la Instagram, whereby
  13739. 11:00:22we might take images and actually run them through a program that
  13740. 11:00:26creates different versions thereof.
  13741. 11:00:28For instance, using a different file format
  13742. 11:00:30called BMP, which essentially lays out all of its pixels from left to right,
  13743. 11:00:33top to bottom, in a grid.
  13744. 11:00:35You're going to see a struct--
  13745. 11:00:36a data struct in C that's way more complicated
  13746. 11:00:38than the candidate structure from the past,
  13747. 11:00:40or the person structure from the past, that
  13748. 11:00:43looks like this, which is just a whole bunch more values in it,
  13749. 11:00:45but we'll walk you through these in the p-set.
  13750. 11:00:47And we might take a photograph like this and ask
  13751. 11:00:49you to run a few different filters on it a la Instagram,
  13752. 11:00:52like a black and white filter, or grayscale, a sepia filter
  13753. 11:00:55to give it some old school feel, or a reflection like this to invert it,
  13754. 11:00:59or blur it, even in this way.
  13755. 11:01:02And just to end on a note here, I have a version
  13756. 11:01:05of this code ready to go that doesn't implement all of those filters,
  13757. 11:01:08it just implements one filter initially.
  13758. 11:01:11Let me go ahead and just ready this on my computer here.
  13759. 11:01:14I'm going to go into my own version of filter
  13760. 11:01:16and you'll see a few files that will give you
  13761. 11:01:18a tour of this coming week in bitmap.h, for instance,
  13762. 11:01:21is a version of this structure that I claimed existed a moment ago.
  13763. 11:01:26And let me show you this file here, helpers.c, in which there is a function
  13764. 11:01:34called filter that I've already implemented in advance today.
  13765. 11:01:38But the ones we give you for the piece that won't already be implemented,
  13766. 11:01:41this function called filter takes the height of an image,
  13767. 11:01:43the width of an image, and a two dimensional array.
  13768. 11:01:46So rows and columns of pixels, and then I
  13769. 11:01:49have a loop like this that iterates over all of the pixels in an image from top
  13770. 11:01:53to bottom, left to right.
  13771. 11:01:55And then notice what I'm going to do here.
  13772. 11:01:57I'm going to change the blue value to be zero in this case,
  13773. 11:02:00and the green value to be zero in this case.
  13774. 11:02:02But why?
  13775. 11:02:03Well, the image I have here in mind is this one,
  13776. 11:02:07whereby we have this hidden image that simply
  13777. 11:02:10has old school style-- a secret message embedded in it.
  13778. 11:02:13And if you don't happen to have in your dorm one of these secret decoder
  13779. 11:02:16glasses that essentially make everything red--
  13780. 11:02:18getting rid of the green in the world and the blue in the world--
  13781. 11:02:21you can actually-- I'm actually probably the only one who
  13782. 11:02:24can read this right now-- see what message
  13783. 11:02:26is hidden behind all of this red noise.
  13784. 11:02:28But if using my code written here in helpers.c I get rid of all the blue
  13785. 11:02:34in the picture and I get rid of all the green in the picture,
  13786. 11:02:37essentially implementing the idea of this filter--
  13787. 11:02:39this red filter where you only see red--
  13788. 11:02:42well, let's go ahead and compile this program.
  13789. 11:02:45Make filter, run ./filter on this hidden message.bmp.
  13790. 11:02:50I'm going to save it in a new file called message.bmp,
  13791. 11:02:53and with one final flourish we're going to open up
  13792. 11:02:56message.bmp, which is the result of having put on these glasses,
  13793. 11:03:00and hopefully now you too will see what I see.
  13794. 11:03:12All right, that's it for CS50!
  13795. 11:03:14We'll see you next time.
  13796. 11:03:17[MUSIC PLAYING]
  13797. 11:04:35SPEAKER 1: All right.
  13798. 11:04:37This is CS 50.
  13799. 11:04:39And this is already week 5, which means this is actually
  13800. 11:04:42our last week in C together.
  13801. 11:04:44In fact, in just a few days' time, what has looked like this
  13802. 11:04:48and much more cryptic than this perhaps, is
  13803. 11:04:50going to be distilled into something much simpler next week.
  13804. 11:04:53When we transition to a language called Python.
  13805. 11:04:55And with Python, we'll still have our conditionals, and loops, and functions,
  13806. 11:04:59and so forth.
  13807. 11:05:00But a lot of the low-level plumbing that you might have been wrestling with,
  13808. 11:05:03struggling with, frustrated by, over the past couple of weeks,
  13809. 11:05:06especially, now that we've introduced pointers.
  13810. 11:05:08And it feels like you probably have to do everything yourself.
  13811. 11:05:11In Python, and in a lot of higher level languages
  13812. 11:05:14so to speak-- more modern, more recent languages,
  13813. 11:05:16you'll be able to do so much more with just single lines of code.
  13814. 11:05:20And indeed, we're going to start leveraging libraries, all the more code
  13815. 11:05:23that other people wrote.
  13816. 11:05:24Frameworks, which is collections of libraries that other people wrote.
  13817. 11:05:27And on top of all that, will you be able to make even better, grander, more
  13818. 11:05:31impressive projects, that actually solve problems of particular interest to you.
  13819. 11:05:34Particularly, by way of your own final project.
  13820. 11:05:37So last week though, in week 4, recall that we focused on memory.
  13821. 11:05:41And we've been treating this memory inside of your computer
  13822. 11:05:43is like a canvas, right.
  13823. 11:05:45At the end of the day, it's just zeros and ones, or bytes, really.
  13824. 11:05:48And it's really up to you what you do with those bytes.
  13825. 11:05:51And how you interconnect them, how you represent information on them.
  13826. 11:05:54And arrays, were like one of the simplest ways.
  13827. 11:05:56We started playing around with that memory.
  13828. 11:05:58Just contiguous chunks of memory.
  13829. 11:06:00Back-to-back, to back.
  13830. 11:06:01But let's consider, for a moment, some of the problems that
  13831. 11:06:04pretty quickly arise with arrays.
  13832. 11:06:06And then, today focus on what more generally are called data structures.
  13833. 11:06:09Using your computer's memory as a much more versatile canvas,
  13834. 11:06:14to create even two-dimensional structures.
  13835. 11:06:16To represent information, and, ultimately,
  13836. 11:06:18to solve more interesting problems.
  13837. 11:06:20So here's an array of size 3.
  13838. 11:06:22Maybe, the size of 3 integers.
  13839. 11:06:24And suppose that this is inside of a program.
  13840. 11:06:26And at this point in the story, you've got 3 numbers in it already.
  13841. 11:06:291, 2 and 3.
  13842. 11:06:30And suppose, whatever the context, you need to now add a fourth number
  13843. 11:06:34to this array.
  13844. 11:06:35Like, the number 4.
  13845. 11:06:36Well, instinctively, where should the number 4 go?
  13846. 11:06:39If this is your computer's memory and we currently
  13847. 11:06:41have this array 1, 2, 3, from what.
  13848. 11:06:43Left to right.
  13849. 11:06:44Where should the number 4 just, perhaps, naively go.
  13850. 11:06:47Yeah, what do you think?
  13851. 11:06:48AUDIENCE: Replace number 1.
  13852. 11:06:49SPEAKER 1: Sorry?
  13853. 11:06:50AUDIENCE: Replace number 1.
  13854. 11:06:51SPEAKER 1: Oh, OK.
  13855. 11:06:52So you could replace number 1.
  13856. 11:06:53I don't really like that, though, because I'd
  13857. 11:06:55like to keep number 1 around.
  13858. 11:06:56But that's an option.
  13859. 11:06:58But I'm losing, of course, information.
  13860. 11:06:59So what else could I do if I want to add the number 4.
  13861. 11:07:02Over there?
  13862. 11:07:02AUDIENCE: On the right side of 3.
  13863. 11:07:04SPEAKER 1: Yeah.
  13864. 11:07:04So, I mean, it feels like if there's some ordering
  13865. 11:07:06to these, which seems kind of a reasonable inference,
  13866. 11:07:09that it probably belongs somewhere over here.
  13867. 11:07:11But recall last week, as we started poking around a computer's memory,
  13868. 11:07:14there's other stuff potentially going on.
  13869. 11:07:16And if fill that in, ideally, we'd want to just plop the number 4 here.
  13870. 11:07:20If we're maintaining this kind of order.
  13871. 11:07:22But recall in the context of your computer's memory,
  13872. 11:07:24there might be other stuff there.
  13873. 11:07:25Some of these garbage values that might be usable,
  13874. 11:07:28but we don't really know or care what they are.
  13875. 11:07:30As represented by Oscar here.
  13876. 11:07:31But there might actually be useful data in use.
  13877. 11:07:34Like, if your program has not just a few integers in this array,
  13878. 11:07:38but also a string that says like, "Hello, world."
  13879. 11:07:40It could be that your computer has plopped the H-E-L-L-O W-O-R-L-D right
  13880. 11:07:46after this array.
  13881. 11:07:47Why?
  13882. 11:07:48Well, maybe, you created the array in one line of code
  13883. 11:07:50and filled it with 1, 2, 3.
  13884. 11:07:52Maybe the next line of code used GET-STRING.
  13885. 11:07:54Or maybe just hard coded a string in your code for "Hello, world."
  13886. 11:07:57And so you painted yourself into a corner, so to speak.
  13887. 11:08:00Now I think you might claim, well, let's just overwrite the H.
  13888. 11:08:03But that's problematic for the same reasons.
  13889. 11:08:04We don't want to do that.
  13890. 11:08:06So where else could the 4 go?
  13891. 11:08:09Or how do we solve this problem if we want to add a number,
  13892. 11:08:12and there's clearly memory available.
  13893. 11:08:14Because those garbage values are junk that we don't care about anymore.
  13894. 11:08:17So we could certainly reuse those.
  13895. 11:08:20Where could the 4, and perhaps this whole array, go?
  13896. 11:08:23OK.
  13897. 11:08:24So I'm hearing we could move it somewhere.
  13898. 11:08:26Maybe, replace some of those garbage values.
  13899. 11:08:27And honestly, we have a lot of options.
  13900. 11:08:29We could use any of these garbage values up here.
  13901. 11:08:32We could use any of these down here, or even further down.
  13902. 11:08:34The point is there is plenty of memory available as
  13903. 11:08:38indicated by these Oscars, where we could put 4, maybe even, 5,
  13904. 11:08:416 or more integers.
  13905. 11:08:43The catch is that we chose poorly early on.
  13906. 11:08:46Or we just got unlucky.
  13907. 11:08:47And 1, 2, 3 ended up back-to-back with some other data that we care about.
  13908. 11:08:51All right, so that's fine.
  13909. 11:08:52Let's go ahead and assume that we'll abstract away everything else.
  13910. 11:08:55And we'll plop the new array in this location here.
  13911. 11:08:58So I'm going to go ahead and copy the 1 over.
  13912. 11:09:00The 2 over.
  13913. 11:09:01The 3 over.
  13914. 11:09:01And then, ultimately, once I'm ready to fill the 4,
  13915. 11:09:04I can throw away, essentially, the old array at this point.
  13916. 11:09:07Because I have it now entirely in duplicate.
  13917. 11:09:09And I can populate it with the number 4.
  13918. 11:09:11All right.
  13919. 11:09:11So problem solved.
  13920. 11:09:12That is a correct potential solution to this problem.
  13921. 11:09:15But, what's the trade off?
  13922. 11:09:16And this is something we're going to start thinking about all the more.
  13923. 11:09:19What's the downside of having solved this problem in this way?
  13924. 11:09:22Yeah.
  13925. 11:09:23I'm adding a lot of running time.
  13926. 11:09:25It took me a lot of effort to copy those additional numbers.
  13927. 11:09:28Now, granted, it's a small array.
  13928. 11:09:293 numbers, who cares.
  13929. 11:09:30It's going to be over in the blink of an eye.
  13930. 11:09:32But if we start talking about interesting data sets,
  13931. 11:09:35web application data sets, mobile app data sets.
  13932. 11:09:37Where you have not just a few, but maybe a few hundred, few thousand,
  13933. 11:09:41a few million pieces of data.
  13934. 11:09:43This is probably a suboptimal solution to just, oh,
  13935. 11:09:46move all your data from one place to another.
  13936. 11:09:48Because who's to say that we're not going
  13937. 11:09:49to paint ourselves into a new corner.
  13938. 11:09:51And it would feel like you're wasting all of this time moving stuff around.
  13939. 11:09:54And, ultimately, just costing yourself a huge amount of time.
  13940. 11:09:58In fact, if we put this now into the context of our Big O notation
  13941. 11:10:01from a few weeks back, what might the running time now of Search
  13942. 11:10:06be for an array?
  13943. 11:10:07Let's start simple.
  13944. 11:10:08A throwback a couple of weeks ago.
  13945. 11:10:10If you're using an array, to recap, what was the running time
  13946. 11:10:14of a Search algorithm in Big O notation?
  13947. 11:10:17So, maybe, in the worst case.
  13948. 11:10:19If you've got n numbers, 3 in this case or 4, but n more generally.
  13949. 11:10:23Big O of what for Search?
  13950. 11:10:25Yeah.
  13951. 11:10:26What do you think?
  13952. 11:10:26AUDIENCE: Big O of n.
  13953. 11:10:27SPEAKER 1: Big O of n.
  13954. 11:10:28And what's your intuition for that?
  13955. 11:10:30AUDIENCE: [INAUDIBLE].
  13956. 11:10:35SPEAKER 1: OK.
  13957. 11:10:36Yeah.
  13958. 11:10:36So if we go through each element, for instance, from left to right,
  13959. 11:10:39then Search is going to take this a Big O running time.
  13960. 11:10:42If, though, we're talking about these numbers, specifically.
  13961. 11:10:46And now I'll explicitly stipulate that, yeah, they're sorted.
  13962. 11:10:48Does that buy us anything?
  13963. 11:10:50What would the Big O notation be for Searching an array in this case,
  13964. 11:10:54be it of size 3, or 4, or n, more generally.
  13965. 11:10:56AUDIENCE: Big O of n.
  13966. 11:10:57SPEAKER 1: Big O of, not n, but rather?
  13967. 11:10:59AUDIENCE: Log n.
  13968. 11:11:00SPEAKER 1: Log n, right.
  13969. 11:11:01Because we could use per week zero binary search on an array like this,
  13970. 11:11:05we'd have to deal with some rounding.
  13971. 11:11:06Because there's not a perfect number of elements at the moment.
  13972. 11:11:08But you could use binary search.
  13973. 11:11:10Go to the middle roughly.
  13974. 11:11:11And then go left or right, left or right,
  13975. 11:11:13until you find the element you care about.
  13976. 11:11:15So Search remains in Big O of log n when using arrays.
  13977. 11:11:19But what about insertion, now?
  13978. 11:11:21If we start to think about other operations.
  13979. 11:11:23Like, adding a number to this array, or adding a friend to your contacts
  13980. 11:11:26app, or Google finding another page on the internet.
  13981. 11:11:29So insertion happens all the time.
  13982. 11:11:31What's the running time of Insert?
  13983. 11:11:34When it comes to inserting into an existing array of size n.
  13984. 11:11:38How many steps might that take?
  13985. 11:11:40Big O of n.
  13986. 11:11:41It would be, indeed, n.
  13987. 11:11:42Why?
  13988. 11:11:43Because in the worst case, where you're out of space,
  13989. 11:11:46you have to allocate, it would seem, a new array.
  13990. 11:11:48Maybe, taking over some of the previous garbage values.
  13991. 11:11:50But the catch is, even though you're only
  13992. 11:11:52inserting one new number, like the number 4,
  13993. 11:11:55you have to copy over all the darn existing numbers into the new one.
  13994. 11:11:58So if your original array of size n, the copying of that
  13995. 11:12:01is going to take Big O of n plus 1.
  13996. 11:12:03But we can throw away the plus 1 because of the math we did in the past.
  13997. 11:12:06So Insert now becomes Big O of n.
  13998. 11:12:09And that might not be ideal.
  13999. 11:12:11Because if you're in the habit of inserting things frequently,
  14000. 11:12:13that could start to add up, and add up, and add up.
  14001. 11:12:16And this is why computer programs, and websites, and mobile apps
  14002. 11:12:19could be slow.
  14003. 11:12:20If you're not being mindful of these trade offs.
  14004. 11:12:23So what about, just for good measure, Omega notation.
  14005. 11:12:27And maybe, the best case.
  14006. 11:12:28Well just to recap here, we could get lucky
  14007. 11:12:31and Search could just take one step.
  14008. 11:12:33Because you might just get lucky, and boom the number
  14009. 11:12:35you're looking for is right there in the middle, if using binary search.
  14010. 11:12:38Or even linear search, for that matter.
  14011. 11:12:40And insert 2.
  14012. 11:12:41If there's enough room, and we didn't have to move all of those numbers--
  14013. 11:12:451, 2, and 3, to a new location.
  14014. 11:12:46You could get lucky.
  14015. 11:12:47And we could have, as someone suggested, just
  14016. 11:12:49put the number 4 right there at the end.
  14017. 11:12:51And if we don't get lucky, it might take n steps.
  14018. 11:12:53If we do get lucky, it might just take the one, or constant number, of steps.
  14019. 11:12:57In fact, let me go ahead and do this.
  14020. 11:12:59How about we do something like this?
  14021. 11:13:00Let me switch over to some code here.
  14022. 11:13:02Let me start to make a program called List.C.
  14023. 11:13:05And in List.C, let's start with the old way.
  14024. 11:13:08So we follow the breadcrumbs we've laid for ourselves as follows.
  14025. 11:13:11So in this List.C, I'm going to include standardio.h.
  14026. 11:13:14Int main(void) as usual.
  14027. 11:13:16Then inside of my code here, I'm going to go ahead and give myself
  14028. 11:13:20the first version of memory.
  14029. 11:13:22So int list 3 is now implemented at the moment, in an array.
  14030. 11:13:26So we're rewinding for now to week 2 style code.
  14031. 11:13:29And then, let me just initialize this thing.
  14032. 11:13:31At the first location will be 1.
  14033. 11:13:32At the next location will be 2.
  14034. 11:13:34And at the last location will be 3.
  14035. 11:13:37So the array is zero indexed always.
  14036. 11:13:39I, for just the sake of discussion though,
  14037. 11:13:41am putting in the numbers 1, 2, 3, like a normal person might.
  14038. 11:13:44All right.
  14039. 11:13:45So now let's just print these out.
  14040. 11:13:464 int i gets 0.
  14041. 11:13:48I less than 3, i++.
  14042. 11:13:50Let's go ahead now and print out using printf.
  14043. 11:13:53%i/n list [i].
  14044. 11:13:56So very simple program, inspired by what we did in week 2.
  14045. 11:13:59Just to create and then print out the contents of an array.
  14046. 11:14:03So let's Make List.
  14047. 11:14:05So far, so good. ./list And voila, we see 1, 2, 3.
  14048. 11:14:09Now let's start to practice some of what we're preaching with this new syntax.
  14049. 11:14:14So let me go in now and get rid of the array version.
  14050. 11:14:19And let me zoom out a little bit to give ourselves some more space.
  14051. 11:14:22And now let's begin to create a list of size 3.
  14052. 11:14:25So if I'm going to do this now, dynamically,
  14053. 11:14:29so that I'm allocating these things again and again,
  14054. 11:14:33let me go ahead and do this.
  14055. 11:14:34Let me give myself a list that's of type int* equal the return value of malloc
  14056. 11:14:41of 3 times the size of an int, so what this is going to do for me is give me
  14057. 11:14:48enough memory for that very first picture we drew on the board.
  14058. 11:14:51Which was the array containing 1, 2, and 3.
  14059. 11:14:54But laying the foundation to be able to resize it,
  14060. 11:14:57which was ultimately the goal.
  14061. 11:14:59So my syntax is a little different here.
  14062. 11:15:01I'm going to use malloc and get memory from the so-called "heap", as we
  14063. 11:15:04called it last week.
  14064. 11:15:05Instead of using the stack by just doing the previous version where I said,
  14065. 11:15:09int list 3.
  14066. 11:15:12That is to say this line of code from the first version is in some sense
  14067. 11:15:16identical to this line of code in the second version.
  14068. 11:15:20But the first line of code puts the memory
  14069. 11:15:22on the stack, automatically, for me.
  14070. 11:15:24The second line of code, that I've left here now,
  14071. 11:15:27is creating an array of size 3, but it's putting it on the heap.
  14072. 11:15:30And that's important because it was only on the heap and via this new function
  14073. 11:15:34last week, malloc.
  14074. 11:15:35That you can actually ask for more memory, and even give it back.
  14075. 11:15:38When you just use the first notation int list 3,
  14076. 11:15:42you have permanently given yourself an array of size 3.
  14077. 11:15:45You cannot add to that in code.
  14078. 11:15:48So let me go ahead and do this.
  14079. 11:15:50If list==null, something went wrong.
  14080. 11:15:53The computers out of memory.
  14081. 11:15:54So let's just return 1 and quit out of this program.
  14082. 11:15:56There's nothing to see here.
  14083. 11:15:58So just a good error check there.
  14084. 11:16:00Now let me go ahead and initialize this list.
  14085. 11:16:02So list [0] will be 1 again.
  14086. 11:16:04List [1] will be 2.
  14087. 11:16:05And list [2] will be 3.
  14088. 11:16:07So that's the same kind of syntax as before.
  14089. 11:16:10And notice this equivalence.
  14090. 11:16:13Recall that there's this relationship between chunks of memory and arrays.
  14091. 11:16:18And arrays are really just doing pointer arithmetic for you,
  14092. 11:16:21where the square bracket notation is.
  14093. 11:16:22So if I've asked myself here, in line 5, for enough memory for 3 integers,
  14094. 11:16:27it is perfectly OK to treat it now like an array using square bracket notation.
  14095. 11:16:32Because the computer will do the arithmetic for me
  14096. 11:16:35and find the first location, the second, and the third.
  14097. 11:16:37If you really want to be cool and hacker-like, well,
  14098. 11:16:42you could say list=1, list+1=2, list+2=3.
  14099. 11:16:51That's the same thing using very explicit,
  14100. 11:16:53pointer arithmetic, which we looked at briefly last week.
  14101. 11:16:56But this is atrocious to look at for most people.
  14102. 11:16:58It's just not very user friendly.
  14103. 11:17:00It's longer to type, so most people, even when
  14104. 11:17:03allocating memory dynamically as I did a second ago,
  14105. 11:17:06would just use the more familiar notation of an array.
  14106. 11:17:10All right.
  14107. 11:17:10So let's go on.
  14108. 11:17:11Now suppose time passes and I realize, oh shoot,
  14109. 11:17:16I really wanted this array to be of size 4 instead of size 3.
  14110. 11:17:21Now, obviously, I could just rewind and like fix the program.
  14111. 11:17:23But suppose that this is a much larger program.
  14112. 11:17:25And I've realized, at this point, that I need
  14113. 11:17:28to be able to dynamically add more things to this array for whatever
  14114. 11:17:31reason.
  14115. 11:17:32Well let me go ahead and do this.
  14116. 11:17:33Let me just say, all right, list should actually
  14117. 11:17:36be the result of asking for 4 chunks of memory from malloc.
  14118. 11:17:42And then, I could do something like this, list [3]=4.
  14119. 11:17:49Now this is buggy, potentially, in a couple of ways.
  14120. 11:17:52But let me ask first, what's really wrong, first, with this code?
  14121. 11:17:59The goal at hand is to start with the array of size 3 with the 1, 2, 3.
  14122. 11:18:03And I want to add a number 4 to it.
  14123. 11:18:05So at the moment, in line 17, I've asked the computer for a chunk of 4 integers.
  14124. 11:18:10Just like the picture.
  14125. 11:18:12And then I'm adding the number 4 to it.
  14126. 11:18:14But I have skipped a few steps and broken this somehow.
  14127. 11:18:18Yeah.
  14128. 11:18:19AUDIENCE: You don't know exactly [INAUDIBLE]..
  14129. 11:18:21SPEAKER 1: Yeah.
  14130. 11:18:22I don't necessarily know where this is going to end up in memory.
  14131. 11:18:24It's probably not going to be immediately
  14132. 11:18:26adjacent to the previous chunk.
  14133. 11:18:27And so, yes, even though I'm putting the number for there,
  14134. 11:18:30I haven't copied the 1, the 2, or the 3 over to this chunk of memory.
  14135. 11:18:34So well let me fix--
  14136. 11:18:35well, that's actually, indeed, really the essence of the problem.
  14137. 11:18:40I am orphaning the original chunk of memory.
  14138. 11:18:43If you think of the picture that I drew earlier, the line of code
  14139. 11:18:46up here on line 5 that allocates space for the initial 3 integers.
  14140. 11:18:52This code is fine.
  14141. 11:18:54This code is fine.
  14142. 11:18:55But as soon as I do this, I'm clobbering the value of list.
  14143. 11:18:59And saying no, don't point at this chunk of memory.
  14144. 11:19:01Point at this chunk of memory, at which point I've forgotten if you will,
  14145. 11:19:05where the original chunk of memory is.
  14146. 11:19:07So the right way to do something like this, would be a little more involved.
  14147. 11:19:12Let me go ahead and give myself a temporary variable.
  14148. 11:19:14And I'll literally call it TMP.
  14149. 11:19:16T-M-P, like I did last week.
  14150. 11:19:18So that I can now ask the computer for a completely different chunk of memory
  14151. 11:19:21of size 4.
  14152. 11:19:22I'm going to again say if TMP equals null,
  14153. 11:19:25I'm going to say bad things happened here.
  14154. 11:19:27So let me just return 1.
  14155. 11:19:29And you know what, just to be tidy, let me
  14156. 11:19:31free the original list before I quit.
  14157. 11:19:34Because remember from last week, any time
  14158. 11:19:35you use malloc you eventually have to use free.
  14159. 11:19:38But this chunk of code here is just a safety check.
  14160. 11:19:41If there's no more memory, there's nothing to see here.
  14161. 11:19:43I'm just going to clean up my state and quit.
  14162. 11:19:46But now, if I have asked for this chunk of memory,
  14163. 11:19:50now I can do this 4 int i gets 0.
  14164. 11:19:55I is less than 3, i++.
  14165. 11:19:58What if I do something like this?
  14166. 11:20:00TMP [i] equals list [i].
  14167. 11:20:04That would seem to have the effect of copying all of the memory from one
  14168. 11:20:08to the other.
  14169. 11:20:09And then, I think I need to do one last thing TMP [3]
  14170. 11:20:12gets the number 4, for instance.
  14171. 11:20:14Again, I'm hard coding the numbers for the sake of discussion.
  14172. 11:20:18After I've done this, what could I now do?
  14173. 11:20:23I could now set list equals to TMP.
  14174. 11:20:28And now, I have updated my linked list properly.
  14175. 11:20:31So let me go ahead and do this.
  14176. 11:20:324 int i gets 0.
  14177. 11:20:34I is less than 4, i++.
  14178. 11:20:36Let me go ahead and print each of these elements out with %i using list [i].
  14179. 11:20:42And then, I'm going to return 0 just to signify that all is successful.
  14180. 11:20:45Now so to recap, we initialize the original array
  14181. 11:20:49of size 3 and plug-in the values 1, 2, 3.
  14182. 11:20:52Time passes.
  14183. 11:20:53And then, I realize, wait a minute, I need more space.
  14184. 11:20:55And so I asked the computer for a second chunk of memory.
  14185. 11:20:58This one of size 4.
  14186. 11:20:59Just as a safety check, I make sure that TMP doesn't equal null.
  14187. 11:21:01Because if it does I'm out of memory.
  14188. 11:21:03So I should just quit altogether.
  14189. 11:21:05But once I'm sure that it's not null, I'm
  14190. 11:21:07going to copy all the values from the old list into the new list.
  14191. 11:21:12And then, I'm going to add my new number at the end of that list.
  14192. 11:21:16And then, now that I'm done playing around with this temporary variable,
  14193. 11:21:19I'm going to remember in my list variable what
  14194. 11:21:23the addresses of this new chunk of memory.
  14195. 11:21:25And then, I'm going to print all of those values out.
  14196. 11:21:28So at least, aesthetically, when I make this new version of my list,
  14197. 11:21:31except for my missing semicolon.
  14198. 11:21:34Let me try this again.
  14199. 11:21:35When I make lists, Oh OK.
  14200. 11:21:36What did I do this time?
  14201. 11:21:38Implicitly declaring a library function malloc.
  14202. 11:21:40What's my mistake any time you see that kind of error?
  14203. 11:21:45AUDIENCE: Library.
  14204. 11:21:45SPEAKER 1: Yeah.
  14205. 11:21:46A library.
  14206. 11:21:46So up here, I forgot to do include stdlib.h, which is where malloc lives.
  14207. 11:21:52Let me go ahead and, again, do make list.
  14208. 11:21:53There we go.
  14209. 11:21:54So I fixed that dot/list.
  14210. 11:21:56And I should see 1, 2, 3, 4.
  14211. 11:21:59But they're still a bug here.
  14212. 11:22:03Does anyone see the the-- bug or question?
  14213. 11:22:05AUDIENCE: You forgot to free them.
  14214. 11:22:07SPEAKER 1: I'm sorry, say again.
  14215. 11:22:08AUDIENCE: You forgot to free them.
  14216. 11:22:09SPEAKER 1: I forgot to free the original list.
  14217. 11:22:12And we could see this, even if not just with our own eyes or intuition.
  14218. 11:22:15If I do something like Valgrind of dot/list,
  14219. 11:22:18remember our tool from this past week.
  14220. 11:22:19Let me increase the size of my terminal window, temporarily.
  14221. 11:22:22The output is crazy cryptic at first.
  14222. 11:22:25But, notice that I have definitely lost some number of bytes here.
  14223. 11:22:30And indeed, it's even pointing at the line number
  14224. 11:22:32in which some of those bytes were lost.
  14225. 11:22:34So let me go ahead and back to my code.
  14226. 11:22:36And indeed, I think what I need to do is, before I clobber the value of list
  14227. 11:22:41pointing it at this new chunk of memory instead of the old,
  14228. 11:22:44I think I now need to first, proactively,
  14229. 11:22:47say free the old list of memory.
  14230. 11:22:49And then, change its value.
  14231. 11:22:51So if I now do Make List and do dot /list, the output is still the same.
  14232. 11:22:56And, if I cross my fingers and run Valgrind again
  14233. 11:22:59after increasing my window size, hopefully here.
  14234. 11:23:03Oh, still a bug.
  14235. 11:23:05So better.
  14236. 11:23:06It seems like less memory is lost.
  14237. 11:23:09What have I now forgotten to do?
  14238. 11:23:11AUDIENCE: You forgot to free the end.
  14239. 11:23:13SPEAKER 1: I forgot to free it at the very end, too.
  14240. 11:23:16Because I still have a chunk of memory that I got from malloc.
  14241. 11:23:19So let me go to the very bottom of the program now.
  14242. 11:23:21And after I'm done senselessly just printing this thing out,
  14243. 11:23:26let me free the new list.
  14244. 11:23:29And now let me do Make List, dot/list.
  14245. 11:23:33It's still works, visually.
  14246. 11:23:35Now let's do Valgrind of dot/list, Enter.
  14247. 11:23:39And now, hopefully, all heap blocks were freed.
  14248. 11:23:43No leaks are possible.
  14249. 11:23:44So this is perhaps the best output you can see from a tool like Valgrind.
  14250. 11:23:47I used the heap, but I freed all the memory as well.
  14251. 11:23:50So there were 2 fixes needed there.
  14252. 11:23:52All right.
  14253. 11:23:52Any questions then on this array-based approach, the first of which
  14254. 11:23:56is statically allocating an array, so to speak.
  14255. 11:23:59By just hard coding the number 3.
  14256. 11:24:00The second version now is dynamically allocating the array,
  14257. 11:24:04using not the stack but the heap.
  14258. 11:24:06But, it too, suffers from the slowness we described earlier,
  14259. 11:24:10of having to copy all those values from one to the other.
  14260. 11:24:12OK.
  14261. 11:24:13A hand was over here.
  14262. 11:24:14AUDIENCE: Why do you not have to free the TMP?
  14263. 11:24:17SPEAKER 1: Good question.
  14264. 11:24:18Why did I not have to free the TMP?
  14265. 11:24:20I essentially did eventually.
  14266. 11:24:22Because TMP was pointing at the chunk of 4 integers.
  14267. 11:24:27But on line 33 here, I assigned list to be
  14268. 11:24:33identical to what TMP was pointing at.
  14269. 11:24:36And so, when I finally freed the list, that was the same thing as freeing TMP.
  14270. 11:24:40In fact, if I wanted to, I could say free TMP here and it would be the same.
  14271. 11:24:43But conceptually, it's wrong.
  14272. 11:24:45Because at this point in the story, I should be freeing the actual list, not
  14273. 11:24:49that temporary variable.
  14274. 11:24:50But they were the same at that point in the story.
  14275. 11:24:52Yeah.
  14276. 11:24:53AUDIENCE: Is [? the line ?] part of it?
  14277. 11:24:55SPEAKER 1: Good question.
  14278. 11:24:56And long story short, everything we're doing thus far
  14279. 11:24:58is still in the world of arrays.
  14280. 11:25:00The only distinction we're making is that
  14281. 11:25:02in version 1, when I said int list [3], that was an array of fixed size.
  14282. 11:25:08So-called statically allocated on the stack, as per last week.
  14283. 11:25:12This version now is still dealing with arrays, but I'm flexing my muscles
  14284. 11:25:16and using dynamic memory allocation.
  14285. 11:25:18So that I can still use an array per the first pictures
  14286. 11:25:20we started talking about.
  14287. 11:25:22But I can at least grow the array if I want.
  14288. 11:25:24So we haven't even now solved this, even better in a sense, with linked lists.
  14289. 11:25:28That's going to come next.
  14290. 11:25:29Yeah.
  14291. 11:25:30AUDIENCE: How are you able to free list and then still make list?
  14292. 11:25:34SPEAKER 1: How am I able to free list?
  14293. 11:25:37I freed the original address of list.
  14294. 11:25:41I, then, changed what list is storing.
  14295. 11:25:44I'm moving its arrow to a new chunk of memory.
  14296. 11:25:47And that is perfectly reasonable for me to now manipulate
  14297. 11:25:51because now list is pointing at the same value of TMP.
  14298. 11:25:54And TMP is what was given the return value of malloc, the second time.
  14299. 11:26:00So that chunk of memory is valid.
  14300. 11:26:02So these are just squares on the board, right.
  14301. 11:26:05There's just pointers inside of them.
  14302. 11:26:07So what I'm technically saying is, and I'm not
  14303. 11:26:09pointing I'm not freeing list per se, I am
  14304. 11:26:11freeing the chunk of memory that begins at the address currently in list.
  14305. 11:26:16Therefore, if a few lines later, I change what the address is in list.
  14306. 11:26:21Totally reasonable to then touch that memory, and eventually free it later.
  14307. 11:26:25Because you're not freeing the variable per se,
  14308. 11:26:27you're freeing the address in the variable.
  14309. 11:26:30Good distinction.
  14310. 11:26:31All right.
  14311. 11:26:31So let me back up here and now make one final edit.
  14312. 11:26:37So let's finish this with one final improvement here.
  14313. 11:26:41Because it turns out, there's a somewhat better way
  14314. 11:26:44to actually resize an array as we've been doing here.
  14315. 11:26:48And there's another function in stdlib that's called realloc, for re-allocate.
  14316. 11:26:52And I'm just going to go in and make a little bit of a change
  14317. 11:26:55here so that I can do the following.
  14318. 11:26:58Let me go ahead and first comment this now,
  14319. 11:26:59just so we can keep track of what's been going on this whole time.
  14320. 11:27:02So dynamically allocate an array of size 3.
  14321. 11:27:09Assign 3 numbers to that array.
  14322. 11:27:14Time passes.
  14323. 11:27:15Allocate new array of size 4.
  14324. 11:27:21Copy numbers from old array into new array.
  14325. 11:27:26And add fourth number to new array.
  14326. 11:27:31Free old array.
  14327. 11:27:36Remember, if you will, new array using my same list variable.
  14328. 11:27:41And now, print new array.
  14329. 11:27:46Free new array.
  14330. 11:27:48Hopefully, that helps.
  14331. 11:27:49And we'll post this code online after 2, which tells a more explicit story.
  14332. 11:27:53So it turns out that we can reduce some of the labor involved with this.
  14333. 11:27:56Not so much with the printing here, but with this copying.
  14334. 11:27:59Turns out c does have a function called realloc,
  14335. 11:28:01that can actually handle the resizing of an array for you, as follows.
  14336. 11:28:07I'm going to scroll up to where I previously
  14337. 11:28:09allocated a new array of size 4.
  14338. 11:28:12And I'm instead going to say this, resize old array to be of size 4.
  14339. 11:28:19Now, previously this wasn't necessarily possible.
  14340. 11:28:21Because recall that we had painted ourselves
  14341. 11:28:23into a corner with the example on the screen
  14342. 11:28:25where "Hello, world" happened to be right after the original array.
  14343. 11:28:28But let me do this.
  14344. 11:28:29Let me use realloc, for re-allocate.
  14345. 11:28:32And pass in not just the size of memory we want this time,
  14346. 11:28:36but also the address that we want to resize.
  14347. 11:28:39Which, again, is this array called list.
  14348. 11:28:43All right.
  14349. 11:28:43The code thereafter is pretty much the same.
  14350. 11:28:46But what I don't need to do is this.
  14351. 11:28:50So realloc is a pretty handy function that will do the following.
  14352. 11:28:54If at the very beginning of class, when we had 1, 2, 3 on the board.
  14353. 11:28:57And someone's instinct was to just plop the 4 right at the end of the list.
  14354. 11:29:00If there's available memory, realloc will just do that.
  14355. 11:29:03And boom, it will just grow the array for you in the computer's memory.
  14356. 11:29:07If, though, it realizes, sorry, there's already a string like "Hello, world"
  14357. 11:29:11or something else there, realloc will handle
  14358. 11:29:14the trouble of moving that whole array from 1 chunk of memory,
  14359. 11:29:18originally, to a new chunk of memory.
  14360. 11:29:20And then realloc will return to you, the address of that new chunk of memory.
  14361. 11:29:26And it will handle the process of freeing the old chunk for you.
  14362. 11:29:31So you do not need to do this yourself.
  14363. 11:29:33So in fact, let me go ahead and get rid of this as well.
  14364. 11:29:36So realloc just condenses, a lot of what we just did, into a single function.
  14365. 11:29:41Whereby, realloc handles it for you.
  14366. 11:29:45All right.
  14367. 11:29:46So that's the final improvement on this array-based approach.
  14368. 11:29:49So what now, knowing what your memory is,
  14369. 11:29:51what can we now do with it that solves that kind of problem?
  14370. 11:29:54Because the world is going to get really slow.
  14371. 11:29:56And our apps, and our phones, and our computers are getting really slow,
  14372. 11:29:59if we're just constantly wasting time moving things around in memory.
  14373. 11:30:04What could we perhaps do instead?
  14374. 11:30:05Well there's one new piece of syntax today
  14375. 11:30:07that builds on these 3 pieces of syntax from the past.
  14376. 11:30:11Recall, that we've looked at struct, which
  14377. 11:30:13is a keyword in C, that just lets you invent your own structure.
  14378. 11:30:16Your own variable, if you will, in conjunction with typedef.
  14379. 11:30:19Which lets you say a person has a name and a number, or something like that.
  14380. 11:30:23Or a candidate has a name and some number of votes.
  14381. 11:30:26You can encapsulate multiple pieces of data inside of just one using struct.
  14382. 11:30:30What did we use the Dot Notation for now, a couple of times?
  14383. 11:30:34What does the Dot operator do in C?
  14384. 11:30:37AUDIENCE: Access the structure.
  14385. 11:30:39SPEAKER 1: Perfect.
  14386. 11:30:39To access the field inside of a structure.
  14387. 11:30:41So if you've got a person with a name and a number,
  14388. 11:30:43you could say something like person.name or person.number,
  14389. 11:30:46if person is the name of one such variable.
  14390. 11:30:48Star, of course, we've seen now in a few ways.
  14391. 11:30:51Like way back in week 1, we saw it as like, multiplication.
  14392. 11:30:55Last week, we began to see it in the context of pointers,
  14393. 11:30:58whereby, you use it to declare a pointer.
  14394. 11:31:00Like, int* p, or something like that.
  14395. 11:31:03But we also saw it in one other context, which
  14396. 11:31:05was like the opposite, which was the dereference operator.
  14397. 11:31:08Which says if this is an address, that is
  14398. 11:31:10if this is a variable like a pointer, and you put a star in front of it
  14399. 11:31:13then with no int or no char, no data type in front of it.
  14400. 11:31:17That means go to that address.
  14401. 11:31:19And it dereferences the pointer and goes to that location.
  14402. 11:31:22So it turns out that using these 3 building blocks,
  14403. 11:31:25you can actually start to now use your computer's memory almost any way
  14404. 11:31:28you want.
  14405. 11:31:28And even next week, when we transition to Python,
  14406. 11:31:31and you start to get a lot of features for free.
  14407. 11:31:33Like a single line of code will just do so much
  14408. 11:31:36more in Python than it does in C. It boils down to those basic primitives.
  14409. 11:31:40And just so you've seen it already.
  14410. 11:31:42It turns out that it's so common in C to use this operator
  14411. 11:31:47to go inside of a structure and this operator to go to an address,
  14412. 11:31:51that there's shorthand notation for it, a.k.a.
  14413. 11:31:53syntactic sugar.
  14414. 11:31:54That literally looks like an arrow.
  14415. 11:31:56So recall last week, I was in the habit of pointing, even
  14416. 11:31:58with the big foam finger.
  14417. 11:32:00This arrow notation, a hyphen and an angled bracket,
  14418. 11:32:04denotes going to an address and looking at a field inside of it.
  14419. 11:32:11But we'll see this in practice in just a bit.
  14420. 11:32:13So what might be the solution, now, to this problem
  14421. 11:32:16we saw a moment ago whereby, we had painted ourselves into a corner.
  14422. 11:32:20And our memory, a few moments ago, looked like this.
  14423. 11:32:23We could just copy the whole existing array to a new location, add the 4,
  14424. 11:32:28and go about our business.
  14425. 11:32:29What would another, perhaps better solution longer term
  14426. 11:32:33be, that doesn't require constantly moving stuff around?
  14427. 11:32:38Maybe hang in there for your instincts if you
  14428. 11:32:40know the buzz phrase we're looking for from past experience, hang in there.
  14429. 11:32:44But if we want to avoid moving the 1, 2, and the 3,
  14430. 11:32:47but we still want to be able to add endless amounts of data.
  14431. 11:32:49What could we do?
  14432. 11:32:51Yeah.
  14433. 11:32:51So maybe create some kind of list using pointers that
  14434. 11:32:54just point at a new location, right.
  14435. 11:32:56In an ideal world, even though this piece of memory
  14436. 11:32:59is being used by this h in the string "Hello, world",
  14437. 11:33:02maybe we could somehow use a pointer from last week.
  14438. 11:33:05Like an arrow, that says after the 3, oh I don't know, go down over here
  14439. 11:33:09to this location in memory.
  14440. 11:33:11And you just stitch together these integers in memory
  14441. 11:33:15so that each one leads to the next.
  14442. 11:33:17It's not necessarily the case that it's literally back-to-back.
  14443. 11:33:21That would have the downside, it would seem,
  14444. 11:33:23of costing us a little bit of space.
  14445. 11:33:24Like a pointer, which recall, takes up some amount of space.
  14446. 11:33:27Typically 8 bytes or 64 bits.
  14447. 11:33:29But I don't have to copy potentially a huge amount of data just
  14448. 11:33:33to add one more number.
  14449. 11:33:34And so these things do have a name.
  14450. 11:33:36And indeed, these things are what generally
  14451. 11:33:38would be called a linked list.
  14452. 11:33:42A linked list captures exactly that intuition
  14453. 11:33:44of linking together things in memory.
  14454. 11:33:46So let's take a look at an example.
  14455. 11:33:48Here's a computer's memory in the abstract.
  14456. 11:33:49Suppose that I'm trying to create an array.
  14457. 11:33:52Let's generalize it as a list, now, of numbers.
  14458. 11:33:55An array has a very specific meaning.
  14459. 11:33:57It's memory that's contiguous, back, to back, to back.
  14460. 11:34:00At the end of the day, I as the programmer, just care about the data--
  14461. 11:34:031, 2, 3, 4, and so forth.
  14462. 11:34:05I don't really care how it's stored.
  14463. 11:34:09I don't care how it's stored when I'm writing the code,
  14464. 11:34:12I just wanted to work at the end of the day.
  14465. 11:34:13So suppose that I first insert my number 1.
  14466. 11:34:16And, who knows, it ends up, up there at location, 0X123,
  14467. 11:34:19for the sake of discussion.
  14468. 11:34:20All right.
  14469. 11:34:21Maybe there's something already here.
  14470. 11:34:23And heck, maybe there's something already here,
  14471. 11:34:25but there's plenty of other options for where this thing can go.
  14472. 11:34:28And suppose that, for the sake of discussion,
  14473. 11:34:30the first available spot for the next number
  14474. 11:34:32happens to be over here at location 0X456, for the sake of discussion.
  14475. 11:34:38So that's where I'm going to plop the number 2.
  14476. 11:34:40And where might the number 3 end up?
  14477. 11:34:41Oh I don't know, maybe down over there at 0X789.
  14478. 11:34:44The point being, I don't know what is, or really care about,
  14479. 11:34:48everything else that's in the computer's memory.
  14480. 11:34:50I just care that there are at least 3 locations available where
  14481. 11:34:54I can put my 1, my 2, and my 3.
  14482. 11:34:57But the catch is, now that we're not using an array,
  14483. 11:35:01we can't just naively assume that you just add 1 to an index and boom,
  14484. 11:35:05you're at the next number.
  14485. 11:35:06Add 2 to an index, and boom you're at the next, next number.
  14486. 11:35:10Now you have to leave these little breadcrumbs, or use the arrow notation,
  14487. 11:35:14to lead from one to the other.
  14488. 11:35:17And sometimes, it might be close, a few bytes away.
  14489. 11:35:19Maybe, it's a whole gigabyte away in an even bigger computer's memory.
  14490. 11:35:23So how might I do this?
  14491. 11:35:25Like where do these pointers go, as you proposed?
  14492. 11:35:30All right.
  14493. 11:35:30All I have access to here are bytes.
  14494. 11:35:32I've already stored the 1, the 2, and the 3.
  14495. 11:35:34So what more should I do?
  14496. 11:35:37OK, yeah.
  14497. 11:35:37So let me, you put the pointers right next to these numbers.
  14498. 11:35:40So let me at least plan ahead, so that when I ask the computer like malloc,
  14499. 11:35:44recall from last week, for some memory, I don't just ask it now
  14500. 11:35:47for space for just the number.
  14501. 11:35:49Let me start getting into the habit of asking
  14502. 11:35:51malloc for enough space for the number and a pointer to another such number.
  14503. 11:35:56So it's a little more aggressive of me to ask for more memory.
  14504. 11:35:59But I'm planning ahead.
  14505. 11:36:00And here is an example of a trade off.
  14506. 11:36:02Almost any time in CS, when you start using more space, you can save time.
  14507. 11:36:06Or if you try to conserve space, you might have to lose time.
  14508. 11:36:10It's being that trade off there.
  14509. 11:36:12So how might I solve this?
  14510. 11:36:14Well let me abstract this away.
  14511. 11:36:15And either next to or below, I'm just drawing it vertically, just
  14512. 11:36:19for the sake of discussion.
  14513. 11:36:20So the arrows are a bit prettier.
  14514. 11:36:22I've asked malloc for now twice as much space,
  14515. 11:36:25it would seem, than I previously needed.
  14516. 11:36:27But I'm going to use this second chunk of memory to refer to the next number.
  14517. 11:36:31And I'm going to use this chunk of memory to refer to the next,
  14518. 11:36:33essentially, stitching this thing together.
  14519. 11:36:35So what should go in this first box?
  14520. 11:36:37Well, I claim the number, 0X456.
  14521. 11:36:41And it's written in hex because it represents a memory address.
  14522. 11:36:43But this is the equivalent of drawing an arrow from one to the other.
  14523. 11:36:47As a little check here, what should go in this second box
  14524. 11:36:51if the goal is to stitch these together in order 1, 2, 3?
  14525. 11:36:55Feel free to just shout this out.
  14526. 11:36:57AUDIENCE: 0X789.
  14527. 11:36:59SPEAKER 1: OK, that worked well.
  14528. 11:37:00So 0X789, indeed.
  14529. 11:37:01And you can't do that with the hands because I can't count that fast.
  14530. 11:37:04So 0X789 should go here because that's like a little breadcrumb to the next.
  14531. 11:37:08And then, we don't really have terribly many possibilities here.
  14532. 11:37:11This has to have a value, right.
  14533. 11:37:14Because at the end of the day, it's got to use its 64 bits in some way.
  14534. 11:37:19So what value should go here, if this is the end of this list?
  14535. 11:37:22AUDIENCE: 0.
  14536. 11:37:23SPEAKER 1: So it could be 0X123.
  14537. 11:37:25The implication being that it would be a cyclical list.
  14538. 11:37:29Which is OK, but potentially problematic.
  14539. 11:37:32If any of you have accidentally lost control over your code space
  14540. 11:37:36because you had an infinite loop, this would seem a very easy way
  14541. 11:37:39to give yourself the accidental probability of an infinite loop.
  14542. 11:37:43What might be simpler than that and ward that off?
  14543. 11:37:46AUDIENCE: Null.
  14544. 11:37:47SPEAKER 1: Say again?
  14545. 11:37:47AUDIENCE: Null.
  14546. 11:37:48SPEAKER 1: So just the null character.
  14547. 11:37:50Not N-U-L, confusingly, which is at the end of strings.
  14548. 11:37:53But N-U-L-L, as we introduced it last week.
  14549. 11:37:56Which is the same as 0x0.
  14550. 11:37:58So this is just a special value that programmers decades ago
  14551. 11:38:00decided that if you store the address 0, that's not a valid address.
  14552. 11:38:04There's never going to be anything useful at 0x0.
  14553. 11:38:07Therefore, it's a sentinel value, just a special value,
  14554. 11:38:11that indicates that's it.
  14555. 11:38:12There's nowhere further to go.
  14556. 11:38:14It's OK to come back to your suggestion of making a cyclical list.
  14557. 11:38:17But we'd better be smart enough to, maybe,
  14558. 11:38:19remember where did the list start so that you can detect cycles.
  14559. 11:38:23If you start looping around in this structure, otherwise.
  14560. 11:38:26All right.
  14561. 11:38:26But these addresses, who really cares at the end of the day
  14562. 11:38:29if we abstract this away.
  14563. 11:38:30It really just now looks like this.
  14564. 11:38:32And indeed, this is how most anyone would draw this on a whiteboard
  14565. 11:38:35if having a discussion at work.
  14566. 11:38:36Talking about what data structure we should
  14567. 11:38:38use to solve some problem in the real world.
  14568. 11:38:40We don't care generally about the addresses.
  14569. 11:38:42We care that in code we can access them.
  14570. 11:38:45But in terms of the concept alone this would be, perhaps,
  14571. 11:38:48the right way to think about this.
  14572. 11:38:49All right, let me pause here and see if there's
  14573. 11:38:51any questions on this idea of creating a linked list in memory by just storing,
  14574. 11:38:55not just the numbers like 1, 2, 3, but twice as much data.
  14575. 11:39:00So that you have little breadcrumbs in the form of pointers
  14576. 11:39:02that can lead you from one to the next.
  14577. 11:39:05Any questions on these linked lists?
  14578. 11:39:11Any questions?
  14579. 11:39:12No?
  14580. 11:39:12All right.
  14581. 11:39:13Oh, yeah.
  14582. 11:39:13Over here.
  14583. 11:39:14AUDIENCE: So does this takes time more memory than an array?
  14584. 11:39:19SPEAKER 1: This does take more memory than an array
  14585. 11:39:21because I now need space for these pointers.
  14586. 11:39:24And to be clear, I technically didn't really draw this to scale.
  14587. 11:39:28Thus far, in the class, we've generally thought about integers
  14588. 11:39:31like, 1, 2 and 3, as being 4 bytes, or 32 bits.
  14589. 11:39:33I made the claim last week that on modern computer's pointers
  14590. 11:39:37tend to be 8 bytes or 64 bits.
  14591. 11:39:40So, technically, this box should actually be a little bigger.
  14592. 11:39:42It was just going to look a little stupid in the picture.
  14593. 11:39:44So I abstracted it away.
  14594. 11:39:45But, indeed, you're using more space as a result.
  14595. 11:39:48AUDIENCE: [INAUDIBLE].
  14596. 11:39:50SPEAKER 1: Oh, how does-- sorry.
  14597. 11:39:51How does the computer identify useful data from used data?
  14598. 11:39:55So, for instance, garbage values or non-garbage values.
  14599. 11:39:58For now, think of that as the job of malloc.
  14600. 11:40:00So when you ask malloc for memory, as we started to last week,
  14601. 11:40:04malloc keeps track of the addresses of the memory
  14602. 11:40:07it has handed to as valid values.
  14603. 11:40:10The other type of memory you use, not just from the heap.
  14604. 11:40:12Because recall we briefly discussed that malloc uses space
  14605. 11:40:15from the heap, which was drawn at the top of the picture, pointing down.
  14606. 11:40:18There's also stack memory, which is where all of your local variables go.
  14607. 11:40:22And where all of the memory used by individual functions go.
  14608. 11:40:25And that was drawn in the picture is working its way up.
  14609. 11:40:27That's just an artist's rendition of direction.
  14610. 11:40:30The compiler, essentially, will also help
  14611. 11:40:33keep track of which values are valid or not inside of the stack.
  14612. 11:40:37Or really the underlying code that you've written
  14613. 11:40:39will keep track of that for you.
  14614. 11:40:40So it's managed for you at that point.
  14615. 11:40:43All right.
  14616. 11:40:44Good question.
  14617. 11:40:44Sorry it took me a bit to catch on.
  14618. 11:40:46So let's now translate this to actual code.
  14619. 11:40:48How could we implement this idea of, let's call these things nodes.
  14620. 11:40:52And that's a term of our NCS.
  14621. 11:40:53Whenever you have some data structure that encapsulates information, node,
  14622. 11:40:57N-O-D-E, is the generic term for that.
  14623. 11:41:00So each of these might be said to be a node.
  14624. 11:41:02Well, how can we do this?
  14625. 11:41:03Well a couple of weeks ago, we saw how we could represent something
  14626. 11:41:06like a student or a candidate.
  14627. 11:41:07And a student, or rather a person, we said has a name and a number.
  14628. 11:41:12And we used a few pieces of syntax here.
  14629. 11:41:14One, we use the struct keyword, which gives us a data structure.
  14630. 11:41:17We use typedef, which defines the name person to be our new data
  14631. 11:41:21type representing that whole structure.
  14632. 11:41:24So we probably have the right ingredients here
  14633. 11:41:26to build up this thing called a node.
  14634. 11:41:28And just to be clear, what should go inside of one of these nodes,
  14635. 11:41:32do we think?
  14636. 11:41:32It's not going to be a name or a number, obviously.
  14637. 11:41:35But what should a node have in terms of those fields, perhaps?
  14638. 11:41:39Yeah?
  14639. 11:41:40AUDIENCE: [? Data. ?]
  14640. 11:41:41SPEAKER 1: So a number like a number and a pointer in some form.
  14641. 11:41:44So let's translate this to actual code.
  14642. 11:41:46So let's rename person to node to capture this notion here.
  14643. 11:41:51And the number is easy.
  14644. 11:41:52If it's just going to be an int, that's fine.
  14645. 11:41:54We can just say int number, or int n, or whatever
  14646. 11:41:56you want to call that particular field.
  14647. 11:41:58The next one is a little non-obvious.
  14648. 11:42:00And this is where things get a little weird at first,
  14649. 11:42:02but, in retrospect, it should all fit together.
  14650. 11:42:05Let me propose that, ideally, we would say something like node* next.
  14651. 11:42:11And I could call the word next anything I want.
  14652. 11:42:13Next just means what comes after me is the notion I'm using it at.
  14653. 11:42:17So a lot of CS people would just use next to represent
  14654. 11:42:19the name of this pointer.
  14655. 11:42:21But there's a catch here.
  14656. 11:42:22C and C compilers are pretty naive, recall.
  14657. 11:42:25They only look at code top to bottom, left to right.
  14658. 11:42:29And any time they encounter a word they have never
  14659. 11:42:31seen before, bad things happen.
  14660. 11:42:33Like, you can't compile your code.
  14661. 11:42:34You get some cryptic error message or the like.
  14662. 11:42:36And that seems to be about to happen here.
  14663. 11:42:39Because if the compiler is reading this code from top to bottom,
  14664. 11:42:42it's going to say, oh, inside of this struct
  14665. 11:42:44should be a variable called next.
  14666. 11:42:46Which is of type node*.
  14667. 11:42:48What the heck is a node?
  14668. 11:42:49Because it literally does not find out until 2 lines
  14669. 11:42:52later, after that semicolon.
  14670. 11:42:55So the way to avoid this, which we haven't quite seen before,
  14671. 11:42:57is that you can temporarily name this whole thing up here, struct node.
  14672. 11:43:02And then, down here inside of the data structure, you say struct node*.
  14673. 11:43:08And then, you leave the rest alone.
  14674. 11:43:09This is a workaround this is possible because now you're
  14675. 11:43:14teaching the compiler, from the first line, that here comes
  14676. 11:43:17a data structure called struct node.
  14677. 11:43:19Down here, you're shortening the name of this whole thing to just node.
  14678. 11:43:22Why?
  14679. 11:43:23It's just a little more convenient than having to write struct everywhere.
  14680. 11:43:26But you do have to write struct node* inside of the data structure.
  14681. 11:43:30But that's OK because it's already come into existence
  14682. 11:43:33now, as of that first line of code.
  14683. 11:43:35So that's the only fundamental difference
  14684. 11:43:37between what we did last week with a person or a candidate.
  14685. 11:43:40We just now have to use this struct workaround, syntactically.
  14686. 11:43:45All right.
  14687. 11:43:45Yeah, question.
  14688. 11:43:46AUDIENCE: So [INAUDIBLE] have like right next to the [INAUDIBLE] point
  14689. 11:43:50to another [INAUDIBLE].
  14690. 11:43:51SPEAKER 1: Why is the next variable a struct node* pointer and not an int
  14691. 11:43:56star pointer, for instance?
  14692. 11:43:58So think about the picture we are trying to draw.
  14693. 11:44:01Technically, yes, each of these arrows I deliberately drew
  14694. 11:44:05is pointing at the number.
  14695. 11:44:06But that's not alone.
  14696. 11:44:07They need to point at the whole data structure in memory.
  14697. 11:44:10Because the computer, ultimately, and the compiler,
  14698. 11:44:13in turn, needs to know that this chunk of memory is not just an int.
  14699. 11:44:16It is a whole node.
  14700. 11:44:18Inside of a node is a number and also another pointer.
  14701. 11:44:21So when you draw these arrows, it would be
  14702. 11:44:24incorrect to point at just the number.
  14703. 11:44:26Because that throws away information that
  14704. 11:44:29would leave the compiler wondering, OK, I'm at a number.
  14705. 11:44:31Where the heck is the pointer?
  14706. 11:44:32You have to tell it that it's pointing at a whole node
  14707. 11:44:34so it knows a few bytes away is that corresponding pointer.
  14708. 11:44:38Good question.
  14709. 11:44:38Yeah.
  14710. 11:44:40AUDIENCE: How do you [INAUDIBLE].
  14711. 11:44:42SPEAKER 1: Really good question.
  14712. 11:44:43It would seem that just as copying the array earlier
  14713. 11:44:46required twice as much memory, because we copied from old to new.
  14714. 11:44:49So, technically, twice as much plus 1 for the new number.
  14715. 11:44:52Here, too, it looks like we're using twice as much memory, also.
  14716. 11:44:56And to my comment earlier, it's even more than twice as much memory
  14717. 11:44:58because these pointers are 8 bytes, and not just 4 bytes like a typical integer
  14718. 11:45:02is.
  14719. 11:45:03The differences are these.
  14720. 11:45:04In the context of the array, you were using that memory temporarily.
  14721. 11:45:08So, yes, you needed twice as much memory.
  14722. 11:45:10But then you were quickly freeing the original array.
  14723. 11:45:13So you weren't consuming long-term, more memory than you might need.
  14724. 11:45:16The difference here, too, is that, as we'll see in a moment,
  14725. 11:45:19it turns out it's going to be relatively quick for me, potentially,
  14726. 11:45:23to insert new numbers in here.
  14727. 11:45:25Because I'm not going to have to do a huge amount of copying.
  14728. 11:45:28And even though I might still have to follow all of these arrows, which
  14729. 11:45:31is going to take some amount of time, I'm
  14730. 11:45:33not going to have to be asking for more memory, freeing more memory.
  14731. 11:45:36And certain operations in the computer, anything involving asking for or giving
  14732. 11:45:40back memory, tends to be slower.
  14733. 11:45:42So we get to avoid that situation as well.
  14734. 11:45:44There's going to be some downsides, though.
  14735. 11:45:46This is not all upside.
  14736. 11:45:47But we'll see in a bit just what some of those trade offs actually are.
  14737. 11:45:51All right.
  14738. 11:45:51So from here, if we go back to the structure in code as we left it,
  14739. 11:45:56let's start to now build up a linked list with some actual code.
  14740. 11:45:59How do you go about, in C, representing a linked list in code?
  14741. 11:46:03Well, at the moment, it would actually be as simple as this.
  14742. 11:46:06You declare a variable, called list, for instance.
  14743. 11:46:09That itself stores the address of a node.
  14744. 11:46:12That's what node* means.
  14745. 11:46:13The address of a node.
  14746. 11:46:14So if you want to store a linked list in memory,
  14747. 11:46:17you just create a variable called list, or whatever else.
  14748. 11:46:19And you just say that this variable is going
  14749. 11:46:21to be pointing at the first node in a list, wherever it happens to end up.
  14750. 11:46:25Because malloc is ultimately going to be the tool that we use just to go
  14751. 11:46:29get at any one particular node in memory.
  14752. 11:46:33All right.
  14753. 11:46:34So let's actually do this in pictorial form.
  14754. 11:46:36When you write a line of code, like I just did here--
  14755. 11:46:39and I do not initialize it to anything with the assignment operator,
  14756. 11:46:43an equal sign.
  14757. 11:46:44It does exist in memory as a box, as I'll draw it here, called list.
  14758. 11:46:48But I've deliberately drawn Oscar inside of it.
  14759. 11:46:50Why?
  14760. 11:46:51To connote what exactly?
  14761. 11:46:53AUDIENCE: Garbage value.
  14762. 11:46:54SPEAKER 1: It's a garbage value.
  14763. 11:46:55I have been allocated the variable in memory, called list.
  14764. 11:46:59Which is going to give me 64 bits or 8 bytes somewhere drawn here
  14765. 11:47:03with this box.
  14766. 11:47:04But if I myself have not used the assignment operator,
  14767. 11:47:07it's not going to get magically initialized to any particular address
  14768. 11:47:11for me.
  14769. 11:47:11It's not going to even give me a node.
  14770. 11:47:13This is literally just going to be an address of a future node that exists.
  14771. 11:47:18So what would be a solution here?
  14772. 11:47:20Suppose that I'm beginning to create my linked list,
  14773. 11:47:23but I don't have any nodes yet.
  14774. 11:47:24What would be a sensible thing to initialize the list to, perhaps?
  14775. 11:47:28AUDIENCE: Null.
  14776. 11:47:29SPEAKER 1: Yeah, again.
  14777. 11:47:30AUDIENCE: To null.
  14778. 11:47:31SPEAKER 1: So just null, right.
  14779. 11:47:32When in doubt with pointers, generally it's
  14780. 11:47:34a good thing to initialize things to null,
  14781. 11:47:36so at least it's not a garbage value.
  14782. 11:47:37It's a known value.
  14783. 11:47:38Invalid, yes.
  14784. 11:47:39But it's a special value you can then check
  14785. 11:47:41for with a conditional, or the like.
  14786. 11:47:43So this might be a better way to create a linked list,
  14787. 11:47:47even before you've inserted any numbers into the thing itself.
  14788. 11:47:51All right.
  14789. 11:47:52So after that, how can we go about adding something to this linked list?
  14790. 11:47:55So now the story looks like this.
  14791. 11:47:56Oscar is gone because inside of this box is all zero bits.
  14792. 11:47:59Just because it's nice and clean, and this represents an empty linked list.
  14793. 11:48:03Well, if I want to add the number 1 to this linked list, what could I do?
  14794. 11:48:08Well, perhaps I could start with code like this.
  14795. 11:48:10Borrowing inspiration from last week.
  14796. 11:48:11Let's ask malloc for enough space for the size of a node.
  14797. 11:48:16And this gets to your question earlier, like, what is it I'm manipulating here?
  14798. 11:48:20I don't just need space for an int and I don't just need space for a pointer.
  14799. 11:48:23I need space for both.
  14800. 11:48:24And I gave that thing a name, node.
  14801. 11:48:27So size of node figures out and does the arithmetic for me.
  14802. 11:48:30And gives me back the right number of bytes.
  14803. 11:48:32This, then, stores the address of that chunk of memory
  14804. 11:48:36in what I'll temporarily called n.
  14805. 11:48:38Just to represent a generic new node.
  14806. 11:48:40And it's of type node*.
  14807. 11:48:42Because just like last week when I asked malloc for enough space for an int
  14808. 11:48:45and I stored it in an int* pointer.
  14809. 11:48:47This week, if I'm asking for memory for a node,
  14810. 11:48:50I'm storing it in a node* pointer.
  14811. 11:48:52So technically, nothing new there except for this new term
  14812. 11:48:56of art in data structure called node.
  14813. 11:48:58All right.
  14814. 11:48:59So what does that do for me?
  14815. 11:49:00It essentially draws a picture like this in memory.
  14816. 11:49:03I still have my list variable from my previous line of code initialize
  14817. 11:49:07to null.
  14818. 11:49:07And that's why I've drawn it blank.
  14819. 11:49:09I also now have a temporary variable called
  14820. 11:49:11n, which I initialize to the return value of malloc.
  14821. 11:49:15Which gave me one of these nodes in memory.
  14822. 11:49:17But I've drawn it having garbage values, too,
  14823. 11:49:19because I don't know what int is there.
  14824. 11:49:21I don't know what pointer is there.
  14825. 11:49:22It's garbage values because malloc does not magically initialize memory for me.
  14826. 11:49:27There is another function for that.
  14827. 11:49:28But malloc alone just says, sure, use this chunk of memory.
  14828. 11:49:31Deal with whatever is there.
  14829. 11:49:33So how can I go about initializing this to known values?
  14830. 11:49:36Well, suppose I want to insert the number 1 and then, leave it at that.
  14831. 11:49:40A list of size 1, I could do something like this.
  14832. 11:49:44And this is where you have to think back to some of these basics.
  14833. 11:49:47My conditional here is asking the question if n does not equal null.
  14834. 11:49:51So that is, if malloc gave me valid memory,
  14835. 11:49:54and I don't have to quit altogether because my computer's out of memory.
  14836. 11:49:58If n does not equal null, but is equal to valid address,
  14837. 11:50:02I'm going to go ahead and do this.
  14838. 11:50:03And this is cryptic looking syntax now.
  14839. 11:50:06But does someone want to take a stab at translating this inside line of code
  14840. 11:50:09to English, in some sense?
  14841. 11:50:13How might you explain what that inner line of code is doing? *n.
  14842. 11:50:18number equals 1.
  14843. 11:50:20Let me go further back.
  14844. 11:50:22Nope?
  14845. 11:50:23OK, over here.
  14846. 11:50:24Yeah.
  14847. 11:50:25AUDIENCE: [INAUDIBLE].
  14848. 11:50:26SPEAKER 1: Perfect.
  14849. 11:50:27The place that n is pointing to, set it equal to 1.
  14850. 11:50:29Or using the vernacular of going there, go to the address in n
  14851. 11:50:33and set it's number field to 1.
  14852. 11:50:35However you want to think about it, that's fine.
  14853. 11:50:37But the * again is the dereference operator here.
  14854. 11:50:40And we're doing the parentheses, which we
  14855. 11:50:42haven't needed to do before because we haven't dealt with pointers and data
  14856. 11:50:45structures together until today.
  14857. 11:50:47This just means go there first.
  14858. 11:50:49And then once you're there, go access number.
  14859. 11:50:52You don't want to do one thing before the other.
  14860. 11:50:54So this is just enforcing order of operations.
  14861. 11:50:56The parentheses just like in grade school math.
  14862. 11:50:58All right.
  14863. 11:50:59So this line of code is cryptic.
  14864. 11:51:00It's ugly.
  14865. 11:51:01It's not something most people easily remember.
  14866. 11:51:03Thankfully, there's that syntactic sugar that simplifies this line of code
  14867. 11:51:07to just this.
  14868. 11:51:08And this, even though it's new to you today,
  14869. 11:51:10should eventually feel a little more familiar.
  14870. 11:51:12Because this now is shorthand notation for saying, start at n.
  14871. 11:51:15Go there as by following the arrow.
  14872. 11:51:17And when you get there, change the number field.
  14873. 11:51:20In this case, to 1.
  14874. 11:51:22So most people would not write code like this.
  14875. 11:51:24It's just ugly.
  14876. 11:51:25It's a couple extra keystrokes.
  14877. 11:51:26This just looks more like the artist's renditions we've been talking about.
  14878. 11:51:30And how most CS people would think about pointers as really just being arrows
  14879. 11:51:35in some form.
  14880. 11:51:36All right.
  14881. 11:51:36So what have we just done?
  14882. 11:51:37The picture now, after setting number to 1, looks a little something like this.
  14883. 11:51:42So there's still one step missing.
  14884. 11:51:43And that's, of course, to initialize, it would seem,
  14885. 11:51:46the pointer in this new node to something known like null.
  14886. 11:51:50So I bet we could do this like this.
  14887. 11:51:52With a different line of code, I'm just going
  14888. 11:51:54to say if n does not equal null, then set n's next field to null.
  14889. 11:52:00Or more pedantically, go to n, follow the arrow,
  14890. 11:52:04and then update the next field that you find there to equal null.
  14891. 11:52:07And again, this is just doing some nice bookkeeping.
  14892. 11:52:10Technically speaking, we might not need to set
  14893. 11:52:13this to null if we're going to keep adding more and more numbers to it.
  14894. 11:52:16But I'm doing it step-by-step so that I have a very clean picture.
  14895. 11:52:19And there's no bugs in my code at this point.
  14896. 11:52:23But I'm still not done.
  14897. 11:52:24There's one last thing I'm going to have to do here.
  14898. 11:52:27If the goal, ultimately, was to insert the number 1 into my linked list,
  14899. 11:52:32what's the last step I should, perhaps, do here?
  14900. 11:52:36Just been English is fine.
  14901. 11:52:37Yeah.
  14902. 11:52:38AUDIENCE: Set the pointer value to null.
  14903. 11:52:40SPEAKER 1: Yes.
  14904. 11:52:41I now need to update the actual variable, that represents my linked
  14905. 11:52:45list, to point at this brand new node.
  14906. 11:52:48That is now perfectly initialized as having an integer and a null pointer.
  14907. 11:52:52Yeah, technically, this is already pointing there.
  14908. 11:52:54But I describe this deliberately earlier as being temporary.
  14909. 11:52:57I just needed this to get it back from malloc and clean things up, initially.
  14910. 11:53:02This is the long term variable I care about.
  14911. 11:53:04So I'm going to want to do something simple like this.
  14912. 11:53:06List equals n.
  14913. 11:53:09And this seems a little weird that list equals n.
  14914. 11:53:11But again, think about what's inside this box.
  14915. 11:53:13At the moment this is null because there is no linked
  14916. 11:53:15list at the beginning of our story.
  14917. 11:53:17N is the address of the beginning, and it turns out, end of our linked list.
  14918. 11:53:21So it stands to reason that if you set list equal to n,
  14919. 11:53:24that has the effect of copying this address up here.
  14920. 11:53:27Or really just copying the arrow into that same location
  14921. 11:53:30so that now the picture looks like this.
  14922. 11:53:32And heck, if this was a temporary variable, it will eventually go away.
  14923. 11:53:35And now, this is the picture.
  14924. 11:53:37So an annoying number of steps, certainly,
  14925. 11:53:39to walk through verbally like this.
  14926. 11:53:42But it's just malloc to give yourself a node,
  14927. 11:53:44initialize the 2 fields inside of it, update the linked list, and boom,
  14928. 11:53:49you're on your way.
  14929. 11:53:50I didn't have to copy anything.
  14930. 11:53:52I just had to insert something in this case.
  14931. 11:53:55Let me pause here to see if there's any questions on those steps.
  14932. 11:53:58And we'll see before long it all in context with some larger code.
  14933. 11:54:02AUDIENCE: So if the statements [INAUDIBLE]..
  14934. 11:54:06SPEAKER 1: Yes.
  14935. 11:54:07I drew them separately just for the sake of the voiceover
  14936. 11:54:10of doing each thing very methodically.
  14937. 11:54:12In real code, as we'll transition to now,
  14938. 11:54:14I could have and should have just done it
  14939. 11:54:16all inside of one conditional after checking if n is not equal to null.
  14940. 11:54:20I could set number to a value like 1.
  14941. 11:54:22And I could set the pointer itself to something like null.
  14942. 11:54:25All right.
  14943. 11:54:26Well let's translate, then, this into some similar code
  14944. 11:54:30that allows us to build up a linked list now using code similar in spirit
  14945. 11:54:34to before.
  14946. 11:54:35But now, using this new primitive.
  14947. 11:54:37So I'm going to go back into VS Code here.
  14948. 11:54:39I'm going to go ahead now and delete the entirety of this old version that
  14949. 11:54:42was entirely array-based.
  14950. 11:54:44And now, inside of my main function, I'm going to go ahead and first do this.
  14951. 11:54:49I'm going to first give myself a list of size 0.
  14952. 11:54:53And I'm going to call that node* list.
  14953. 11:54:56And I'm going to initialize that to null, as we proposed earlier.
  14954. 11:54:59But I'm also now going to have to take the additional step of defining
  14955. 11:55:02what this node is.
  14956. 11:55:03So recall that I might do something like typedef, struct node.
  14957. 11:55:06Inside of this struct node, I'm going to have a number, which
  14958. 11:55:09I'll call number of type int.
  14959. 11:55:11And I'm going to have a structure called node
  14960. 11:55:13with a * that says the next pointer is called next.
  14961. 11:55:16And I'm going to call this whole thing, more succinctly, node,
  14962. 11:55:20instead of struct node.
  14963. 11:55:22Now as an aside, for those of you wondering what the difference really
  14964. 11:55:25is between struct and node.
  14965. 11:55:27Technically, I could do something like this.
  14966. 11:55:29Not use typedef and not use the word node alone.
  14967. 11:55:33This syntax here would actually create for me a new data
  14968. 11:55:37type called, verbosely, struct node.
  14969. 11:55:40And I could use this throughout my code saying struct node.
  14970. 11:55:42Struct node.
  14971. 11:55:43That just gets a little tedious.
  14972. 11:55:45And it would be nicer just to refer to this thing more simplistically
  14973. 11:55:48as a node.
  14974. 11:55:49So what typedef has been doing for us is it,
  14975. 11:55:51again, lets us invent our own word that's even more succinct.
  14976. 11:55:55And this just has the effect now of calling this whole thing
  14977. 11:55:58node without the need, subsequently, to keep saying struct all over the place.
  14978. 11:56:02Just FYI.
  14979. 11:56:03All right.
  14980. 11:56:04So now that this thing exists in main, let's go ahead and do this.
  14981. 11:56:07Let's add a number to list.
  14982. 11:56:10And to do this, I'm going to give myself a temporary variable.
  14983. 11:56:12I'll call it n for consistency.
  14984. 11:56:14I'm going to use malloc to give myself the size of a node,
  14985. 11:56:18just like in our slides.
  14986. 11:56:19And then, I'm going to do a little safety check.
  14987. 11:56:21If n equals equals null, I'm going to do the opposite of the slides.
  14988. 11:56:23I'm just going to quit out of this program
  14989. 11:56:25because there's nothing useful to be done at this point.
  14990. 11:56:28But most likely my computer is not going to run out of memory.
  14991. 11:56:31So I'm going to assume we can keep going with some of the logic here.
  14992. 11:56:34If n does not equal null, and that is it's a valid memory address,
  14993. 11:56:38I'm going to say n []--
  14994. 11:56:40I'm going to build this up backwards.
  14995. 11:56:42Well let's do.
  14996. 11:56:44That's OK, let's go ahead and do this.
  14997. 11:56:45N [number] equals 1.
  14998. 11:56:48And then n [arrow next] equals null.
  14999. 11:56:52And now, update list to point to new node, list equals n.
  15000. 11:56:59So at this point in the story, we've essentially
  15001. 11:57:02constructed what was that first picture, which looks like this.
  15002. 11:57:06This is the corresponding code via which we built up this node in memory.
  15003. 11:57:11Suppose now, we want to add the number 2 to the list.
  15004. 11:57:14So let's do this again.
  15005. 11:57:15Add a number to list.
  15006. 11:57:20How might I do this?
  15007. 11:57:21Well, I don't need to redeclare n because I can use
  15008. 11:57:23the same temporary variables before.
  15009. 11:57:25So this time, I'm just going to say n equals malloc and the size of a node.
  15010. 11:57:30I'm, again, going to have my safety check.
  15011. 11:57:32So if n equals equals null, then let's just quit out of this altogether.
  15012. 11:57:36But, I have to be a little more careful now.
  15013. 11:57:41Technically speaking, what do I still need
  15014. 11:57:43to do before I quit out of my program to be really proper?
  15015. 11:57:48Free the memory that did succeed a little higher up.
  15016. 11:57:51So I think it suffices to free what is now called list, way at the top.
  15017. 11:57:56All right.
  15018. 11:57:57Now, if all was well, though, let's go ahead and say n [number] equals 2.
  15019. 11:58:03And now, n [arrow next] equals null.
  15020. 11:58:09And now, let's go ahead and add it to the list.
  15021. 11:58:12If I go ahead and do list arrow next equals n,
  15022. 11:58:20I think what we've just done is build up the equivalent, now,
  15023. 11:58:24of this in the computer's memory.
  15024. 11:58:27By going to the list field's next field, which
  15025. 11:58:29is synonymous with the 1 nodes, bottom-most box.
  15026. 11:58:33And store the address of what was n, which a moment ago looked like this.
  15027. 11:58:37And I'm just throwing away, in the picture, the temporary variable.
  15028. 11:58:39All right.
  15029. 11:58:40One last thing to do.
  15030. 11:58:42Let me go down here and say, add a number to list, n equals malloc.
  15031. 11:58:47Let's do it one more time.
  15032. 11:58:48Size of node.
  15033. 11:58:49And clearly, in a real program, we might want to start using a loop.
  15034. 11:58:52And do this dynamically or a function because it's a lot of repetition now.
  15035. 11:58:56But just to go through the syntax here, this is fine.
  15036. 11:58:59If n equals equals null, out of memory for some reason.
  15037. 11:59:03Let's return 1, but we should free the list itself
  15038. 11:59:09and even the second node, list [next].
  15039. 11:59:12But I've deliberately done this poorly.
  15040. 11:59:16All right.
  15041. 11:59:16This is a little more subtle now.
  15042. 11:59:18And let me get rid of the highlighting just so it's a little more visible.
  15043. 11:59:22If n happens to equal equal null, and something really just
  15044. 11:59:26went wrong they're out of memory, why am I freeing 2 addresses now?
  15045. 11:59:32And again, it's not that I'm freeing those variables per se.
  15046. 11:59:35I'm freeing the addresses at in those variables.
  15047. 11:59:39But there's also a bug with my code here.
  15048. 11:59:41And it's subtle.
  15049. 11:59:43Let me ask more pointedly.
  15050. 11:59:45This line here, 43, what is that freeing specifically?
  15051. 11:59:49Can I go to you?
  15052. 11:59:49AUDIENCE: You're freeing list 2 times.
  15053. 11:59:52SPEAKER 1: I'm freeing, not so.
  15054. 11:59:54That's OK.
  15055. 11:59:54I'm not freeing list 2 times.
  15056. 11:59:56Technically, I'm freeing list once and list next once.
  15057. 11:59:59But let me just ask the more explicit question.
  15058. 12:00:01What am I freeing with line 43 at the moment?
  15059. 12:00:03Which node?
  15060. 12:00:06I think node number 1.
  15061. 12:00:08Why?
  15062. 12:00:08Because if 1 is at the beginning of the list,
  15063. 12:00:10list contains the address of that number 1 node.
  15064. 12:00:14And so this frees that node.
  15065. 12:00:15This line of code, you might think now intuitively, OK,
  15066. 12:00:18it's probably freeing the node number 2.
  15067. 12:00:21But this is bad.
  15068. 12:00:22And this is subtle.
  15069. 12:00:22Valgrind might help you catch this.
  15070. 12:00:24But by eyeing it, it's not necessarily obvious.
  15071. 12:00:27You should never touch memory that you have already freed.
  15072. 12:00:31And so, the fact that I did in this order, very bad.
  15073. 12:00:34Because I'm telling the operating system, I don't know.
  15074. 12:00:37I don't need the list address anymore.
  15075. 12:00:39Do with it what you want.
  15076. 12:00:40And then, literally one line later, you're saying, wait a minute.
  15077. 12:00:43Let me actually go to that address for a moment
  15078. 12:00:45and look at the next field of that first node.
  15079. 12:00:47It's too late.
  15080. 12:00:48You've already given up control over the node.
  15081. 12:00:51So it's an easy fix in this case, logically.
  15082. 12:00:54But we should be freeing the second node first
  15083. 12:00:56and then the first one so that we're doing it
  15084. 12:01:00in, essentially, reverse order.
  15085. 12:01:02And again, Valgrind would help you catch that.
  15086. 12:01:04But that's the kind of thing one needs to be careful about when
  15087. 12:01:07touching memory at all.
  15088. 12:01:08You cannot touch memory after you freed it.
  15089. 12:01:10But here is my last step.
  15090. 12:01:12Let me go ahead and update the number field of n to be 3.
  15091. 12:01:17The next node of n to be null.
  15092. 12:01:20And then, just like in the slide earlier,
  15093. 12:01:22I think I can do list next, next equals n.
  15094. 12:01:28And that has the effect now of building up in the computer's memory,
  15095. 12:01:32essentially, this data structure.
  15096. 12:01:34Very manually.
  15097. 12:01:35Very pedantically.
  15098. 12:01:36Like, in a better world, we'd have a loop and some functions
  15099. 12:01:38that are automating this process.
  15100. 12:01:39But, for now, we're doing it just to play around with the syntax.
  15101. 12:01:44So at this point, unfortunately, suppose I want to print the numbers.
  15102. 12:01:48It's no longer as easy as int i equals 0, i less than 3, i++.
  15103. 12:01:53Because you cannot just do something like this.
  15104. 12:02:00Because pointer arithmetic no longer comes into play
  15105. 12:02:06when it's you, who are stitching together the data structure in memory.
  15106. 12:02:10In all of our past examples with arrays, you've
  15107. 12:02:12been trusting that all of the bytes in the array are back, to back, to back.
  15108. 12:02:16So it's perfectly reasonable for the compiler and the computer
  15109. 12:02:19to just figure out, oh, well if you want [0], that's at the beginning.
  15110. 12:02:21[1], it's one location over.
  15111. 12:02:23[2], it's one location over.
  15112. 12:02:25This is way less obvious now.
  15113. 12:02:28Because even though you might want to go to the first element in the linked
  15114. 12:02:32list, or the second, or the third, you can't just jump to those arithmetically
  15115. 12:02:36by doing a bit of math.
  15116. 12:02:38Instead, you have to follow all of those arrows.
  15117. 12:02:41So with linked lists, you can't use this square bracket notation anymore
  15118. 12:02:44because one node might be here, over here, over here, over here.
  15119. 12:02:47You can't just use some simple offset.
  15120. 12:02:51So I think our code is going to have to be a little fancier.
  15121. 12:02:53And this might look scary at first, but it's just an application
  15122. 12:02:57of some of the basic definitions here.
  15123. 12:02:59Let me do a for-loop that actually uses a node* variable initialized
  15124. 12:03:06to the list itself.
  15125. 12:03:08I'm going to keep doing this, so long as TMP does not equal null.
  15126. 12:03:13And on each iteration of this loop, I'm going
  15127. 12:03:15to update TMP to be whatever TMP arrow next is.
  15128. 12:03:20And I'll remind you in a moment and explain in more detail.
  15129. 12:03:23But when I print something here with printf, I can still use %i.
  15130. 12:03:27Because it's still a number at the end of the day.
  15131. 12:03:29But what I want to print out is the number in this temporary variable.
  15132. 12:03:34So maybe the ugliest for-loop we've ever seen.
  15133. 12:03:36Because it's mixing, not just the idea of a for-loop, which
  15134. 12:03:38itself was a bit cryptic weeks ago.
  15135. 12:03:40But now, I'm using pointers instead of integers.
  15136. 12:03:43But I'm not violating the definition of a for-loop.
  15137. 12:03:45Recall that a for-loop has 3 main things in parentheses.
  15138. 12:03:48What do you want to initialize first?
  15139. 12:03:50What condition do you want to keep checking again and again?
  15140. 12:03:53And what update do you want to make on every iteration of the loop?
  15141. 12:03:56So with that basic definition in mind, this
  15142. 12:03:59is giving me a temporary variable called TMP
  15143. 12:04:01that is initialized to the beginning of the loop.
  15144. 12:04:04So it's like pointing my finger at the number 1 node.
  15145. 12:04:07Then, I'm asking the question, does TMP not equal null?
  15146. 12:04:11Well, hopefully, not because I'm pointing at a valid node
  15147. 12:04:13that is the number 1 node.
  15148. 12:04:15So, of course, it doesn't equal null yet.
  15149. 12:04:17Null won't be until we get to the end of the list.
  15150. 12:04:19So what do I do?
  15151. 12:04:21I started this TMP variable.
  15152. 12:04:22I follow the arrow and go to the number field they're in.
  15153. 12:04:27What do I then do?
  15154. 12:04:28The for-loop says, change TMP to be whatever
  15155. 12:04:32is at TMP, by following the arrow and grabbing the next field.
  15156. 12:04:36That, then, has the result of being checked against this conditional.
  15157. 12:04:39No, of course, it doesn't equal null because the second node
  15158. 12:04:42is the number 2 node.
  15159. 12:04:43Null is still at the very end.
  15160. 12:04:45So I print out the number 2.
  15161. 12:04:47Next step, I update TMP one more time to be whatever is next.
  15162. 12:04:51That, then, does not yet equal null.
  15163. 12:04:53So I go ahead and print out the number 3 node.
  15164. 12:04:55Then one last time, I update TMP to be whatever TMP is in the next field.
  15165. 12:05:01But after 1, 2, 3, that last next field is null.
  15166. 12:05:05And so, I break out of this for-loop altogether.
  15167. 12:05:09So if I do this in pictorial form, all we're
  15168. 12:05:12doing, if I now use my finger to represent the TMP variable.
  15169. 12:05:15I initialize TMP to be whatever list is, so it points here.
  15170. 12:05:19That's obviously not null so I print out whatever
  15171. 12:05:22is that TMP, follow the arrow in number, and I print that out.
  15172. 12:05:26Then I update TMP to point here.
  15173. 12:05:28Then I update TMP to point here.
  15174. 12:05:30Then I update TMP to point here.
  15175. 12:05:31Wait, that's null.
  15176. 12:05:32The for-loop ends.
  15177. 12:05:34So, again, admittedly much more cryptic than our familiar int i equals 0,
  15178. 12:05:39and so forth.
  15179. 12:05:40But it's just a different utilization of the for-loop syntax.
  15180. 12:05:46Yes.
  15181. 12:05:46AUDIENCE: How does it happen that you're always printing out the numbers.
  15182. 12:05:50Because it seems to me that addresses-
  15183. 12:05:52SPEAKER 1: Good question.
  15184. 12:05:53How is it that I'm actually printing numbers and not printing out
  15185. 12:05:56addresses instead.
  15186. 12:05:57The compiler is helping me here.
  15187. 12:05:59Because I taught it, in the very beginning of my program,
  15188. 12:06:02what a node is.
  15189. 12:06:02Which looks like this here.
  15190. 12:06:05The compiler knows that a node has a number of fields and a next field
  15191. 12:06:08down here, in the for-loop.
  15192. 12:06:10Because I'm iterating using a node* pointer, and not an int* pointer,
  15193. 12:06:16the compiler knows that any time I'm pointing at something,
  15194. 12:06:19I'm pointing at the whole node.
  15195. 12:06:21Doesn't matter where specifically in the rectangle I'm pointing per se.
  15196. 12:06:24It's, ultimately, pointing at the whole node itself.
  15197. 12:06:26And the fact that I, then, use TMP arrow number means, OK,
  15198. 12:06:30adjust your finger slightly.
  15199. 12:06:31So you're literally pointing at the number field and not the next field.
  15200. 12:06:35So that's sufficient information for the computer to distinguish the 2.
  15201. 12:06:40Good question.
  15202. 12:06:41Other questions then on this approach here.
  15203. 12:06:44Yeah, in the back.
  15204. 12:06:45AUDIENCE: How would you--
  15205. 12:06:46SPEAKER 1: How would I use a for-loop to add elements to a linked list?
  15206. 12:06:51You will do something like this, if I may, in problem set 5.
  15207. 12:06:56We will give you some of the scaffolding for doing this.
  15208. 12:06:59But in this coming weeks materials will we guide you to that.
  15209. 12:07:02But let me not spoil it just yet.
  15210. 12:07:04Fair question, though.
  15211. 12:07:05Yeah.
  15212. 12:07:06AUDIENCE: So I had a question about line 49.
  15213. 12:07:08SPEAKER 1: OK.
  15214. 12:07:09AUDIENCE: Is line 49 possible in line 43?
  15215. 12:07:11SPEAKER 1: Good question.
  15216. 12:07:12Is line 49 acceptable, even if we freed it earlier.
  15217. 12:07:15We didn't free it in line 43, in this case, right.
  15218. 12:07:18You can only reach line 49, if n does not equal null.
  15219. 12:07:22And you do not return on line 45.
  15220. 12:07:24So that's safe.
  15221. 12:07:25I was only doing those freeing, if I knew on line 45 that I'm out of here
  15222. 12:07:29anyway, at that point.
  15223. 12:07:31Good question.
  15224. 12:07:31And, yeah.
  15225. 12:07:32AUDIENCE: I had a quick question.
  15226. 12:07:33Is TMP [INAUDIBLE].
  15227. 12:07:36SPEAKER 1: Correct You're asking about TMP, because it's in a for-loop,
  15228. 12:07:40does that mean you don't have to free it?
  15229. 12:07:41You never have to free pointers, per se.
  15230. 12:07:44You should only free addresses that were returned to you by malloc.
  15231. 12:07:49So I haven't finished the program, to be fair.
  15232. 12:07:51But you're not freeing variables.
  15233. 12:07:53You're not freeing like, fields.
  15234. 12:07:55You are freeing specific addresses, whatever they may be.
  15235. 12:07:58So the last thing, and I was stalling on showing this
  15236. 12:08:01because it too is a little cryptic.
  15237. 12:08:02Here is how you can free, now, a whole linked list.
  15238. 12:08:06In the world of arrays, recall, it was so easy.
  15239. 12:08:08You just say free list.
  15240. 12:08:09You return 0 and you're done.
  15241. 12:08:11Not with a linked list.
  15242. 12:08:12Because, again, the computer doesn't know
  15243. 12:08:14what you have stitched together using all of these pointers
  15244. 12:08:17all over the computer's memory.
  15245. 12:08:18You need to follow those arrows.
  15246. 12:08:20So one way to do this would be as follows.
  15247. 12:08:23While the list itself is not null, so while there's a list to be freed.
  15248. 12:08:28What do I want to do?
  15249. 12:08:29I'm going to give myself a temporary variable called TMP again.
  15250. 12:08:32And it's a different TMP because it's in a different scope.
  15251. 12:08:34It's inside of the while loop instead the for-loop, a few lines earlier.
  15252. 12:08:38I am going to initialize TMP to be the address of the next node.
  15253. 12:08:44Just so I can get one step ahead of things.
  15254. 12:08:46Why am I doing this?
  15255. 12:08:47Because now, I can boldly free the list itself,
  15256. 12:08:51which does not mean the whole list.
  15257. 12:08:53Again, I'm freeing the address in list, which
  15258. 12:08:56is the address of the number 1 node.
  15259. 12:08:58That's what list is.
  15260. 12:08:59It's just the address of the number 1 node.
  15261. 12:09:02So if I first use TMP to point out the number
  15262. 12:09:052 slightly in the middle of the picture, then it is safe for me on line 61,
  15263. 12:09:10at the moment, to free list.
  15264. 12:09:12That is the address of the first node.
  15265. 12:09:15Now I'm going to say, all right, once I freed the first node in the list,
  15266. 12:09:19I can update the list itself to be literally TMP.
  15267. 12:09:24And now, the loop repeats.
  15268. 12:09:26So what's happening here?
  15269. 12:09:27If you think about this picture, TMP is initially pointing at not the list,
  15270. 12:09:33but list arrow next.
  15271. 12:09:35So TMP, represented by my right hand here, is pointing at the number 2.
  15272. 12:09:38Totally safe and reasonable to free now the list itself a.k.a.
  15273. 12:09:43the address of the number 1 node.
  15274. 12:09:44That has the effect of just throwing away the number 1 node,
  15275. 12:09:47telling the computer you can reuse that memory for you.
  15276. 12:09:50The last line of code I wrote updated list to point at the number
  15277. 12:09:532, at which point my loop proceeded to do the exact same thing again.
  15278. 12:09:58And only once my finger is literally pointing at nowhere,
  15279. 12:10:01the null symbol, will the loop, by nature of a while
  15280. 12:10:03loop as I'll toggle back to, break out.
  15281. 12:10:06And there's nothing more to be freed.
  15282. 12:10:09So again, what you'll see, ultimately, in problem set 5,
  15283. 12:10:12more on that later, is an opportunity to play around with just this syntax.
  15284. 12:10:16But also these ideas.
  15285. 12:10:17But again, even though the syntax is admittedly pretty cryptic,
  15286. 12:10:20we're still using basics like these for-loops or while loops.
  15287. 12:10:23We're just starting to now follow explicit addresses rather
  15288. 12:10:27than letting the computer do all of the arithmetic for us,
  15289. 12:10:31as we previously benefited from.
  15290. 12:10:33At the very end of this thing, I'm going to return 0 as though all is well.
  15291. 12:10:36And I think, then, we're good to go.
  15292. 12:10:39All right.
  15293. 12:10:40Questions on this linked list code now?
  15294. 12:10:43And again, we'll walk through this again in the coming weeks spec.
  15295. 12:10:46Yeah.
  15296. 12:10:46AUDIENCE: Can you explain the while loop [INAUDIBLE] starts in other ways?
  15297. 12:10:51SPEAKER 1: Sure.
  15298. 12:10:51Can we explain this while loop here for freeing the list.
  15299. 12:10:55So notice that, first, I'm just asking the obvious question.
  15300. 12:10:58Is the list null?
  15301. 12:10:58Because if it is, there's no work to be done.
  15302. 12:11:02However, while the list is not null, according to line 58,
  15303. 12:11:06what do we want to do?
  15304. 12:11:08I want to create a temporary variable that points at the same thing
  15305. 12:11:12that list arrow next is pointing at.
  15306. 12:11:15So what does that mean?
  15307. 12:11:16Here is list.
  15308. 12:11:17List arrow next is whatever this thing is here.
  15309. 12:11:21So if my right hand represents the temporary variable,
  15310. 12:11:23I'm literally pointing at the same thing as the list is itself.
  15311. 12:11:27The next line of code, recall, was free the list.
  15312. 12:11:31And unlike, in our world of arrays, like half an hour
  15313. 12:11:33ago where that just meant free the whole darn list,
  15314. 12:11:36you now have taken over control over the computer's memory with a linked list,
  15315. 12:11:41in ways that you didn't with the array.
  15316. 12:11:43The computer knew how to free the whole array because you
  15317. 12:11:46malloc the whole thing at once.
  15318. 12:11:48You are now mallocing the linked list one node at a time.
  15319. 12:11:52And the operating system does not keep track of for you
  15320. 12:11:54where all these nodes are.
  15321. 12:11:56So when you free list, you are literally freeing
  15322. 12:11:59the value of the list variable, which is just this first node here.
  15323. 12:12:03Then my last line of code, which I'll flip back to in a second, updates
  15324. 12:12:07list to now ignore the free memory and point at 2.
  15325. 12:12:11And the story then repeats.
  15326. 12:12:14So, again, it's just a very pedantic way of using
  15327. 12:12:17this new syntax of star notation, and the arrow notation, and the like,
  15328. 12:12:21to do the equivalent of walking down all of these arrows.
  15329. 12:12:25Following all of these breadcrumbs.
  15330. 12:12:28But it does take admittedly some getting used to.
  15331. 12:12:31Syntax, you only have to do one week.
  15332. 12:12:33But, again, next week in Python will we begin
  15333. 12:12:35to abstract a lot of this complexity away.
  15334. 12:12:37But none of this complexity is going away.
  15335. 12:12:39It's just that someone else, the authors of Python for instance,
  15336. 12:12:42will have automated this stuff for us.
  15337. 12:12:44The goal this week is to understand what it
  15338. 12:12:46is we're going to get for free, so to speak, next week.
  15339. 12:12:49All right.
  15340. 12:12:49Questions on these length lists.
  15341. 12:12:54All right.
  15342. 12:12:54Just, yeah, in the back.
  15343. 12:12:55AUDIENCE: So are the while loops strictly necessary
  15344. 12:12:58for the freeing [INAUDIBLE].
  15345. 12:13:00SPEAKER 1: Fair question.
  15346. 12:13:01Let me summarize as, could we have freed this with a for-loop?
  15347. 12:13:03Absolutely.
  15348. 12:13:04It just is a matter of style.
  15349. 12:13:06It's a little more elegant to do it in a while loop, according to me.
  15350. 12:13:09But other people will reasonably disagree.
  15351. 12:13:11Anything you can do with a while loop you can do with a for-loop,
  15352. 12:13:13and vise versa.
  15353. 12:13:14Do while loops, recall, are a little different.
  15354. 12:13:17But they will always do at least one thing.
  15355. 12:13:19But for-loops and while loops behave the same in this case.
  15356. 12:13:22AUDIENCE: Thank you.
  15357. 12:13:23SPEAKER 1: Sure.
  15358. 12:13:24Other questions?
  15359. 12:13:25All right, well let's just vary things a little bit here.
  15360. 12:13:27Just to see what some of the pitfalls might now be
  15361. 12:13:29without getting into the weeds of code.
  15362. 12:13:31Indeed, we'll try to save some of that for problem set 5's exploration.
  15363. 12:13:35But instead, let's imagine that we want to create a list here of our own.
  15364. 12:13:40I can offer, in exchange for a few volunteers, some foam fingers
  15365. 12:13:43to bring to the next game, perhaps.
  15366. 12:13:45Could we get maybe just one volunteer first?
  15367. 12:13:46Come on up.
  15368. 12:13:47You will be our linked list from the get go.
  15369. 12:13:50What's your name?
  15370. 12:13:51AUDIENCE: Pedro.
  15371. 12:13:52SPEAKER 1: Pedro, come on up.
  15372. 12:13:54All right, thank you to Pedro.
  15373. 12:13:55[AUDIENCE CLAPPING]
  15374. 12:13:58And if you want to just stand roughly over here.
  15375. 12:14:00But you are a null pointer so just point sort of at the ground,
  15376. 12:14:03as though you're pointing at 0.
  15377. 12:14:04All right.
  15378. 12:14:04So Pedro is our linked list of size 0, which pictorially
  15379. 12:14:07might look a little something like this for consistency with our past pictures.
  15380. 12:14:10Now suppose that we want to go ahead and malloc, oh, how about the number 2.
  15381. 12:14:15Can we get a volunteer to be on camera here?
  15382. 12:14:17OK.
  15383. 12:14:18You jumped out of your seat.
  15384. 12:14:19Do you want to come up?
  15385. 12:14:21OK, you really want the foam finger, I say.
  15386. 12:14:23All right.
  15387. 12:14:23Round of applause, sure.
  15388. 12:14:24[AUDIENCE CLAPPING]
  15389. 12:14:30OK.
  15390. 12:14:30And what's your name?
  15391. 12:14:31AUDIENCE: Caleb.
  15392. 12:14:32SPEAKER 1: Say again?
  15393. 12:14:32AUDIENCE: Caleb.
  15394. 12:14:33SPEAKER 1: Halen?
  15395. 12:14:33AUDIENCE: Caleb.
  15396. 12:14:34SPEAKER 1: Caleb.
  15397. 12:14:34Caleb, sorry.
  15398. 12:14:36All right.
  15399. 12:14:36So here is your number 2 for your number field.
  15400. 12:14:39And here is your pointer.
  15401. 12:14:40And come on, let's say that there was room for Caleb like, right there.
  15402. 12:14:43That's perfect.
  15403. 12:14:44So Caleb got malloced, if you will, over here.
  15404. 12:14:46So now if we want to insert Caleb and the number 2 into this linked list,
  15405. 12:14:51well what do we need to do?
  15406. 12:14:52I already initialized you to 2.
  15407. 12:14:53And pointing as you are to the ground means
  15408. 12:14:55you're initialized to null for your next field.
  15409. 12:14:58Pedro, what you should you-- perfect.
  15410. 12:14:59What should Pedro do.
  15411. 12:15:01That's fine, too.
  15412. 12:15:02So Pedro is now pointing at the list.
  15413. 12:15:03So now our list looks a little something like this.
  15414. 12:15:05So far, so good.
  15415. 12:15:07All is well.
  15416. 12:15:07So the first couple of these will be pretty straightforward.
  15417. 12:15:10Let's insert one more, if anyone really wants another foam finger.
  15418. 12:15:13Here, how about right in the middle.
  15419. 12:15:15Come on down.
  15420. 12:15:16And just in anticipation, how about let's malloc someone else.
  15421. 12:15:19OK, your friends are pointing at you.
  15422. 12:15:20Do you want to come down too, preemptively?
  15423. 12:15:22This is a pool of memory, if you will.
  15424. 12:15:25What's your name?
  15425. 12:15:26AUDIENCE: Hannah.
  15426. 12:15:26SPEAKER 1: Hannah.
  15427. 12:15:27All right, Hanna.
  15428. 12:15:28You are number 4.
  15429. 12:15:28[AUDIENCE CLAPPING]
  15430. 12:15:30And hang there for just a moment.
  15431. 12:15:32All right.
  15432. 12:15:32So we've just malloced Hannah.
  15433. 12:15:34And Hannah, how about Hannah, suppose you ended up over there
  15434. 12:15:37in just some random location.
  15435. 12:15:39All right.
  15436. 12:15:39So what should we now do, if the goal is to keep these things sorted?
  15437. 12:15:43How about?
  15438. 12:15:44So Pedro, do you have to update yourself?
  15439. 12:15:46AUDIENCE: No.
  15440. 12:15:46SPEAKER 1: No.
  15441. 12:15:46All right.
  15442. 12:15:47Caleb, what do you have to do?
  15443. 12:15:48OK.
  15444. 12:15:49And Hannah what should you be doing?
  15445. 12:15:52I would, it's just for you for now, so point at the ground representing null.
  15446. 12:15:55OK.
  15447. 12:15:55So, again demonstrating the fact that, unlike in past weeks where
  15448. 12:15:58we had our nice, clean array back, to back, to back,
  15449. 12:16:01contiguously, these guys are deliberately all over the stage.
  15450. 12:16:03So let's malloc another.
  15451. 12:16:04How about number 5.
  15452. 12:16:06What's your name?
  15453. 12:16:07AUDIENCE: Jonathan.
  15454. 12:16:07SPEAKER 1: Jonathan.
  15455. 12:16:08All right, Jonathan.
  15456. 12:16:09You are our number 5.
  15457. 12:16:10And pick your favorite place in memory.
  15458. 12:16:12[AUDIENCE CLAPPING]
  15459. 12:16:13OK.
  15460. 12:16:16All right.
  15461. 12:16:16So Jonathan's now over there.
  15462. 12:16:19And Hannah is over there.
  15463. 12:16:20So 5, we want to point Hannah at number 5.
  15464. 12:16:21So you, of course, are going to point there.
  15465. 12:16:23And where should you be pointing?
  15466. 12:16:25Down to represent null, as well.
  15467. 12:16:26OK.
  15468. 12:16:27So pretty straightforward.
  15469. 12:16:29But now things get a little interesting.
  15470. 12:16:30And here, we'll use a chance to, without the weeds of code,
  15471. 12:16:33point out how order of operations is really going to matter.
  15472. 12:16:36Suppose that I next want to allocate say, the number 1.
  15473. 12:16:40And I want to insert the number 1 into this list.
  15474. 12:16:42Yes.
  15475. 12:16:43This is what the code would look like.
  15476. 12:16:45But if we act this out-- could we get one more volunteer?
  15477. 12:16:48How about on the end there in the sweater.
  15478. 12:16:50Yeah.
  15479. 12:16:50Come on down.
  15480. 12:16:52We have, what's your name?
  15481. 12:16:53AUDIENCE: Lauren.
  15482. 12:16:54SPEAKER 1: Lauren.
  15483. 12:16:54OK.
  15484. 12:16:55Lauren, come on down.
  15485. 12:16:56[AUDIENCE CLAPPING]
  15486. 12:17:01And how about, Lauren, why don't you go right
  15487. 12:17:03in here in front, if you don't mind.
  15488. 12:17:04Here is your number.
  15489. 12:17:06Here is your pointer.
  15490. 12:17:07So I've initialized Lauren to the number 1.
  15491. 12:17:09And your pointer will be null, pointing at the ground.
  15492. 12:17:11Where do you belong if we're maintaining sorted order?
  15493. 12:17:14Looks like right at the beginning.
  15494. 12:17:15What should happen here?
  15495. 12:17:18OK.
  15496. 12:17:18So Pedro has presumed to point now at Lauren.
  15497. 12:17:23But how do you know where to point?
  15498. 12:17:27AUDIENCE: He's number 2.
  15499. 12:17:28SPEAKER 1: Pedro's undoing what he did a moment ago.
  15500. 12:17:30So this was deliberate.
  15501. 12:17:31And that was perfect that Pedro presumed to point immediately at Lauren.
  15502. 12:17:35Why?
  15503. 12:17:35You literally just orphaned all of these folks, all of these chunks of memory.
  15504. 12:17:39Why?
  15505. 12:17:39Because if Pedro was our only variable pointing at that chunk of memory,
  15506. 12:17:44this is the danger of using pointers, and dynamic memory allocation,
  15507. 12:17:47and building your own data structures.
  15508. 12:17:48The moment you point temporarily, if you could,
  15509. 12:17:50to Lauren, I have no idea where he's pointing to.
  15510. 12:17:53I have no idea how to get back to Caleb, or Hannah, or anyone else on stage.
  15511. 12:17:58So that was bad.
  15512. 12:17:59So you did undo it.
  15513. 12:18:00So that's good.
  15514. 12:18:01I think we need Lauren to make a decision first.
  15515. 12:18:03Who should you point at?
  15516. 12:18:04AUDIENCE: Caleb.
  15517. 12:18:05SPEAKER 1: So pointing at Caleb.
  15518. 12:18:06Why?
  15519. 12:18:06Because you're pointing at literally who Pedro is pointing at.
  15520. 12:18:09Pedro, now what are you safe to do?
  15521. 12:18:10Good.
  15522. 12:18:11So order of operations there matters.
  15523. 12:18:13And if we had just done this line of code in red here, list equals n.
  15524. 12:18:17That was like Pedro's first instinct, bad things happen.
  15525. 12:18:20And we orphaned the rest of the list.
  15526. 12:18:22But if we think through it logically and do this, as Lauren did for us, instead,
  15527. 12:18:25we've now updated the list to look a little something more like this.
  15528. 12:18:29Let's do one last one.
  15529. 12:18:30We got one more foam finger here for the number 3.
  15530. 12:18:32How about on the end?
  15531. 12:18:33Yeah.
  15532. 12:18:34You want to come down.
  15533. 12:18:35All right.
  15534. 12:18:36One final volunteer.
  15535. 12:18:37[AUDIENCE CLAPPING]
  15536. 12:18:43All right.
  15537. 12:18:43And what's your name?
  15538. 12:18:44AUDIENCE: Miriam.
  15539. 12:18:45SPEAKER 1: I'm sorry?
  15540. 12:18:45AUDIENCE: Miriam.
  15541. 12:18:46SPEAKER 1: Miriam.
  15542. 12:18:46All right.
  15543. 12:18:47So here is your number 3.
  15544. 12:18:48Here is your pointer.
  15545. 12:18:49If you want to go maybe in the middle of the stage in a random memory location.
  15546. 12:18:52So here, too, the goal is to maintain sorted order.
  15547. 12:18:56So let's ask the audience, who or what number should point at whom first here?
  15548. 12:19:01So we don't screw up and orphan some of the memory.
  15549. 12:19:04And if we do orphan memory, this is what's called, again per last week,
  15550. 12:19:07a memory leak.
  15551. 12:19:08Your Mac, your PC, your phone can start to slow down
  15552. 12:19:10if you keep asking for memory but never give it back or lose track of it.
  15553. 12:19:14So we want to get this right.
  15554. 12:19:15Who should point at whom?
  15555. 12:19:17Or what number?
  15556. 12:19:18Say again.
  15557. 12:19:19AUDIENCE: 3 to 4.
  15558. 12:19:20SPEAKER 1: 3 should point at 4.
  15559. 12:19:22So 3, do you want to point at 4.
  15560. 12:19:25And not, so, OK, good.
  15561. 12:19:27And how did you know, Miriam, whom to point at?
  15562. 12:19:32AUDIENCE: Copying Caleb.
  15563. 12:19:33SPEAKER 1: Perfect.
  15564. 12:19:34OK, so copying Caleb.
  15565. 12:19:35Why?
  15566. 12:19:36Because if you look at where this list is currently constructed,
  15567. 12:19:39and you can cheat on the board here, 2 is pointing to 4.
  15568. 12:19:42If you point at whoever Caleb, number 2, is pointing out,
  15569. 12:19:46that, indeed, leads you to Hannah for number 4.
  15570. 12:19:48So now what's the next step to stitch this together?
  15571. 12:19:53Our voice in the crowd.
  15572. 12:19:54AUDIENCE: 2 to 3.
  15573. 12:19:55SPEAKER 1: 2 to 3.
  15574. 12:19:56So, 2 to 3.
  15575. 12:19:57So Caleb, I think it's now safe for you to decouple.
  15576. 12:20:00Because someone is already pointing at Hannah.
  15577. 12:20:02We haven't orphaned anyone.
  15578. 12:20:03So now, if we follow the breadcrumbs, we've
  15579. 12:20:05got Pedro leading to 1, to 2, to 3, to 4, to 5.
  15580. 12:20:10We need the numbers back, but you can keep the foam fingers.
  15581. 12:20:12Thank you to our volunteers here.
  15582. 12:20:15AUDIENCE: Thank you.
  15583. 12:20:15Thank you.
  15584. 12:20:16[AUDIENCE CLAPPING]
  15585. 12:20:17SPEAKER 1: You can just put the numbers here.
  15586. 12:20:20AUDIENCE: Thank you.
  15587. 12:20:21SPEAKER 1: Thank you to all.
  15588. 12:20:22So this is only to say that when you start looking at the code this week
  15589. 12:20:26and in the problem set, it's going to be very easy to lose
  15590. 12:20:29sight of the forest for the trees.
  15591. 12:20:30Because the code does get really dense.
  15592. 12:20:32But the idea is, again, really do bubble up to these higher level descriptions.
  15593. 12:20:37And if you think about data structures at this level.
  15594. 12:20:40If you go off in program after a class like CS50
  15595. 12:20:42and your whiteboarding something with a friend or a colleague,
  15596. 12:20:45most people think at and talk at this level.
  15597. 12:20:48And they just assume that, yeah, if we went back and looked
  15598. 12:20:51at our textbooks or class notes, we could figure out how to implement this.
  15599. 12:20:54But the important stuff is the conversation.
  15600. 12:20:56And the idea is up here.
  15601. 12:20:57Even though, via this week, will we get some practice with the actual code.
  15602. 12:21:02So when it comes to analyzing an algorithm like this,
  15603. 12:21:06let's consider the following.
  15604. 12:21:08What might be now the running time of operations like searching and inserting
  15605. 12:21:15into a linked list?
  15606. 12:21:17We talked about arrays earlier.
  15607. 12:21:19And we had some binary search possibilities still, as soon
  15608. 12:21:22as it's an array.
  15609. 12:21:23But as soon as we have a linked list, these arrows, like our volunteers,
  15610. 12:21:26could be anywhere on stage.
  15611. 12:21:27And so you can't just assume that you can
  15612. 12:21:29jump arithmetically to the middle element, to the middle element,
  15613. 12:21:32to the middle one.
  15614. 12:21:32You pretty much have to follow all of these breadcrumbs again and again.
  15615. 12:21:36So how might that inform what we see?
  15616. 12:21:39Well, consider this too.
  15617. 12:21:41Even though I keep drawing all these pictures with all of the numbers
  15618. 12:21:43exposed.
  15619. 12:21:44And all of us humans in the room can easily
  15620. 12:21:46spot where the 1 is, where the 2 is, where the 3 is, the computer, again,
  15621. 12:21:49just like with our lockers and arrays, can only see one location at a time.
  15622. 12:21:54And the key thing with a linked list is that the only address
  15623. 12:21:57we've fundamentally been remembering is what Pedro represented a moment ago.
  15624. 12:22:01He was the link to all of the other nodes.
  15625. 12:22:05And, in turn, each person led to the next.
  15626. 12:22:07But without Pedro, we would have lost some of, or all of, the linked list.
  15627. 12:22:12So when you start with a linked list, if you
  15628. 12:22:14want to find an element as via search, you have to do it linearly.
  15629. 12:22:18Following all of the arrows.
  15630. 12:22:19Following all of the pointers on the stage
  15631. 12:22:21in order to get to the node in question.
  15632. 12:22:23And only once you hit null can you conclude, yep, it was there.
  15633. 12:22:27Or no, it was not.
  15634. 12:22:28So given that if a computer, essentially,
  15635. 12:22:31can only see the number 1, or the number 2, or the number 3, or the number 4,
  15636. 12:22:36or the number 5, one at a time, how might we
  15637. 12:22:39think about the running time of search?
  15638. 12:22:43And it is indeed Big O of n.
  15639. 12:22:45But why is that?
  15640. 12:22:45Well, in the worst case, the number you might be looking for
  15641. 12:22:48is all the way at the end.
  15642. 12:22:49And so, obviously, you're going to have to search all of the n elements.
  15643. 12:22:53And I drew these things with boxes on top of them.
  15644. 12:22:55Because, again, even though you and I can immediately see,
  15645. 12:22:57where the 5 is for instance, the computer
  15646. 12:23:00can only figure that out by starting at the beginning and going there.
  15647. 12:23:03So there, too, is another trade off.
  15648. 12:23:05It would seem that, overnight, we have lost the ability
  15649. 12:23:09to do a very powerful algorithm from week 0 known as binary search, right.
  15650. 12:23:14It's gone.
  15651. 12:23:15Because there's no way in this picture to jump mathematically
  15652. 12:23:19to the middle node, unless you remember where it is.
  15653. 12:23:21And then, remember where every other node is.
  15654. 12:23:23And at that point, you're back to an array.
  15655. 12:23:25Linked list, by design, only remember the next node in the list.
  15656. 12:23:29All right.
  15657. 12:23:30How about something like insert?
  15658. 12:23:32In the worst case, perhaps, how many steps
  15659. 12:23:35might it take to insert something into a linked list?
  15660. 12:23:38Someone else.
  15661. 12:23:40Someone else.
  15662. 12:23:41Yeah.
  15663. 12:23:41AUDIENCE: N squared.
  15664. 12:23:42SPEAKER 1: Say again?
  15665. 12:23:42AUDIENCE: N squared.
  15666. 12:23:43SPEAKER 1: N squared.
  15667. 12:23:44Fortunately, it's not that bad.
  15668. 12:23:45It's not as bad as n squared.
  15669. 12:23:46That typically means doing n things, n times.
  15670. 12:23:49And I think we can stay under that, but not a bad thought.
  15671. 12:23:53Yeah.
  15672. 12:23:54AUDIENCE: Is it n?
  15673. 12:23:55SPEAKER 1: Why would it be n?
  15674. 12:23:56AUDIENCE: Because the [INAUDIBLE].
  15675. 12:24:00SPEAKER 1: OK.
  15676. 12:24:00So to summarize, you're proposing n.
  15677. 12:24:03Because to find where the thing goes, you
  15678. 12:24:05have to traverse, potentially, the whole list.
  15679. 12:24:06Because if I'm inserting the number 6 or the number 99,
  15680. 12:24:09that numerically belongs at the very end,
  15681. 12:24:12I can only find its location by looking for all of them.
  15682. 12:24:15At this point, though, in the term.
  15683. 12:24:16And really, at this point in the story, you
  15684. 12:24:18should start to question these very simplistic questions, to be honest.
  15685. 12:24:22Because the answer is almost always going to depend, right.
  15686. 12:24:25If I've just got a link to list that looks like this,
  15687. 12:24:28the first question back to someone asking this question
  15688. 12:24:31would be, well does the list need to be sorted, right?
  15689. 12:24:34I've drawn it as sorted and it might imply as much.
  15690. 12:24:37So that's a reasonable assumption to have made.
  15691. 12:24:39But if I don't care about maintaining sorted order,
  15692. 12:24:41I could actually insert into a linked list in constant time.
  15693. 12:24:45Why?
  15694. 12:24:46I could just keep inserting into the beginning, into the beginning,
  15695. 12:24:49into the beginning.
  15696. 12:24:49And even though the list is getting longer,
  15697. 12:24:51the number of steps required to insert something between the first element
  15698. 12:24:55is not growing at all.
  15699. 12:24:57You just keep inserting.
  15700. 12:25:00If you want to keep it sorted though, yes, it's
  15701. 12:25:02going to be, indeed, Big O of n.
  15702. 12:25:03But again, these kinds of, now, assumptions
  15703. 12:25:05are going to start to matter.
  15704. 12:25:06So let's for the sake of discussion say it's Big O of n,
  15705. 12:25:09if we do want to maintain sorted order.
  15706. 12:25:11But what about in the case of not caring.
  15707. 12:25:14It might indeed be a Big O of 1.
  15708. 12:25:16And now these are the kinds of decisions that will start to leave to you.
  15709. 12:25:19What about in the best case here?
  15710. 12:25:20If we're thinking about Big Omega notation,
  15711. 12:25:22then, frankly, we could just get lucky in the best case.
  15712. 12:25:25And the element we're looking for happens to be at the beginning.
  15713. 12:25:27Or heck, we just blindly insert to the beginning irrespective of the order
  15714. 12:25:32that we want to keep things in.
  15715. 12:25:33All right.
  15716. 12:25:34So besides then, how can we improve further on this design?
  15717. 12:25:39We don't need to stop at linked list.
  15718. 12:25:41Because, honestly, it's not been a clear win.
  15719. 12:25:43Like, linked list allow us to use more of our memory
  15720. 12:25:46because we don't need massive growing chunks of contiguous memory.
  15721. 12:25:49So that's a win.
  15722. 12:25:50But they still require Big O of n time to find the end of it,
  15723. 12:25:54if we care about order.
  15724. 12:25:56We're using at least twice as much memory for the darn pointer.
  15725. 12:25:59So that seems like a sidestep.
  15726. 12:26:01It's not really a step forward.
  15727. 12:26:03So can we do better?
  15728. 12:26:05Here's where we can now accelerate the story by just stipulating that, hey,
  15729. 12:26:09even if you haven't used this technique yet,
  15730. 12:26:11we would seem to have an ability to stitch together pieces of memory just
  15731. 12:26:15using pointers .
  15732. 12:26:16And anything you could imagine drawing with arrows,
  15733. 12:26:19you can implement, it would seem, in code.
  15734. 12:26:21So what if we leverage a second dimension.
  15735. 12:26:24Instead of just stringing together things laterally,
  15736. 12:26:26left to right, essentially, even though they
  15737. 12:26:28were bouncing around on the screen.
  15738. 12:26:30What if we start to leverage a second dimension here, so to speak.
  15739. 12:26:33And build more interesting structures in the computer's memory.
  15740. 12:26:36Well it turns out that in a computer's memory,
  15741. 12:26:39we could create a tree, similar to a family tree.
  15742. 12:26:42If you've ever seen or draw on a family tree with grandparents, and parents,
  15743. 12:26:46and siblings, and so forth.
  15744. 12:26:50So inverted branch of a tree that grows, typically
  15745. 12:26:53when it's drawn, downward instead of upward like a typical tree.
  15746. 12:26:56But that's something we could translate into code as well.
  15747. 12:26:59Specifically, let's do something called a binary search tree.
  15748. 12:27:02Which is a type of tree.
  15749. 12:27:04And what I mean by this is the following.
  15750. 12:27:07Notice this.
  15751. 12:27:07This is an example of an array from like week 2,
  15752. 12:27:10when we first talked about those.
  15753. 12:27:12And we had the lockers on stage.
  15754. 12:27:13And recall that what was nice about an array, if 1, it's sorted.
  15755. 12:27:19And 2, all of its numbers are indeed contiguous,
  15756. 12:27:23which is by definition an array.
  15757. 12:27:25We can just do some simple math.
  15758. 12:27:26For instance, if there are 7 elements in this array, and we do 7 divided by 2,
  15759. 12:27:31that's what?
  15760. 12:27:313 and 1/2, round down through truncation, that's 3.
  15761. 12:27:340, 1, 2, 3.
  15762. 12:27:36That gives me the middle element, arithmetically, in this thing.
  15763. 12:27:39And even though I have to be careful about rounding, using
  15764. 12:27:41simple arithmetic, I can very quickly, with a single line of code or math,
  15765. 12:27:45find for you the middle of the left half, of the left half,
  15766. 12:27:48of the right half, or whatever.
  15767. 12:27:49That's the power of arrays.
  15768. 12:27:50And that's what gave us binary search.
  15769. 12:27:52And how did binary search work?
  15770. 12:27:54Well, we looked at the middle.
  15771. 12:27:55And then, we went left or right.
  15772. 12:27:57And then, we went left or right again, implied by this color scheme here.
  15773. 12:28:02Wouldn't it be nice if we somehow preserved the new upsides
  15774. 12:28:07today of dynamic memory allocation, giving ourselves
  15775. 12:28:10the ability to just add another element, add another element,
  15776. 12:28:13add another element.
  15777. 12:28:14But retain the power of binary search.
  15778. 12:28:16Because log of n was much better than n, certainly for large data sets, right.
  15779. 12:28:21Even the phone book demonstrated as much weeks ago.
  15780. 12:28:24So what if I draw this same picture in 2 dimensions.
  15781. 12:28:28And I preserve the color scheme, just so it's obvious what came where.
  15782. 12:28:32What are these things look like now?
  15783. 12:28:35Maybe, like, things we might now call nodes, right.
  15784. 12:28:38A node is just a generic term for like, storing some data.
  15785. 12:28:42What if the data these nodes are storing are numbers.
  15786. 12:28:45So still integers.
  15787. 12:28:47But what if we connected these cleverly, like an old family tree.
  15788. 12:28:51Whereby, every node has not one pointer now, but as many as 2.
  15789. 12:28:56Maybe 0, like in the leaves at the bottom are in green.
  15790. 12:28:59But other nodes on the interior might have as many as 2.
  15791. 12:29:02Like having 2 children, so to speak.
  15792. 12:29:04And indeed, the vernacular here is exactly that.
  15793. 12:29:06This would be called the root of the tree.
  15794. 12:29:08Or this would be a parent, with respect to these children.
  15795. 12:29:11The green ones would be grandchildren, respect to these.
  15796. 12:29:14The green ones would be siblings with respect to each other.
  15797. 12:29:19And over there, too.
  15798. 12:29:19So all the same jargon you might use in the real world,
  15799. 12:29:22applies in the world of data structures and CS trees.
  15800. 12:29:25But this is interesting because I think we could build this now, this data
  15801. 12:29:30structure in the computer's memory.
  15802. 12:29:32How?
  15803. 12:29:33Well, suppose that we defined a node to be no longer just
  15804. 12:29:37this, a number in a next field.
  15805. 12:29:39What if we give ourselves a bit more room here?
  15806. 12:29:42And give ourselves a pointer called left and another one called right.
  15807. 12:29:47Both of which is a pointer to a struct node.
  15808. 12:29:49So same idea as before, but now we just make sure we think of these things
  15809. 12:29:53as pointing this way and this way, not just this way.
  15810. 12:29:56Not just a single direction, but 2.
  15811. 12:29:58So you could imagine, in code, building something up like this with a node.
  15812. 12:30:02That creates, in essence, this diagram here.
  15813. 12:30:06But why is this compelling?
  15814. 12:30:07Suppose I want to find the number 3.
  15815. 12:30:09I want to search for the number 3 in this tree.
  15816. 12:30:12It would seem, just like Pedro was the beginning of our linked list,
  15817. 12:30:15in the world of trees, the root, so to speak,
  15818. 12:30:18is the beginning of your data structure.
  15819. 12:30:20You can retain and remember this entire tree just by pointing at the root node,
  15820. 12:30:26ultimately.
  15821. 12:30:26One variable can hang on to this whole tree.
  15822. 12:30:29So how can I find the number 3?
  15823. 12:30:32Well, if I look at the root node and the number I'm looking for is less than.
  15824. 12:30:36Notice, I can go this way.
  15825. 12:30:37Or if it's greater than, I can go this way.
  15826. 12:30:40So I preserve that property of the phone book,
  15827. 12:30:42or just assorted array in general.
  15828. 12:30:44What's true over here?
  15829. 12:30:45If I'm looking for 3, I can go to the right of the 2
  15830. 12:30:48because that number is going to be greater.
  15831. 12:30:50If I go left, it's going to be smaller instead.
  15832. 12:30:53And here's an example of actually recursion.
  15833. 12:30:55Recursion in a physical sense much like the Mario's pyramid.
  15834. 12:30:59Which was recursively to find.
  15835. 12:31:01Notice this.
  15836. 12:31:02I claim this whole thing is a tree.
  15837. 12:31:04Specifically, a binary search tree, which means every node
  15838. 12:31:08has 2, or maybe 1, or maybe 0 children.
  15839. 12:31:11But no more than 2.
  15840. 12:31:12Hence the bi in binary.
  15841. 12:31:14And it's the case that every left child is smaller than the root.
  15842. 12:31:19And every right child is larger than the root.
  15843. 12:31:22That definition certainly works for 2, 4, and 6.
  15844. 12:31:25But it also works recursively for every sub tree, or branch of this tree.
  15845. 12:31:30Notice, if you think of this as the root,
  15846. 12:31:32it is indeed bigger than this left child.
  15847. 12:31:34And it's smaller than this right child.
  15848. 12:31:36And if you look even at the leaves, so to speak.
  15849. 12:31:39The grandchildren here.
  15850. 12:31:40This root node is bigger than its left child, if it existed.
  15851. 12:31:44So it's a meaningless statement.
  15852. 12:31:45And it's less than its right child.
  15853. 12:31:47Or it's not greater than, certainly, so that's meaningless too.
  15854. 12:31:50So we haven't violated the definition even for these leaves, as well.
  15855. 12:31:54And so, now, how many steps does it take to find in the worst case
  15856. 12:31:57any number in a binary search tree, it would seem?
  15857. 12:32:02So it seems 2, literally.
  15858. 12:32:04And the height of this thing is actually 3.
  15859. 12:32:05And so long story short, especially, if you're a little less comfy
  15860. 12:32:08with your logarithms from yesteryear.
  15861. 12:32:10Log base 2 is the number of times you can divide something in half, and half,
  15862. 12:32:14and half, until you get down to 1.
  15863. 12:32:16This is like a logarithm in the reverse direction.
  15864. 12:32:19Here's a whole lot of elements.
  15865. 12:32:20And we're having, we're having until we get down to 1.
  15866. 12:32:22So the height of this tree, that is to say, is log base 2 of n.
  15867. 12:32:27Which means that even in the worst case, the number you're looking for maybe
  15868. 12:32:30it's all the way at the bottom in the leaves.
  15869. 12:32:32Doesn't matter.
  15870. 12:32:32It's going to take log base 2 of n steps, or log of n steps,
  15871. 12:32:37to find, maximally, any one of those numbers.
  15872. 12:32:41So, again, binary search is back.
  15873. 12:32:46But we've paid a price, right.
  15874. 12:32:48This isn't a linked list anymore.
  15875. 12:32:49It's a tree.
  15876. 12:32:50But we've gained back binary search, which is pretty compelling, right.
  15877. 12:32:53That's where the whole class began, on making that distinction.
  15878. 12:32:56But what price have we paid to retain binary search in this new world.
  15879. 12:33:01Yeah.
  15880. 12:33:04It's no longer sorted left to right, but this
  15881. 12:33:06is a claim sorted, according to the binary search tree definition.
  15882. 12:33:09Where, again, left child is smaller than root.
  15883. 12:33:13And right child is greater than root.
  15884. 12:33:15So it is sorted, but it's sorted in a 2-dimensional sense, if you will.
  15885. 12:33:19Not just 1.
  15886. 12:33:20But another price paid?
  15887. 12:33:22AUDIENCE: [INAUDIBLE] nodes now.
  15888. 12:33:24SPEAKER 1: Exactly.
  15889. 12:33:24Every node now needs not one number, but 2, 3 pieces of data.
  15890. 12:33:29A number and now 2 pointers.
  15891. 12:33:31So, again, there's that trade off again.
  15892. 12:33:32Where, well, if you want to save time, you've
  15893. 12:33:34got to give something if you start giving space.
  15894. 12:33:37And you start using more space, you can speed up time.
  15895. 12:33:40Like, you've got it.
  15896. 12:33:40There's always a price paid.
  15897. 12:33:42And it's very often in space, or time, or complexity, or developer time,
  15898. 12:33:47the number of bugs you have to solve.
  15899. 12:33:49I mean, all of these are finite resources
  15900. 12:33:51that you have to juggle them on.
  15901. 12:33:53So if we consider now the code with which we can implement this,
  15902. 12:33:55here might be the node.
  15903. 12:33:57And how might we actually use something like this?
  15904. 12:34:00Well, let's take a look at, maybe, one final program.
  15905. 12:34:03And see here, before we transition to higher level concepts, ultimately.
  15906. 12:34:07Let me go ahead here and let me just open a program I wrote here in advance.
  15907. 12:34:11So let me, in a moment, copy over file called tree.c.
  15908. 12:34:15Which we'll have on the course's websites.
  15909. 12:34:18And I'll walk you through some of the logic
  15910. 12:34:20here that I've written for tree.c.
  15911. 12:34:25All right.
  15912. 12:34:25So what do we have here first?
  15913. 12:34:27So here is an implementation of a binary search tree for numbers.
  15914. 12:34:31And as before, I've played around and I've inserted the numbers manually.
  15915. 12:34:36So what's going on first?
  15916. 12:34:37Here is my definition of a node for a binary search tree, copied and pasted
  15917. 12:34:41from what I proposed on the board a moment ago.
  15918. 12:34:44Here are 2 prototypes for 2 functions, that I'll
  15919. 12:34:47show you in a moment, that allow me to free
  15920. 12:34:49an entire tree, one node at a time.
  15921. 12:34:52And then, also allow me to print the tree in order.
  15922. 12:34:55So even though they're not sorted left to right,
  15923. 12:34:57I bet if I'm clever about what child I print first,
  15924. 12:35:00I can reconstruct the idea of printing this tree properly.
  15925. 12:35:04So how might I implement a binary search tree?
  15926. 12:35:06Here's my main function.
  15927. 12:35:07Here is how I might represent a tree of size 0.
  15928. 12:35:10It's just a null pointer called tree.
  15929. 12:35:13Here's how I might add a number to that list.
  15930. 12:35:15So here, for instance, is me malllocing space for a node.
  15931. 12:35:19Storing it in a temporary variable called n.
  15932. 12:35:21Here is me just doing a safety check.
  15933. 12:35:23Make sure n does not equal null.
  15934. 12:35:25And then, here is me initializing this node to contain the number 2, first.
  15935. 12:35:29Then, initializing the left child of that node to be null.
  15936. 12:35:32And the right child of that null node to be null.
  15937. 12:35:34And then, initializing the tree itself to be equal to that particular node.
  15938. 12:35:40So at this point in the story, there's just one rectangle on the screen
  15939. 12:35:43containing the number 2 with no children.
  15940. 12:35:46All right.
  15941. 12:35:46Let's just add manually to this a little further.
  15942. 12:35:49Let's add another number to the list, by mallocing another node.
  15943. 12:35:52I don't need to declare n as a node* because it already exists at this
  15944. 12:35:55point.
  15945. 12:35:56Here's a little safety check.
  15946. 12:35:58I'm going to not bother with my, let me do this, free memory here.
  15947. 12:36:02Just to be safe.
  15948. 12:36:04Do I want to do this?
  15949. 12:36:07We want a free memory too, which I've not done here,
  15950. 12:36:09but I'll save that for another time.
  15951. 12:36:11Here, I'm going to initialize the number to 1.
  15952. 12:36:13I'm going to initialize the children of this node to null and null.
  15953. 12:36:17And now, I'm going to do this.
  15954. 12:36:19Initialize the tree's left child to be n.
  15955. 12:36:23So what that's essentially doing here is if this
  15956. 12:36:26is my root node, the single rectangle I described a moment ago that currently
  15957. 12:36:29has no children, neither left nor right.
  15958. 12:36:32Here's my new node with the number 1.
  15959. 12:36:33I want it to become the new left child.
  15960. 12:36:36So that line of code on the screen there, tree left equals n,
  15961. 12:36:39is like stitching these 2 together with a pointer from 2 to the 1.
  15962. 12:36:44All right.
  15963. 12:36:44The next lines of code, you can probably guess,
  15964. 12:36:47are me adding another number to the list.
  15965. 12:36:50Just the number 3.
  15966. 12:36:51So this is a simpler tree with 2, 1, and, 3 respectively.
  15967. 12:36:56And this code, let me wave my hands, is almost the same.
  15968. 12:36:59Except for the fact that I'm updating the tree's right child
  15969. 12:37:02to be this new and third node.
  15970. 12:37:04Let's now run the code before looking at those 2 functions.
  15971. 12:37:07Let me do make tree, ./tree.
  15972. 12:37:11And while I'll 1, 2, 3.
  15973. 12:37:12So it sounds like the data structure is sorted, to your concern earlier.
  15974. 12:37:16But how did I actually print this?
  15975. 12:37:18And then, eventually, free the whole thing?
  15976. 12:37:20Well let's look at the definition of first print tree.
  15977. 12:37:23And this is where things get interesting.
  15978. 12:37:26Print tree returns nothing so it's a void function.
  15979. 12:37:30But it takes a pointer to a root element as its sole argument, node* root.
  15980. 12:37:36Here's my safety check.
  15981. 12:37:37If root equals equals null, there's obviously
  15982. 12:37:39nothing to print, just return.
  15983. 12:37:40That goes without saying.
  15984. 12:37:42But here's where things get a little magical.
  15985. 12:37:44Otherwise, print your left child.
  15986. 12:37:47Then print your own number.
  15987. 12:37:50Then, print your right child.
  15988. 12:37:53What is this an example of, even though it's not mentioned by name here?
  15989. 12:37:59What programming technique here?
  15990. 12:38:00AUDIENCE: Recursion.
  15991. 12:38:01SPEAKER 1: Yeah.
  15992. 12:38:02So this is actually perhaps the most compelling use of recursion, yet.
  15993. 12:38:05It wasn't really that compelling with the Mario thing
  15994. 12:38:08because we had such an easy implementation with a for-loop loop
  15995. 12:38:10weeks ago.
  15996. 12:38:11But here is a perfect application of recursion, where your data structure
  15997. 12:38:15itself is recursive, right.
  15998. 12:38:17If you take any snip of any branch, it all
  15999. 12:38:19still looks like a tree, just a smaller one.
  16000. 12:38:22That lends itself to recursion.
  16001. 12:38:23So here is this leap of faith where I say, print my left tree, or my left sub
  16002. 12:38:28tree, if you will, via my child at the left.
  16003. 12:38:31Then, I'll print my own root node here in the middle.
  16004. 12:38:34Then, go ahead and print my right sub tree.
  16005. 12:38:37And because we have this base case that makes sure that if the root is null,
  16006. 12:38:41there's nothing to do, you're not going to recurse infinitely.
  16007. 12:38:44You're not going to call yourself again, and again, and again,
  16008. 12:38:47infinitely, many times.
  16009. 12:38:48So it works out and prints the 1, the 2, and the 3.
  16010. 12:38:52And notice what we could do, too.
  16011. 12:38:54If you wanted to print the tree in reverse order, you could do that.
  16012. 12:38:57Print your right tree first, the greater element.
  16013. 12:39:00Then, yourself.
  16014. 12:39:01Then, your smaller sub tree.
  16015. 12:39:02And if I do make tree here and ./tree, well now,
  16016. 12:39:05I've reversed the order of the list.
  16017. 12:39:07And that's pretty cool.
  16018. 12:39:08You can do it with a for-loop in an array.
  16019. 12:39:10But you can also do it, even with this 2-dimensional structure.
  16020. 12:39:13Let's lastly look at this free tree function.
  16021. 12:39:17And this one's almost the same.
  16022. 12:39:19Order doesn't matter in quite the same way, but it does still matter.
  16023. 12:39:22Here's what I did with free tree.
  16024. 12:39:24Well, if the root of the tree is null, there's obviously nothing to do.
  16025. 12:39:27Just return.
  16026. 12:39:28Otherwise, go ahead and free your left child and all of its descendants.
  16027. 12:39:32Then free your right child and all of its descendants.
  16028. 12:39:35And then, free yourself.
  16029. 12:39:37And again, free literally just frees the address in that variable.
  16030. 12:39:43It doesn't free the whole darn thing.
  16031. 12:39:45It just frees literally what's at that address.
  16032. 12:39:47Why was it important that I did line 72 last, though?
  16033. 12:39:51Why did I free the left child and the right child
  16034. 12:39:53before I freed myself, so to speak?
  16035. 12:39:57AUDIENCE: [INAUDIBLE].
  16036. 12:39:58SPEAKER 1: Exactly.
  16037. 12:39:59If you free yourself first, if I had done incorrectly this line higher up,
  16038. 12:40:03you're not allowed to touch the left child tree or the right child tree.
  16039. 12:40:08Because the memory address is no longer valid at that point.
  16040. 12:40:10You would get some memory error, perhaps.
  16041. 12:40:12The program would crash.
  16042. 12:40:13Valgrind definitely wouldn't like it.
  16043. 12:40:15Bad things would otherwise happen.
  16044. 12:40:17But here, then, is an example of recursion.
  16045. 12:40:19And again, just a recursive use of an actual data structure.
  16046. 12:40:23And what's even cooler here is, relatively speaking,
  16047. 12:40:26suppose we wanted to search something like this.
  16048. 12:40:29Binary search actually gets pretty straightforward to implement 2.
  16049. 12:40:33For instance.
  16050. 12:40:33here might be the prototype for a search function for a binary search tree.
  16051. 12:40:38You give me the root of a tree, and you give me a number I'm looking for,
  16052. 12:40:43and I can pretty easily now return true if it's in there or false if it's not.
  16053. 12:40:47How?
  16054. 12:40:47Well, let's first ask a question.
  16055. 12:40:49If tree equals equals null, then you just return false.
  16056. 12:40:52Because if there's no tree, there's no number, so it's obviously not there.
  16057. 12:40:56Return false.
  16058. 12:40:57Else if, the number you're looking for is less than the tree's own number,
  16059. 12:41:04which direction should we go?
  16060. 12:41:06AUDIENCE: Left.
  16061. 12:41:06SPEAKER 1: OK, left.
  16062. 12:41:07How do we express that?
  16063. 12:41:08Well, let's just return the answer to this question.
  16064. 12:41:11Search the left sub tree, by way of my left child,
  16065. 12:41:15looking for the same number.
  16066. 12:41:17And you just assume through the beauty of recursion
  16067. 12:41:19that you're kicking the can and let yourself figure it out
  16068. 12:41:22with a smaller problem.
  16069. 12:41:24Just that snipped left tree instead.
  16070. 12:41:26Else if, the number you're looking for is greater than the tree's own number,
  16071. 12:41:30go to the right, as you might infer.
  16072. 12:41:32So I can just return the answer to this question.
  16073. 12:41:35Search my right sub tree for that same number.
  16074. 12:41:38And there's a fourth and final condition.
  16075. 12:41:40What's the fourth scenario we have to consider, explicitly?
  16076. 12:41:43Yeah.
  16077. 12:41:44AUDIENCE: The number.
  16078. 12:41:45SPEAKER 1: If the number, itself, is right there.
  16079. 12:41:47So else if, the number I'm looking for equals the tree's own number,
  16080. 12:41:50then and only then, should you return true.
  16081. 12:41:53And if you're thinking quickly here, there's
  16082. 12:41:55an optimization possible, better design opportunity.
  16083. 12:41:59Think back to even our scratch days.
  16084. 12:42:01What could we do a little better here?
  16085. 12:42:03You're pointing at it.
  16086. 12:42:04AUDIENCE: Else.
  16087. 12:42:04SPEAKER 1: Exactly.
  16088. 12:42:05An else suffices.
  16089. 12:42:06Because if there's logically only 4 things that could happen,
  16090. 12:42:09you're wasting your time by asking a fourth gratuitous question.
  16091. 12:42:12And else here suffices.
  16092. 12:42:13So here to, more so than the Mario example a few weeks ago,
  16093. 12:42:16there's just this elegance arguably to recursion.
  16094. 12:42:19And that's it.
  16095. 12:42:20This is not pseudocode.
  16096. 12:42:21This is the code for binary search on a binary search tree.
  16097. 12:42:25And so, recursion tends to work in lockstep
  16098. 12:42:27with these kinds of data structures that have this structure to them
  16099. 12:42:32as we're seeing here.
  16100. 12:42:33All right.
  16101. 12:42:34Any questions, then, on binary search as implemented here with a tree?
  16102. 12:42:39Yeah.
  16103. 12:42:40AUDIENCE: About like third years.
  16104. 12:42:42[INAUDIBLE]
  16105. 12:42:47SPEAKER 1: Good question.
  16106. 12:42:48So when returning a Boolean value, true and false are values that are defined
  16107. 12:42:54in a library called Standard Bool, S-T-D-B-O-O-L dot H.
  16108. 12:42:57With a header file that you can use.
  16109. 12:42:59It is the case that true is, it's not well defined what they are.
  16110. 12:43:06But they would map indeed, yes.
  16111. 12:43:08To 0 and 1, essentially.
  16112. 12:43:09But you should not compare them explicitly to 0 and 1.
  16113. 12:43:11When you're using true and false, you should compare them to each other.
  16114. 12:43:14AUDIENCE: I meant if it's in a code return.
  16115. 12:43:18SPEAKER 1: Oh, sorry.
  16116. 12:43:19So if I am in my own code from earlier, an avoid function,
  16117. 12:43:23it is totally fine to return.
  16118. 12:43:25You just can't return something explicitly.
  16119. 12:43:28So return just means that's it.
  16120. 12:43:30Quit out of this function.
  16121. 12:43:31You're not actually handing back a value.
  16122. 12:43:33So it's a way of short circuiting the execution.
  16123. 12:43:37If you don't like that, and some people do frown
  16124. 12:43:39upon having code return from functions prematurely, you could invert the logic
  16125. 12:43:44and do something like this.
  16126. 12:43:45If the root does not equal null, do all of these things.
  16127. 12:43:49And then, indent all three of these lines underneath.
  16128. 12:43:51That's perfectly fine too.
  16129. 12:43:52I happen to write it the other way just so
  16130. 12:43:54that there was explicitly a base case that I could point to on the screen.
  16131. 12:43:58Whereas, now, it's implicitly there for us only.
  16132. 12:44:01But a good observation too.
  16133. 12:44:03All right.
  16134. 12:44:03So let's ask the question as before about running time of this.
  16135. 12:44:07It would look like binary search is back.
  16136. 12:44:09And we can now do things in logarithmic time, but we should be careful.
  16137. 12:44:15Is this a binary search tree?
  16138. 12:44:17Just to be clear.
  16139. 12:44:19And again, a binary search tree is a tree
  16140. 12:44:21where the root is greater than its left child and smaller than its right child.
  16141. 12:44:28That's the essence.
  16142. 12:44:29So you're nodding your head.
  16143. 12:44:30You agree?
  16144. 12:44:32I agree.
  16145. 12:44:33So this is a binary search tree.
  16146. 12:44:35Is this a binary search tree?
  16147. 12:44:37[INTERPOSING VOICES]
  16148. 12:44:38OK.
  16149. 12:44:39I'm hearing yeses.
  16150. 12:44:40Or I'm hearing just my delay changing the vote it would seem.
  16151. 12:44:43So this is one of those trick questions.
  16152. 12:44:45This is a binary search tree because I've not
  16153. 12:44:47violated the definition of what I gave you, right.
  16154. 12:44:50Is there any example of a left child that is greater than its parent?
  16155. 12:44:56Or is there any example of a right child that's smaller than its parent?
  16156. 12:44:59That's just the opposite way of describing the same thing.
  16157. 12:45:02No, this is a binary search tree.
  16158. 12:45:04Unfortunately, it also looks like, albeit at a different axis, what?
  16159. 12:45:07AUDIENCE: A linked list.
  16160. 12:45:08SPEAKER 1: A linked list.
  16161. 12:45:09But you could imagine this happening, right.
  16162. 12:45:11Suppose that I hadn't been as thoughtful as I was earlier
  16163. 12:45:14by inserting 2, And then 1, and then 3.
  16164. 12:45:17Which nicely balanced everything out.
  16165. 12:45:19Suppose that instead, because of what the user is typing in
  16166. 12:45:22or whatever you contrive in your own code, suppose you insert a 1,
  16167. 12:45:25and then a 2, and then a 3.
  16168. 12:45:27Like, you've created a problem for yourself.
  16169. 12:45:30Because if we follow the same logic as before, going left or going right,
  16170. 12:45:33this is how you might implement a binary search tree accidentally
  16171. 12:45:38if you just blindly keep following that definition.
  16172. 12:45:42I mean, this would be better designed as what?
  16173. 12:45:44If we rotated the whole thing around.
  16174. 12:45:46And that's totally fine.
  16175. 12:45:48And those kinds of trees actually have names.
  16176. 12:45:50There's trees called AVL trees in computer science.
  16177. 12:45:52There are red-black black trees in computer science.
  16178. 12:45:54There are other types of trees that, additionally,
  16179. 12:45:56add some logic that tell you when you got to pivot the thing,
  16180. 12:45:59and rotate it, and snip off the root, and fix things in this way.
  16181. 12:46:03But a binary search tree, in and of itself,
  16182. 12:46:05does not guarantee that it will be balanced, so to speak.
  16183. 12:46:09And so, if you consider the worst case scenario
  16184. 12:46:11of even using a binary search tree.
  16185. 12:46:13If you're not smart about the code you're writing
  16186. 12:46:15and you just blindly follow this definition,
  16187. 12:46:17you might accidentally create a crazy, long and stringy binary search
  16188. 12:46:21tree that essentially looks like a linked list.
  16189. 12:46:24Because you're not even using any of the left children.
  16190. 12:46:26So unfortunately, the literal answer to the question
  16191. 12:46:30here is what's the running time of search?
  16192. 12:46:32Well, hopefully, log n.
  16193. 12:46:34But not if you don't maintain the balance of the tree.
  16194. 12:46:37Both, in certain search, could actually devolve into instead of big O of log n,
  16195. 12:46:42literally, big O of n.
  16196. 12:46:44If you don't somehow take into account, and we're not
  16197. 12:46:46going to do the code for that here.
  16198. 12:46:48It's a higher level thing you might explore down the road.
  16199. 12:46:51It can devolve into something that you might not have intended.
  16200. 12:46:55And so, now that we're talking about 2 dimensions,
  16201. 12:46:57it's really the onus is on the programmer
  16202. 12:46:59to consider what kinds of perverse situations might happen.
  16203. 12:47:01Where the thing devolves into a structure
  16204. 12:47:04that you don't actually want it to devolve into.
  16205. 12:47:07All right.
  16206. 12:47:08We've got just a few structures to go.
  16207. 12:47:09Let's go ahead and take one more 5 minute break here.
  16208. 12:47:11When we come back, we'll talk at this level
  16209. 12:47:12about some final applications of this.
  16210. 12:47:14See you in 5.
  16211. 12:47:15All right.
  16212. 12:47:17So we are back.
  16213. 12:47:19And as promised, we'll operate now at this higher level.
  16214. 12:47:22Where if we take for granted that, even though you haven't had an opportunity
  16215. 12:47:26to play with these techniques yet, you have the ability now in code
  16216. 12:47:28to stitch things together.
  16217. 12:47:30Both in a one dimension and even 2 dimensions,
  16218. 12:47:33to build things like lists and trees.
  16219. 12:47:35So if we have these building blocks.
  16220. 12:47:37Things like now arrays, and lists, and trees,
  16221. 12:47:40what if we start to amalgamate them such that we build things out
  16222. 12:47:44of multiple data structures?
  16223. 12:47:46Can we start to get some of the best of both worlds by way of, for instance,
  16224. 12:47:49something called a hash table.
  16225. 12:47:51So a hash table is a Swiss army knife of data structures
  16226. 12:47:55in that it's so commonly used.
  16227. 12:47:56Because it allows you to associate keys with value, so to speak.
  16228. 12:48:01So, for instance, it allows you to associate a username with a password.
  16229. 12:48:06Or a name with a number.
  16230. 12:48:08Or anything where you have to take something as input,
  16231. 12:48:11and get as output a corresponding piece of information.
  16232. 12:48:13A hash table is often a data structure of choice.
  16233. 12:48:16And here's what it looks like.
  16234. 12:48:17It's actually looks like an array, at first glance.
  16235. 12:48:20But for discussion's sake, I've drawn this array vertically,
  16236. 12:48:23which is totally fine.
  16237. 12:48:24It's still just an array.
  16238. 12:48:26But it allows you, a hash table, to jump to any of these locations randomly.
  16239. 12:48:31That is instantly.
  16240. 12:48:32So, for instance, there's actually 26 locations in this array.
  16241. 12:48:35Because I want to, for instance, store initially
  16242. 12:48:38names of people, for instance.
  16243. 12:48:41And wouldn't it be nice if the person's name starts with A,
  16244. 12:48:44I have a go to place for it.
  16245. 12:48:45Maybe the first box.
  16246. 12:48:46And if it starts with Z, I put them at the bottom.
  16247. 12:48:48So that I can jump instantly, arithmetically,
  16248. 12:48:50using a little bit of Ascii or Unicode fanciness,
  16249. 12:48:52exactly to the location that they want to they need to go.
  16250. 12:48:56So, for instance, here's our array 0 index.
  16251. 12:48:580 through 25.
  16252. 12:48:59If I think of this, though, as A through Z,
  16253. 12:49:01I'm going to think of these 26 locations,
  16254. 12:49:03now in the context of a hash table, is what we'll generally call buckets.
  16255. 12:49:07So buckets into which you can put values.
  16256. 12:49:09So, for instance, suppose that we want to insert a value, one name
  16257. 12:49:13into this data structure.
  16258. 12:49:15And that name is say, Albus.
  16259. 12:49:16So Albus starting with A. Albus might go at the very beginning of this list.
  16260. 12:49:21All right.
  16261. 12:49:21And then, we want to insert another name.
  16262. 12:49:23This one happens to be Zacharias.
  16263. 12:49:25Starting with Z, so it goes all the way at the end of this data
  16264. 12:49:28structure in location 25 a.k.a.
  16265. 12:49:29Z.
  16266. 12:49:30And then, maybe a third name like Hermione, and that goes at location H
  16267. 12:49:34according to that position in the alphabet.
  16268. 12:49:36So this is great because in constant time,
  16269. 12:49:39I can insert and conversely search for any of these names,
  16270. 12:49:43based on the first letter of their name.
  16271. 12:49:45A, or Z, or H, in this case.
  16272. 12:49:47Let's fast forward and assume we put a whole bunch of other names--
  16273. 12:49:50might look familiar, into this hash table.
  16274. 12:49:52It's great because every name has its own location.
  16275. 12:49:56But if you're thinking of names you don't yet see it on the screen,
  16276. 12:50:00we eventually encounter a problem with this, right.
  16277. 12:50:03When could something go wrong using a hash table like this
  16278. 12:50:06if we wanted to insert even more names?
  16279. 12:50:09What's going to eventually happen?
  16280. 12:50:11Yeah.
  16281. 12:50:12There's already someone with the first letter, right.
  16282. 12:50:14Like I haven't even mentioned Harry, for instance, or Hagrid.
  16283. 12:50:17And yet, Hermione's already using that spot.
  16284. 12:50:19So that invites the question, well, what happens?
  16285. 12:50:21Maybe, if we want to insert Harry next, do we maybe cheat and put him
  16286. 12:50:25at location I?
  16287. 12:50:26But then if there's a location I, where do we put them?
  16288. 12:50:28And it just feels like the situation could very quickly devolve.
  16289. 12:50:31But I've deliberately drawn this data structure,
  16290. 12:50:34that I claim as a hash table, in 2 directions.
  16291. 12:50:37An array vertically, here.
  16292. 12:50:39But what might this be hinting I'm using horizontally,
  16293. 12:50:42even though I'm drawing the rectangles a little differently from before?
  16294. 12:50:45AUDIENCE: An array.
  16295. 12:50:46SPEAKER 1: Yeah.
  16296. 12:50:47Maybe another array, to be fair.
  16297. 12:50:48But, honestly, arrays are such a pain with the allocating, and reallocating,
  16298. 12:50:51and so forth.
  16299. 12:50:52These look like the beginnings of a linked list, if you will.
  16300. 12:50:56Where the name is where the number used to be, even though I'm drawing it
  16301. 12:50:59horizontally now just for discussion's sake.
  16302. 12:51:01And this seems to be a pointer that isn't pointing anywhere yet.
  16303. 12:51:05But it looks like the array is 26 pointers, some of which are null,
  16304. 12:51:10that is empty.
  16305. 12:51:11Some of which are pointing at the first node in a linked list.
  16306. 12:51:14So that's really what a hash table might be in your mind.
  16307. 12:51:16An amalgam of an array, whose elements are linked lists.
  16308. 12:51:21And in theory, this gives you the best of both worlds, right.
  16309. 12:51:23You get random access with high probability, right.
  16310. 12:51:26You get to jump immediately to the location you want to put someone.
  16311. 12:51:30But, if you run into this perverse situation where there's someone
  16312. 12:51:32already there, OK, fine.
  16313. 12:51:34It starts to devolve into a linked list, but it's at least 26
  16314. 12:51:37smaller length lists.
  16315. 12:51:39Not one massive linked list, which would be Big O of n.
  16316. 12:51:42And quite slow to solve.
  16317. 12:51:43So if Harry gets inserted in Hagrid.
  16318. 12:51:46Yeah, you have to chain them together, so to speak, in this way.
  16319. 12:51:50But, at least you've not painted yourself into a corner.
  16320. 12:51:53And in fact, if we fast forward and put a whole bunch of familiar names in,
  16321. 12:51:56the data structure starts to look like this.
  16322. 12:51:58So the chains not terribly long.
  16323. 12:52:00And some of them are actually of size 0 because there's just
  16324. 12:52:03some unpopular letters of the alphabet among these names.
  16325. 12:52:06But it seems better than just putting everyone
  16326. 12:52:08in one big array, or one big linked list.
  16327. 12:52:11We're trying to balance these trade offs a little bit in the middle here.
  16328. 12:52:15Well, how might we represent something like this?
  16329. 12:52:17Here's how we could describe this thing.
  16330. 12:52:19A node in the context of a linked list could be this.
  16331. 12:52:22I have an array called word of type char.
  16332. 12:52:26And it's big enough to fit the longest word in the alphabet plus 1.
  16333. 12:52:30And the plus 1 why, probably?
  16334. 12:52:32AUDIENCE: The null.
  16335. 12:52:33SPEAKER 1: The null character.
  16336. 12:52:34So I'm assuming that longest word is like a constant defined elsewhere
  16337. 12:52:37in the story.
  16338. 12:52:37And it's something big like 40, 100, whatever.
  16339. 12:52:40Whatever the longest word in the Harry Potter universe
  16340. 12:52:43is or the English dictionary is.
  16341. 12:52:45Longest word plus 1 should be sufficient to store any name in the story here.
  16342. 12:52:51And then, what else does it each of these nodes have?
  16343. 12:52:53Well it has a pointer to another node.
  16344. 12:52:57So here's how we might implement the notion of a node
  16345. 12:52:59in the context of storing not integers, but names.
  16346. 12:53:04Instead, like this.
  16347. 12:53:05But how do we decide what the hash table itself is?
  16348. 12:53:08Well, if we now have a definition of a node, we could have a variable in main,
  16349. 12:53:12or even globally, called hash table.
  16350. 12:53:14That itself is an array of node* pointers.
  16351. 12:53:20That is an array of pointers to nodes.
  16352. 12:53:22The beginnings of linked lists.
  16353. 12:53:24Number of buckets is to me.
  16354. 12:53:26I proposed, verbally, that it be 26.
  16355. 12:53:28But honestly, if you get a lot of collisions, so to speak.
  16356. 12:53:30A lot of H names trying to go to the same place.
  16357. 12:53:33Well, maybe, we need to be smarter and not just look
  16358. 12:53:35at the first letter of their name.
  16359. 12:53:36But, maybe, the first and the second.
  16360. 12:53:38So it's H-A and H-E. But wait, no, then Harry and Hagrid still collide.
  16361. 12:53:42But we start to at least make the problem a little less
  16362. 12:53:45impactful by tinkering with something like the number of buckets
  16363. 12:53:48in a hash table like this.
  16364. 12:53:50But how do we decide where someone goes in a hash table in this way?
  16365. 12:53:55Well, it's an old school problem of input and output.
  16366. 12:53:57The input to the problem is going to be something like the name.
  16367. 12:54:00And the algorithm in the middle, as of today,
  16368. 12:54:02is going to be something called a hash function.
  16369. 12:54:05A hash function is generally something that
  16370. 12:54:07takes as input, a string, a number, whatever, and produces
  16371. 12:54:10as output a location in our context.
  16372. 12:54:13Like a number 0 through 25.
  16373. 12:54:15Or 0 through 16,000.
  16374. 12:54:16Or whatever the number of buckets you want is,
  16375. 12:54:19it's going to just tell you where to put that input at a specific location.
  16376. 12:54:23So, for instance, Albus, according to the story thus far, gave me back to 0
  16377. 12:54:27as output.
  16378. 12:54:28Zacharias gave me 25.
  16379. 12:54:30So the hash function, in the middle of that black box,
  16380. 12:54:32is pretty simplistic in this story.
  16381. 12:54:35It's just looking at the Ascii value, it seems, of the first letter
  16382. 12:54:38in their name.
  16383. 12:54:39And then, subtracting off what capital A is 65.
  16384. 12:54:42So like doing some math to get back in number between 0 and 25.
  16385. 12:54:46So that's how we got to this point in the story.
  16386. 12:54:50And how might we, then, resolve the problem further and use
  16387. 12:54:54this notion of hashing more generally?
  16388. 12:54:56Well just for demonstration sake here, here's
  16389. 12:54:58actually some buckets, literally.
  16390. 12:55:00And we've labeled, in advance, these buckets with the suits
  16391. 12:55:03from a deck of cards.
  16392. 12:55:05So we've got some spades.
  16393. 12:55:07And we've got diamonds here.
  16394. 12:55:12And we've got, what else here?
  16395. 12:55:15Clubs and hearts.
  16396. 12:55:19So we have a deck of cards here, for instance, right.
  16397. 12:55:22And this is something you, yourself, might do instinctively
  16398. 12:55:24if you're getting ready to start playing a game of cards.
  16399. 12:55:26You're just cleaning up or you want things in order.
  16400. 12:55:29Like, here is literally a jumbo deck of cards.
  16401. 12:55:31What would be the easiest way for me to sort these things?
  16402. 12:55:33Well we've got a whole bunch of sorting algorithms from the past.
  16403. 12:55:36So I could go through like, here's the 3 of diamonds.
  16404. 12:55:39And I could, here let me throw this up on the screen.
  16405. 12:55:41Just so, if you're far in back.
  16406. 12:55:43So here's diamonds.
  16407. 12:55:45I could put this here.
  16408. 12:55:463, 4.
  16409. 12:55:47I could do this in order here.
  16410. 12:55:49But a lot of us, honestly, if given a deck of cards.
  16411. 12:55:52And you just want to clean it up and sort it in order,
  16412. 12:55:54you might do things like this.
  16413. 12:55:56Well here's my input, 3 of diamonds, let's put it in this bucket.
  16414. 12:55:594 of diamonds, this bucket.
  16415. 12:56:015 of diamonds, this bucket.
  16416. 12:56:03And if you keep going through the cards, here's seven of hearts, hearts bucket.
  16417. 12:56:068's bucket.
  16418. 12:56:08Queen of spades over here.
  16419. 12:56:10And it's still going to take you 52 steps.
  16420. 12:56:12But at the end of it, you have hashed all of the cards
  16421. 12:56:15into 4 distinct buckets.
  16422. 12:56:17And now you have problems of size 13, which
  16423. 12:56:19is a little more tenable than doing one massive 52 card problem.
  16424. 12:56:23You can now do 4, 13 size problems.
  16425. 12:56:25And so hashing is something that even you and I might do instinctively.
  16426. 12:56:29Taking as input some card, some name, and producing as output some location.
  16427. 12:56:34A temporary pile in which you want to stage things, so to speak.
  16428. 12:56:39But these collisions are inevitable.
  16429. 12:56:41And honestly, if we kept going through the Harry Potter universe,
  16430. 12:56:44some of these chains would get longer, and longer and longer.
  16431. 12:56:47Which means that instead of getting someone's name quickly,
  16432. 12:56:50by searching for them or inserting them, might
  16433. 12:56:53start taking a decent amount of time.
  16434. 12:56:55So what could we do instead to resolve situations like this?
  16435. 12:56:58If the problem, fundamentally, is that the first letter is just too darn
  16436. 12:57:01popular, H, we need to take in more input.
  16437. 12:57:04Not just the first letter but maybe the first 2 letters.
  16438. 12:57:07So if we do that, we can go from A through Z
  16439. 12:57:10to something more extreme like maybe H-A, H-B, H-C, H-D, H-F, and so forth.
  16440. 12:57:16So that now Harry and Hermione end up at different locations.
  16441. 12:57:20But, darn it, Hagrid still collides with Harry.
  16442. 12:57:23So it's better than before.
  16443. 12:57:24The chains aren't quite as long.
  16444. 12:57:27But the problem isn't fundamentally gone.
  16445. 12:57:28And in this case here, anyone know how many buckets we just
  16446. 12:57:32increased to, if we now look at not just a through Z but AA through ZZ, roughly?
  16447. 12:57:40AUDIENCE: 26 squared.
  16448. 12:57:41SPEAKER 1: Yeah.
  16449. 12:57:42OK, good.
  16450. 12:57:42So the easy answer to 26 squared are 676.
  16451. 12:57:46So that's a lot more buckets.
  16452. 12:57:48And this is why I only showed a few of them on the screen.
  16453. 12:57:50So that's a lot more.
  16454. 12:57:51And it spreads things out in particular.
  16455. 12:57:54What if we take this one step further?
  16456. 12:57:56Instead of H-A, we do like H-A-A, H-A-B, H-A-C, H-Z-Z, and so forth.
  16457. 12:58:01Well now, we have an even better situation.
  16458. 12:58:03Because Hermoine has her one spot.
  16459. 12:58:05Harry has his one spot.
  16460. 12:58:07Hagrid has his one spot.
  16461. 12:58:09But there's a trade off here.
  16462. 12:58:11The upside is now, arithmetically, we can find their locations
  16463. 12:58:14in constant time.
  16464. 12:58:16Maybe, technically 3 steps.
  16465. 12:58:17But 3 is constant, no matter how many other names are in here, it would seem.
  16466. 12:58:21But what's the downside here?
  16467. 12:58:24Sorry, say again.
  16468. 12:58:25AUDIENCE: Memory.
  16469. 12:58:25SPEAKER 1: Memory.
  16470. 12:58:26So significantly more.
  16471. 12:58:27We're now up to 17,576 buckets, which itself isn't that big a deal, right.
  16472. 12:58:33Computers have a lot of memory these days.
  16473. 12:58:35But as you can infer, I can't really think
  16474. 12:58:38of someone whose name started with H-E-Q, for instance, in the Harry
  16475. 12:58:43Potter universe.
  16476. 12:58:44And if we keep going, definitely don't know of anyone
  16477. 12:58:46whose name started with Z-Z-Z or A-A-A. There's
  16478. 12:58:49a lot of not useful combinations that have to be there mathematically,
  16479. 12:58:54so that you can do a bit of math and jump to randomly, so to speak,
  16480. 12:58:58the precise location.
  16481. 12:58:59But they're just going to be empty.
  16482. 12:59:01So it's a very sparsely populated array, so to speak.
  16483. 12:59:04So what does that really mean for performance, ultimately?
  16484. 12:59:08Well let's consider, again, in the context of our Big O notation.
  16485. 12:59:10It turns out that a hash table, technically speaking,
  16486. 12:59:14is still just going to give us Big O of n in the worst case.
  16487. 12:59:18Why?
  16488. 12:59:18If you have some crazy perverse case where everyone in the universe
  16489. 12:59:21has a name that starts with A, or starts with H, or starts with Z,
  16490. 12:59:25you just get really unlucky.
  16491. 12:59:26And your chain is massively long.
  16492. 12:59:28Well then, at that point, it's just a linked list.
  16493. 12:59:30It's not a hash table.
  16494. 12:59:31It's like the perverse situation with the tree, where
  16495. 12:59:33if you insert it without any mind for keeping it balance, it just evolves.
  16496. 12:59:39But there's a difference here between a theoretical performance
  16497. 12:59:43and an actual performance.
  16498. 12:59:45If you look back at the the hash table here,
  16499. 12:59:48this is absolutely, in practice, going to be faster than a single linked list.
  16500. 12:59:55Mathematically, asymptotically, big O notation, sure.
  16501. 12:59:58It's all the same.
  16502. 12:59:59Big O of n.
  16503. 13:00:00But if what we're really caring about is real humans using our software,
  16504. 13:00:03there's something to be said for crafting a data structure.
  16505. 13:00:06That technically, if this data were uniformly distributed,
  16506. 13:00:09is 26 times faster than a linked list alone.
  16507. 13:00:12And so, there's this tension too between systems, types of CS,
  16508. 13:00:18and theoretical CS.
  16509. 13:00:19Where yeah, theoretically, these are all the same.
  16510. 13:00:21But in practice, for making real-world software,
  16511. 13:00:24improving this speed by a factor of 26 in this case, let alone 576 or more,
  16512. 13:00:29might actually make a big difference.
  16513. 13:00:31But there's going to be a trade off.
  16514. 13:00:33And that's typically some other resource like giving up more space.
  16515. 13:00:37All right.
  16516. 13:00:37How about another data structure we could build.
  16517. 13:00:40Let me fast forward to something here called a trie.
  16518. 13:00:43So a trie, a weird name in pronunciation.
  16519. 13:00:46Short for retrieval, pronounced trie typically.
  16520. 13:00:49A trie is a tree that actually gives us constant time lookup,
  16521. 13:00:55even for massive data sets.
  16522. 13:00:58What do I mean by this?
  16523. 13:00:59In the world of a trie, you create a tree out of arrays.
  16524. 13:01:04So we're really getting into the Frankenstein territory
  16525. 13:01:07of just building things up with spare parts of data structures
  16526. 13:01:09that we have here.
  16527. 13:01:10But the root of a trie is, itself, an array.
  16528. 13:01:13For instance, of size 26.
  16529. 13:01:16Where each element in that trie points to another node,
  16530. 13:01:22which is to say another array.
  16531. 13:01:23And each of those locations in the array represents a letter
  16532. 13:01:26of the alphabet like A through Z.
  16533. 13:01:28So for instance, if you wanted to store the names of the Harry Potter universe,
  16534. 13:01:32not in a hash table, not in a linked list, not in a tree, but in a trie.
  16535. 13:01:36What you would do is hash on every letter in the person's name one
  16536. 13:01:41at a time.
  16537. 13:01:42So a trie is like a multi-tier hash table, in a sense.
  16538. 13:01:45Where you first look at the first letter,
  16539. 13:01:47then the second letter, then the third, and you do the following.
  16540. 13:01:49For instance, each of these locations represents a letter A
  16541. 13:01:53through Z. Suppose I wanted to insert someone's name into this
  16542. 13:01:56that starts with the letter H, like Hagrid for instance.
  16543. 13:02:01Well, I go to the location H. I see it's null,
  16544. 13:02:03which means I need to malloc myself another node or another array.
  16545. 13:02:06And that's depicted here.
  16546. 13:02:08Then, suppose I want to store the second letter in Hagrid's name,
  16547. 13:02:12an A. So I go to that location in the second node.
  16548. 13:02:14And I see, OK, it's currently null.
  16549. 13:02:16There's nothing below it.
  16550. 13:02:17So I allocate another node using malloc or the like.
  16551. 13:02:19And now I have H-A-G. And I continue this with R-I-D.
  16552. 13:02:24And then, when I get to the bottom of this person's name,
  16553. 13:02:27I just have to indicate here in color, but probably
  16554. 13:02:30with a Boolean value or something.
  16555. 13:02:31Like a true value that says, a name stops here.
  16556. 13:02:35So that it's clear that the person's name is not H-A, or H-A-G, or H-A-G-R,
  16557. 13:02:41or H-A-G-R-I. It's H-A-G-R-I-D. And the D is green,
  16558. 13:02:45just to indicate there's like some other Boolean value that just says, yes.
  16559. 13:02:49This is the node in which the name stops.
  16560. 13:02:52And if I continue this logic, here's how I might insert someone like Harry.
  16561. 13:02:57And here's how I might insert someone like Hermione.
  16562. 13:03:00And what's interesting about the design here is that some of these names
  16563. 13:03:05share a common prefix.
  16564. 13:03:07Which starts to get compelling because you're reusing space.
  16565. 13:03:10You're using the same nodes for names like H-A-G and H-A-R
  16566. 13:03:15because they share H and an A in common.
  16567. 13:03:17And they all share an H in common.
  16568. 13:03:20So you have this data structure now that, itself, is a tree.
  16569. 13:03:23Each node in the tree is, itself, an array.
  16570. 13:03:27And we, therefore, might implement this thing using code like this.
  16571. 13:03:31Every node is containing, I'll do it in reverse order, an array.
  16572. 13:03:36I'll call it children because that's what it really represents.
  16573. 13:03:39Up to 26 children for each of these nodes.
  16574. 13:03:41Size of the alphabet.
  16575. 13:03:42So I might have used just a constant for number 26,
  16576. 13:03:45to give myself 26 letters of the alphabet.
  16577. 13:03:47And each of those arrays stores that many node stars.
  16578. 13:03:52That many pointers to another node.
  16579. 13:03:54And here's an example of the Bool.
  16580. 13:03:55This is what I represented in green on the slide a moment ago.
  16581. 13:03:58I also need another piece of data.
  16582. 13:04:00Just a 0 or 1, a true or false, that says yes.
  16583. 13:04:03A name stops in this node or it's just a path to the rest of the person's name.
  16584. 13:04:08But the upside of this is that the height of this tree
  16585. 13:04:12is only as tall as the person's longest name.
  16586. 13:04:15H-A-G-R-I-D or H-E-R-M-O-I-N-E. And notice that no matter how many other
  16587. 13:04:22people are in this data structure, there's 3 at the moment,
  16588. 13:04:26if there were 3 million, it would still take me how many steps to search
  16589. 13:04:30for Hermoine?
  16590. 13:04:31H-E-R-M-I-O-N-E. So, 8 steps total.
  16591. 13:04:37No matter if there's 2 other people, 2 million, 10 million other people.
  16592. 13:04:42Because the path to her name is always on the same path.
  16593. 13:04:46And if you assume that there's a maximum limit on the length of names
  16594. 13:04:51in the human world.
  16595. 13:04:51Maybe it's 40, 100, whatever.
  16596. 13:04:53Whatever the longest name in the world is.
  16597. 13:04:55That's constant.
  16598. 13:04:56Maybe it's 40, 100, but that's constant.
  16599. 13:04:59Which is to say that with a trie, technically speaking,
  16600. 13:05:02it is the case that your lookup time, Big O of n, a big O notation,
  16601. 13:05:06would be big O of 1.
  16602. 13:05:09It's constant time, because unlike every other data structure
  16603. 13:05:12we've looked at, with a trie, the amount of time it takes you to find one person
  16604. 13:05:16or insert one person is completely independent of how
  16605. 13:05:20many other pieces of data are already in the data structure.
  16606. 13:05:24And this holds true even if one name is a prefix of another.
  16607. 13:05:27I don't think there was a Daniel or Danielle in the Harry Potter universe
  16608. 13:05:30that I could think of.
  16609. 13:05:31But, D-A-N-I-E-L could be one name.
  16610. 13:05:35And, therefore, we have a true there in green.
  16611. 13:05:38And if there's a longer name like Danielle.
  16612. 13:05:40Then, you keep going until you get to the E.
  16613. 13:05:42So you can still have with a trie, one name that's
  16614. 13:05:45a substring of another name.
  16615. 13:05:47So it's not as though we've created a problem there.
  16616. 13:05:49That, too, is still possible.
  16617. 13:05:51But at the end of the day, it only takes a finite number of steps
  16618. 13:05:54to find any of these people.
  16619. 13:05:55And again, that's what's particularly compelling.
  16620. 13:05:58That you effectively have constant time lookup.
  16621. 13:06:00So that's amazing, right.
  16622. 13:06:01We've gone through this whole story for weeks now of like, linear time.
  16623. 13:06:05And then, it went up to n squared.
  16624. 13:06:07And then, log n.
  16625. 13:06:07And now constant time, what's the price paid for a data structure like this?
  16626. 13:06:12This so-called trie?
  16627. 13:06:16What's the downside here?
  16628. 13:06:17There's got to be a catch.
  16629. 13:06:19And in fact, tries are not actually used that often,
  16630. 13:06:21amazing as they might sound on some CS level here.
  16631. 13:06:24AUDIENCE: Memory.
  16632. 13:06:25SPEAKER 1: Memory.
  16633. 13:06:27In what sense?
  16634. 13:06:28AUDIENCE: Much like a [INAUDIBLE].
  16635. 13:06:30SPEAKER 1: Exactly.
  16636. 13:06:31If you're storing all of these darn arrays
  16637. 13:06:33it's, again, a sparsely populated data structure.
  16638. 13:06:36And you can see it here.
  16639. 13:06:37Granted there's only 3 names, but most of those boxes, most of those pointers,
  16640. 13:06:41are going to remain null.
  16641. 13:06:42So this is an incredibly wide data structure, if you will.
  16642. 13:06:46It uses a huge amount of memory to store the names.
  16643. 13:06:48But again, you've got to pick a lane.
  16644. 13:06:50Either you're going to minimize space or you're going to minimize time.
  16645. 13:06:53It's not really possible to get truly the best of both worlds.
  16646. 13:06:56You have to decide where the inflection point is
  16647. 13:06:58for the device you're writing software for, how much memory it has,
  16648. 13:07:01how expensive it is.
  16649. 13:07:02And again, taking all of these things into account.
  16650. 13:07:06So lastly, let's do one further abstraction.
  16651. 13:07:08So even higher level to discuss something that are generally
  16652. 13:07:12known as abstract data structures.
  16653. 13:07:14It turns out we could spend like all day,
  16654. 13:07:16all week, talking about different things we
  16655. 13:07:17could build with these data structures.
  16656. 13:07:19But for the most part, now that we have arrays.
  16657. 13:07:21Now that we have linked lists or their cousin's trees, which
  16658. 13:07:23are 2-dimensional.
  16659. 13:07:24And beyond that, there's even graphs, where
  16660. 13:07:26the arrows can go in multiple directions, not just down, so to speak.
  16661. 13:07:29Now that we have this ability to stitch things together,
  16662. 13:07:32we can solve all different types of problems.
  16663. 13:07:34So, for instance, a very common type of data structure
  16664. 13:07:38to use in a program, or even our human world, are things called queues.
  16665. 13:07:42A queue being a data structure like a line outside of a store.
  16666. 13:07:46Where it has what's called a FIFO property.
  16667. 13:07:48First In, First Out.
  16668. 13:07:49Which is great for fairness, at least in the human world.
  16669. 13:07:52And if you've ever waited outside of Tasty Burger, or Salsa Fresca,
  16670. 13:07:56or some other restaurant nearby, presumably,
  16671. 13:07:58if you're queuing up at the counter, you want
  16672. 13:08:01them store to maintain a FIFO system.
  16673. 13:08:03First in and first out.
  16674. 13:08:05So that whoever's first in line gets their food first and gets out first.
  16675. 13:08:08So a queue is actually a computer science term, too.
  16676. 13:08:12And even if you're still in the habit of printing things on paper,
  16677. 13:08:14there are things you might have heard called printer
  16678. 13:08:17queues, which also do things in order.
  16679. 13:08:19The first person to send their essay to the printer
  16680. 13:08:21should, ideally, be printed before the last person
  16681. 13:08:24to send their essay to the printer.
  16682. 13:08:26Again, in the interest of fairness.
  16683. 13:08:28But how can you implement a queue?
  16684. 13:08:29Well, you typically have to implement 2 fundamental operations,
  16685. 13:08:32enqueue and dequeue.
  16686. 13:08:34So adding something to it and removing something from it.
  16687. 13:08:37And the interesting thing here is that how do you implement a queue?
  16688. 13:08:41Well in the human world, you would just have literally physical space
  16689. 13:08:44for humans to line up from left to right, or right to left.
  16690. 13:08:46Same in a computer.
  16691. 13:08:47Like a printer queue, if you send a whole bunch of jobs to be printed,
  16692. 13:08:50a whole bunch of essays or documents, well, you
  16693. 13:08:52need a chunk of memory like an array.
  16694. 13:08:54All right.
  16695. 13:08:55Well, if you use an array, what's a problem
  16696. 13:08:57that could happen in the world of printing, for instance?
  16697. 13:09:01If you use an array to store all of the documents that need to be printed.
  16698. 13:09:04AUDIENCE: It can be filled.
  16699. 13:09:05SPEAKER 1: It could be filled, right.
  16700. 13:09:07So if the programmer decided, HP or whoever makes the printer decides,
  16701. 13:09:10oh, you can send like a megabyte worth of documents to this printer at once.
  16702. 13:09:14At some point you might get an error message,
  16703. 13:09:16which says, sorry out of memory.
  16704. 13:09:17Wait a few minutes.
  16705. 13:09:18Which is maybe a reasonable solution, but a little annoy.
  16706. 13:09:20Or HP could write code that maybe dynamically resizes the array
  16707. 13:09:24or so forth.
  16708. 13:09:25But at that point, maybe they should just use a linked list.
  16709. 13:09:27And they could.
  16710. 13:09:28So there, too, you could implement the notion of a queue
  16711. 13:09:32using a linked list instead.
  16712. 13:09:33You're going to spend more memory, but you're not
  16713. 13:09:35going to run out of space in your array.
  16714. 13:09:38Which might be more compelling.
  16715. 13:09:39This happens even in the physical world.
  16716. 13:09:41You go to the store and you start having to line up outside and down the road.
  16717. 13:09:45And like, for a really busy store, they run out of space so they make do.
  16718. 13:09:49But in that case, it tends to be more of an array just because
  16719. 13:09:51of the physical notion of humans lining up.
  16720. 13:09:54But there's other data structures, too.
  16721. 13:09:56If you've ever gone to the dining hall and picked up like a Harvard or Yale
  16722. 13:09:59tray, you're typically picking up the last tray that was just cleaned,
  16723. 13:10:04not the first tray that was cleaned.
  16724. 13:10:06Why?
  16725. 13:10:06Because these cafeteria trays stack up on top of each other.
  16726. 13:10:10And indeed a stack is another type of abstract data structure.
  16727. 13:10:13In the physical world, it's literally something physical
  16728. 13:10:16like a stack of trays.
  16729. 13:10:18Which have what we would call a LIFO property.
  16730. 13:10:21Last In, First Out.
  16731. 13:10:22So as these things come out of the washer,
  16732. 13:10:24they're putting the most recent ones on the top.
  16733. 13:10:27And then you, the human, are probably taking the most recently cleaned one.
  16734. 13:10:30Which means in the extreme, no one on campus
  16735. 13:10:33might ever use that very first tray.
  16736. 13:10:36Which is probably fine in the world of trays,
  16737. 13:10:38but would really be bad in the world of Tasty Burger lining up for food if LIFO
  16738. 13:10:42were the property being implemented.
  16739. 13:10:44But here, too, it could be an array.
  16740. 13:10:46It could be a linked list.
  16741. 13:10:47And you see this, honestly, every day.
  16742. 13:10:49If you're using Gmail and your Gmail inbox.
  16743. 13:10:51That is actually a stack, at least by default,
  16744. 13:10:53where your newest message last in are the first ones
  16745. 13:10:57at the top of the screen.
  16746. 13:10:58That's a LIFO data structure.
  16747. 13:11:00And it means that you see your most recent emails.
  16748. 13:11:02But if you have a busy day, you're getting a lot of emails,
  16749. 13:11:04it might not be a good thing.
  16750. 13:11:05Because now you're ignoring the people who wrote you
  16751. 13:11:08way earlier in the day or the week.
  16752. 13:11:10So LIFO and FIFO are just properties that you
  16753. 13:11:13can achieve with these very specific types of data structures.
  16754. 13:11:15And the parliaments in the world of stacks
  16755. 13:11:17is to push something onto a stack or pop something out.
  16756. 13:11:21These are here, for instance, as an example of why
  16757. 13:11:23might you always wear the same color.
  16758. 13:11:24Well, if you're storing all of your clothes in a stack,
  16759. 13:11:27you might not ever get to the different colored
  16760. 13:11:29clothes at the bottom of the list.
  16761. 13:11:30And in fact, to paint this picture, we have a couple of minute video here.
  16762. 13:11:35Just to paint this here, made by a faculty member elsewhere.
  16763. 13:11:38Let's go ahead and dim the lights for just a minute or 2 here.
  16764. 13:11:41So that we can take a look at Jack learning some facts.
  16765. 13:11:45[VIDEO PLAYING]
  16766. 13:11:46SPEAKER 2: Once upon a time, there was a guy named Jack.
  16767. 13:11:48When it came to making friends Jack did not have the knack.
  16768. 13:11:52So Jack went to talk to the most popular guy he knew.
  16769. 13:11:55He went up to Lou and asked, what do I do?
  16770. 13:11:57Lou saw that his friend was really distressed.
  16771. 13:12:00Well, Lou began, just look how you're dressed.
  16772. 13:12:03Don't you have any clothes with a different look?
  16773. 13:12:05Yes, said Jack.
  16774. 13:12:06I sure do.
  16775. 13:12:08Come to my house and I'll showed them to you.
  16776. 13:12:10So they went off the Jack's.
  16777. 13:12:11And Jack showed Lou the box, where he kept all his shirts, and his pants,
  16778. 13:12:15at his socks.
  16779. 13:12:16Lou said, I see you have all your clothes in a pile.
  16780. 13:12:19Why don't you wear some others once in a while?
  16781. 13:12:21Jack said, well, when I remove clothes and socks,
  16782. 13:12:24I wash them and put them away in the box.
  16783. 13:12:27Then comes the next morning and up I hop.
  16784. 13:12:30I go to the box and get my clothes off the top.
  16785. 13:12:33Lou quickly realized the problem with Jack.
  16786. 13:12:36He kept clothes, CDs, and books in a stack.
  16787. 13:12:38When he'd reached for something to read or to wear,
  16788. 13:12:41he chose a top book or underwear.
  16789. 13:12:44Then when he was done he would put it right back.
  16790. 13:12:46Back it would go on top of the stack.
  16791. 13:12:48I know the solution, said a triumphant Lou.
  16792. 13:12:51You need to learn to start using a queue.
  16793. 13:12:53Lou took Jack's clothes and hung them in a closet.
  16794. 13:12:56And when he had emptied the box, he just tossed it.
  16795. 13:12:59Then he said, now Jack, at the end of the day, put your clothes on the left
  16796. 13:13:03when you put them away.
  16797. 13:13:04Then tomorrow morning when you see the sunshine, get
  16798. 13:13:07your clothes from the right, from the end of the line.
  16799. 13:13:10Don't you see, said Lou, it will be so nice.
  16800. 13:13:13You'll wear everything once before you wear something twice.
  16801. 13:13:16And with everything in queues in his closet and shelf,
  16802. 13:13:19Jack started to feel quite sure of himself.
  16803. 13:13:22All thanks to Lou and his wonderful queue.
  16804. 13:13:26SPEAKER 1: So just to help you realize that these things are everywhere.
  16805. 13:13:29[AUDIENCE CLAPPING]
  16806. 13:13:32Even in our human world.
  16807. 13:13:33If you've ever lined up at this place.
  16808. 13:13:35Anyone recognize this?
  16809. 13:13:37OK, so sweetgreen, little salad place in the square.
  16810. 13:13:40This is if you order online or in advance,
  16811. 13:13:42your food ends up according to the first letter in your name.
  16812. 13:13:44Which actually sounds awfully reminiscent of something
  16813. 13:13:46like a hash table.
  16814. 13:13:47And in fact, no matter whether you implement a hash table like we
  16815. 13:13:50did, with an array and linked list.
  16816. 13:13:52Or with 3 shelves like this.
  16817. 13:13:54This is actually an abstract data type called a dictionary.
  16818. 13:13:57And a dictionary, just like in our human world, has keys and values.
  16819. 13:14:01Words and their definitions.
  16820. 13:14:02This just has letters of the alphabet and salads as their value.
  16821. 13:14:07But here, too, there's a real world constraint.
  16822. 13:14:09In what kind of scenario does this system at sweetgreen
  16823. 13:14:13devolve into a problem, for instance?
  16824. 13:14:15Because they, too, are using only finite space, finite storage.
  16825. 13:14:19What could go wrong?
  16826. 13:14:20Yeah.
  16827. 13:14:20AUDIENCE: Run out of space.
  16828. 13:14:21SPEAKER 1: Yeah.
  16829. 13:14:22If they run out of space on the shelf and there's
  16830. 13:14:23a lot of people whose names start with D, or E, or whatever.
  16831. 13:14:25And so, they just pile up.
  16832. 13:14:26And then, maybe, they kind of overflow into the E's or the F's.
  16833. 13:14:29And they probably don't really care because any human
  16834. 13:14:31is going to come by, and just eyeball it, and figure it out anyway.
  16835. 13:14:33But in the world of a computer, you're the one coding
  16836. 13:14:36and have to be ever so precise.
  16837. 13:14:38We thought we would lastly do one final thing here.
  16838. 13:14:41In advance, we prepared a linked list of sorts in the audience.
  16839. 13:14:45Since this has become a bit of a thing.
  16840. 13:14:47I am starting to represent the beginning of this linked list.
  16841. 13:14:50And so far as I have a pointer here with seat location G9.
  16842. 13:14:54Whoever is in G9, would you mind standing up?
  16843. 13:14:57And what letter is on your sheet there?
  16844. 13:15:00AUDIENCE: F15.
  16845. 13:15:01SPEAKER 1: OK, so you have S15 and your letter--
  16846. 13:15:04AUDIENCE: F15.
  16847. 13:15:04SPEAKER 1: Say again?
  16848. 13:15:05AUDIENCE: F.
  16849. 13:15:06SPEAKER 1: F15.
  16850. 13:15:07So I see you're holding a C in your node.
  16851. 13:15:09You are pointing to, if you could physically, F15.
  16852. 13:15:12F15, what do you hold?
  16853. 13:15:14AUDIENCE: S.
  16854. 13:15:15SPEAKER 1: You have an S. And who should you be pointing at?
  16855. 13:15:17AUDIENCE: F5.
  16856. 13:15:18SPEAKER 1: F5.
  16857. 13:15:19Could you stand up, F5.
  16858. 13:15:20You're holding a 5, I see.
  16859. 13:15:22What address?
  16860. 13:15:23AUDIENCE: F12.
  16861. 13:15:24SPEAKER 1: F12.
  16862. 13:15:25Big finale.
  16863. 13:15:26F12, if you'd like to stand up holding a 0 and null, which means that was CS50.
  16864. 13:15:30[AUDIENCE CLAPPING]
  16865. 13:15:34All right.
  16866. 13:15:34We'll see you next time.
  16867. 13:15:36[MUSIC PLAYING]
  16868. 13:16:54DAVID J. MALAN: All right, this is CS50, and this is already week 6.
  16869. 13:16:58And this is the week in which you learn yet another language.
  16870. 13:17:00But the goal is not just to teach you another language,
  16871. 13:17:03for languages sake, as we transition today
  16872. 13:17:06and in the coming weeks from C, where we've spent the past several weeks, now
  16873. 13:17:09to Python.
  16874. 13:17:09The goal ultimately is to teach you all how to teach yourselves new languages,
  16875. 13:17:14so that by the end of this course, it's not in your mind,
  16876. 13:17:16the fact that you learned how to program in C
  16877. 13:17:19or learned some weeks back how to program in Scratch,
  16878. 13:17:21but really how you learned how to program fundamentally,
  16879. 13:17:24in a paradigm known as procedural programming,
  16880. 13:17:27as well as with some taste today, and in the weeks to come,
  16881. 13:17:29of other aspects of programming languages,
  16882. 13:17:31like object-oriented programming, and more.
  16883. 13:17:34So recall, though, back in week zero, Hello, world
  16884. 13:17:36looked a little something like this.
  16885. 13:17:38And the world was quite simple.
  16886. 13:17:39All you had to do was drag and drop these puzzle pieces.
  16887. 13:17:42But there were still functions and conditionals and loops and variables
  16888. 13:17:45and all of those kinds of primitives.
  16889. 13:17:47We then transitioned, of course, to a much more arcane language that
  16890. 13:17:50looked a little something like this.
  16891. 13:17:52And even now, some weeks later, you might still
  16892. 13:17:54be struggling with some of the syntax or getting annoying bugs
  16893. 13:17:56when you try to compile your code, and it just doesn't work.
  16894. 13:17:59But there, too, the past few weeks, we've
  16895. 13:18:01been focusing on functions and loops and variables, conditionals, and really
  16896. 13:18:04all of those same ideas.
  16897. 13:18:06And so what we begin to do today is to, one, simplify the language
  16898. 13:18:10we're using, transitioning from C now to Python, this now being the equivalent
  16899. 13:18:15program in Python, and look at its relative simplicity,
  16900. 13:18:18but also transitioning to look at how you
  16901. 13:18:20can implement these same kinds of features,
  16902. 13:18:22just using a different language.
  16903. 13:18:23So we're going to see a lot of code today.
  16904. 13:18:25And you won't have nearly as much practice with Python as you did with C.
  16905. 13:18:29But that's because so many of the ideas are still going to be with us.
  16906. 13:18:32And, really, it's going to be a process of figuring out, all right,
  16907. 13:18:35I want to do a loop.
  16908. 13:18:35I know how to do it in C. How do I do this in Python?
  16909. 13:18:38How do I do the same with conditionals?
  16910. 13:18:39How do I declare variables, and the like,
  16911. 13:18:41and moving forward, not just in CS50, but in life in general,
  16912. 13:18:43if you continue programming and learn some other language after the class,
  16913. 13:18:47if in 5-10 years, there's a new, more popular language that you pick up,
  16914. 13:18:50it's just going to be a matter of googling and looking
  16915. 13:18:53at websites like Stack Overflow and the like,
  16916. 13:18:54to look at just basic building blocks of programming languages,
  16917. 13:18:57because you already speak, after these past 6 plus weeks,
  16918. 13:19:01you already speak programming itself fundamentally.
  16919. 13:19:04All right, so let's do a few quick comparisons, left and right, of what
  16920. 13:19:07something might have looked like in Scratch,
  16921. 13:19:09and what it then looked like in C, but now,
  16922. 13:19:11as of today, what it's going to look like in Python.
  16923. 13:19:13Then we'll turn our attention to the command line,
  16924. 13:19:15ultimately, in order to implement some actual programs.
  16925. 13:19:19So in Scratch, we had functions like this, say Hello,
  16926. 13:19:22world, a verb or an action.
  16927. 13:19:23In C it looked a little something like this,
  16928. 13:19:26and a bit of a cryptic mess the first week, you had the printf,
  16929. 13:19:29you had the double quotes.
  16930. 13:19:30You had the semicolon, the parentheses.
  16931. 13:19:32So there's a lot more syntax just to do the same thing.
  16932. 13:19:34We're not going to get rid of all of that syntax now, but as of today,
  16933. 13:19:37in Python, that same statement is going to look a little something like this.
  16934. 13:19:42And just to perhaps call out the obvious, what
  16935. 13:19:44is different or, now, simpler in Python versus C, even
  16936. 13:19:48in this simple example here?
  16937. 13:19:50Yeah.
  16938. 13:19:51AUDIENCE: Now print, instead of printf would be, something like that.
  16939. 13:19:53DAVID J. MALAN: Good, so it's now print instead of printf.
  16940. 13:19:56And there's also no semicolon.
  16941. 13:19:57And there's one other subtlety, over here.
  16942. 13:19:59AUDIENCE: No new line.
  16943. 13:20:00DAVID J. MALAN: Yeah, so no new line, and that
  16944. 13:20:02doesn't mean it's not going to be printed.
  16945. 13:20:03It just turns out that one of the differences we'll see
  16946. 13:20:05is that, with print, you get the new line for free.
  16947. 13:20:08It automatically gets outputted by default, being sort of a common case.
  16948. 13:20:11But you can override it, we'll see, ultimately, too.
  16949. 13:20:13How about in Scratch?
  16950. 13:20:14We had multiple functions like this, that not only said something
  16951. 13:20:18on the screen, but also asked a question,
  16952. 13:20:20thereby being another function that returned a value, called answer.
  16953. 13:20:23In C we saw code that looked a little something
  16954. 13:20:26like this, whereby that first line declares a variable called answer,
  16955. 13:20:29sets it equal to the return value of getString,
  16956. 13:20:32one of the functions from the CS50 library,
  16957. 13:20:34and then the same double quotes and parentheses and semicolon.
  16958. 13:20:37Then we had this format code in C that allowed us, with %S,
  16959. 13:20:41to actually print out that same value.
  16960. 13:20:44In Python, this, too, is going to look a little bit simpler.
  16961. 13:20:46Instead, we're going to have answer equals getString,
  16962. 13:20:49quote unquote "What's your name," and then print,
  16963. 13:20:52with a plus sign and a little bit of new syntax.
  16964. 13:20:55But let's see if we can't just infer from this example what
  16965. 13:20:58it is that's going on.
  16966. 13:20:59Well, first missing on the left is what?
  16967. 13:21:02To the left of the equal sign, there's no what this time?
  16968. 13:21:05Feel free to just call it out.
  16969. 13:21:06AUDIENCE: Type.
  16970. 13:21:07DAVID J. MALAN: So there's no type.
  16971. 13:21:07There's no type, like the word string, which
  16972. 13:21:10even though that was a type in CS50, every other variable in C
  16973. 13:21:14did we use Int or string or float, or Bool or something else.
  16974. 13:21:17In Python, there are still going to be data types,
  16975. 13:21:20today onward, but you, the programmer, don't
  16976. 13:21:22have to bother telling the computer what types you're using.
  16977. 13:21:25The computer is going to be smart enough,
  16978. 13:21:27the language, really, is going to be smart enough, to just figure it out
  16979. 13:21:29from context.
  16980. 13:21:30Meanwhile, on the right hand side, getString
  16981. 13:21:32is going to be a function we'll use today
  16982. 13:21:34and this week, which comes from a Python version of the CS50 library.
  16983. 13:21:37But we'll also start to take off those training wheels, so that you'll
  16984. 13:21:40see how to do things without any CS50 library moving forward,
  16985. 13:21:44using a different function instead.
  16986. 13:21:45As before, no semicolon, but the rest of the syntax is pretty much the same
  16987. 13:21:49here.
  16988. 13:21:49This starts, of course, to get a little bit different, though.
  16989. 13:21:52We're using print instead of printf.
  16990. 13:21:54But now, even though this looks a little cryptic,
  16991. 13:21:57perhaps, if you've never programmed before CS50,
  16992. 13:21:59what might that plus be doing, just based on inference here.
  16993. 13:22:03What do you think?
  16994. 13:22:04AUDIENCE: Adding answer to the string Hello.
  16995. 13:22:08DAVID J. MALAN: Yeah, so adding answer to the string Hello,
  16996. 13:22:11and adding, so to speak, not mathematically,
  16997. 13:22:13but in the form of joining them together, much like we
  16998. 13:22:16saw the joined block in Scratch, or concatenation was the term of art
  16999. 13:22:19there.
  17000. 13:22:20This plus sign appends, if you will, whatever's
  17001. 13:22:23in answer to whatever is quoted here.
  17002. 13:22:25And I deliberately left a space there, so that grammatically it
  17003. 13:22:27looks nice, after the comma as well.
  17004. 13:22:29Now there's another way to do this.
  17005. 13:22:31And it, too, is going to look cryptic at first glance.
  17006. 13:22:33But it just gets easier and more convenient over time.
  17007. 13:22:36You can also change this second line to be this, instead.
  17008. 13:22:41So what's going on here.
  17009. 13:22:42This is actually a relatively new feature of Python in the past couple
  17010. 13:22:45of years, where now what you're seeing is, yes,
  17011. 13:22:47a string, between these same double quotes,
  17012. 13:22:50but this is what Python would call a format string, or Fstring.
  17013. 13:22:53And it literally starts with the letter F, which admittedly looks, I think,
  17014. 13:22:56a little weird.
  17015. 13:22:57But that just indicates that Python should
  17016. 13:23:01assume that anything inside of curly braces inside of the string
  17017. 13:23:05should be interpolated, so to speak, which is a fancy term saying,
  17018. 13:23:09substitute the value of any variables therein.
  17019. 13:23:12And it can do some other things as well.
  17020. 13:23:14So answer is a variable, declared, of course, on this first line.
  17021. 13:23:18This Fstring, then, says to Python, print out Hello comma space, and then
  17022. 13:23:22the value of Answer.
  17023. 13:23:24If, by contrast, you omitted the curly braces,
  17024. 13:23:28just take a guess, what would happen?
  17025. 13:23:30What would the symptom of that bug be, if you accidentally
  17026. 13:23:33forgot the curly braces, but maybe still had the F there?
  17027. 13:23:36AUDIENCE: It would print below it, too.
  17028. 13:23:38DAVID J. MALAN: Yeah, it would literally print Hello, comma answer, because it's
  17029. 13:23:40going to take you literally.
  17030. 13:23:41So the curly braces just kind of allow you to plug things in.
  17031. 13:23:44And, again, it looks a little more cryptic,
  17032. 13:23:45but it's just going to save us time over time.
  17033. 13:23:47And if any of you programmed in Java in high school, for instance,
  17034. 13:23:50you saw plus in that context, too, for concatenation.
  17035. 13:23:53This just kind of makes your code a little tighter, a little more succinct.
  17036. 13:23:56So it's a convenient feature now in Python.
  17037. 13:23:58All right, this was an example in Scratch of a variable,
  17038. 13:24:00setting a variable like counter equal to 0.
  17039. 13:24:03In C it looked like this, where you specify the type, the name,
  17040. 13:24:06and then the value, with a semicolon.
  17041. 13:24:08In Python, it's going to look like this.
  17042. 13:24:11And I'll state the obvious here.
  17043. 13:24:12You don't need to mention the type, just like before with string.
  17044. 13:24:15And you don't need a semicolon.
  17045. 13:24:17So it's a little simpler.
  17046. 13:24:18If you want a variable, just write it and set it equal to some value.
  17047. 13:24:21But the single equal sign still behaves the same as in C.
  17048. 13:24:24Suppose we wanted to increment counter by one.
  17049. 13:24:26In Scratch, we use this puzzle piece here.
  17050. 13:24:29In C, we could do this, actually, in a few different ways.
  17051. 13:24:31There was this way, if counter already exists,
  17052. 13:24:33you just say counter equals counter plus 1.
  17053. 13:24:36There was the slightly less verbose way, where you could say, oops, sorry.
  17054. 13:24:41Let me do the first sentence first.
  17055. 13:24:42In Python, that same thing, as you might guess,
  17056. 13:24:45is actually going to be almost the same, you just throw away the semicolon.
  17057. 13:24:48And the mathematics are ultimately the same, copying from right to left,
  17058. 13:24:51via the assignment operator.
  17059. 13:24:53Now, recall, in C, that we had this shorthand
  17060. 13:24:56notation, which did the same thing.
  17061. 13:24:58In Python, you can similarly do the same thing, just no need for the semicolon.
  17062. 13:25:03The only step backwards we're taking, if you
  17063. 13:25:05were a big fan of counter plus plus, that doesn't exist in Python,
  17064. 13:25:10nor minus minus.
  17065. 13:25:11You just can't do it.
  17066. 13:25:12You have to do the plus equals 1 or plus/minus or minus equals 1
  17067. 13:25:16to achieve that same result. All right, how about in Python 2?
  17068. 13:25:20Here in Scratch, recall, was a conditional,
  17069. 13:25:22asking a silly question like is x less than y, and if so, just say as much.
  17070. 13:25:26In C, that looked a little something like this, printf and if
  17071. 13:25:30with the parentheses, the curly braces, the semicolon, and all of that.
  17072. 13:25:33In Python, this is going to get a little more pleasant to type, too.
  17073. 13:25:37It's going to be just this.
  17074. 13:25:39And if someone wants to call out some of the obvious changes here,
  17075. 13:25:42what has been simplified now in Python for a conditional, it would seem?
  17076. 13:25:46Yeah, what's missing, or changed?
  17077. 13:25:48AUDIENCE: Braces.
  17078. 13:25:48DAVID J. MALAN: So no curly braces.
  17079. 13:25:49AUDIENCE: Colon is back.
  17080. 13:25:51DAVID J. MALAN: I'm sorry?
  17081. 13:25:51AUDIENCE: Using the colon instead.
  17082. 13:25:53DAVID J. MALAN: And we're using the colon instead.
  17083. 13:25:55So I got rid of the curly braces in Python.
  17084. 13:25:57But I'm using a colon instead.
  17085. 13:25:58And even though this is a single line of code,
  17086. 13:26:00so long as you indent subsequent lines along with the printf,
  17087. 13:26:04that's going to imply that everything, if the if condition is true,
  17088. 13:26:09should be executed below it, until you start to un-indent and start writing
  17089. 13:26:13a different line of code altogether.
  17090. 13:26:14So indentation in Python is important.
  17091. 13:26:17So this is among the reasons we've emphasized axes like style,
  17092. 13:26:21just how well styled your code is.
  17093. 13:26:23And honestly, we've seen, certainly, in office hours,
  17094. 13:26:25and you've seen in your own code, sort of a tendency sometimes
  17095. 13:26:28to be a little lax when it comes to indentation, right?
  17096. 13:26:31If you're one of those folks who likes to indent everything
  17097. 13:26:34on the left hand side of the window, yeah, it might compile and run.
  17098. 13:26:37But it's not particularly readable by you or anyone else.
  17099. 13:26:41Python actually addresses this by just requiring indentation,
  17100. 13:26:45when logically needed.
  17101. 13:26:46So Python is going to force you to start inventing properly now, if that's been,
  17102. 13:26:50perhaps, a tendency otherwise.
  17103. 13:26:53What else is missing?
  17104. 13:26:54Well, we have no semicolon here.
  17105. 13:26:55Of course, it's print instead of printf.
  17106. 13:26:57But otherwise, those seem to be the primary differences.
  17107. 13:27:00What about something larger in Scratch?
  17108. 13:27:02If an if-else block, like this, you can perhaps
  17109. 13:27:05guess what it's going to look like.
  17110. 13:27:06In C it looks like this, curly braces semicolons, and so forth.
  17111. 13:27:10In Python, it's going to now look like this, almost the same,
  17112. 13:27:14but indentation is important.
  17113. 13:27:15The colons are important.
  17114. 13:27:16And there's one other difference that's now again visible here,
  17115. 13:27:19but we didn't call it out a second ago.
  17116. 13:27:21What else is different in Python versus C for these conditionals?
  17117. 13:27:24Yeah.
  17118. 13:27:24AUDIENCE: You don't have any parentheses around the condition.
  17119. 13:27:27DAVID J. MALAN: Perfect.
  17120. 13:27:28We don't have any parentheses around the condition,
  17121. 13:27:30the Boolean expression itself.
  17122. 13:27:32And why not?
  17123. 13:27:33Well, it's just simpler to type.
  17124. 13:27:34It's less to type.
  17125. 13:27:35You can still use parentheses.
  17126. 13:27:36And, in fact, you might want to or need to,
  17127. 13:27:39if you want to combine thoughts and do this and that, or this or that.
  17128. 13:27:43But by default, you no longer need or should have those parentheses.
  17129. 13:27:47Just say what you mean.
  17130. 13:27:48Lastly, with conditionals, we had something like this,
  17131. 13:27:50an if else if else statement.
  17132. 13:27:53In C, it looked a little something like this.
  17133. 13:27:55In Python, it's going to get really tighter now.
  17134. 13:27:57It's just if, and this is the curiosity, elif x greater than y.
  17135. 13:28:02So it's not else if, it's literally one keyword, elif, and the colons
  17136. 13:28:07remain now on each of the three lines.
  17137. 13:28:09But the indentation is important.
  17138. 13:28:11And if we did want to do multiple things,
  17139. 13:28:13we could just indent below each of these conditionals, as well.
  17140. 13:28:16All right, let me pause there first, to see
  17141. 13:28:18if there's any questions on these syntactic differences.
  17142. 13:28:21Yeah.
  17143. 13:28:21AUDIENCE: My thought is maybe like, it's good,
  17144. 13:28:24though, does it matter if there's this in between thing like that, but
  17145. 13:28:27and why.
  17146. 13:28:28DAVID J. MALAN: In between, between what and what?
  17147. 13:28:31AUDIENCE: So like the left-hand side and like the right side spaces?
  17148. 13:28:34DAVID J. MALAN: Ah, good question, is Python sensitive
  17149. 13:28:38to spaces and where they go?
  17150. 13:28:40Sometimes no, sometimes yes, is the short answer.
  17151. 13:28:42Stylistically, though, you should be practicing what we're preaching here,
  17152. 13:28:46whereby you do have spaces to the left and right of binary operators,
  17153. 13:28:50that they're called, something like less than
  17154. 13:28:52or greater than is a binary operator, because there's
  17155. 13:28:54two operands to the left and to the right of them.
  17156. 13:28:57And in fact, in Python, more so than the world of C,
  17157. 13:29:00there's actually formal style conventions.
  17158. 13:29:02Not only within CS50 have we had a style guide on the course's website,
  17159. 13:29:07for instance, that just dictates how you should write your code so that it looks
  17160. 13:29:10like everyone else's.
  17161. 13:29:11In the Python community, they take this one step further,
  17162. 13:29:13and there's an actual standard whereby you don't have to adhere to it,
  17163. 13:29:17but generally speaking, in the real world, someone would reprimand you,
  17164. 13:29:20would reject your code, if you're trying to contribute it to another project,
  17165. 13:29:23if you don't adhere to these standards.
  17166. 13:29:25So while you could be lax with some of this white space,
  17167. 13:29:28do make things readable.
  17168. 13:29:29And that's Python theme, for the code to be as readable as possible.
  17169. 13:29:33All right, so let's take a look at a couple of other constructs
  17170. 13:29:35before transitioning to some actual code.
  17171. 13:29:37This, of course, in Scratch was a loop, meowing forever.
  17172. 13:29:40In C, the closest we could get was doing something while true, because true
  17173. 13:29:44never changes.
  17174. 13:29:45So it's sort of a simple way of just saying do this forever.
  17175. 13:29:48In Python, it's pretty much the same thing,
  17176. 13:29:51but a couple of small differences here.
  17177. 13:29:53The parentheses are gone.
  17178. 13:29:55The colon is there.
  17179. 13:29:56The indentation is there.
  17180. 13:29:57No semicolon, and there's one other subtle difference.
  17181. 13:30:00What do you see?
  17182. 13:30:01AUDIENCE: True is capitalized?
  17183. 13:30:02DAVID J. MALAN: True is capitalized, just because.
  17184. 13:30:04Both true and false are Boolean values in Python.
  17185. 13:30:07But you've got to start capitalizing them, just because.
  17186. 13:30:09All right, how about a loop like this, where
  17187. 13:30:11you repeat something a finite number of times, like meowing three times.
  17188. 13:30:14In C, we could do this a few different ways.
  17189. 13:30:17There's this very mechanical way, where you initialize a variable like i
  17190. 13:30:21to zero.
  17191. 13:30:22You then use a while loop and check if i is less than 3,
  17192. 13:30:25the total number of times you want to meow.
  17193. 13:30:27Then you print what you want to print.
  17194. 13:30:29You increment i using this syntax, or the longer, more verbose syntax,
  17195. 13:30:32with plus equals or whatnot.
  17196. 13:30:34And then you do it again and again and again.
  17197. 13:30:36In Python, you can do it functionally the same way, same idea,
  17198. 13:30:40slightly different syntax.
  17199. 13:30:42You just don't bother saying what type of variable you want.
  17200. 13:30:44Python will infer from the fact that there's a 0 right there.
  17201. 13:30:47You don't need the parentheses.
  17202. 13:30:48You do need the colon.
  17203. 13:30:49You do need the indentation.
  17204. 13:30:51You can't do the i plus plus, but you can do this other technique,
  17205. 13:30:54as we could have done in C, as well.
  17206. 13:30:56How else might we do this, though, too?
  17207. 13:30:58Well. it turns out in C, we could do something
  17208. 13:31:01like this, which, again, sort of cryptic at first glance,
  17209. 13:31:04became perhaps more familiar, where you have initialization,
  17210. 13:31:07a conditional, and then an update that you do after each iteration.
  17211. 13:31:11In Python, there isn't really an analog.
  17212. 13:31:14There is no analog in Python, where you have
  17213. 13:31:17the parentheses and the multiple semicolons in the same line.
  17214. 13:31:19Instead, there is a for loop, but it's meant to read a little more
  17215. 13:31:23like English, for i in 0, 1, and 2.
  17216. 13:31:27So we'll see in a bit, these square brackets represent an array, now
  17217. 13:31:31to be called a list in Python.
  17218. 13:31:33So lists in Python are more like link lists than they are arrays.
  17219. 13:31:37More on that soon.
  17220. 13:31:38So this just means for i and the following list of three values.
  17221. 13:31:42And on each iteration of this loop, Python automatically, for you,
  17222. 13:31:46it first sets i to zero.
  17223. 13:31:47Then it sets i to one.
  17224. 13:31:49Then it sets i to two, so that you effectively do things three times.
  17225. 13:31:54But this doesn't necessarily scale, as I've drawn it on the board.
  17226. 13:31:57Suppose you took this at face value as the way
  17227. 13:32:01you iterate some number of times in Python, using a for loop.
  17228. 13:32:05At what point does this approach perhaps get bad, or bad design?
  17229. 13:32:10Let me give folks just a moment to think.
  17230. 13:32:11Yeah, in back.
  17231. 13:32:12AUDIENCE: If you don't know how many times, last time, you know,
  17232. 13:32:15you've got the link in there.
  17233. 13:32:17DAVID J. MALAN: Sure, if you don't know how many times you
  17234. 13:32:20want to loop or iterate, you can't really create a hard-coded list
  17235. 13:32:23like that, of 0, 1, 2.
  17236. 13:32:25Other thoughts?
  17237. 13:32:26AUDIENCE: So you want to say raise a large number of allowances.
  17238. 13:32:29DAVID J. MALAN: Yeah, if you're iterating a large number of times,
  17239. 13:32:32this list is going to get longer and longer,
  17240. 13:32:34and you're just kind of stupidly going to be typing out
  17241. 13:32:36like comma 3, comma 4, comma 5, comma dot dot dot, comma 99, comma 100.
  17242. 13:32:40I mean, your code would start to look atrocious, eventually.
  17243. 13:32:42So there is a better way.
  17244. 13:32:44In Python, there is a function, or technically a type,
  17245. 13:32:46called range, that essentially magically gives you back a range of values
  17246. 13:32:51from 0 on up to, but not through a value.
  17247. 13:32:54So the effect of this line of code, for i in the following range,
  17248. 13:32:58essentially hands you back a list of three values,
  17249. 13:33:01thereby letting you do something three times.
  17250. 13:33:02And if you want to do something 99 times instead, you, of course,
  17251. 13:33:05just change the 3 to a 99.
  17252. 13:33:07Question.
  17253. 13:33:07AUDIENCE: Is there a way to start the beginning point of that range
  17254. 13:33:11at a number or an integer that's higher than zero, or is there never a really
  17255. 13:33:15any point to do so?
  17256. 13:33:16DAVID J. MALAN: A really good question, can
  17257. 13:33:18you start counting at a higher number.
  17258. 13:33:19So not 0, which is the implied default, but something larger than that.
  17259. 13:33:23Yes, so it turns out the range function takes multiple arguments, not just one
  17260. 13:33:28but maybe two or even three, that allows you to customize this behavior.
  17261. 13:33:31So you can customize where it begins.
  17262. 13:33:33You can customize the increment.
  17263. 13:33:34By default, it's one, but if you want to do
  17264. 13:33:36every two values, for like evens or odds, you could do that as well,
  17265. 13:33:39and a few other things.
  17266. 13:33:40And before long, we'll take a look at some Python documentation
  17267. 13:33:42that will become your authoritative source for answers like that.
  17268. 13:33:45Like, what can this function do.
  17269. 13:33:47Other questions on this thus far?
  17270. 13:33:51Seeing none, so what else might we compare and contrast here.
  17271. 13:33:56Well, in the world of C, recall that we had a whole bunch of built-in data
  17272. 13:34:00types, like these here, Bool and char and double and float, and so forth,
  17273. 13:34:04string, which happened to come from the CS50 library.
  17274. 13:34:08But the language C itself certainly understood the idea of strings,
  17275. 13:34:12because the backslash 0, the support for %S and printf, that's all native,
  17276. 13:34:17built into C, not a CS50 simplification.
  17277. 13:34:19All we did, and revealed, as of a couple of weeks
  17278. 13:34:22ago, is that string, this data type, is just
  17279. 13:34:24a synonym for a typedef for char star, which is part of the language natively.
  17280. 13:34:29In Python now, this list actually gets a little shorter, at least
  17281. 13:34:32for these common primitive data types.
  17282. 13:34:33Still going to have bulls, we're going to have floats, and Ints,
  17283. 13:34:36and we're going to have strings, but we're going to call them STRs.
  17284. 13:34:39And this is not a CS50 thing from the library,
  17285. 13:34:41STR, S-T-R, is, in fact, a data type in Python,
  17286. 13:34:44that's going to do a lot more than strings did for us automatically in C.
  17287. 13:34:48Ints and floats, meanwhile, don't need the corresponding longs and doubles,
  17288. 13:34:53because, in fact, among the problems Python solves for us,
  17289. 13:34:56too, Ints can get as big as you want.
  17290. 13:34:58Integer overflow is no longer going to be an issue.
  17291. 13:35:01Per week 1, the language solves that for us.
  17292. 13:35:04Floating point imprecision, unfortunately,
  17293. 13:35:06is still a problem that remains.
  17294. 13:35:07But there are libraries, code that other people have written, as we briefly
  17295. 13:35:11discussed in weeks past, that allow you to do
  17296. 13:35:13scientific or financial computing, using libraries that build
  17297. 13:35:16on top of these data types, as well.
  17298. 13:35:19So there's other data types, too, in Python, which we'll see actually
  17299. 13:35:22gives us a whole bunch of more power and capability,
  17300. 13:35:25things called ranges, like we just saw, lists,
  17301. 13:35:28like I called out verbally, with the square brackets,
  17302. 13:35:30things called tuples, for things like x comma y,
  17303. 13:35:33or latitude, longitude, dictionaries, or Dicts,
  17304. 13:35:36which allow you to store keys and values, much like our hash tables
  17305. 13:35:40from last time, and then sets in the mathematical sense, where they filter
  17306. 13:35:43out duplicates for you, and you can just put a whole bunch of numbers,
  17307. 13:35:46a whole bunch of words or whatnot, and the language, via this data type,
  17308. 13:35:50will filter out duplicates for you.
  17309. 13:35:52Now there's going to be a few functions we give you this week and beyond,
  17310. 13:35:56training wheels that we're then going to very quickly take off,
  17311. 13:35:59just because, as we'll see today, they just simplify the process of getting
  17312. 13:36:02user input correctly, without accidentally writing buggy code,
  17313. 13:36:05just when you're trying to get Hello, World, or something similar, to work.
  17314. 13:36:08And we'll give you functions, not like, not as long as this list in C,
  17315. 13:36:12but a subset of these, get float, get Int,
  17316. 13:36:15and get string, that'll automate the process of getting
  17317. 13:36:18user input in a way that's more resilient against potential bugs.
  17318. 13:36:21But we'll see what those bugs might be.
  17319. 13:36:23And the way we're going to do this is similar in spirit to C.
  17320. 13:36:26Instead of doing include, CS50.h, like we did in C,
  17321. 13:36:30you're going to now start saying import CS50.
  17322. 13:36:33Python supports, similar to C, libraries,
  17323. 13:36:37but there aren't header files anymore.
  17324. 13:36:38You just use the name of the library in Python.
  17325. 13:36:41And if you want to import CS50's functions, you just say import CS50.
  17326. 13:36:44Or, if you want to be more precise, and not just import the whole thing, which
  17327. 13:36:48could be slow, if you've got a really big library with a lot of functionality
  17328. 13:36:52in it, you can be more precise and say from CS50, import get float.
  17329. 13:36:56From CS50 import get Int, from CSM 50 import get string,
  17330. 13:37:00or you can just separate them by commas and import 3
  17331. 13:37:02and only 3 things from a particular library, like ours.
  17332. 13:37:07But starting today and onward, we're going
  17333. 13:37:08to start making much more heavy use of libraries, code
  17334. 13:37:11that other people wrote, so that we're no longer reinventing the wheel.
  17335. 13:37:15We're not making our own linked lists, our own trees, our own dictionaries.
  17336. 13:37:18We're going to start standing on the shoulders of others,
  17337. 13:37:20so that you can get real work done, so to speak, faster,
  17338. 13:37:23by building your software on top of others' code as well.
  17339. 13:37:28All right, so that's it for the syntactic tour of the language,
  17340. 13:37:31and the sort of core features.
  17341. 13:37:32Soon we'll transition to application thereof.
  17342. 13:37:34But let me pause here to see if there's any questions on syntax or primitives
  17343. 13:37:40or otherwise, or otherwise.
  17344. 13:37:46Oh, yes, in back.
  17345. 13:37:48AUDIENCE: Why don't Python have the increment operators.
  17346. 13:37:52DAVID J. MALAN: I'm sorry, say it again, why doesn't
  17347. 13:37:54Python have what kind of operators?
  17348. 13:37:56AUDIENCE: Why doesn't Python have the increment operator?
  17349. 13:37:59DAVID J. MALAN: Sorry, someone coughed when you said something operators.
  17350. 13:38:02AUDIENCE: The increment.
  17351. 13:38:03DAVID J. MALAN: Oh, the increment operator?
  17352. 13:38:05I'd have to check the history, honestly.
  17353. 13:38:06Python has tended to be a fairly minimus language.
  17354. 13:38:09And if you can do something one way, the community, arguably,
  17355. 13:38:12has tended to not give you multiple ways to do the same thing syntactically.
  17356. 13:38:16There's probably a better answer.
  17357. 13:38:18And I'll see if I can dig in and post something online, to follow up on that.
  17358. 13:38:22All right, so before we transition to now writing some actual code,
  17359. 13:38:26let me go ahead and consider exactly how we're going to write code.
  17360. 13:38:31In the world of C, recall that it's generally been a 2-step process.
  17361. 13:38:35We create a file called like Hello.c, and then, step one, make Hello, step 2,
  17362. 13:38:40./Hello.
  17363. 13:38:41Or, if you think back to week two, when we sort of peeled back
  17364. 13:38:44the layer of what Hello, of what make was doing,
  17365. 13:38:47you could more verbosely type out the name of the actual compiler,
  17366. 13:38:50Clang in our case, command line arguments like dash Oh, Hello,
  17367. 13:38:54to specify what name you want to create.
  17368. 13:38:56And then you can specify the file name.
  17369. 13:38:58And then you can specify what libraries you want to link in.
  17370. 13:39:01So that was a very verbose approach.
  17371. 13:39:03But it was always a two-step approach.
  17372. 13:39:05And so, even as you've been doing recent problem sets,
  17373. 13:39:08odds are you've realized that, any time you want to make a change to your code,
  17374. 13:39:11or make a change to your code and try and test your code again,
  17375. 13:39:16you're constantly doing those two steps.
  17376. 13:39:18Moving forward in Python, it's going to become simpler,
  17377. 13:39:22and it's going to be just this.
  17378. 13:39:24The file name is going to change, but that might go without saying.
  17379. 13:39:26It's going to be something like Hello.py, P-Y, instead of Hello.c.
  17380. 13:39:31And that's just a convention, using a different file extension.
  17381. 13:39:34But there's no compilation step per se.
  17382. 13:39:37You jump right to the execution of your code.
  17383. 13:39:40And so Python, it turns out, is the name, not only of the language
  17384. 13:39:43we're going to start using, it's also the name of a program on a Mac, a PC,
  17385. 13:39:48assuming it's been pre-installed, that interprets the language for you.
  17386. 13:39:52This is to say that Python is generally described as being interpreted,
  17387. 13:39:56not compiled.
  17388. 13:39:57And by that, I mean you get to skip, from the programmer's perspective,
  17389. 13:40:01that compilation step.
  17390. 13:40:02There is no manual step in the world of Python, typically, of writing your code
  17391. 13:40:07and then compiling it to zeros and ones, and then running the zeros and ones.
  17392. 13:40:11Instead, these kind of two steps get collapsed
  17393. 13:40:13into the illusion of one, whereby you, instead, are able to just run the code,
  17394. 13:40:19and let the computer figure out how to actually convert it
  17395. 13:40:22to something the computer understands.
  17396. 13:40:24And the way we do that is via this old process, input and output.
  17397. 13:40:28But now, when you have source code, it's going
  17398. 13:40:30to be passed into an interpreter, not a compiler.
  17399. 13:40:33And the best analog of this is just to perhaps point out
  17400. 13:40:35that, in the human world, if you speak, or don't speak,
  17401. 13:40:38multiple human languages, it can be a pretty slow process from going
  17402. 13:40:42from one language to another.
  17403. 13:40:43For instance, here are step-by-step instructions for finding someone
  17404. 13:40:46in a phone book, unfortunately, in Spanish.
  17405. 13:40:49Unfortunately, if you don't speak or read Spanish.
  17406. 13:40:51You could figure this out.
  17407. 13:40:53You could run this algorithm, but you're going to have to do some googling,
  17408. 13:40:55or you're going to have to open up literal dictionary from Spanish
  17409. 13:40:58to English and convert this.
  17410. 13:40:59And the catch with translating any language, human or computer
  17411. 13:41:03or otherwise, is that you're going to pay a price, typically some time.
  17412. 13:41:07And so converting this in Spanish to this in English
  17413. 13:41:10is just going to take you longer than if this were already
  17414. 13:41:12in your native language.
  17415. 13:41:14And that's going to be one of the subtleties with the world of Python.
  17416. 13:41:17Yes, it's a feature that you can just run the code without having
  17417. 13:41:21to bother compiling it manually first.
  17418. 13:41:24But we might pay a price.
  17419. 13:41:25And things might be a little slower.
  17420. 13:41:27Now, there's ways to chip away at that.
  17421. 13:41:28But we'll see an example thereof.
  17422. 13:41:30In fact, let me transition now to just a couple of examples
  17423. 13:41:33that demonstrate how Python is not only easier for many people
  17424. 13:41:37to use, perhaps yourselves too, because it throws away
  17425. 13:41:39a lot of the annoying syntax, it shortens the number of lines
  17426. 13:41:42you have to write, and also it comes with so many darn libraries,
  17427. 13:41:46you can just do so much more without having to write the code yourself.
  17428. 13:41:51So, as an example of this, let me switch over here
  17429. 13:41:54to this image from problem set 4, which is the Weeks Bridge down by the Charles
  17430. 13:42:00River here in Cambridge.
  17431. 13:42:01And this is the original photo, pretty clear,
  17432. 13:42:03and it's even higher res if we looked at the original version of the photo.
  17433. 13:42:06But there have been no filters, a la Instagram, applied to this photo.
  17434. 13:42:10Recall, for problem set four, you had to implement a few filters.
  17435. 13:42:13And among them might have been blur.
  17436. 13:42:14And blur was probably among the more challenging of the ones,
  17437. 13:42:18because you had to iterate over all of the pixels,
  17438. 13:42:20you had to take into account what's above, what's below, to the left,
  17439. 13:42:23to the right.
  17440. 13:42:24I mean, there was a lot of math and arithmetic.
  17441. 13:42:25And if you ultimately got it, it was probably a great sense of satisfaction.
  17442. 13:42:29But that was probably several hours later.
  17443. 13:42:31In a language like Python, where there might
  17444. 13:42:34be libraries that had been written by others, on whose shoulders
  17445. 13:42:37you can stand, we could perhaps do something like this.
  17446. 13:42:40Let me go ahead and run a program, or write a program, called Blur.py here.
  17447. 13:42:44And in Blur.py, in VS Code, let me just do this.
  17448. 13:42:48Let me import from a library, not the CS50 library,
  17449. 13:42:51but the Pillow library, so to speak, a keyword called image
  17450. 13:42:56and another one called image filter, then let me go ahead
  17451. 13:42:59and say, let me open the current version of this image, which
  17452. 13:43:02is called Bridge.bmp.
  17453. 13:43:04So the before version of the image will be
  17454. 13:43:06the result of calling image.open quote unquote "Bridge.bmp,"
  17455. 13:43:11and then, let me create an after version.
  17456. 13:43:13So you'll see before and after.
  17457. 13:43:15After equals the before version .filter of image filter.
  17458. 13:43:21And there is, if I read the documentation,
  17459. 13:43:23I'll see that there's something called a box blur, that
  17460. 13:43:25allows you to blur in box format, like one pixel above,
  17461. 13:43:28below, left, and right.
  17462. 13:43:30So I'll do one pixel there.
  17463. 13:43:31And then, after that's done, let me go ahead and save the file
  17464. 13:43:34as something like Out.bmp.
  17465. 13:43:37That's it.
  17466. 13:43:38Assuming this library works as described,
  17467. 13:43:41I am opening the file in Python, using line 3.
  17468. 13:43:44And this is somewhat new syntax.
  17469. 13:43:46In the world of Python, we're going to start making use of the dot operator
  17470. 13:43:49more, because in the world of Python, you have
  17471. 13:43:51what's called object-oriented programming, or OOP, as a term of art.
  17472. 13:43:56And what this means is that you still have functions,
  17473. 13:43:58you still have variables, but sometimes those functions
  17474. 13:44:01are embedded inside of the variables, or, more specifically,
  17475. 13:44:05inside of the data types themselves.
  17476. 13:44:07Think back to C. When you wanted to convert something to uppercase,
  17477. 13:44:10there was a to upper function that takes as input an argument that's a char.
  17478. 13:44:15And you can pass in any char you want, and it will uppercase it for you
  17479. 13:44:18and give you back a value.
  17480. 13:44:19Well, you know what, if that's such a common paradigm, where
  17481. 13:44:22upper-casing chars is a useful thing, what the world of Python does
  17482. 13:44:26is it embeds into the string data type, or char if you will,
  17483. 13:44:30the ability just to uppercase any char by treating the char, or the string,
  17484. 13:44:35as though it's a struct in C. Recall that structs
  17485. 13:44:38encapsulate multiple types of values.
  17486. 13:44:40In object-oriented programming, in a language like Python,
  17487. 13:44:44you can encapsulate not just values, but also functionality.
  17488. 13:44:48Functions can now be inside of structs.
  17489. 13:44:50But we're not going to call them structs anymore.
  17490. 13:44:52We're going to call them objects.
  17491. 13:44:53But that's just a different vernacular.
  17492. 13:44:55So what am I doing here?
  17493. 13:44:57Inside of the image library, there's a function called open,
  17494. 13:45:00and it takes an argument, the name of the file, to open.
  17495. 13:45:03Once I have a variable called before, that is a struct, or technically
  17496. 13:45:06an object, inside of which is now, because it
  17497. 13:45:09was returned from this function, a function
  17498. 13:45:12called filter, that takes an argument.
  17499. 13:45:14The argument here happens to be image.boxblur1,
  17500. 13:45:18which itself is a function.
  17501. 13:45:19But it just returns the filter to use.
  17502. 13:45:21And then, after, dot save does what you might think.
  17503. 13:45:23It just saves the file.
  17504. 13:45:24So instead of using fopen and fwrite, you just say dot save,
  17505. 13:45:27and that does all of that messy work for you.
  17506. 13:45:31So it's just, what, four lines of code total?
  17507. 13:45:33Let me go ahead and go down to my terminal window.
  17508. 13:45:36Let me go ahead and show you with LS that, at the moment,
  17509. 13:45:40whoops, sorry, let me not bother showing that,
  17510. 13:45:41because I have other examples to come.
  17511. 13:45:43I'm going to go ahead and do Python of Blur.py, nope, sorry, wrong place.
  17512. 13:45:50I did need to make a command.
  17513. 13:45:52There we go.
  17514. 13:45:52OK, let me go ahead and type LS inside of my filter directory, which
  17515. 13:45:55is among the sample code online today.
  17516. 13:45:58There's only one file called Bridge.bmp, dammit,
  17517. 13:46:01I'm trying to get these things ready at the same time.
  17518. 13:46:04Let me rewind.
  17519. 13:46:05Let me move this code into place.
  17520. 13:46:08All right, I've gone ahead and moved this file, Blur.py,
  17521. 13:46:11into a folder called filter, inside of which
  17522. 13:46:13there's another file called Bridge.bmp, which we can confer with LS.
  17523. 13:46:18Let me now go ahead and run Python, which
  17524. 13:46:20is my interpreter, and also the name of the language,
  17525. 13:46:23and run Python on this file.
  17526. 13:46:25So much like running the Spanish algorithm
  17527. 13:46:27through Google Translate, or something like that,
  17528. 13:46:29as input, to get back the English output,
  17529. 13:46:32this is going to translate the Python language to something
  17530. 13:46:36this computer, or this cloud-based environment,
  17531. 13:46:38understands, and then run the corresponding code, top to bottom,
  17532. 13:46:41left to right.
  17533. 13:46:42I'm going to go ahead and Enter.
  17534. 13:46:43No error message is generally a good thing.
  17535. 13:46:45If I type LS you'll now see out.bmp.
  17536. 13:46:48Let me go ahead and open that.
  17537. 13:46:49And, you know what, just to make clear what's really happening,
  17538. 13:46:52let me blur it even further.
  17539. 13:46:53Let's make a box that's not just one pixel around, but 10.
  17540. 13:46:57So let's make that change.
  17541. 13:46:58And let me just go ahead and rerun it with Python of Blur.py.
  17542. 13:47:01I still have Out.bmp.
  17543. 13:47:03Let me go ahead and open Out.bmp and show you first the before,
  17544. 13:47:08which looks like this.
  17545. 13:47:10That's the original.
  17546. 13:47:11And now, crossing my fingers, four lines of code later,
  17547. 13:47:14the result of blurring it, as well.
  17548. 13:47:16So the library is doing all of the same kind of legwork
  17549. 13:47:18that you all did for the assignment, but it's
  17550. 13:47:20encapsulated it all into a single library, that you can then use instead.
  17551. 13:47:24Those of you who might have been feeling more comfortable,
  17552. 13:47:27might have done a little something like this.
  17553. 13:47:29Let me go ahead and open up one other file, called Edges.py.
  17554. 13:47:33And in Edges.py, I'm again going to import from the Pillow library
  17555. 13:47:36the image keyword, and the image filter.
  17556. 13:47:39Then I'm going to go ahead and create a before image, that's
  17557. 13:47:42a result of calling image.open of the same thing, Bridge.bmp,
  17558. 13:47:46then I'm going to go ahead and run a filter on that, called image, whoops,
  17559. 13:47:53image filter.find edges, which is like a content, if you will,
  17560. 13:47:58defined inside of this library for us.
  17561. 13:48:00And then I'm going to do after.save quote unquote
  17562. 13:48:02"Out.bmp," using the same file name.
  17563. 13:48:04I'm now going to run Python of Edges.py, after, sorry, user error.
  17564. 13:48:13We'll see what syntax error means soon.
  17565. 13:48:15Let me go ahead and run the code now, Edges.py.
  17566. 13:48:17Let me now open that new file, Out.bmp.
  17567. 13:48:21And before we had this, and now, especially if what will look familiar
  17568. 13:48:26if we did the more comfortable version of P set 4,
  17569. 13:48:28we now get this, after just four lines of code.
  17570. 13:48:31So again, suggesting the power of using a language that's better
  17571. 13:48:34optimized for the tool at hand.
  17572. 13:48:36And at the risk of really making folks sad, let's go ahead
  17573. 13:48:39and re-implement, if we could, problem set five, real quickly here.
  17574. 13:48:43Let me go ahead and open another version of this code,
  17575. 13:48:47wherein I have a C version, just from problem
  17576. 13:48:50set five, wherein you implemented a spell checker,
  17577. 13:48:52loading 100,000 plus words into memory.
  17578. 13:48:55And then you kept track of just how much time and memory it took.
  17579. 13:48:58And that probably took a while, implementing
  17580. 13:49:00all of those functions in Dictionary.c.
  17581. 13:49:03Let me instead now go into a new file, called Dictionary.py.
  17582. 13:49:08And let me stipulate, for the sake of discussion,
  17583. 13:49:11that we already wrote in advance, Speller.py,
  17584. 13:49:14which corresponds to Speller.c.
  17585. 13:49:16You didn't write either of those.
  17586. 13:49:17Recall for problem set five, we gave you Speller.c.
  17587. 13:49:20Assume that we're going to give you Speller.py.
  17588. 13:49:22So the onus on us right now is only to implement Speller, Dictionary.py.
  17589. 13:49:28All right, so I'm going to go ahead and define a few functions.
  17590. 13:49:31And we're going to see now the syntax for defining functions in Python.
  17591. 13:49:34I want to go ahead and define first, a hash table, which
  17592. 13:49:38was the very first thing you defined in Dictionary.c.
  17593. 13:49:41I'm going to go ahead, then, and say words gets this, give me a dictionary,
  17594. 13:49:46otherwise known as a hash table.
  17595. 13:49:48All right, now let me define a function called
  17596. 13:49:50check, which was the first function you might have implemented.
  17597. 13:49:53Check is going to take a word, and you'll see in Python,
  17598. 13:49:55the syntax is a little different.
  17599. 13:49:56You don't specify the return type.
  17600. 13:49:58You use the word Def instead to define.
  17601. 13:50:01You still specify the name of the function and any arguments thereto.
  17602. 13:50:05But you omit any mention of types.
  17603. 13:50:07But you do use a colon and indent.
  17604. 13:50:09So how do I check if a word is in my dictionary, or in my hash table?
  17605. 13:50:14Well, in Python, I can just say, if word in words,
  17606. 13:50:17go ahead and return true, else go ahead and return false, done,
  17607. 13:50:23with the check function.
  17608. 13:50:24All right, now I want to do like load.
  17609. 13:50:26That was the heavy lift, where you had to load the big file into memory.
  17610. 13:50:29So let me define a function called load.
  17611. 13:50:30It takes a string, the name of a file to load.
  17612. 13:50:33So I'll call that Dictionary, just like in C, but no data type.
  17613. 13:50:36Let me go ahead and open a file by using an open function in Python,
  17614. 13:50:40by opening that Dictionary in read mode.
  17615. 13:50:43So this is a little similar to fopen, a function in C you might recall.
  17616. 13:50:46Then let me iterate over every line in the file.
  17617. 13:50:49In Python, this is pretty pleasant, for line in file colon indent.
  17618. 13:50:54How, now, do I get at the current word, and then strip off the new line,
  17619. 13:50:59because in this file of words, 140,000 words,
  17620. 13:51:02there's word backslash n, word backslash n, all right?
  17621. 13:51:05Well, let me go ahead and get a word from the current line,
  17622. 13:51:07but strip off, from the right end of the string, the new line, which
  17623. 13:51:11the Rstrip function in Python does for me.
  17624. 13:51:14Then let me go ahead and add to my dictionary, or hash table, that word,
  17625. 13:51:18done.
  17626. 13:51:19Let me go ahead and close the file for good measure.
  17627. 13:51:22And then let me go ahead and return true, because all was well.
  17628. 13:51:24That's it for the load function in Python.
  17629. 13:51:26How about the size function?
  17630. 13:51:28This did not take any arguments, it just returns the size of the hash table
  17631. 13:51:31or dictionary in Python.
  17632. 13:51:32I can do that by returning the length of the dictionary in question.
  17633. 13:51:36And then lastly, gone from the world of Python is malloc and free.
  17634. 13:51:41Memory is managed for you.
  17635. 13:51:42So no matter what I do, there's nothing to unload.
  17636. 13:51:45The computer will do that for me.
  17637. 13:51:47So I give you, in these functions, problem set five in Python.
  17638. 13:51:51So, I'm sorry, we made you write it in C first.
  17639. 13:51:53But the implication now is that, what are you getting for free,
  17640. 13:51:57in a language like Python?
  17641. 13:51:58Well, encapsulated in this one line of code
  17642. 13:52:00is much of what you wrote for problem set five, implementing
  17643. 13:52:04your array for all of your letters of the alphabet or more,
  17644. 13:52:07all of the linked lists that you implemented to create chains,
  17645. 13:52:10to store all of those words.
  17646. 13:52:12All of that is happening.
  17647. 13:52:13It's just someone else in the world wrote that code for you.
  17648. 13:52:16And you can now use it by way of a dictionary.
  17649. 13:52:19And actually, I can change this a little bit,
  17650. 13:52:22because add is technically not the right function to use here.
  17651. 13:52:25I'm actually treating the dictionary as something simpler, a set.
  17652. 13:52:28So I'm going to make one tweak, set recall was another data type in Python.
  17653. 13:52:31But set just allows it to handle duplicates,
  17654. 13:52:34and it allows me to just throw things into it by literally
  17655. 13:52:36using a function as simple as add.
  17656. 13:52:38And I'm going to make one other tweak here,
  17657. 13:52:41because, when I'm checking a word, it's possible it might be given
  17658. 13:52:46to me in uppercase or capitalized.
  17659. 13:52:49It's not going to necessarily come in in the same lowercase format
  17660. 13:52:52that my dictionary did.
  17661. 13:52:53I can force every word to lowercase by using word.lower.
  17662. 13:52:58And I don't have to do it character for character,
  17663. 13:53:01I can do the whole darn string at once, by just saying word.lower.
  17664. 13:53:06All right, let me go ahead and open up a terminal window here.
  17665. 13:53:09And let me go into, first, my C version, on the left.
  17666. 13:53:12And actually I'm going to go ahead and split my terminal window into two.
  17667. 13:53:15And on the right, I'm going to go into a version that I essentially just wrote.
  17668. 13:53:20But it's also available online, if you want to play along afterward.
  17669. 13:53:23I'm going to go ahead and make speller in C on the left,
  17670. 13:53:26and note that it takes a moment to compile.
  17671. 13:53:28Then I'm going to be ready to run speller of dictionaries,
  17672. 13:53:33let's do like the Sherlock Holmes text, which is pretty big.
  17673. 13:53:35And then over here, let me get ready to run Python of speller
  17674. 13:53:40on texts/homes.txt2.
  17675. 13:53:44So the syntax is a little different at the command prompt.
  17676. 13:53:46I just, on the left, have to compile the code, with make,
  17677. 13:53:49and then run it with ./speller.
  17678. 13:53:51On the right, I don't need to compile it.
  17679. 13:53:52But I do need to use the interpreter.
  17680. 13:53:54So even though the lines are wrapping a little bit here,
  17681. 13:53:56let me go ahead and run it on the right.
  17682. 13:53:58And I'm going to count how long it takes, verbally,
  17683. 13:54:00for demonstration sake.
  17684. 13:54:02One Mississippi, two Mississippi, three Mississippi, OK,
  17685. 13:54:05so it's like three seconds, give or take.
  17686. 13:54:07Now running it in Python, keeping in mind,
  17687. 13:54:10I spent way fewer hours implementing a spell checker in Python
  17688. 13:54:13than you might have in problem set five.
  17689. 13:54:15But what's the trade-off going to be, and what kinds of design decisions
  17690. 13:54:18do we all now need to be making consciously?
  17691. 13:54:20Here we go, on the right, in Python.
  17692. 13:54:22One Mississippi, two Mississippi, three Mississippi, four Mississippi,
  17693. 13:54:26five Mississippi, six Mississippi, seven Mississippi, eight Mississippi,
  17694. 13:54:30nine Mississippi, 10 Mississippi, 11 Mississippi,
  17695. 13:54:33all right, so 10 or 11 seconds.
  17696. 13:54:36So which one is better?
  17697. 13:54:38Let's go to the group here, which of these programs is the better one?
  17698. 13:54:43How might you answer that question, based on demonstration alone?
  17699. 13:54:47What do you think?
  17700. 13:54:48AUDIENCE: I think Python's better for the programmer,
  17701. 13:54:50more comfortable for the programmer, but C is better for the user.
  17702. 13:54:54DAVID J. MALAN: OK, so Python, to summarize,
  17703. 13:54:56is better for the programmer, because it was way faster to write,
  17704. 13:54:59but C is maybe better for the computer, because it's much faster to run.
  17705. 13:55:02I think that's a reasonable formulation.
  17706. 13:55:04Other opinions?
  17707. 13:55:05Yeah.
  17708. 13:55:07AUDIENCE: I think it depends on the size of the project
  17709. 13:55:09that you're dealing with.
  17710. 13:55:10So if it's going to be something that's relatively quick,
  17711. 13:55:12I might not care that it takes 10 seconds to do it.
  17712. 13:55:15And it could be way faster to do it with Python.
  17713. 13:55:17Whereas with C, if I'm dealing with something like a massive data
  17714. 13:55:20set or something huge, then that time is going to really build up on,
  17715. 13:55:24it might be worth it to put in the upfront effort and just load it into C,
  17716. 13:55:29so the process continually will run faster over a longer period of time.
  17717. 13:55:32DAVID J. MALAN: Absolutely, a really good answer.
  17718. 13:55:33And let me summarize, is it depends on the workload, if you will.
  17719. 13:55:36If you have a very large data set, you might
  17720. 13:55:40want to optimize your code to be as fast and performant as it can be,
  17721. 13:55:43especially if you're running that code again and again.
  17722. 13:55:45Maybe you're a company like Google.
  17723. 13:55:47People are searching a huge database all the time.
  17724. 13:55:49You really want to squeeze every bit of performance
  17725. 13:55:52as you can out of the computer.
  17726. 13:55:53You might want to have someone smart take a language like C
  17727. 13:55:56and write it at a very low level.
  17728. 13:55:57It's going to be painful.
  17729. 13:55:59They're going to have bugs.
  17730. 13:55:59They're going to have to deal with memory management and the like.
  17731. 13:56:02But if and when it works correctly, it's going to be much faster, it would seem.
  17732. 13:56:06By contrast, if you have a data set that's big,
  17733. 13:56:08and 140,000 words is not small, but you don't
  17734. 13:56:12want to spend like 5 hours, 10 hours, a week of your time,
  17735. 13:56:15building a spell checker or a dictionary,
  17736. 13:56:17you can instead leverage a different language with different libraries
  17737. 13:56:20and build on top of it, in order to prioritize the human time instead.
  17738. 13:56:25Other thoughts?
  17739. 13:56:27AUDIENCE: Would you, because with Python,
  17740. 13:56:29doesn't it also like convert the words, or like
  17741. 13:56:33convert the words, for a lesson?
  17742. 13:56:35When we convert that into the same version again,
  17743. 13:56:37do we just take that into view?
  17744. 13:56:40DAVID J. MALAN: That's a perfect segue to exactly the next point we
  17745. 13:56:43wanted to make, which was, is there something in between?
  17746. 13:56:45And indeed there is.
  17747. 13:56:46I'm oversimplifying what this language is actually doing.
  17748. 13:56:49It's not as stark a difference as saying, like, hey,
  17749. 13:56:51Python is four times slower than C. Like that's not the right takeaway.
  17750. 13:56:54There are absolutely ways that engineers can optimize languages,
  17751. 13:56:57as they have already done for Python.
  17752. 13:56:59And in fact, I've configured my settings in such a way
  17753. 13:57:02that I've kind of dramatized just how big the difference is.
  17754. 13:57:05It is going to be slower, Python, typically,
  17755. 13:57:07than the equivalent C program.
  17756. 13:57:08But it doesn't have to be as big of a gap
  17757. 13:57:10as it is here, because, indeed, among the features you can turn on in Python
  17758. 13:57:14is to save some intermediate results.
  17759. 13:57:16Technically speaking, yes, Python is interpreting
  17760. 13:57:19Dictionary.py and these other files, translating them
  17761. 13:57:23from one language to another.
  17762. 13:57:24But that doesn't mean it has to do that every darn time you run the program.
  17763. 13:57:27As you propose, you can save, or cache, C-A-C-H-E, the results of that process.
  17764. 13:57:33So that the second time and the third time are actually notably faster.
  17765. 13:57:36And, in fact, Python itself, the interpreter, the most popular version
  17766. 13:57:39thereof, itself is actually implemented in C.
  17767. 13:57:42So you can make sure that your interpreter is as fast as possible.
  17768. 13:57:45And what then is maybe the high level takeaway?
  17769. 13:57:47Yes, if you are going to try to squeeze every bit of performance
  17770. 13:57:50out of your code, and maybe code is constrained.
  17771. 13:57:54Maybe you have very small devices.
  17772. 13:57:55Maybe it's like a watch nowadays.
  17773. 13:57:57Or maybe it's a sensor that's installed in some small format in an appliance,
  17774. 13:58:02or in infrastructure, where you don't have much battery life
  17775. 13:58:06and you don't have much size, you might want
  17776. 13:58:08to minimize just how much work is being done.
  17777. 13:58:10And so the faster the code runs, and the better it's going to be,
  17778. 13:58:13if it's implemented something low level.
  17779. 13:58:14So C is still very commonly used for certain types of applications.
  17780. 13:58:18But, again, if you just want to solve real world problems,
  17781. 13:58:22and get real work done, and your time is just as, if not more, valuable
  17782. 13:58:26than the device you're running it on, long term,
  17783. 13:58:28you know what, Python is among the most popular languages as well.
  17784. 13:58:31And frankly, if I were implementing a spell checker moving forward,
  17785. 13:58:34I'm probably starting with Python.
  17786. 13:58:36And I'm not going to waste time implementing
  17787. 13:58:38all of that low-level stuff, because the whole point of using newer,
  17788. 13:58:41modern languages is to use abstractions that other people have created for you.
  17789. 13:58:45And by abstraction, I mean something like the dictionary function,
  17790. 13:58:49that just gives you a dictionary, or hash table,
  17791. 13:58:51or the equivalent version that I used, which in this case was a set.
  17792. 13:58:55All right, any questions, then, on Python thus far?
  17793. 13:59:02No, all right.
  17794. 13:59:03Oh, yeah, in the middle.
  17795. 13:59:04AUDIENCE: Could you compile the Python code,
  17796. 13:59:06or is there some, I'd imagine that with the audience that can happen,
  17797. 13:59:11but it feels like if you can just come up with a Python compiler,
  17798. 13:59:14that would give you the best of both worlds.
  17799. 13:59:16DAVID J. MALAN: Really good question or observation,
  17800. 13:59:18could you just compile Python code?
  17801. 13:59:20Yes, absolutely, this idea of compiling code or interpreting code
  17802. 13:59:23is not native to the language itself.
  17803. 13:59:26It tends to be native to the conventions that we humans use.
  17804. 13:59:28So you could actually write an interpreter for C
  17805. 13:59:31that would read it top to bottom, left to right, converting it to, on the fly,
  17806. 13:59:34something the computer understands, but historically that's not been the case.
  17807. 13:59:38C is generally a compiled language.
  17808. 13:59:40But it doesn't have to be.
  17809. 13:59:41What Python nowadays is actually doing is what you described earlier.
  17810. 13:59:44It technically is, sort of unbeknownst to us,
  17811. 13:59:46compiling the code, technically not into 0's and 1's, technically
  17812. 13:59:50into something called byte code, which is this intermediate step that
  17813. 13:59:54just doesn't take as much time as it would to recompile the whole thing.
  17814. 13:59:58And this is an area of research for computer scientists working
  17815. 14:00:00in programming languages, to improve these kinds of paradigms.
  17816. 14:00:03Why?
  17817. 14:00:04Well, honestly, for you and I, the programmer, it's just much easier to,
  17818. 14:00:07one, run the code and not worry about the stupid second step
  17819. 14:00:10of compiling it all the time.
  17820. 14:00:11Why?
  17821. 14:00:12It's literally half as many steps for me, the human.
  17822. 14:00:14And that's a nice thing to optimize for.
  17823. 14:00:17And ultimately, too, you might want all of the fancy features that
  17824. 14:00:20come with these other languages.
  17825. 14:00:22So you should really just be fine-tuning how
  17826. 14:00:24you can enable these features, as opposed to shying away from them here.
  17827. 14:00:28And, in fact, the only time I personally ever use C
  17828. 14:00:31is from like September to October of every year, during CS50.
  17829. 14:00:34Almost every other month do I reach for Python,
  17830. 14:00:36or another language called JavaScript, to actually get real work done,
  17831. 14:00:40which is not to impugn C. It's just that those other languages tend to be better
  17832. 14:00:44fits for the amount of time I have to allocate, and the types of problems
  17833. 14:00:47that I want to solve.
  17834. 14:00:48All right, let's go ahead and take a five minute break here.
  17835. 14:00:50And when we come back, we'll start writing some programs from Scratch.
  17836. 14:00:53All right.
  17837. 14:00:54So let's go ahead and start writing some code from the beginning
  17838. 14:00:58here, whereby we start small with some simple examples,
  17839. 14:01:01and then we'll build our way up to more sophisticated examples in Python.
  17840. 14:01:04But what we'll do along the way is first,
  17841. 14:01:06look side by side at what the C code looked
  17842. 14:01:08like way back in week 1 or 2 or 3 and so forth,
  17843. 14:01:11and then write the corresponding Python code at right.
  17844. 14:01:13And then we'll transition just to focusing on Python itself.
  17845. 14:01:16What I've done in advance today is I've downloaded some of the code
  17846. 14:01:18from the course's website, my source 6 directory, which
  17847. 14:01:21contains all of the pre-written C code from weeks past.
  17848. 14:01:24But it'll also have copies of the Python code
  17849. 14:01:26we'll write here together and look at.
  17850. 14:01:28So first, here is Hello.c back from week 0.
  17851. 14:01:31And this was version 0 of it.
  17852. 14:01:33I'm going to go ahead and do this.
  17853. 14:01:35I'm going to go ahead and split my code window up here.
  17854. 14:01:38I'm going to go ahead and create a new file called Hello.py.
  17855. 14:01:41And this isn't something you'll typically have to do,
  17856. 14:01:43laying your code out side by side.
  17857. 14:01:45But I've just clicked the little icon in VS Code
  17858. 14:01:47that looks like two columns, that splits my code editor into two places,
  17859. 14:01:50so that we can, in fact, see things, for now, side by side,
  17860. 14:01:53with my terminal window down below.
  17861. 14:01:55All right, now I'm going to go ahead and write the corresponding Python
  17862. 14:01:58program on the right, which, recall, was just print, quote
  17863. 14:02:01unquote, "Hello, world," and that's it.
  17864. 14:02:03Now down in my terminal window, I'm going
  17865. 14:02:05to go ahead and run Python of Hello.py, Enter, and voila,
  17866. 14:02:09we've got Hello.py working.
  17867. 14:02:10So again, I'm not going to play any further with the C code.
  17868. 14:02:13It's there just to jog your memory left and right.
  17869. 14:02:15So let's now look at a second version of Hello, world
  17870. 14:02:17from that first week, whereby if I go and get Hello1.c,
  17871. 14:02:20I'm going to drag that over to the right.
  17872. 14:02:22Whoops, I'm going to go ahead and drag that over to the left here.
  17873. 14:02:25And now, on the right, let's modify Hello.py
  17874. 14:02:28to look a little more like this second version in C, all right?
  17875. 14:02:32I want to get an answer from the user as a return value,
  17876. 14:02:36but I also want to get some input from them.
  17877. 14:02:38So from CS50, I'm going to import the function called getString for now.
  17878. 14:02:41We're going to get rid of that eventually,
  17879. 14:02:43but for now, it's a helpful training wheel.
  17880. 14:02:45And then down here, I'm going to say, answer
  17881. 14:02:47equals getString quote unquote, "What's your name"?
  17882. 14:02:51Question mark, space.
  17883. 14:02:52But no semicolon, no data type.
  17884. 14:02:53And then I'm going to go ahead and print, just
  17885. 14:02:55like the first example on the slide, Hello, comma space plus answer.
  17886. 14:03:01And now let me go ahead and run this.
  17887. 14:03:03Python, of Hello.py, all right, it's asking me what's my name.
  17888. 14:03:06David.
  17889. 14:03:06Hello comma David.
  17890. 14:03:07But it's worth calling attention to the fact that I've also simplified further.
  17891. 14:03:13It's not just that the individual functions are simpler.
  17892. 14:03:15What is also now glaringly omitted from my Python code at right,
  17893. 14:03:18both in this version, and the previous version.
  17894. 14:03:21What did I not bother implementing?
  17895. 14:03:22AUDIENCE: The main code.
  17896. 14:03:23DAVID J. MALAN: Yeah, so I didn't even need to implement main.
  17897. 14:03:26We'll revisit the main function, because having a main function
  17898. 14:03:29actually does solve problems sometimes.
  17899. 14:03:31But it's no longer required.
  17900. 14:03:32In C you have to have that to kick-start the entire process of actually running
  17901. 14:03:36your code.
  17902. 14:03:36And in fact, if you were missing main, as you might have experienced
  17903. 14:03:39if you accidentally compiled Helpers.c instead of the file
  17904. 14:03:42that contained main, you would have seen a compiler error.
  17905. 14:03:44In Python it's not necessary.
  17906. 14:03:46In Python you can just jump right in, start programming, and boom,
  17907. 14:03:48you're good to go.
  17908. 14:03:49Especially if it's a small program like this,
  17909. 14:03:51you don't need the added overhead or complexity of a main function.
  17910. 14:03:54So that's one other difference here.
  17911. 14:03:56All right, there are a few other ways we could say Hello, world.
  17912. 14:03:59Recall that I could use a format string.
  17913. 14:04:02So I could put this whole thing in quotes, I could use this f prefix.
  17914. 14:04:06And then let me go ahead and run Python of Hello.py again.
  17915. 14:04:09You can perhaps see where we're going with this.
  17916. 14:04:11Let me type my name, David, and here we go.
  17917. 14:04:13OK, that's the mistake that someone identified earlier,
  17918. 14:04:16you need the curly braces.
  17919. 14:04:17Otherwise no variables are interpolated, that is substituted,
  17920. 14:04:21with their actual values.
  17921. 14:04:22So if I go back in and add those curly braces to the F string,
  17922. 14:04:26now let me run Python of Hello.py, type in my name, and there we go.
  17923. 14:04:31We're back in business.
  17924. 14:04:32Which one's better?
  17925. 14:04:32I mean, it depends.
  17926. 14:04:33But generally speaking, making shorter, more concise code
  17927. 14:04:37tends to be a good thing.
  17928. 14:04:38So stylistically, the F string is probably a reasonable instinct to have.
  17929. 14:04:42All right, well, what more can we do besides this?
  17930. 14:04:45Well, let me go ahead here and let's get rid of the training wheel
  17931. 14:04:48altogether, actually.
  17932. 14:04:49So same C code at left.
  17933. 14:04:51Let me get rid of the CS50 library, which we will ultimately,
  17934. 14:04:54in a couple of weeks, anyway.
  17935. 14:04:56I can't use getString, but I can use a function
  17936. 14:04:59that comes with Python called input.
  17937. 14:05:01And, in fact, this is actually a one-for-one substitution, pretty much.
  17938. 14:05:04There's really no downside to using input instead of getString.
  17939. 14:05:07We implement getString just for consistency
  17940. 14:05:09with what you saw in C. Python of Hello.py, what's your name, David.
  17941. 14:05:14Still actually works the same.
  17942. 14:05:15So gone are the CS50 specific training wheels.
  17943. 14:05:17But we're going to bring them back shortly, just
  17944. 14:05:19to deal with integers or floats or other values,
  17945. 14:05:21too, because it's going to make our lives a little simpler,
  17946. 14:05:24with error checking.
  17947. 14:05:25All right, any questions, before we now pivot to revisiting other examples
  17948. 14:05:28from week 1, but now in Python?
  17949. 14:05:32All right, let me go ahead and open up now.
  17950. 14:05:34Let's say Calculator0.c, which was one of the first examples we did involving
  17951. 14:05:39math and operators like that, as well as functions like getInt,
  17952. 14:05:43let me go ahead and create a new file now called Calculator.py,
  17953. 14:05:48at right, so that I have my C code at left still,
  17954. 14:05:51and my Python code at right.
  17955. 14:05:53All right, let me go dive into a translation of this code into Python.
  17956. 14:05:57I am going to use getInt from the CS50 library.
  17957. 14:05:59So let me import that.
  17958. 14:06:01I'm going to go ahead now and get an Int from the user.
  17959. 14:06:03So x equals getInt, and I'll ask them for an x value,
  17960. 14:06:07just like we did weeks ago.
  17961. 14:06:08No need to specify a semicolon, though, or an Int for the x.
  17962. 14:06:14It will just figure it out.
  17963. 14:06:15Y is going to get another Int via y colon,
  17964. 14:06:18and then down here, I'm going to go ahead and say print of x plus y.
  17965. 14:06:23So this is already a bit new.
  17966. 14:06:25Recall, the C version required that I use this format string, as well
  17967. 14:06:29as printf itself.
  17968. 14:06:30Python is just a little more user-friendly.
  17969. 14:06:32If all you want to do is print out a value, like x plus y, just print it.
  17970. 14:06:36Don't futz with any percent signs or format codes.
  17971. 14:06:39It's not printf, it's indeed just print now.
  17972. 14:06:41All right, let me go ahead and run Python of Calculator.py,
  17973. 14:06:45Enter, just do a quick sample, 1 plus 2 indeed equals 3.
  17974. 14:06:50As an aside, suppose I had taken a different approach
  17975. 14:06:52to importing the whole CS50 library, functionally, it's the same.
  17976. 14:06:56You're not to notice any performance impact here.
  17977. 14:06:58It's a small library.
  17978. 14:06:59But notice what does not work now, whereas it did work
  17979. 14:07:02in C. Python of Calculator.py, Enter, we see our first traceback deliberately
  17980. 14:07:07here.
  17981. 14:07:08So a traceback is just a term of art that
  17982. 14:07:10says, here is a trace back through all of the functions
  17983. 14:07:13that just got executed.
  17984. 14:07:14In the world of C, you might call this a stack
  17985. 14:07:16trace, stack being the operative word.
  17986. 14:07:19Recall that when we talked about the stack and the heap,
  17987. 14:07:21the stack, like a stack of trays, was all of the functions that
  17988. 14:07:24might get called, one after the other.
  17989. 14:07:26We had main, we had swap, then swap went away, and then main finished, recall.
  17990. 14:07:30So here's a trace back of all of the functions or code that got executed.
  17991. 14:07:34There's not really any functions other than my file itself.
  17992. 14:07:37Otherwise there'd be more detail.
  17993. 14:07:38But even though it's a little cryptic, we can perhaps infer from the output
  17994. 14:07:42here, name error, so something related to the name of something, name, getInt
  17995. 14:07:46is not defined.
  17996. 14:07:47And this of course, happens on line 3 over there.
  17997. 14:07:50All right, so why is that?
  17998. 14:07:52Well, Python essentially allows us to namespace
  17999. 14:07:55our functions that come from libraries.
  18000. 14:07:58There was a problem in C. If you were using the CS50 library,
  18001. 14:08:01and thus had access to getInt, getString,
  18002. 14:08:03and so forth, you could not use another library
  18003. 14:08:06that had the same function names.
  18004. 14:08:08They would collide, and the compiler would not
  18005. 14:08:10know how to link them together correctly.
  18006. 14:08:12In Python, and other languages like JavaScript, and in Java,
  18007. 14:08:18you have support for effectively what would be called namespaces.
  18008. 14:08:21You can isolate variables and function names to their own namespace,
  18009. 14:08:26like their own container in memory.
  18010. 14:08:29And what this means is, if you import all of CS50,
  18011. 14:08:32you have to say that the getInt you want is inside the CS50 library.
  18012. 14:08:36So just like with the image blurring, and the image edges
  18013. 14:08:39before, where I had to specify image dot and image filter dot, similarly here,
  18014. 14:08:44am I specifying with a dot operator, albeit a little differently, that I
  18015. 14:08:48want CS50.getInt in both places.
  18016. 14:08:50And now if I rerun Python of Calculator.py, 1 and 2,
  18017. 14:08:54now we're back in business.
  18018. 14:08:56Which one is better?
  18019. 14:08:57Generally speaking, it depends on just how many functions
  18020. 14:09:01you're using from the library.
  18021. 14:09:02If you're using a whole bunch of functions, just import the whole thing.
  18022. 14:09:05If you're only using maybe one or two, import them line by line.
  18023. 14:09:09All right, so let's go ahead and make a little tweak here.
  18024. 14:09:12Let's get rid of this library and take this training wheel off,
  18025. 14:09:15too, as quickly as we introduced it, though for the problems set six
  18026. 14:09:18you'll be able to use all of these same functions.
  18027. 14:09:20Suppose I get rid of this, and I just use the input function,
  18028. 14:09:24just like I did by replacing getString earlier.
  18029. 14:09:28Let me go ahead now and run this version of the code.
  18030. 14:09:31Python of Calculator.py, OK, how about 1 plus 2 equals 3.
  18031. 14:09:37Huh.
  18032. 14:09:39All right, obviously wrong, incorrect.
  18033. 14:09:41Can anyone explain what just happened, based on instincts?
  18034. 14:09:46What just happened here.
  18035. 14:09:47Yeah.
  18036. 14:09:47AUDIENCE: You want an answer?
  18037. 14:09:49DAVID J. MALAN: Sure, yeah.
  18038. 14:09:50AUDIENCE: Say you have a number of strings that don't have Ints,
  18039. 14:09:54so you would part with them and say, printing one, two, better.
  18040. 14:09:57DAVID J. MALAN: Exactly, Python is interpreting, or treating,
  18041. 14:10:01both x and y as strings, which is actually
  18042. 14:10:03what the input function returns by default.
  18043. 14:10:05And so plus is now being interpreted as concatenation, as we defined it
  18044. 14:10:08earlier.
  18045. 14:10:09So x plus y isn't x plus y mathematically,
  18046. 14:10:12but in terms of string joining, just like in Scratch.
  18047. 14:10:15So that's why we're getting 12, or really one two,
  18048. 14:10:18which isn't itself a number.
  18049. 14:10:19It, too, is another string.
  18050. 14:10:20So we somehow need to convert things.
  18051. 14:10:22And we didn't have this ability quite as easily in C.
  18052. 14:10:25We did have like the A to i function, ASCII to integer,
  18053. 14:10:29which did allow you to do this.
  18054. 14:10:30The analog in Python is actually just to do a cast, a typecast, using Int.
  18055. 14:10:35So just like in C, you can use the keyword Int,
  18056. 14:10:39but you use it a little differently.
  18057. 14:10:41Notice that I'm not doing parenthesis Int close parenthesis before the value.
  18058. 14:10:45I'm using Int as a function.
  18059. 14:10:47So indeed, in Python, Int is a function.
  18060. 14:10:49Float is a function, that you can pass values into,
  18061. 14:10:53to do this kind of conversion.
  18062. 14:10:54So now, if I run Python of Calculator.py, 1 and 2,
  18063. 14:10:58now we're back in business, and getting the answer of 3.
  18064. 14:11:01But there's kind of a catch here.
  18065. 14:11:03There's always going to be a trade-off.
  18066. 14:11:04Like that sounds amazing that it just works in this way.
  18067. 14:11:07We can throw away the CS50 library already.
  18068. 14:11:08But what if the user accidentally types, or maliciously types in,
  18069. 14:11:13like a cat, instead of a number.
  18070. 14:11:15Damn, well, there's one of these trace backs.
  18071. 14:11:17Like, now my program has crashed.
  18072. 14:11:19This is similar in spirit to the kinds of segfaults
  18073. 14:11:21that you might have had in C.
  18074. 14:11:23But they're not segfaults per se.
  18075. 14:11:24It doesn't necessarily relate to memory.
  18076. 14:11:26This time it relates to actual runtime values, not being as expected.
  18077. 14:11:31So this time it's not a name error, it's a value error,
  18078. 14:11:34invalid literal for Int with base 10 quote unquote "cat."
  18079. 14:11:39So, again, it's written for sort of a programmer, more than sort
  18080. 14:11:43of a typical person, because it's pretty arcane, the language here.
  18081. 14:11:46But let's try to interpret it.
  18082. 14:11:47Invalid literal, a literal is just something someone typed for Int, which
  18083. 14:11:51is the function name, with base 10.
  18084. 14:11:52It's just defaulting to decimal numbers.
  18085. 14:11:54Cat is apparently not a decimal number.
  18086. 14:11:56It doesn't look like it, therefore it can't be treated like it.
  18087. 14:11:59Therefore, there's a value error.
  18088. 14:12:01So what can we do?
  18089. 14:12:03Unfortunately, you would have to somehow catch this error.
  18090. 14:12:06And the only way to do that in Python really
  18091. 14:12:08is by way of another feature that C did not have,
  18092. 14:12:11namely, what are called exceptions.
  18093. 14:12:13An exception is exactly what just happened, name error, value error.
  18094. 14:12:18They are things that can go wrong when your Python code is running,
  18095. 14:12:22that aren't necessarily going to be detected until you run your code.
  18096. 14:12:27So in Python, and in JavaScript, and in Java, and other more modern languages,
  18097. 14:12:32there's this ability to actually try to do something,
  18098. 14:12:35except if something goes wrong.
  18099. 14:12:37And in fact, I'm going to introduce a bit of syntax
  18100. 14:12:39here, even though we won't have to use this much just yet.
  18101. 14:12:42Instead of just blindly converting x to an Int, let me go ahead
  18102. 14:12:46and try to do that.
  18103. 14:12:48And if there's an exception, go ahead and say something
  18104. 14:12:51like print, that is not an Int.
  18105. 14:12:58And then I'm going to do something like exit, right there.
  18106. 14:13:02And let me go ahead and do this here.
  18107. 14:13:03Let me try to get y, except if there's an exception.
  18108. 14:13:07Then let me go ahead and say, again, that is not an Int exclamation point.
  18109. 14:13:12And then I'm going to exit from there to, otherwise I'll
  18110. 14:13:14go ahead and print x plus y.
  18111. 14:13:16If I run Python of Calculator.py now, whoops, oh,
  18112. 14:13:22forgot my close quote, sorry.
  18113. 14:13:25All right, so close quote, Python of Calculator.py, 1 and 2 still work.
  18114. 14:13:31But if I try to type in something wrong like cat, now
  18115. 14:13:34it actually detects the error.
  18116. 14:13:35So what is the CS50 library in Python doing?
  18117. 14:13:38It's actually doing that try and accept for you, because suffice it to say,
  18118. 14:13:42otherwise your programs for something simple, like a calculator,
  18119. 14:13:45start to get longer and longer.
  18120. 14:13:46So we factored that kind of logic out to the CS50 getInt
  18121. 14:13:49function and get float function.
  18122. 14:13:51But underneath the hood, they're essentially doing this, try except,
  18123. 14:13:55but they're being a little more precise.
  18124. 14:13:56They're detecting a specific error, and they are doing it in a loop,
  18125. 14:14:00so that these functions will get executed again and again.
  18126. 14:14:03In fact, the best way to do this is to say except if there's a value error,
  18127. 14:14:07then print that error message out to the user.
  18128. 14:14:10And again, let's not get too into the weeds here with this feature.
  18129. 14:14:13We've already put into the CS50 library.
  18130. 14:14:15But that's why, for instance, we bootstrap things,
  18131. 14:14:17by just using these functions out of the box.
  18132. 14:14:20All right, let's do something more with our calculator here.
  18133. 14:14:24How about this.
  18134. 14:14:25In the world of C, we had another version
  18135. 14:14:28of this code, which actually did some division by way of--
  18136. 14:14:33which actually did division of numbers, not just the addition herein.
  18137. 14:14:38So let me go ahead and close the C version, and let's focus only on Python
  18138. 14:14:42now, doing some of these same lines of codes.
  18139. 14:14:44But I'm going to go ahead and just assume
  18140. 14:14:46that the user is going to cooperate and use proper input.
  18141. 14:14:48So from CS50, import getInt, that will deal with any errors for me.
  18142. 14:14:52X gets getInt, ask the user for an Int x, y equals getInt,
  18143. 14:15:00ask the user for an Int y.
  18144. 14:15:01And then, let's go ahead and do this.
  18145. 14:15:03Let's declare a variable called z, set it equal to x divided by y.
  18146. 14:15:07Then let's go ahead and print z.
  18147. 14:15:09Still no need for a format string, I can just print out the variable's value.
  18148. 14:15:13Let me go ahead and run Python of Calculator.py.
  18149. 14:15:15Let me do 1, 10, and I get 0.1.
  18150. 14:15:20What did I get in C, though, if you think back.
  18151. 14:15:25What would we have happened in C?
  18152. 14:15:28AUDIENCE: Zero?
  18153. 14:15:29DAVID J. MALAN: Yeah, we would have gotten zero in C.
  18154. 14:15:32But why, in C, when you divide one Int by another,
  18155. 14:15:34and those Ints are like 1 and 10 respectively?
  18156. 14:15:36AUDIENCE: It'll give you an integer back.
  18157. 14:15:38DAVID J. MALAN: It will give you what?
  18158. 14:15:39AUDIENCE: An integer back.
  18159. 14:15:40DAVID J. MALAN: It will give you an integer back, and, unfortunately, 0.1,
  18160. 14:15:44the integer part of it is indeed zero.
  18161. 14:15:46So this was an example of truncation.
  18162. 14:15:48So truncation was an issue in C. But it would
  18163. 14:15:51seem as though this is no longer a problem in Python,
  18164. 14:15:53insofar as the division operator actually handles that for us.
  18165. 14:15:57As an aside, if you want the old behavior, because it actually
  18166. 14:16:00is sometimes useful for rounding or flooring values,
  18167. 14:16:03you can actually use two slashes.
  18168. 14:16:06And now you get the C behavior.
  18169. 14:16:08So that now 1 divided by 10 is zero.
  18170. 14:16:10So you don't give up that capability, but at least it
  18171. 14:16:12does a more sensible default.
  18172. 14:16:14Most people, especially new programmers, when dividing one value by another,
  18173. 14:16:17would want to get 0.1, not 0, for reasons
  18174. 14:16:20that indeed we had to explain weeks ago.
  18175. 14:16:22But what about another problem we had with the world of floats before,
  18176. 14:16:26whereby there is imprecision?
  18177. 14:16:28Let me go ahead and, somewhat cryptically, print out the value of z
  18178. 14:16:31as follows.
  18179. 14:16:32I'm going to format it using an f-string.
  18180. 14:16:34And I'm going to go ahead and format, not just z, because this is essentially
  18181. 14:16:39the same thing.
  18182. 14:16:39Notice this, if I do Python of Calculator.py, 1 and 10,
  18183. 14:16:43I get, by default, just one significant digit.
  18184. 14:16:46But if I use this syntax in Python, which we won't have to use often,
  18185. 14:16:50I can actually do in C like I did before,
  18186. 14:16:5350 significant digits after the decimal point.
  18187. 14:16:56So now let me rerun Python of Calculator.py 1 and 10,
  18188. 14:17:00and let's see if floating point imprecision is still with us.
  18189. 14:17:03Unfortunately, it is.
  18190. 14:17:04And you can see as much here, the f-string, the format string,
  18191. 14:17:07is just showing us now 50 digits instead of the default one.
  18192. 14:17:10So we've not solved all problems.
  18193. 14:17:12But we have solved at least some.
  18194. 14:17:15All right, before we pivot away from a mere calculator, any questions
  18195. 14:17:18now on syntax or concepts or the like?
  18196. 14:17:21Yeah.
  18197. 14:17:22AUDIENCE: Do you think the double slash you get
  18198. 14:17:25has merit, how do you comment on that?
  18199. 14:17:28DAVID J. MALAN: How do you what?
  18200. 14:17:29Oh, how do you comment.
  18201. 14:17:30Really good question, if you're using double slash for division
  18202. 14:17:33with flooring or truncation, like I described,
  18203. 14:17:36how do you do a comment in Python.
  18204. 14:17:38This is a comment.
  18205. 14:17:39And the convention is actually to use a complete sentence,
  18206. 14:17:42like with a capital T here.
  18207. 14:17:44You don't need a period unless there's multiple sentences.
  18208. 14:17:46And technically, it should be above the line of code by convention.
  18209. 14:17:49So you would use a hash symbol instead.
  18210. 14:17:51Good question.
  18211. 14:17:52I haven't seen those yet.
  18212. 14:17:53All right, let's go ahead and make something else here, how about.
  18213. 14:17:57Let me go ahead and open up, for instance,
  18214. 14:17:59an example called Points1.c, which we saw a few weeks back.
  18215. 14:18:05And let me go ahead on the other side and create a file called Points.py.
  18216. 14:18:10This was a program, recall, that asked the user how many points they
  18217. 14:18:13lost on the first assignment.
  18218. 14:18:15And then it went ahead and just printed out
  18219. 14:18:17whether they lost fewer points than me, because I lost two,
  18220. 14:18:20if you recall the photo, more points than me, or the same points as me.
  18221. 14:18:23Let me go ahead and zoom out so we can see a bit more of this.
  18222. 14:18:26And let me now, on the top right here, go about implementing this in Python.
  18223. 14:18:30So I want to first prompt the user for some number of points.
  18224. 14:18:33So from CS50 let's import getInt, so it handles the error-checking.
  18225. 14:18:37Let's then do points equals getInt, and ask
  18226. 14:18:39the user, how many points did you lose, question mark.
  18227. 14:18:43Then let's go ahead and say, if points less than two, which was my value,
  18228. 14:18:48print, you lost fewer points than me.
  18229. 14:18:52Otherwise, if it's else if points greater than 2, go ahead and print,
  18230. 14:18:59you lost more points than me.
  18231. 14:19:03Else let's go ahead and handle the final scenario, which is you
  18232. 14:19:07lost the same number of points as me.
  18233. 14:19:11Before I run this, does anyone want to point out a mistake I've already made?
  18234. 14:19:15Yeah.
  18235. 14:19:16AUDIENCE: Else if has to be elif.
  18236. 14:19:17DAVID J. MALAN: Yeah, so else if in C is actually now elif in Python.
  18237. 14:19:21It's a single word.
  18238. 14:19:22So let me change this to elif, and now cross my fingers, Python of Points.py,
  18239. 14:19:26suppose you lost three points on some assignment.
  18240. 14:19:29You lost more points than my two.
  18241. 14:19:31If you only lost one point, you lost fewer points than me.
  18242. 14:19:34So the logic is the same.
  18243. 14:19:35But notice the code is much tighter.
  18244. 14:19:37In 10 total lines, we did in what was 24 lines, because we've
  18245. 14:19:41thrown away a lot of the syntax.
  18246. 14:19:42The curly braces are no longer necessary.
  18247. 14:19:44The parentheses are gone, the semicolons.
  18248. 14:19:46So this is why it just tends to be more pleasant pretty quickly,
  18249. 14:19:50using a language like this.
  18250. 14:19:52All right, let's do one other example here.
  18251. 14:19:55In C, recall that we were able to determine the parity of some number,
  18252. 14:19:59if something is even or odd.
  18253. 14:20:01Well, in Python, let me go ahead and create a file called Parity.py,
  18254. 14:20:05and let's look for a moment at the C version at left.
  18255. 14:20:09Here was the code in C that we used to determine the parity of a number.
  18256. 14:20:13And, really, the key takeaway from all these lines
  18257. 14:20:16was just the remainder operator.
  18258. 14:20:17And that one is still with us.
  18259. 14:20:19So this is a simple demonstration, just to make that point,
  18260. 14:20:21if in Python, I want to determine whether a number is even or odd.
  18261. 14:20:25Well, let's go ahead and from CS50, import getInt, then let's go ahead
  18262. 14:20:29and get a number like n from the user, using getInt, and ask them for n.
  18263. 14:20:35And then let's go ahead and say, if n percent sign 2 equals 0,
  18264. 14:20:40then let's go ahead and print quote unquote "Even."
  18265. 14:20:44Else let's go ahead and print out Odd, but before I run this,
  18266. 14:20:50anyone want to instinctively, even though we've not talked about this,
  18267. 14:20:53point out a mistake here?
  18268. 14:20:55What I did wrong?
  18269. 14:20:56AUDIENCE: Double equals.
  18270. 14:20:57DAVID J. MALAN: Yeah, so double equals.
  18271. 14:20:58Again, so even though some of the stuff is changing, some of the same ideas
  18272. 14:21:02are the same.
  18273. 14:21:02So this, too, should be a double equal sign,
  18274. 14:21:05because I'm comparing for equality here.
  18275. 14:21:07And why is this the right math?
  18276. 14:21:08Well, if you divide a number by 2, it's either
  18277. 14:21:10going to have 0 or 1 as a remainder.
  18278. 14:21:12And that's going to determine if it's even or odd for us.
  18279. 14:21:15So let's run Python of Parity.py, type in a number like 50,
  18280. 14:21:18and hopefully we get, indeed, even.
  18281. 14:21:21So again, same idea, but now we're down to eight lines
  18282. 14:21:23of code instead of the 20.
  18283. 14:21:25Well, let's now do something a little more interactive
  18284. 14:21:27and a little representative of tools that actually ask the user questions.
  18285. 14:21:31In C, recall that we had this agreement program, Agree.c.
  18286. 14:21:36And then let's go ahead and implement a corresponding version in Python,
  18287. 14:21:40in a file called Agree.py.
  18288. 14:21:42And let's look at the C version first.
  18289. 14:21:45On the left, we used get char here.
  18290. 14:21:47And then we used the double vertical bars
  18291. 14:21:49to check if C is equal to capital Y or lowercase y.
  18292. 14:21:52And then we did the same thing for n for no.
  18293. 14:21:55And so let's go over here and let's do from CS50, import get--
  18294. 14:22:00OK, get char is not a thing.
  18295. 14:22:03And this here is another difference with Python.
  18296. 14:22:05There is no data type for individual characters.
  18297. 14:22:09You have strings, STRs, and, honestly, those
  18298. 14:22:11are fine, because if you have a STR that's
  18299. 14:22:13just one character, for all intents and purposes,
  18300. 14:22:15it is just a single character.
  18301. 14:22:17So it's just a simplification.
  18302. 14:22:18You don't have to think as much.
  18303. 14:22:19You don't have to worry about double quotes, single quotes.
  18304. 14:22:22In fact, in Python, you can use double quotes or single quotes,
  18305. 14:22:25so long as you're consistent.
  18306. 14:22:27So long as you're consistent, the single quotes
  18307. 14:22:29do not mean something different, like they do in C.
  18308. 14:22:32So I'm going to go ahead and use getString here,
  18309. 14:22:34although, strictly speaking, I could just use the input function,
  18310. 14:22:37as we saw before.
  18311. 14:22:39I'm going to get a string from the user that asks them this, getString,
  18312. 14:22:43quote unquote, "Do you agree," like a little checkbox or interactive prompt,
  18313. 14:22:47where you have to say yes or no, you want to agree to the following terms,
  18314. 14:22:50or whatnot.
  18315. 14:22:51And then let's translate the conditionals to Python, now, too.
  18316. 14:22:54So if S equals equals quote-unquote "Y," or S equals equals lowercase y,
  18317. 14:23:02let's go ahead and print out agreed, just like in C, elif S equals
  18318. 14:23:08equals N or S equals equals little n.
  18319. 14:23:12Let's go ahead, then, and print out not agreed.
  18320. 14:23:14And you can already see, perhaps, one of the differences here, too.
  18321. 14:23:17Is Python a little more English-like, in that
  18322. 14:23:20you just literally use the English word or, instead of the two vertical bars.
  18323. 14:23:24But it's ultimately doing the same thing.
  18324. 14:23:26Can we simplify this code a bit, though.
  18325. 14:23:29This would be a little annoying if we wanted
  18326. 14:23:31to add support, not just for big Y and little y,
  18327. 14:23:34but Yes or big Yes or little yes or big Y, lowercase e, capital S, right?
  18328. 14:23:40There's a lot of permutations of Y-E-S or just y,
  18329. 14:23:43that we ideally should tolerate.
  18330. 14:23:45Otherwise, the user is going to have to type exactly what we want,
  18331. 14:23:47which isn't very user-friendly.
  18332. 14:23:49Any intuition for how we could logically,
  18333. 14:23:51even if you don't know how to do it in code, make this better?
  18334. 14:23:54Yeah.
  18335. 14:23:55AUDIENCE: Write way over the list, and then up,
  18336. 14:23:58it's like the things in the list.
  18337. 14:23:59DAVID J. MALAN: Nice, yeah, we saw an example of a list before, just 0, 1, 2.
  18338. 14:24:03Why don't we take that same idea and ask a similar question.
  18339. 14:24:06If S is in the following list of values, Y or little y,
  18340. 14:24:11or heck, let me add to the list now, yes, or maybe all capital YES.
  18341. 14:24:15And it's going to get a little annoying, admittedly,
  18342. 14:24:17but this is still better than the alternative, with all the or's.
  18343. 14:24:20I could do things like this, and so forth.
  18344. 14:24:22There's a whole bunch more permutations.
  18345. 14:24:24But let's leave this alone, and let me just go into here
  18346. 14:24:26and change this to, if S is in the following list of N or little n or no,
  18347. 14:24:33and I won't do as, let's just not worry about the weird capitalizations
  18348. 14:24:36there, for now.
  18349. 14:24:38Let's go ahead and run this.
  18350. 14:24:39Python of Agree.py, do I agree?
  18351. 14:24:42Y. OK, how about yes?
  18352. 14:24:45All right, how about big Yes.
  18353. 14:24:46OK, that does not seem to work.
  18354. 14:24:48Notice it did not say agreed, and it did not say not agreed.
  18355. 14:24:50It didn't detect it.
  18356. 14:24:51So how can I do this?
  18357. 14:24:53Well, you know what I could do, what I don't really
  18358. 14:24:57need the uppercase and lowercase.
  18359. 14:24:58Let me tighten this list up a little bit.
  18360. 14:25:00And why don't I just force S to be lowercase.
  18361. 14:25:04S.lower, recall, whether it's one character or more,
  18362. 14:25:07is a function built into STRs now, strings in Python,
  18363. 14:25:10that forces the whole thing to lowercase.
  18364. 14:25:12So now, watch what I can do.
  18365. 14:25:13Python of Agree.py, little y, that works, big Y, that works.
  18366. 14:25:19Big Yes, that works, big Y, little e, big S, that also works.
  18367. 14:25:24So we've now handled, in one fell swoop, a whole bunch more logic.
  18368. 14:25:27And you know what, we can tighten this up a bit.
  18369. 14:25:29Here's an opportunity, in Python, for slightly better design.
  18370. 14:25:32What have I done in here that's a little redundant?
  18371. 14:25:36Does anyone see an opportunity to eliminate a redundancy,
  18372. 14:25:40doing something more times than you need.
  18373. 14:25:43Is a stretch here, no.
  18374. 14:25:44Yep.
  18375. 14:25:45AUDIENCE: You can do S dot lower, above.
  18376. 14:25:47DAVID J. MALAN: We could move the S dot lower above.
  18377. 14:25:49Notice that I'm using S dot lower twice.
  18378. 14:25:51But it's going to give me the same answer both times.
  18379. 14:25:54So I could do a couple of things here.
  18380. 14:25:56I could, first of all, get rid of this lower, and get rid of this lower,
  18381. 14:26:01and then above this, maybe I could do something like this, S equal--
  18382. 14:26:05I can't just do this, because that throws the value away.
  18383. 14:26:08It does the math, but it doesn't convert the string itself.
  18384. 14:26:10It's going to return a value.
  18385. 14:26:12So I have to say S equals s.lower.
  18386. 14:26:14I could do that.
  18387. 14:26:15Or, honestly, I can chain these things together.
  18388. 14:26:18And this is not something we saw in C. If getString returns a string,
  18389. 14:26:22and strings have functions like lower in them,
  18390. 14:26:25you can chain these functions together, like this, and do dot this,
  18391. 14:26:28dot that, dot this other thing.
  18392. 14:26:30And eventually you want to stop, because it's going to become crazy long.
  18393. 14:26:33But this is reasonable, still fits on the screen.
  18394. 14:26:35It's pretty tight.
  18395. 14:26:36It does in one place what I was doing in two.
  18396. 14:26:38So I think that's OK.
  18397. 14:26:39Let me go ahead and do Python of Agree.py one last time.
  18398. 14:26:42Let's try it one last time.
  18399. 14:26:43And it's still working as intended.
  18400. 14:26:46Also if I tried those other inputs as well.
  18401. 14:26:49Yeah, question.
  18402. 14:26:49AUDIENCE: Could you add on like a for uppercase as well, for like upper,
  18403. 14:26:55and then cover all the functions where it's lowercase, for all the functions
  18404. 14:26:59where it's uppercase as well, or could you not just do this again.
  18405. 14:27:05DAVID J. MALAN: Let me summarize.
  18406. 14:27:06Could we handle uppercase and lowercase together in some form?
  18407. 14:27:09I'm actually doing that already.
  18408. 14:27:11I just have to pick a lane.
  18409. 14:27:12I have to either be all lowercase in my logic or all uppercase,
  18410. 14:27:15and not worry about what the human types in,
  18411. 14:27:17because no matter what the human types in, I'm
  18412. 14:27:19forcing their input to lowercase.
  18413. 14:27:21And then I am using a lowercase list of values.
  18414. 14:27:24If I want to flip that, fine.
  18415. 14:27:26I just have to be self-consistent.
  18416. 14:27:27But I'm handling that already.
  18417. 14:27:28Yeah.
  18418. 14:27:29AUDIENCE: Are strings no longer an array of characters?
  18419. 14:27:33DAVID J. MALAN: A really good loaded questions
  18420. 14:27:35are strings no longer an array of characters?
  18421. 14:27:38Conceptually, yes, underneath the hood, no.
  18422. 14:27:40They're a little more sophisticated than that,
  18423. 14:27:42because with strings, you have a few changes.
  18424. 14:27:45Not only do they have functions built into them,
  18425. 14:27:47because strings are now what we call objects,
  18426. 14:27:49in what's called object-oriented programming.
  18427. 14:27:51And we're going to keep seeing examples of this dot operator.
  18428. 14:27:53They are also immutable, so to speak, I-M-M-U-T-A-B-L-E.
  18429. 14:27:58Immutable means they cannot be changed, which means, unlike C,
  18430. 14:28:01you can't go into a string and change its individual characters.
  18431. 14:28:05You can make a copy of the string that makes a change,
  18432. 14:28:08but you can't change the original string itself.
  18433. 14:28:10This is both a little annoying, maybe, sometimes.
  18434. 14:28:12But it's also pretty protective, because you can't do screw-ups
  18435. 14:28:14like I did weeks ago, when I was trying to copy S and call it T.
  18436. 14:28:18And then one affected the other.
  18437. 14:28:19Python, underneath the hood, is handling all of the memory management
  18438. 14:28:23and the pointers and all of that.
  18439. 14:28:25There are no pointers in Python.
  18440. 14:28:27So If that wasn't clear, all of that pain, if you will, all of that power,
  18441. 14:28:32is now handled by the language itself, not by us, the programmers.
  18442. 14:28:36All right, so let's introduce maybe some loops,
  18443. 14:28:38like we've been in the habit of doing.
  18444. 14:28:40Let me open up Meow.c, which was an example in C, just meowing
  18445. 14:28:44a bunch of times textually.
  18446. 14:28:46Let me create a file called Meow.py here on the right.
  18447. 14:28:49And notice on the left, this was correct code in C,
  18448. 14:28:51but it was kind of poorly designed.
  18449. 14:28:53Why?
  18450. 14:28:53Because it was a missed opportunity for a loop.
  18451. 14:28:55Why say something three times when you can say it just once?
  18452. 14:28:58So in Python, let me do it the poorly designed way first.
  18453. 14:29:02Let me print out meow.
  18454. 14:29:03And, like I generally should not, let me copy, paste it three times,
  18455. 14:29:07run Python of Meow.py, and it works.
  18456. 14:29:10OK, but not good practice.
  18457. 14:29:11So let me go ahead and improve this a little bit.
  18458. 14:29:13And there's a few ways to do this.
  18459. 14:29:15If I wanted to do this three times, I could instead do something like this.
  18460. 14:29:20For i in range of 3, recall that that was the better version,
  18461. 14:29:24rather than arbitrarily enumerate numbers yourself, let me go ahead
  18462. 14:29:27and print out quote unquote "Meow."
  18463. 14:29:30Now if I run Python of Meow, still seems to work.
  18464. 14:29:32So it's a little tighter, and, my God, like,
  18465. 14:29:34programs can't really get much shorter than this.
  18466. 14:29:36We're down to two lines of code, no main function, no gratuitous syntax.
  18467. 14:29:40Let's now improve the design further, like we
  18468. 14:29:43did in C, by introducing a function called
  18469. 14:29:46meow, that actually does the meowing.
  18470. 14:29:47So this was our first abstraction, recall,
  18471. 14:29:49both in Scratch and in C. Let me focus now entirely on the Python version
  18472. 14:29:54here.
  18473. 14:29:55Let me go ahead and first define a function.
  18474. 14:30:03Let me first go ahead and do this, for i in range of 3,
  18475. 14:30:06let's assume for the moment that there's a meow function,
  18476. 14:30:09that I'm just going to call.
  18477. 14:30:11Let's now go ahead and define, using the Def key word, which we saw briefly
  18478. 14:30:14with the speller demonstration, a function
  18479. 14:30:17called meow that takes no arguments.
  18480. 14:30:19And all it does for now is print meow.
  18481. 14:30:21Let me now go ahead and run Python of Meow.py Enter, huh, one
  18482. 14:30:27of those trace backs.
  18483. 14:30:28So this is another name error.
  18484. 14:30:30And, again, name meow is not defined.
  18485. 14:30:33What's your instinct here, even though we've not
  18486. 14:30:35tripped over this yet in Python?
  18487. 14:30:37Where does your mind go here?
  18488. 14:30:39Yeah.
  18489. 14:30:40AUDIENCE: Does it read top to bottom, left to right?
  18490. 14:30:42I'm guessing we could find a new case.
  18491. 14:30:46DAVID J. MALAN: Perfect, as smart, as smarter as Python seems to be,
  18492. 14:30:49it still makes certain assumptions.
  18493. 14:30:51And if it hasn't seen a keyword yet, it just doesn't exist.
  18494. 14:30:54So if you want it to exist, we have to be a little clever here.
  18495. 14:30:57I could just put it, flip it around, like this.
  18496. 14:31:00But this honestly isn't particularly good design.
  18497. 14:31:02Why?
  18498. 14:31:03Because now, if you, the reader of your code, whether you
  18499. 14:31:06wrote it or someone else, you kind of have to go fishing now.
  18500. 14:31:09Like where does this program begin?
  18501. 14:31:11And even though, yes, it's obvious that it begins on line four, logically,
  18502. 14:31:14like, if the file were longer, you're going to be annoyed
  18503. 14:31:17and fishing visually for the right lines of code.
  18504. 14:31:19So let's reintroduce main.
  18505. 14:31:20And indeed, this would be a common paradigm.
  18506. 14:31:22When you want to start having abstractions in your own functions,
  18507. 14:31:25just put your own code in main, so that, one, you can leave it up top, and two,
  18508. 14:31:29you can solve the problem we just encountered.
  18509. 14:31:32So let me define a function called main that has that same loop,
  18510. 14:31:35meowing three times.
  18511. 14:31:36But now watch what happens.
  18512. 14:31:38Let me go into my terminal and run Python of Meow.py, Enter.
  18513. 14:31:43Nothing.
  18514. 14:31:47All right, investigate this.
  18515. 14:31:50What could explain this symptom.
  18516. 14:31:52I have not told you the answer yet.
  18517. 14:31:54So all you have is your instinct, assuming
  18518. 14:31:56you've never touched Python before.
  18519. 14:31:58What might explain this symptom, where nothing is meowing?
  18520. 14:32:03Yeah?
  18521. 14:32:03AUDIENCE: Didn't run the main function.
  18522. 14:32:05DAVID J. MALAN: Yeah, I didn't run the main function.
  18523. 14:32:07So in C, this is functionality you get for free.
  18524. 14:32:09You have to have a main function.
  18525. 14:32:11But, heck, so long as you make it, it will be called for you.
  18526. 14:32:14In Python, this is just a convention, to create a main function,
  18527. 14:32:17borrowing a very common name for it.
  18528. 14:32:19But if you want to call that main function, you have to do it.
  18529. 14:32:22So this looks a little weird, admittedly,
  18530. 14:32:24that you have to call your own main function now,
  18531. 14:32:26and it has to be at the bottom of the file,
  18532. 14:32:28because only once the interpreter gets to the bottom of the file,
  18533. 14:32:31have all of your functions been defined, higher up.
  18534. 14:32:34But this solves both problems.
  18535. 14:32:36It keeps your code, that's the main part of your code,
  18536. 14:32:38at the very top of the file.
  18537. 14:32:40So it's just obvious to you, and a TF, or any reader in the future,
  18538. 14:32:43where the program logically starts.
  18539. 14:32:45But it also ensures that main is not called until everything else, main
  18540. 14:32:49included, has been defined.
  18541. 14:32:52So this is another perfect example of we're
  18542. 14:32:54learning a new language for the first time.
  18543. 14:32:55You're not going to have heard all of the answers before.
  18544. 14:32:57Just apply some logic, as to, like, all right, what could explain this symptom.
  18545. 14:33:01Start to infer how the language does or doesn't work.
  18546. 14:33:04If I now go and run this, Python of Meow.py, now we're back in business.
  18547. 14:33:08And just so you have seen it, there is a quote
  18548. 14:33:11unquote "better" way of doing this, that solves different problems that we
  18549. 14:33:15are not going to encounter, certainly in these initial days.
  18550. 14:33:18Typically, you would see in online tutorials or books,
  18551. 14:33:21something that looks like this, where you actually have a weird conditional
  18552. 14:33:25with multiple underscores.
  18553. 14:33:27That's functionally the same thing, but it solves problems with libraries,
  18554. 14:33:30if we ourselves were implementing a library or something similar in spirit.
  18555. 14:33:34But we're going to keep things simpler and just write main at the bottom,
  18556. 14:33:37because we're not going to encounter that problem just yet.
  18557. 14:33:39All right, let's make one change to this, just to show how it's done.
  18558. 14:33:42In C, the last version of meow also took command line argument, sorry, also
  18559. 14:33:47took arguments to the function meow.
  18560. 14:33:50So suppose that I want to factor this out.
  18561. 14:33:53And I want to just call meow as a better abstraction, where I just
  18562. 14:33:55say meow this number of times.
  18563. 14:33:57And I figure out how many times by just, like, putting in number 3
  18564. 14:34:00or using getInt or something like that, to figure out
  18565. 14:34:03how many times to say meow.
  18566. 14:34:05Well, now, I have to define inside my meow function, in input,
  18567. 14:34:08let's call it n, and then use that, as by doing this, for i in range of n,
  18568. 14:34:14let me go ahead and print out meow that many times.
  18569. 14:34:18So again, the only thing that's different in C
  18570. 14:34:20is we don't bother specifying return types for any of these functions,
  18571. 14:34:24and we don't bother specifying the type of our arguments or our variables.
  18572. 14:34:28So same ideas, simpler in some sense.
  18573. 14:34:31We're just throwing away keystrokes.
  18574. 14:34:33All right, let me run this one final time, Python of Meow.py,
  18575. 14:34:35and we still have the same program.
  18576. 14:34:38All right, let me pause here.
  18577. 14:34:40Any questions?
  18578. 14:34:41And I know this is going fast.
  18579. 14:34:42But hopefully, the C code is still somewhat familiar.
  18580. 14:34:47Yeah.
  18581. 14:34:48AUDIENCE: Is there any difference between global and local variables.
  18582. 14:34:54DAVID J. MALAN: Good question.
  18583. 14:34:55Is there any difference between global and local variables?
  18584. 14:34:57Short answer, yes, and we would run into that same problem,
  18585. 14:35:00if we declare a variable in one function,
  18586. 14:35:01another function is not going to have access to it.
  18587. 14:35:03We can solve that by putting variables globally.
  18588. 14:35:07But we don't have all of the features we had in C,
  18589. 14:35:09like there's no such thing as a constant in Python.
  18590. 14:35:11The mentality in the Python community is,
  18591. 14:35:13if you don't want some value to change, don't touch it.
  18592. 14:35:16Like just don't screw up.
  18593. 14:35:17So there's trade-offs here, too.
  18594. 14:35:18Some languages are stronger or more defensive than that.
  18595. 14:35:21But that, too, is part of the mindset with this particular language.
  18596. 14:35:25[SIREN]
  18597. 14:35:26DAVID J. MALAN: Yeah.
  18598. 14:35:27AUDIENCE: There is really only one green line, in the--
  18599. 14:35:29DAVID J. MALAN: Oh, sorry, where's--
  18600. 14:35:30say it louder.
  18601. 14:35:31AUDIENCE: There has only been one green line printed at a time.
  18602. 14:35:34DAVID J. MALAN: That is an amazing segue.
  18603. 14:35:36Let's come to that in just a moment, because we're
  18604. 14:35:37going to recreate also that Mario example, where
  18605. 14:35:40we had like the question marks for the coins and the vertical bars.
  18606. 14:35:43So let's come back to that in a second.
  18607. 14:35:45And your question?
  18608. 14:35:46AUDIENCE: If strings are immutable, and every time you like make a copy.
  18609. 14:35:49DAVID J. MALAN: Correct, strings are immutable.
  18610. 14:35:51Any time you seem to be modifying it, as with the lower function,
  18611. 14:35:55you're getting back a copy.
  18612. 14:35:57So it's taking a little more memory somewhere.
  18613. 14:35:59But you don't have to deal with it Python's doing that for you.
  18614. 14:36:02AUDIENCE: So you don't free anything.
  18615. 14:36:05DAVID J. MALAN: Say it again?
  18616. 14:36:06You don't need what?
  18617. 14:36:07AUDIENCE: You don't free like taking leave on stuff.
  18618. 14:36:11DAVID J. MALAN: You don't free anything.
  18619. 14:36:12So if you weren't a big fan, over the past couple of weeks,
  18620. 14:36:15of malloc or free or memory or addresses, or all
  18621. 14:36:19of those low level implementation details,
  18622. 14:36:21Python is the language for you, because all of that
  18623. 14:36:23is handled for you automatically.
  18624. 14:36:25Java does the same.
  18625. 14:36:27JavaScript does the same.
  18626. 14:36:28Yeah.
  18627. 14:36:28AUDIENCE: Each up for the variable, you put it before the name, use of the body
  18628. 14:36:34before the name, correct?
  18629. 14:36:36Well, if there isn't a main function in Python, how do you define those words?
  18630. 14:36:40DAVID J. MALAN: How do you define a global variable
  18631. 14:36:42if there's no main function in Python?
  18632. 14:36:44Global variables, by definition, always need to be outside of main, as well.
  18633. 14:36:48So that's not a problem.
  18634. 14:36:49If I wanted to have a function that's outside of,
  18635. 14:36:51and, therefore, global to all of these, like global--
  18636. 14:36:56actually, don't use the word global, that's a special word in Python--
  18637. 14:36:59variable equals Foo, F-O-O, just as an arbitrary string
  18638. 14:37:03value that a computer scientist would typically use, that is now global.
  18639. 14:37:07There are some caveats, though, as to how you access that.
  18640. 14:37:10But let's come back to that another time.
  18641. 14:37:12But that problem is solvable, too.
  18642. 14:37:14All right.
  18643. 14:37:15So let's go ahead and do this.
  18644. 14:37:16To come back to the question about the print command, let me go ahead
  18645. 14:37:19and create a file now called Mario.py.
  18646. 14:37:21Won't bother showing the C code anymore.
  18647. 14:37:24We'll focus just on the new language here.
  18648. 14:37:26But recall that, in Python, in Mario, we wanted to first do something like this.
  18649. 14:37:31This was a random screen from the side scroller version 1
  18650. 14:37:34of Super Mario Brothers.
  18651. 14:37:35And we just want to print like three hashes to represent those three blocks.
  18652. 14:37:39Well, in Python, we could do something like this,
  18653. 14:37:41print, oh, sorry, for i in the range of 3, go ahead and print out quote unquote
  18654. 14:37:47"hash."
  18655. 14:37:48And I think this is pretty straightforward.
  18656. 14:37:50Python of Mario.py, we get our three hashes.
  18657. 14:37:52You could imagine parameterizing this now, though,
  18658. 14:37:55and getting actual user input.
  18659. 14:37:56So let's do that.
  18660. 14:37:58Let me go up here and let me go and say from CS50, import getInt,
  18661. 14:38:03and then let's get the input from the user.
  18662. 14:38:07So it actually is a value n, like, all right,
  18663. 14:38:09getInt the height of the column of bricks that you want to do.
  18664. 14:38:14And then, let's go ahead and print out n hashes instead of three.
  18665. 14:38:18So let me run this.
  18666. 14:38:20Let's print out like five hashes.
  18667. 14:38:21OK, one, two, three, four, five, that seems to work, too.
  18668. 14:38:24And it's going to work for any positive value.
  18669. 14:38:26But it's not going to work for, how about negative 1?
  18670. 14:38:29That just doesn't do anything.
  18671. 14:38:31But that seems OK.
  18672. 14:38:32But also recall that it's not going to work if the user types in something
  18673. 14:38:35weird, like, oh, sorry, it is going to work if the user types in something
  18674. 14:38:40weird like cat, why?
  18675. 14:38:42We're using CS50's getInt function, which is
  18676. 14:38:45handling all of those headaches for us.
  18677. 14:38:48But, what if the user indeed types a negative number?
  18678. 14:38:51We're tolerating that.
  18679. 14:38:52So that was the bug I wanted to highlight.
  18680. 14:38:54It would be nice to re-prompt them and re-prompt them.
  18681. 14:38:56And in C, what was the programming construct we
  18682. 14:38:59used when we wanted to ask the user a question.
  18683. 14:39:01And then, if they didn't cooperate, prompt them again, prompt them again.
  18684. 14:39:05What was that?
  18685. 14:39:06Yeah.
  18686. 14:39:06AUDIENCE: Do while loop.
  18687. 14:39:07DAVID J. MALAN: Yeah, do while loop, right?
  18688. 14:39:08That was useful, because it's almost the same as a while loop.
  18689. 14:39:11But instead of checking a condition, and then doing something,
  18690. 14:39:14you do something and then check a condition,
  18691. 14:39:16which makes sense with user input, because what are you
  18692. 14:39:18even going to check if the user hasn't done anything yet?
  18693. 14:39:21You need that inverted logic.
  18694. 14:39:22Unfortunately in Python, there is no do while loop.
  18695. 14:39:26There is a for loop.
  18696. 14:39:27There is a while loop.
  18697. 14:39:29And frankly, those are enough to recreate this idea.
  18698. 14:39:32And the way to do this in Python, the Pythonic way, which
  18699. 14:39:35is another term of art in the community, is to say this.
  18700. 14:39:38Deliberately induce an infinite loop, while True, with capital T for true.
  18701. 14:39:42And then do what you got to do, like get an Int from a user,
  18702. 14:39:46asking them for the height of this thing.
  18703. 14:39:48And then, if that is what you want, like a number greater than zero, go ahead
  18704. 14:39:54and break out of the loop.
  18705. 14:39:56So this is how, in Python, you could recreate the idea of a do while loop.
  18706. 14:40:01You deliberately induce an infinite loop.
  18707. 14:40:03So something's going to happen at least once.
  18708. 14:40:05Then, if you get the answer you want, you break out of it,
  18709. 14:40:08effectively achieving the same logic.
  18710. 14:40:10So this is the Pythonic way of doing a do while loop.
  18711. 14:40:13Let me go ahead and run Python of Mario.py, type in 3 this time.
  18712. 14:40:18And now I get back just the 3 hashes as well.
  18713. 14:40:21What if, though, I wanted to get rid of, how about ultimately
  18714. 14:40:26that CS50 library function, and also encapsulate this in a function.
  18715. 14:40:31Well, let's go ahead and tweak this a little bit.
  18716. 14:40:33Let me go ahead and remove this temporarily.
  18717. 14:40:35Give myself a main function, so I don't make the same mistake
  18718. 14:40:38as I did initially earlier.
  18719. 14:40:39And let me give myself a function called get height that takes no arguments.
  18720. 14:40:43And inside of that function is going to be that same code.
  18721. 14:40:47But I don't want to break in this case, I want to return n.
  18722. 14:40:50So, recall, that if you return from a function, you're done,
  18723. 14:40:53you're going to exit from right at that point.
  18724. 14:40:55So this would be fine.
  18725. 14:40:56You can just say return n inside of the loop,
  18726. 14:40:59or, if you would prefer to break out, you
  18727. 14:41:01could do something like this instead.
  18728. 14:41:03Break, and then down here, you could return, down here,
  18729. 14:41:09you could return n as well.
  18730. 14:41:11And let me make one point here before we go back up to main.
  18731. 14:41:13This is a little different from C. And this one's subtle.
  18732. 14:41:18What have I done here that in C would have been a bug, but is apparently not,
  18733. 14:41:23I claim, in Python.
  18734. 14:41:27It's super subtle, this one.
  18735. 14:41:28Yeah.
  18736. 14:41:29AUDIENCE: So aren't we like defining mostly object,
  18737. 14:41:32like we're using it first, defining an object?
  18738. 14:41:35[INAUDIBLE]
  18739. 14:41:40DAVID J. MALAN: So similar, it's not quite that we're using it first.
  18740. 14:41:43So it's OK not to declare a variable with like the data type.
  18741. 14:41:47We've addressed that before, but on line 9, we're assigning n a value, it seems.
  18742. 14:41:51And then we return n on line 12.
  18743. 14:41:55But notice the indentation.
  18744. 14:41:56In the world of C, if we had declared a variable inside of a loop, on line 9,
  18745. 14:42:01it would have been scoped to that loop, which
  18746. 14:42:04means as soon as you get out of that loop, like further down in the program,
  18747. 14:42:08n would not exist.
  18748. 14:42:09It would be local to the curly braces therein.
  18749. 14:42:12Here, logically, curly braces are gone, but the indentation
  18750. 14:42:16makes clear that n is still inside of this loop, between lines 8 through 11.
  18751. 14:42:20But n is actually still in scope in Python.
  18752. 14:42:23The moment you create a variable in Python, for better or for worse,
  18753. 14:42:26It is available everywhere within that function, even outside
  18754. 14:42:30of the loop in which you defined it.
  18755. 14:42:32So this logic is actually OK in Python.
  18756. 14:42:35In C, recall, to solve this same problem,
  18757. 14:42:38we would have had to do something a little hackish like this,
  18758. 14:42:41like define n up here on line 8, so that it exists, now, on line 10,
  18759. 14:42:46and so that it exists on line 13.
  18760. 14:42:48That is no longer an issue or need, in Python.
  18761. 14:42:52Once you create a variable, even if it's nested,
  18762. 14:42:54nested, nested inside of some loops or conditionals,
  18763. 14:42:56it still exists within the function itself.
  18764. 14:43:00All right, any questions then on this, before we now run this and then get
  18765. 14:43:04rid of the CS50 library again?
  18766. 14:43:08OK, so let me go ahead and get the height from the user.
  18767. 14:43:10Let's go ahead and create a variable in main called height.
  18768. 14:43:13Let's call this get height function.
  18769. 14:43:14And then let's use that height value, instead of something hardcoded there.
  18770. 14:43:19And let me see if this all works now.
  18771. 14:43:21Python of Mario.py.
  18772. 14:43:22Hopefully, I haven't messed up, but I did.
  18773. 14:43:25But this is an easy fix now.
  18774. 14:43:27Yeah.
  18775. 14:43:28AUDIENCE: Got to call main.
  18776. 14:43:29DAVID J. MALAN: I got to call main.
  18777. 14:43:31So again, I deleted that earlier.
  18778. 14:43:32But let me bring it back.
  18779. 14:43:33So I'm actually calling main.
  18780. 14:43:34Let me rerun Python of Mario.py, there we go, height 3.
  18781. 14:43:38Now it seems to be working.
  18782. 14:43:40So let's do one last thing with Mario, just
  18783. 14:43:42to tie together that idea now of exceptions from before.
  18784. 14:43:45Again, exceptions are a feature of Python,
  18785. 14:43:47whereby you can try to do something.
  18786. 14:43:49And if there's a problem, you can handle it in any way you see fit.
  18787. 14:43:53Previously, I handled it by just yelling at the user that that's not an Int.
  18788. 14:43:56But let's actually use this to re-implement CS50's own getInt
  18789. 14:43:59function.
  18790. 14:44:00Let me throw away CS50's getInt function.
  18791. 14:44:03And now let me go ahead and replace getInt with input.
  18792. 14:44:09But it's not sufficient to just use input.
  18793. 14:44:12What do I have to add to this line of code on line 8?
  18794. 14:44:16If I want to get back an Int?
  18795. 14:44:17AUDIENCE: The Int function.
  18796. 14:44:18DAVID J. MALAN: Yeah, I have to cast it to an Int
  18797. 14:44:20by calling the Int function around that value,
  18798. 14:44:23or I could do it on a separate line, just to be clear.
  18799. 14:44:25I could also do n equals Int of n.
  18800. 14:44:28That would work too, but it's sort of an unnecessary extra line.
  18801. 14:44:31This is not sufficient, because that does not change the value.
  18802. 14:44:34It creates the value.
  18803. 14:44:35But then it throws it away.
  18804. 14:44:36We need to assign it.
  18805. 14:44:37So the conventional way to do this would probably be in one line,
  18806. 14:44:40just to keep things nice and tight.
  18807. 14:44:41So that works fine now.
  18808. 14:44:43If I run Python of Mario.py, I can still type in 3, and all as well.
  18809. 14:44:47I can still type in negative 1, because that is an Int that I am handling.
  18810. 14:44:52What I'm not yet handling is weird input like cat
  18811. 14:44:55or some string that is not a base 10 number.
  18812. 14:44:58So here, again, is my traceback.
  18813. 14:45:00And notice that here, let me scroll up a little bit,
  18814. 14:45:03here we can actually see more detail in the traceback.
  18815. 14:45:08Notice that, just like in C, or just like in the debugger in VS Code,
  18816. 14:45:13you can see a few things.
  18817. 14:45:14You can see mention of module, that just means your file, main, which
  18818. 14:45:18is my main function, and get height.
  18819. 14:45:19So notice, it's kind of backwards.
  18820. 14:45:20It's top to bottom instead of bottom up, as we drew it
  18821. 14:45:23on the board the other day, and as we envisioned
  18822. 14:45:25stacks of trays in the cafeteria.
  18823. 14:45:27But this is your stack, of functions that
  18824. 14:45:29have been called, from top to bottom.
  18825. 14:45:30Get height is the most recent, main is the very first,
  18826. 14:45:33value error is the problem.
  18827. 14:45:35So let's try to do, let's try to do this literally, except if there's an error.
  18828. 14:45:40So what do I want to do?
  18829. 14:45:41I'm going to go in here, and I'm going to say, try to do the following.
  18830. 14:45:46Whoops, try to do the following, except if there's a value error, value error,
  18831. 14:45:53then go ahead and say something, well, like before, print,
  18832. 14:45:57that's not an integer exclamation point.
  18833. 14:46:00But the difference this time is because I'm in a loop, the user
  18834. 14:46:03is going to have a chance to recover from this issue.
  18835. 14:46:05So if I run Mario.py, 3 still works as before.
  18836. 14:46:08If I run Mario.py and type in cat, I detect it now,
  18837. 14:46:12and because I'm still in that loop, and because the program hasn't crashed,
  18838. 14:46:15because I've caught, so to speak, the value error, using this line of code
  18839. 14:46:19here, that's the way in Python to detect these kinds of errors,
  18840. 14:46:23that would otherwise end up being on the user's own screen.
  18841. 14:46:26If I type in cat, dog, that doesn't work.
  18842. 14:46:28If I type in, though, 2, I get my two hashes, because that's, indeed, an Int.
  18843. 14:46:33Are any questions on this, and we're not going
  18844. 14:46:35to spend too much time on exceptions, but just wanted
  18845. 14:46:37to show you what's involved with getting rid of those training wheels.
  18846. 14:46:40Yeah.
  18847. 14:46:40AUDIENCE: Then the hash marks in line.
  18848. 14:46:42DAVID J. MALAN: OK, so let's do this.
  18849. 14:46:43That actually comes to the earlier question
  18850. 14:46:45about printing the hashes on the same line,
  18851. 14:46:47or maybe something like this, where we have the little bricks
  18852. 14:46:50in the sky, or little question marks.
  18853. 14:46:51Let's recreate this idea, because the problem with print,
  18854. 14:46:54as was noted earlier, is you're automatically printing out new lines.
  18855. 14:46:57But what if we don't want that.
  18856. 14:46:58Well, let's change this program entirely.
  18857. 14:47:01Let me throw away all the functions.
  18858. 14:47:02Let's just go to a simpler world, where we're just doing this.
  18859. 14:47:05So let me start fresh in Mario.py.
  18860. 14:47:07I'm not going to bother with exceptions or functions.
  18861. 14:47:09Let's just do a very simple program, to create this idea, for i in range of 4
  18862. 14:47:15this time, because there are four of these things in the sky.
  18863. 14:47:19Let's go ahead and just print out a question mark
  18864. 14:47:21to represent each of those bricks.
  18865. 14:47:23Odds are you know this not going to end well, because these are unfortunately,
  18866. 14:47:27as you've predicted, on separate lines.
  18867. 14:47:30So it turns out that the print function actually
  18868. 14:47:33takes in multiple arguments, not just the thing you want to print,
  18869. 14:47:36but also some additional arguments, that allow you to specify
  18870. 14:47:40what the default line ending should be.
  18871. 14:47:42But what's interesting about this is that, if you
  18872. 14:47:45want to change the line ending to be something like,
  18873. 14:47:49quote unquote, "that is nothing," instead of backslash n,
  18874. 14:47:53this is not sufficient, because in Python, you
  18875. 14:47:55can have two types of arguments, or parameters.
  18876. 14:47:58Some arguments are positional, which is the fancy way of saying it's
  18877. 14:48:01a comma separated list of arguments.
  18878. 14:48:03And that's what we did all the time in C. Something comma, something
  18879. 14:48:06comma, something, we did it in printf all the time,
  18880. 14:48:08and in other functions that took multiple arguments.
  18881. 14:48:10In Python, you have, not only positional arguments,
  18882. 14:48:14where you just separate them by commas, to give one or two or three or more
  18883. 14:48:18arguments.
  18884. 14:48:19There are also named arguments, which looks weird but is
  18885. 14:48:22helpful for reasons like this.
  18886. 14:48:24If you read the documentation, you will see
  18887. 14:48:27that there is a named argument that Python accepts, called end.
  18888. 14:48:31And if you set that equal to something, that
  18889. 14:48:34will be used as the end of every line, instead
  18890. 14:48:36of the default, which the documentation will also say
  18891. 14:48:39is quote unquote backslash n.
  18892. 14:48:41So this line here has no effect on my logic at the moment.
  18893. 14:48:45But if I change it to just quote unquote, essentially overriding
  18894. 14:48:49the default new line character, and now run Mario again, now I get all four
  18895. 14:48:54on the same line.
  18896. 14:48:55There's a bit of a bug, though.
  18897. 14:48:57My prompt is not meant to be on the same line.
  18898. 14:49:00So I can fix that by just printing nothing.
  18899. 14:49:02But, really, it's not nothing, because you get the new line for free.
  18900. 14:49:05So let me run Python of Mario.py again, and now we
  18901. 14:49:09have what I intended in the first place, which was a little something that
  18902. 14:49:12looked like this.
  18903. 14:49:13And this is just one example of an argument that has a name.
  18904. 14:49:17But this is a common paradigm in Python 2,
  18905. 14:49:19to not just separate things by commas, but to be very specific,
  18906. 14:49:22because the print function might take 5, 10, even 20 different arguments.
  18907. 14:49:27And my God, if you had to enumerate like 10 or 20 commas,
  18908. 14:49:31you're going to screw up.
  18909. 14:49:32You're going to get things in the wrong order.
  18910. 14:49:34Named arguments allow you to be resilient against that.
  18911. 14:49:37So you only specify arguments by name, and it
  18912. 14:49:39doesn't matter what order they are in.
  18913. 14:49:42All right, any questions, then, on this, and the overriding of new line.
  18914. 14:49:46And to be clear, you can do something like, very weird,
  18915. 14:49:50but logically expected, like this, by just changing the line ending, too.
  18916. 14:49:56But the right way to solve the Mario problem
  18917. 14:49:58would be just to override it to be nothing like this.
  18918. 14:50:02All right, how about this for cool.
  18919. 14:50:03And this is why a lot of people like Python.
  18920. 14:50:05Suppose you don't really like loops.
  18921. 14:50:06You don't really like three-line programs,
  18922. 14:50:08because that was kind of three times longer than it needs to be.
  18923. 14:50:11What if you just printed out a question mark four times?
  18924. 14:50:15Python, whoops, Python of Mario.py, that also works.
  18925. 14:50:19So it turns out that, just like the plus operator in Python
  18926. 14:50:23can join things together, the multiply operator is not
  18927. 14:50:27arithmetic in this case.
  18928. 14:50:28It actually means, take this and concatenate it four times over.
  18929. 14:50:32So that's a way of just distilling into one line what
  18930. 14:50:35would have otherwise taken multiple lines in C, fewer, but still multiple
  18931. 14:50:39lines in Python, but is really now rather succinct in Python,
  18932. 14:50:43by doing that instead.
  18933. 14:50:44Let's do one last Mario example, which looked a little something like this.
  18934. 14:50:48If this is another part of the Mario interface,
  18935. 14:50:50this is like a grid of like 3 by 3 bricks, for instance.
  18936. 14:50:53So two dimensions now, just not just vertical, not horizontal, but now both.
  18937. 14:50:57Let's print out something like that, using hashes.
  18938. 14:50:59Well, how about, how do I do this.
  18939. 14:51:02So how about for i in range of 3.
  18940. 14:51:05Then I could do for j in range of 3, just because j comes after I
  18941. 14:51:10and that's reasonable for counting.
  18942. 14:51:12I could now print out a hash symbol, well, let's see what this does.
  18943. 14:51:17Python of Mario.py, OK, that's just one crazy long column.
  18944. 14:51:24What do I need to fix and where here, to make this look like this?
  18945. 14:51:27So 3 by 3 bricks, instead of one long column.
  18946. 14:51:32Any instincts?
  18947. 14:51:32AUDIENCE: Why don't we create a line and then we'll skip it.
  18948. 14:51:37DAVID J. MALAN: OK, so after printing 3, we want to skip a line.
  18949. 14:51:39So maybe like print out a blank line here.
  18950. 14:51:42OK, let's try that.
  18951. 14:51:43I like that instinct, right, print 3, new line, print 3, new line.
  18952. 14:51:46Let's go ahead and run Python of Mario.py.
  18953. 14:51:48OK, it's more visible, what I'm doing, but still wrong.
  18954. 14:51:53What can I, what's the remaining fix, though?
  18955. 14:51:55Yeah.
  18956. 14:51:56AUDIENCE: So right behind the two.
  18957. 14:51:59DAVID J. MALAN: Yeah, I'm getting an extra new line here,
  18958. 14:52:02which I don't want while I'm on this row.
  18959. 14:52:04So let me do n equals quote unquote, and now, together, your solutions might
  18960. 14:52:08take us the whole way there.
  18961. 14:52:10Python of Mario.py, voila, now we've got it, in two dimensions.
  18962. 14:52:13And even this, we can tighten up.
  18963. 14:52:15Like, we could just use the little trick we learned.
  18964. 14:52:17So we could just say, print a hash times 3 times,
  18965. 14:52:21and we can get rid of one of those loops altogether.
  18966. 14:52:24All it's doing is, whoops, all it's doing is automating that process.
  18967. 14:52:27But, no, I don't want to do that.
  18968. 14:52:29What do I, how do I fix this here.
  18969. 14:52:31I don't think I want this anymore, right?
  18970. 14:52:33Because that's giving me an extra new line.
  18971. 14:52:34So now this program is really tightened up.
  18972. 14:52:37Same thing, two lines of code.
  18973. 14:52:39But we're now implementing this same two dimensional structure here.
  18974. 14:52:43All right, any questions here on these?
  18975. 14:52:46Yeah.
  18976. 14:52:47AUDIENCE: Is there any practical reason why when we write n, n is, I mean,
  18977. 14:52:53the print function, you don't put any spaces in it.
  18978. 14:52:56DAVID J. MALAN: If I print n, any spaces.
  18979. 14:52:58Say that once more.
  18980. 14:52:59AUDIENCE: Whenever we write n, for example,
  18981. 14:53:01the print function is, you know, in order
  18982. 14:53:05to stop it from going to a new line, it seems like any spaces,
  18983. 14:53:10we did like n equals and then too close.
  18984. 14:53:14There were no spaces.
  18985. 14:53:15Did you do that on purpose?
  18986. 14:53:16DAVID J. MALAN: Oh.
  18987. 14:53:18yes, good question.
  18988. 14:53:19I see what you're saying.
  18989. 14:53:20So in a previous version, let me rewind in time, when we had this,
  18990. 14:53:24I did not put spaces.
  18991. 14:53:25The convention in Python is not to do that.
  18992. 14:53:28Why?
  18993. 14:53:28It just starts to add too much space.
  18994. 14:53:30And this is a little inconsistent, because, earlier,
  18995. 14:53:32when we talked about like pluses or spaces
  18996. 14:53:34around the less than or equal signs, I did say add it.
  18997. 14:53:37Here it's actually clearer and recommended
  18998. 14:53:39to keep them tighter together.
  18999. 14:53:40Otherwise it just becomes harder to read where the gaps are.
  19000. 14:53:44Good observation.
  19001. 14:53:45All right, let's do, how about, another five minute break.
  19002. 14:53:50Let's do that.
  19003. 14:53:51And then we're going to dive into some more sophisticated problems,
  19004. 14:53:54and then ultimately build with some audio and visual examples, as well.
  19005. 14:53:57See you in five.
  19006. 14:53:59All right, so almost all of the examples we just did
  19007. 14:54:04were recreations of what we did in week 1.
  19008. 14:54:07And recall that week 1 was like our most syntax-heavy week.
  19009. 14:54:09It was when we were first learning how to program in C. But after week 1,
  19010. 14:54:13we began to focus a bit more on ideas, like arrays,
  19011. 14:54:16and other higher-level constructs.
  19012. 14:54:18And we'll do that again here, condensing some of those first early weeks
  19013. 14:54:21into a fewer set of examples in Python.
  19014. 14:54:23And we'll culminate by actually taking Python out for a spin,
  19015. 14:54:26and doing things that would be way harder to do,
  19016. 14:54:28and way more time-consuming to do in C, even more so than the speller example.
  19017. 14:54:33But how do you go about figuring out what functions exist,
  19018. 14:54:36if you didn't hear it in class, you don't see it online,
  19019. 14:54:39but you want to see it officially, you can go to the Python documentation,
  19020. 14:54:43docs.python.org here.
  19021. 14:54:44And I will disclaim that, honestly, the Python documentation is not
  19022. 14:54:47terribly user-friendly.
  19023. 14:54:49Google will often be your friend, so googling something
  19024. 14:54:51you're interested in, to find your way to the appropriate page on Python.org,
  19025. 14:54:55or StackOverflow.com is another popular website.
  19026. 14:54:58As always, though, the line should be googling
  19027. 14:55:01things like, how do I convert a string to lowercase.
  19028. 14:55:04Like that's reasonable to Google.
  19029. 14:55:05Or how to convert to uppercase or how implement function in Python.
  19030. 14:55:09But googling, of course, things like how to implement problem set 6 in CS50,
  19031. 14:55:14of course, crosses the line.
  19032. 14:55:15But moving forward, and really with programming in general, like Google
  19033. 14:55:18and Stack Overflow are your friends, but the line
  19034. 14:55:20is between the reasonable and the unreasonable.
  19035. 14:55:23So let me officially use the Python documentation search, just
  19036. 14:55:26to search for something like the lowercase function.
  19037. 14:55:29Like, I know I can lowercase things in Python.
  19038. 14:55:31I don't quite remember how.
  19039. 14:55:32So let me just search for the word lower.
  19040. 14:55:34You're going to get, often, an overwhelming number of results,
  19041. 14:55:37because Python is a pretty big language, with lots of functionality.
  19042. 14:55:40And you're going to want to look for familiar patterns.
  19043. 14:55:42For whatever reason, string.lower, which is probably
  19044. 14:55:45more popular or more commonly used than these other ones, is third on the list.
  19045. 14:55:48But it's purple, because I clicked it a moment ago, when looking for it.
  19046. 14:55:51So str.lower is probably what I want, because I
  19047. 14:55:54am interested at the moment in lower casing strings.
  19048. 14:55:57When I click on that, this is an example of what Python's documentation tends
  19049. 14:56:01to look like.
  19050. 14:56:02It's in this general format.
  19051. 14:56:03Here's my str.lower function.
  19052. 14:56:05This returns a copy of the string, with all
  19053. 14:56:08of the cased characters converted to lowercase,
  19054. 14:56:10and the lower-casing algorithm, dot dot dot.
  19055. 14:56:12So that doesn't give me much.
  19056. 14:56:13It doesn't give me sample code.
  19057. 14:56:14But it does say what the function does.
  19058. 14:56:16And if we keep looking, you'll see mention of Lstrip, which is left strip.
  19059. 14:56:20I used its analog, Rstrip before, right strip, which allows you to remove,
  19060. 14:56:24that is strip, from the end of a string, something like white space,
  19061. 14:56:27like a new line, or even something else.
  19062. 14:56:29And if you scroll through string, this web page here.
  19063. 14:56:32And we're halfway down the page already.
  19064. 14:56:34If you see my scroll bar, tiny on the right,
  19065. 14:56:36there's a huge amount of functionality built into string objects, here.
  19066. 14:56:41And this is just testament to just how rich the language itself is.
  19067. 14:56:44But it's also reason to reassure that the goal, when
  19068. 14:56:49playing around with some new language and learning it,
  19069. 14:56:51is not to learn it exhaustively.
  19070. 14:56:53Just like in English or any human language,
  19071. 14:56:54there's always going to be vocab words you don't know,
  19072. 14:56:57ways of presenting the same information in some language.
  19073. 14:57:00That's going to be the case with Python.
  19074. 14:57:01And what we'll do today and this week in problem set 6 is really
  19075. 14:57:05get your footing with this language.
  19076. 14:57:06But you won't know all of Python, just like you won't know all of C.
  19077. 14:57:09And, honestly, you won't know all of any of these languages on your own,
  19078. 14:57:12unless you're, perhaps, using them full time professionally,
  19079. 14:57:15and even then, there's more libraries than one might even retain themselves.
  19080. 14:57:18So let's actually now pivot to a few other ideas,
  19081. 14:57:21that we'll implement in Python, in a moment.
  19082. 14:57:24Let me switch back over to VS Code here.
  19083. 14:57:26And let me whip up, say, a recreation of our scores example from week two,
  19084. 14:57:31where we averaged like three scores together.
  19085. 14:57:34And that was an opportunity in week 2 to play with arrays,
  19086. 14:57:36to realize how constrained arrays are.
  19087. 14:57:38They can't grow or shrink.
  19088. 14:57:40You have to decide in advance.
  19089. 14:57:41But let's see what's different here in Python.
  19090. 14:57:43So let me do Scores.py, and let me give myself an array in Python
  19091. 14:57:48called scores, sorry, let me give myself a variable in Python called scores.
  19092. 14:57:52Set it equal to a list of three scores, which
  19093. 14:57:54are the same ones we've used before, 72, 73, 33, in this context
  19094. 14:57:59meant to be scores, not ASCII values.
  19095. 14:58:01And then let's just do the average of these.
  19096. 14:58:03So average will be another variable.
  19097. 14:58:05And it turns out I can do, well, how did I sum these before?
  19098. 14:58:09I probably had a for loop to add one, then I knew how long they were.
  19099. 14:58:13Turns out in Python, you can just say sum of scores
  19100. 14:58:16divided by the length of scores.
  19101. 14:58:18That's going to give me my average.
  19102. 14:58:19So sum is a function that takes a list, in this case, as input,
  19103. 14:58:22and it just does the sum for you, with a for loop or whatever
  19104. 14:58:25underneath the hood.
  19105. 14:58:26Len gives you the length of the list, how many things are in it.
  19106. 14:58:30So I can dynamically figure that out.
  19107. 14:58:31Now let me go ahead and print out, using print, the word average, and then,
  19108. 14:58:36in curly braces, the actual average, close quote.
  19109. 14:58:40All right, so let's run this code, Python of Scores.py.
  19110. 14:58:42And there is my average, in this case, 59.33333 and so forth,
  19111. 14:58:47based on the math.
  19112. 14:58:48Well, let's actually, now, change this a little bit
  19113. 14:58:51and make it a little more interesting, and actually get input from the user
  19114. 14:58:54rather than hard coding this.
  19115. 14:58:55Let me go back up here and use from CS50 import getInt,
  19116. 14:58:59because I don't want to deal with all the exceptions and the loops.
  19117. 14:59:01Like, I just want to use someone else's function here.
  19118. 14:59:04Let me give myself an empty list called scores.
  19119. 14:59:08And this is not something we were able to do in C, right?
  19120. 14:59:11Because in C, if you tried to make an empty array,
  19121. 14:59:13well, that's pretty stupid, because you can't add things to it.
  19122. 14:59:16It's a fixed size.
  19123. 14:59:17So it wouldn't even let you do that.
  19124. 14:59:19But I can just create an empty list in Python,
  19125. 14:59:22because lists, unlike arrays, are really lengthless.
  19126. 14:59:24They'll grow and shrink.
  19127. 14:59:26But you and I are not dealing with all the pointers underneath the hood.
  19128. 14:59:29Python's doing that for us.
  19129. 14:59:31So now, let's go ahead and get a whole bunch of scores from the user.
  19130. 14:59:34How about three of them in total.
  19131. 14:59:36So for i in range of 3, let's go ahead and grab a score from the user,
  19132. 14:59:41using getInt, asking them for score.
  19133. 14:59:44And then let's go ahead and append, to the scores list, that particular score.
  19134. 14:59:51So it turns out that a list, and I could read the Python
  19135. 14:59:53documentation to confirm as much, lists have a function built into them,
  19136. 14:59:57and functions built into objects are generally known as methods,
  19137. 15:00:01if you've heard that term before.
  19138. 15:00:03Same idea, but whereas a function kind of stands on its own,
  19139. 15:00:05a method is a function built into an object, like a list here.
  19140. 15:00:09That's going to achieve the same result. Strictly speaking,
  19141. 15:00:12I don't need the variable.
  19142. 15:00:13Just like in C, I could tighten this up and do something like this as well.
  19143. 15:00:17But, I don't know, I kind of like it this way.
  19144. 15:00:19It's more clear, to me, at least, that what I'm doing here, getting the score
  19145. 15:00:22and then appending it to the list.
  19146. 15:00:24Now the rest of the code can stay the same.
  19147. 15:00:26Python of Scores.py, score will be 72, 73, 33.
  19148. 15:00:31And I get back the math.
  19149. 15:00:32But now the program's a little more dynamic, which is nice.
  19150. 15:00:35But there's other syntax I could use here.
  19151. 15:00:37Just so you've seen it, Python does have some neat syntactic tricks,
  19152. 15:00:40whereby, if you don't want to do scores.append,
  19153. 15:00:43you can actually say scores plus equals this score.
  19154. 15:00:47So you can actually concatenate lists together in Python 2.
  19155. 15:00:52Just as we used plus to join two strings together,
  19156. 15:00:54you can use plus to join two lists together.
  19157. 15:00:57The catch is, you need to put the one score I'm
  19158. 15:01:00adding here in a list of its own, which is kind of silly.
  19159. 15:01:03But it's necessary, so that this thing and this thing are both lists.
  19160. 15:01:07To do this more verbosely, which most programmers wouldn't
  19161. 15:01:10do, but just for clarity, this is the same thing
  19162. 15:01:12as saying scores plus this score.
  19163. 15:01:15So now maybe it's a little more clear that scores and brackets score
  19164. 15:01:19plural, sorry, singular, are both lists themselves, being concatenated
  19165. 15:01:24or joined together.
  19166. 15:01:25So two different ways, not sure one is better than the other.
  19167. 15:01:28This way is pretty common, but .append is also quite reasonable as well.
  19168. 15:01:34All right, how about another example from week two.
  19169. 15:01:36This one was called uppercase.
  19170. 15:01:39So let me do this in Uppercase.py, though, this time.
  19171. 15:01:42And let me import from CS50, get string again.
  19172. 15:01:46And let me go ahead and say, before will be my first variable.
  19173. 15:01:50Let me get a string from the user, asking them for a before string.
  19174. 15:01:54And then let me go ahead and say, after, just to demonstrate some changes,
  19175. 15:01:59upper-casing to this string.
  19176. 15:02:01Let me change my line ending to be that, using our new trick.
  19177. 15:02:04And this is where things get cool in Python, relatively speaking.
  19178. 15:02:08If I want to iterate over all of the characters in a string,
  19179. 15:02:11and print them out in uppercase, one way to do that would be this.
  19180. 15:02:14For c in the before string, go ahead and print out C.uppercase, sorry, C.upper,
  19181. 15:02:22but don't end the line yet, because I want to keep these all on the same line
  19182. 15:02:25until I'm all done.
  19183. 15:02:26So what am I doing?
  19184. 15:02:28Python of Uppercase.py, let me type in Hello in all lowercase.
  19185. 15:02:31I've just upper-cased the whole string.
  19186. 15:02:33How?
  19187. 15:02:34I first get string, calling it before.
  19188. 15:02:36I then just print out some fluffy text that says after colon,
  19189. 15:02:39and I get rid of the line ending, just so I can kind of line these up.
  19190. 15:02:41Notice I hit the spacebar a couple of times
  19191. 15:02:43just so letters line up to be pretty.
  19192. 15:02:45For c and before, this is new.
  19193. 15:02:47This is powerful in C, sorry, in Python, whereby
  19194. 15:02:51you don't have to do like Int i equals 0 and i less than this,
  19195. 15:02:54you could just say, for c in the string in question, for c and before.
  19196. 15:02:58And then here is just upper-casing that specific character,
  19197. 15:03:02and making sure we don't output a new line too soon.
  19198. 15:03:04But this is actually more work than I need to do.
  19199. 15:03:06Based on what we've seen thus far, like from our agreement example,
  19200. 15:03:10can I tighten this up further?
  19201. 15:03:12Can I collapse lines 5 and 6, maybe even 7, all together?
  19202. 15:03:16If the goal of this program is just to uppercase the before string,
  19203. 15:03:23how might I do this?
  19204. 15:03:26Yeah, in back.
  19205. 15:03:27AUDIENCE: Would it be str.upper?
  19206. 15:03:28DAVID J. MALAN: Str.upper, yeah, so I could do something
  19207. 15:03:31like this, after gets before.upper.
  19208. 15:03:34So it's not stir literally dot upper, stir
  19209. 15:03:36just represents the string in question.
  19210. 15:03:38So it would be before.upper, but right idea otherwise.
  19211. 15:03:41And so let me go ahead and just tweak my print statement a little bit.
  19212. 15:03:44Let me just go ahead and print out the after variable here, after creating it.
  19213. 15:03:49So this line is the same, I'm getting a string called before.
  19214. 15:03:51I'm creating another variable called after, and, as you propose,
  19215. 15:03:55I'm calling upper on the whole string, not one character at a time.
  19216. 15:03:58Why?
  19217. 15:03:58Because it's allowed.
  19218. 15:03:59And, again, in Python, there aren't technically characters individually.
  19219. 15:04:03There's only strings, anyway.
  19220. 15:04:05So I might as well do them all at once.
  19221. 15:04:07So if I rerun the code now, Python of Uppercase.py.
  19222. 15:04:10Now I'll type in Hello in all lowercase, and, oh, so close,
  19223. 15:04:15I think I can get rid of this override, because I'm
  19224. 15:04:18printing the whole thing out at once, not character by character.
  19225. 15:04:22So now if I type in Hello before, now I have an even tighter version
  19226. 15:04:26of the program here.
  19227. 15:04:28All right, any questions, then, on lists or on strings,
  19228. 15:04:32and what this kind of function, upper, represents, with its docs.
  19229. 15:04:37No?
  19230. 15:04:38All right, so a couple other building blocks before we start.
  19231. 15:04:41Oh.
  19232. 15:04:42Where was that?
  19233. 15:04:43AUDIENCE: To the right.
  19234. 15:04:44DAVID J. MALAN: To the right, right.
  19235. 15:04:46Yes, thank you.
  19236. 15:04:47AUDIENCE: Could you write, very close to variable string, and then print upper,
  19237. 15:04:53you start creating a variable upper.
  19238. 15:04:55DAVID J. MALAN: Yes, do I have to create this variable, upper?
  19239. 15:04:58No, I don't.
  19240. 15:04:59I could actually tighten this up, and, if you really
  19241. 15:05:01want to see something neat, inside of the curly braces,
  19242. 15:05:04you don't have to just put the names of variables.
  19243. 15:05:07You can put a small amount of logic, so long
  19244. 15:05:10as it doesn't start to look stupid and kind of overwhelmingly complex, such
  19245. 15:05:13that it's sort of bad design at that point.
  19246. 15:05:15I can tighten this up like this.
  19247. 15:05:17And now we're in Python of Uppercase.py, writing Hello again.
  19248. 15:05:21And that, too, works.
  19249. 15:05:22But I would be careful about this.
  19250. 15:05:23You want to resist the temptation of having like a long line of code that's
  19251. 15:05:27inside the curly braces, because it's just going to be harder to read.
  19252. 15:05:29But, absolutely, you could indeed do that, too.
  19253. 15:05:32All right, how about command line arguments, which was one thing
  19254. 15:05:35we introduced in week two also, so that we could actually have the ability
  19255. 15:05:39to take input from the user, whoops.
  19256. 15:05:43So we could actually take input from the user at the command line,
  19257. 15:05:46so as to take literally command line arguments.
  19258. 15:05:49These are a little different, but it follows the same paradigm.
  19259. 15:05:52There's no main by default. And there's no Def main int
  19260. 15:05:56arg c char, or we called it string, argv by default. There's none of this.
  19261. 15:06:02So if you want access to the argument vector, argv, you import it.
  19262. 15:06:07And it turns out, there's another module in Python, or library in Python
  19263. 15:06:11called CIS, and you can import from the system this thing called argv.
  19264. 15:06:15So same idea, different place.
  19265. 15:06:17Now I'm going to go ahead and do this.
  19266. 15:06:19Let's write a program that just requires that the user types in two, a word,
  19267. 15:06:24after the program's name, or none at all.
  19268. 15:06:26So if the length of argv equals 2, let's go ahead and print out, how about,
  19269. 15:06:33Hello comma argv bracket 1 close quote, else if they don't type two words
  19270. 15:06:41total at the prompt, let's just say the default's, like we did weeks ago,
  19271. 15:06:44Hello, world.
  19272. 15:06:45So the only thing that's new here is we're importing argv from CIS,
  19273. 15:06:48and we're using this fancy f-string format, which kind of to your point,
  19274. 15:06:51too, it's putting more complex logic in the curly braces.
  19275. 15:06:55But that's OK.
  19276. 15:06:55In this case, it's a list called argv, and we're getting bracket 1 from it.
  19277. 15:07:00Let's do Python of Argv.py, Enter, Hello, world.
  19278. 15:07:04What if I do Argv.py David at the command line.
  19279. 15:07:08Now I get Hello, David.
  19280. 15:07:09So there's one curiosity here.
  19281. 15:07:11Python is not included in argv, whereas in C, dot
  19282. 15:07:15slash whatever was the first thing.
  19283. 15:07:18If the analog in Python is that the name of your Python program
  19284. 15:07:22is the first thing, in bracket 0, which is why David is in bracket 1,
  19285. 15:07:26the word Python does not appear in the argv list, just to be clear.
  19286. 15:07:32But otherwise, the idea of these arguments
  19287. 15:07:34is exactly the same as before.
  19288. 15:07:36And in fact, what you can do, which is kind of cool,
  19289. 15:07:39is, because argv is a list, you can do things like this.
  19290. 15:07:42For arg in argv, go ahead and print out each argument.
  19291. 15:07:47So instead of using a for loop and i and all
  19292. 15:07:49of this, if I do Python of argv Enter, it just writes the program's name.
  19293. 15:07:53If I do Python of argv Foo, it puts Argv.py and Foo.
  19294. 15:07:58If I do, sorry, if I do Foo and bar, those words all print out.
  19295. 15:08:03If I do Foobar baz, those print out too.
  19296. 15:08:05And Foo and bar or baz are like a mathematician's x and y and z
  19297. 15:08:08for computer scientists, when you just need some placeholder words.
  19298. 15:08:11So this is just nice.
  19299. 15:08:12It reads a little more like English, and a for loop is just much more concise,
  19300. 15:08:16allows you to iterate very quickly when you want something like that.
  19301. 15:08:20Suppose I only wanted the real words that the human typed
  19302. 15:08:22after the program's name.
  19303. 15:08:23Like, suppose I want to ignore Argv.py.
  19304. 15:08:26I mean I could do something hackish like this.
  19305. 15:08:30If arg equals Argv.py, I could just ignore,
  19306. 15:08:35you know, let's invert the logic.
  19307. 15:08:37I could do this, for instance.
  19308. 15:08:39So if the arg does not equal the program name,
  19309. 15:08:41then go ahead and print out the word.
  19310. 15:08:44So I get Foobar and baz only.
  19311. 15:08:46Or, this is what's kind of neat about Python 2, let me undo that.
  19312. 15:08:50And let me just take a slice of the array of the list instead.
  19313. 15:08:54So it turns out, if argv is a list, I can actually say,
  19314. 15:08:59you know what, go into that list, start at element 1, instead of 0,
  19315. 15:09:03and then go all the way to the end.
  19316. 15:09:05And we have not seen this syntax in C. But this
  19317. 15:09:08is a way of slicing a list in Python.
  19318. 15:09:10So now watch what happens.
  19319. 15:09:12If I run Python of Argv.py, Foo bar baz Enter,
  19320. 15:09:17I get only a subset of the list, starting at position 1,
  19321. 15:09:21going all of the way to the end.
  19322. 15:09:23And you can even do kind of the opposite.
  19323. 15:09:25If, for whatever reason, you want to ignore the last element,
  19324. 15:09:27you can say colon, we could say colon negative 1,
  19325. 15:09:33and use a negative number, which we've not seen before,
  19326. 15:09:36which slices off the end of the list, as well.
  19327. 15:09:38So there's some syntactic tricks that tend to be powerful in Python 2,
  19328. 15:09:42even if at first glance, you might not need them for typical things.
  19329. 15:09:46All right, let's do one other example with exit,
  19330. 15:09:49and then we'll start actually applying some algorithms,
  19331. 15:09:51to make things interesting.
  19332. 15:09:52So in one last program here, let's do Exit.py, just to do one more mechanic,
  19333. 15:09:56before we introduce some algorithms.
  19334. 15:09:58And let's do this.
  19335. 15:10:00Let's import from CIS, import argv.
  19336. 15:10:05Let's now do this.
  19337. 15:10:07Let's make sure the user gives me one command line argument.
  19338. 15:10:09So if the length of argv does not equal 2 in total, then let's go ahead
  19339. 15:10:16and print out something like missing command line argument,
  19340. 15:10:19just to explain what the problem is.
  19341. 15:10:21And then let's do this.
  19342. 15:10:23We can exit.
  19343. 15:10:25But I'm going to use a better version of exit here.
  19344. 15:10:27Let me import two functions from CIS.
  19345. 15:10:29Turns out the better way to do this is with CIS.exit, because I can then exit
  19346. 15:10:33specifically 2, with this exit code.
  19347. 15:10:36Otherwise, down here, I'm going to go ahead and print out,
  19348. 15:10:38something like Hello, comma argv bracket 1, same as before.
  19349. 15:10:43And then I'm going to exit with zero.
  19350. 15:10:44So, again, this was a subtle thing we introduced
  19351. 15:10:46in week two, where you can actually have your programs exit,
  19352. 15:10:49with some number, where 0 signifies success,
  19353. 15:10:51and anything else signifies error.
  19354. 15:10:53This is just the same idea in Python.
  19355. 15:10:55So if I, for instance, just run the program like this, oops, I screwed up.
  19356. 15:11:00I meant to say exit here and exit here.
  19357. 15:11:03Let me do that again.
  19358. 15:11:04If I run this like this, I'm missing a command line argument.
  19359. 15:11:07So let me rerun it with like my name at the prompt.
  19360. 15:11:09So I have exactly two command line arguments, the file name and my name,
  19361. 15:11:13Hello comma David.
  19362. 15:11:14And if I do David Malan, it's not going to work either,
  19363. 15:11:16because now argv does not equal 2.
  19364. 15:11:18But the difference here is that we're exiting with 1,
  19365. 15:11:21so that special programs can detect an error, or 0 in the event of success.
  19366. 15:11:26And now there's one other way to do this, too.
  19367. 15:11:28Suppose that you're importing a lot of functions,
  19368. 15:11:30and you don't really want to make a mess of things
  19369. 15:11:33and just have all of these function names available,
  19370. 15:11:35without it being clear where they came from.
  19371. 15:11:38Let's just import all of CIS.
  19372. 15:11:39And let's just change our syntax, kind of like I proposed for CS50,
  19373. 15:11:43where we just prepend to all of these library functions,
  19374. 15:11:46CIS, just to be super-explicit where they came from,
  19375. 15:11:49and if there's another exit or argv value
  19376. 15:11:55that we want to import from a library, this is one way to avoid collision.
  19377. 15:11:58So if I do it one last time here, missing command line argument.
  19378. 15:12:01But David still actually worked.
  19379. 15:12:03All right, only to demonstrate how we can implement that same idea.
  19380. 15:12:06Let's now do something more powerful, like a search algorithm,
  19381. 15:12:09like binary search.
  19382. 15:12:10I'm going to go ahead and open up a file called Numbers.py,
  19383. 15:12:13and let's just do some searching or linear search, rather,
  19384. 15:12:16on a list of numbers.
  19385. 15:12:18Let's go ahead and do this.
  19386. 15:12:20How about import CIS as before.
  19387. 15:12:23Let me give myself a list of numbers, like 4, 6, 8, 2, 7, 5, 0,
  19388. 15:12:29so just a bunch of integers.
  19389. 15:12:31And then let's do this.
  19390. 15:12:32If you recall from week three, we searched for the number 0
  19391. 15:12:36at the end of the lockers on stage.
  19392. 15:12:38So let's just ask that question in Python.
  19393. 15:12:40No need for a loop or anything like that.
  19394. 15:12:42If 0 is in the numbers, go ahead and print out found.
  19395. 15:12:46And then let's just exit successfully, with 0, else, if we get down here,
  19396. 15:12:49let's just say print not found.
  19397. 15:12:52And then we'll CIS exit with 1.
  19398. 15:12:55So this is where Python starts to get powerful again.
  19399. 15:12:58Here's your list.
  19400. 15:12:59Here is your loop, that's doing all of the checking for you.
  19401. 15:13:02Underneath the hood, Python is going to use linear search.
  19402. 15:13:04You don't have to implement it yourself.
  19403. 15:13:06No while loop, no for loop, you just ask a question.
  19404. 15:13:08If 0 is in numbers, then do the following.
  19405. 15:13:12So that's one feature we now get with Python,
  19406. 15:13:14and get to throw away a lot of that code.
  19407. 15:13:16We can do it with strings, too.
  19408. 15:13:18Let me open a file called Names.py instead,
  19409. 15:13:21and do something that was even more involved in C,
  19410. 15:13:23because we needed Str Comp and the for loop, and so forth.
  19411. 15:13:26Let me import CIS for this file.
  19412. 15:13:28Let's give myself a bunch of names like we did in C.
  19413. 15:13:30And those were Bill and Charlie and Fred and George and Ginny,
  19414. 15:13:38and two more, Percy, and lastly Ron.
  19415. 15:13:41And recall, at the time, we looked for Ron.
  19416. 15:13:43And so we had to iterate through the whole thing,
  19417. 15:13:45doing Str Comp and i plus plus and all of that.
  19418. 15:13:48Now just ask the question, if Ron is in names, then let's go ahead
  19419. 15:13:55and, whoops, let me hide that.
  19420. 15:13:56I hit the command too soon.
  19421. 15:13:58Let me go ahead and say print, found, as before.
  19422. 15:14:02CIS exit 1, just to indicate success, and then down here,
  19423. 15:14:06if we get to this point, we can say not found.
  19424. 15:14:09And then we'll just CIS exit 1 instead.
  19425. 15:14:12So, again, this just does linear search for us by default, Python of Names.py,
  19426. 15:14:17we found Ron, because, indeed, he's there, and at the end of the list.
  19427. 15:14:20But we don't need to deal with all of the mechanics of it.
  19428. 15:14:24All right, let's take things one step further.
  19429. 15:14:27In week three, we also implemented the idea
  19430. 15:14:29of a phone book, that actually associated keys with values.
  19431. 15:14:33But remember, the phone book in C, was kind of a hack, right?
  19432. 15:14:36Because we first had two arrays, one with names, one with numbers.
  19433. 15:14:40Then we introduced structs, and so we gave you a person structure.
  19434. 15:14:43And then we had an array of persons.
  19435. 15:14:47You can do this in Python, using objects and things called classes.
  19436. 15:14:51But we can also just use a general purpose dictionary,
  19437. 15:14:54because just like in P set 5, you can associate keys with values, using
  19438. 15:14:57a hash table, using a try.
  19439. 15:14:59Well, similarly, can Python just do this for us.
  19440. 15:15:02From CS50, let's import get string.
  19441. 15:15:05And now let's give myself a dictionary of people,
  19442. 15:15:09D-I-C-T () open paren closed paren gives you a dictionary.
  19443. 15:15:13Or you can simplify the syntax, actually,
  19444. 15:15:15and a dictionary again is just keys and values, words and definitions.
  19445. 15:15:18You can also just use curly braces instead.
  19446. 15:15:21That gives me an empty dictionary.
  19447. 15:15:23But if I know what I want to put in it by default, let's put Carter in there,
  19448. 15:15:26with a number of plus 1-617-495-1000, just like last time, and put myself,
  19449. 15:15:34David, with plus 1-949-468-2750.
  19450. 15:15:40And it came to my attention, tragically, after class that day,
  19451. 15:15:42that we had a bug in our little Easter egg.
  19452. 15:15:44If today, you would like to call me or text me, at that number,
  19453. 15:15:47we have fixed the code that underlies that little Easter egg.
  19454. 15:15:50Spoiler ahead.
  19455. 15:15:51All right, so this now gives me a variable
  19456. 15:15:53called people, that's associating keys with values.
  19457. 15:15:57There is some new syntax here in Python, not just the curly braces,
  19458. 15:16:01but the colons, and the quotes on the left and the right.
  19459. 15:16:04This is a way, in Python, of associating keys
  19460. 15:16:07with values, words with definitions, anything with anything else.
  19461. 15:16:11And it's going to be a super-common paradigm, including in week seven,
  19462. 15:16:15when we look at CSS and HTML and web programming, keys and values
  19463. 15:16:18are like this omnipresent idea in computer science and programming,
  19464. 15:16:22because it's just a really useful way of associating one thing with another.
  19465. 15:16:25So, at this point in the story, we have a dictionary, a hash table,
  19466. 15:16:29if you will, of people, associating names with phone numbers,
  19467. 15:16:32just like a real world phone book.
  19468. 15:16:34So let's write a program that gets a string from the user and asks them
  19469. 15:16:37whose number they would like to look up.
  19470. 15:16:39Then, let's go ahead and say, if that name is in the people dictionary,
  19471. 15:16:46go ahead and print out that person's number,
  19472. 15:16:48by going into the people dictionary and going
  19473. 15:16:51to that specific name, within there, using an f-string for the whole thing.
  19474. 15:16:56So this is similar in spirit to before.
  19475. 15:16:58Linear search and dictionary lookups will just happen automatically for you
  19476. 15:17:02in Python, by just asking the question, if name and people.
  19477. 15:17:05And this line is just going to print out,
  19478. 15:17:07whoever is in the people dictionary, at that name.
  19479. 15:17:12So I'm using square brackets, because here's the interesting thing in Python,
  19480. 15:17:16just like you can index into an array, or a list in Python,
  19481. 15:17:19using numbers, 0, 1, 2, you can very conveniently index
  19482. 15:17:24into a dictionary in Python, using square brackets, as well.
  19483. 15:17:29And just to make clear what's going on here, let me go
  19484. 15:17:32and create a temporary variable, person equals people bracket name.
  19485. 15:17:37And then let's just, or, sorry, let's say, number equals people bracket name.
  19486. 15:17:41And that will just print out the number in question.
  19487. 15:17:44In C, and previously in Python, anything with square brackets like this
  19488. 15:17:48would have been go to a location in a list or an array, using a number.
  19489. 15:17:53But that can actually be a string, like a word the human has typed.
  19490. 15:17:57And this is what's amazing about dictionaries,
  19491. 15:17:59it's not like a big line, a big linear thing.
  19492. 15:18:02It's this table, that you can look up in one column the name,
  19493. 15:18:05and get back in the other column the number.
  19494. 15:18:07So let's go ahead and run Python of Phonebook.py,
  19495. 15:18:09found, not that, oh, wait.
  19496. 15:18:14That's not what's supposed to happen at all.
  19497. 15:18:18I think I'm in the wrong play.
  19498. 15:18:19Phonebook.py.
  19499. 15:18:23What's going on?
  19500. 15:18:25Print found.
  19501. 15:18:28I am confused.
  19502. 15:18:30OK, let's run this again.
  19503. 15:18:32Python of Phonebook.py, what the--
  19504. 15:18:36OK, stand by.
  19505. 15:18:43[KEYS CLICKING]
  19506. 15:18:54What the heck?
  19507. 15:18:55What am I not understanding here?
  19508. 15:19:00OK, Roxanne, Carter, do you see what I'm doing wrong?
  19509. 15:19:03AUDIENCE: I don't.
  19510. 15:19:05DAVID J. MALAN: What the--
  19511. 15:19:08[LAUGHTER]
  19512. 15:19:10Say again?
  19513. 15:19:10SPEAKER 47: When you found the test results, it was doing both commands.
  19514. 15:19:14DAVID J. MALAN: Oh, yeah, found, OK, we're going to do this.
  19515. 15:19:19One sec.
  19516. 15:19:22[KEYS CLICKING]
  19517. 15:19:28Whoa, OK.
  19518. 15:19:31All this is coming out of the video.
  19519. 15:19:33So.
  19520. 15:19:34[LAUGHTER]
  19521. 15:19:35[APPLAUSE]
  19522. 15:19:37Thanks.
  19523. 15:19:41All right.
  19524. 15:19:42I will try to figure out what was going wrong.
  19525. 15:19:44The best I can tell, it was running the wrong program.
  19526. 15:19:47I don't quite understand why.
  19527. 15:19:49So we will diagnose this later.
  19528. 15:19:50I just put the file into a temporary directory, for now, to run it.
  19529. 15:19:53So let me go ahead and just run this, Python of Phonebook.py,
  19530. 15:19:59type in, for instance, my name.
  19531. 15:20:00And there's my corresponding number.
  19532. 15:20:02Have no idea what was just happening.
  19533. 15:20:04But I will get to the bottom of it and update you,
  19534. 15:20:06if we can put our finger on it.
  19535. 15:20:07So this was just an example, now, of implementing a phone book.
  19536. 15:20:11Let's now consider what we can do that's a little more
  19537. 15:20:14powerful, in these examples, like a phone book that
  19538. 15:20:16actually keeps this information around.
  19539. 15:20:18Thus far, these simple phone book examples throw the information away.
  19540. 15:20:22But using CSV files, comma separated values,
  19541. 15:20:25maybe we could actually keep around the names and numbers,
  19542. 15:20:28so that, like on your phone, you can actually
  19543. 15:20:29keep your contacts around long-term.
  19544. 15:20:32So I'm going to go ahead now and do a slightly different example.
  19545. 15:20:35And let me just hide this detail, so it's not confusing.
  19546. 15:20:39Whoops, I'm going to change my prompt temporarily.
  19547. 15:20:43So let me go ahead now and refine this example as follows.
  19548. 15:20:47I'm going to go into Phonebook.py, and I'm
  19549. 15:20:50going to import a whole library called CSV.
  19550. 15:20:52And this is a powerful one, because Python
  19551. 15:20:54comes with a library that just handles CSV files for you.
  19552. 15:20:58A CSV file is just a file with comma separated values.
  19553. 15:21:02And, in fact, to demonstrate this, let me check on one thing
  19554. 15:21:06here, just to make this a little more real.
  19555. 15:21:08To demonstrate this, let's go ahead and do this.
  19556. 15:21:15Let me import the CSV library from CS50.
  19557. 15:21:18Let me import getString.
  19558. 15:21:20Let me then open a file, using the open function,
  19559. 15:21:24open a file called Phonebook.csv, in append format,
  19560. 15:21:28in contrast with read format and write format.
  19561. 15:21:31Write just blows it away if it exists, append adds to the bottom of it.
  19562. 15:21:34So I keep this phone book around, just like you might
  19563. 15:21:37keep adding contacts to your phone.
  19564. 15:21:39Now let me go ahead and get a couple of values from the user.
  19565. 15:21:41Let me say getString and ask the user for a name.
  19566. 15:21:45Then let me getString again, and ask the user for their number.
  19567. 15:21:50And now, let me go ahead and do this.
  19568. 15:21:52And this is new, and this is Python-specific.
  19569. 15:21:54And you would only know this by following a tutorial,
  19570. 15:21:57or reading the documentation.
  19571. 15:21:59Let me give myself a variable called writer,
  19572. 15:22:01and ask the CSV library for a writer to that file.
  19573. 15:22:06Then, let me go ahead and use that writer variable,
  19574. 15:22:09use a function or a method inside of it, called write row,
  19575. 15:22:13to write out a list containing that person's name and number.
  19576. 15:22:17Notice the square brackets inside the parentheses,
  19577. 15:22:20because I'm just printing a list to that particular row in the file.
  19578. 15:22:25And then I'm just going to close the file.
  19579. 15:22:27So what is the effect of all of this?
  19580. 15:22:29Well, let me go ahead and run this version of Phonebook.py,
  19581. 15:22:31and I'm prompted for a name.
  19582. 15:22:33Let's do Carter's first, plus 1-617-495-1000, and then,
  19583. 15:22:41let's go ahead and LS.
  19584. 15:22:44Notice in my current directory, there's two files now, Phonebook.py,
  19585. 15:22:47which I wrote, and apparently Phonebook.csv.
  19586. 15:22:50CSV just stands for comma separated values.
  19587. 15:22:53And it's like a very simple way of storing data in a spreadsheet,
  19588. 15:22:56if you will, where the comma represents the separation between your columns.
  19589. 15:23:00There's only two columns here, name and number.
  19590. 15:23:02But, because I'm writing to this file in append mode,
  19591. 15:23:06let me run it one more time, Python of Phonebook.py,
  19592. 15:23:09and let me go ahead and do David and plus 1-949-468-2750, Enter.
  19593. 15:23:18And notice what happened in the CSV file.
  19594. 15:23:19It automatically updated, because I'm now persisting
  19595. 15:23:22this data to the file in question.
  19596. 15:23:25So if I wanted to now read this file in, I
  19597. 15:23:27could actually go ahead and do linear search on the data,
  19598. 15:23:32using a read function to actually read from the CSV.
  19599. 15:23:35But, for now, we'll just leave it a little simply as write.
  19600. 15:23:37And let me make one refinement here.
  19601. 15:23:39It turns out that, if you're in the habit of re-opening a file,
  19602. 15:23:43you don't have to even close it explicitly.
  19603. 15:23:45You can instead do this.
  19604. 15:23:47You can instead say, with the opening of a file called Phonebook.csv
  19605. 15:23:52in append mode, calling the thing file, go ahead and do all of these lines
  19606. 15:23:57here.
  19607. 15:23:58So the with keyword is a new thing in Python.
  19608. 15:24:00And it's used in a few different ways, but one of the ways it's used
  19609. 15:24:03is to tighten up code here.
  19610. 15:24:04And I'm going to move my variables to the outside,
  19611. 15:24:06because they don't need to be inside of the with statement,
  19612. 15:24:09where the file is open.
  19613. 15:24:10This just has the effect of ensuring that you, the programmer,
  19614. 15:24:12don't screw up, and accidentally don't close your file.
  19615. 15:24:15In fact, you might recall, from C, Valgrind
  19616. 15:24:17might have complained at you, if you had a file that, you didn't close a file,
  19617. 15:24:21you might have had a memory leak as a result. The with keyword
  19618. 15:24:24takes care of all of that for you, as well.
  19619. 15:24:28How about let's do, want to do this.
  19620. 15:24:31How about, let's do one other thing.
  19621. 15:24:34Let's do this.
  19622. 15:24:35Let me go ahead and propose, that on your phone or laptop
  19623. 15:24:38here, or online, go to this URL here, where you'll find a Google form.
  19624. 15:24:43And just to show that these CSVs are actually kind of omnipresent,
  19625. 15:24:46and if you've ever like used a Google Form
  19626. 15:24:48or managed a student group, or something where you've
  19627. 15:24:50collected data via Google Forms, you can actually
  19628. 15:24:52export all of that data via CSV files.
  19629. 15:24:55So go ahead to this URL here.
  19630. 15:24:57And those of you watching on demand later,
  19631. 15:24:59will find that the form is no longer working,
  19632. 15:25:01since we're only doing this live.
  19633. 15:25:02But that will lead to a Google Form that's
  19634. 15:25:04going to let everyone input their answer to a question,
  19635. 15:25:07like what house do you want to end up into,
  19636. 15:25:10sort of an approximation of the sorting hat in Harry Potter.
  19637. 15:25:13And via this form, will we then have the ability to export,
  19638. 15:25:17we'll see, a CSV file.
  19639. 15:25:20So let's give you a moment to do that.
  19640. 15:25:24In just a moment, I'll share my version of the screen, which
  19641. 15:25:26is going to let me actually open the file, the form itself.
  19642. 15:25:30And in just a moment, I'll switch over.
  19643. 15:25:35OK, so this is now my version of the form
  19644. 15:25:37here, where we have 200 plus responses to a simple question of the form, what
  19645. 15:25:40house do you belong in, Gryffindor, Hufflepuff, Ravenclaw, or Slytherin.
  19646. 15:25:44If I go over to responses, I'll see all of the responses in the GUI form here.
  19647. 15:25:49So graphical user interface, and we could flip through this.
  19648. 15:25:51And it looks like, interestingly, 40% of Harvard students
  19649. 15:25:56want to be in Gryffindor, 22% in Slytherin, and everyone else
  19650. 15:26:00in between the others.
  19651. 15:26:01But you might have noticed, if ever using a Google Form,
  19652. 15:26:03this Google Spreadsheets link.
  19653. 15:26:05So I'm going to go ahead and click that.
  19654. 15:26:06And that's going to automatically open, in this case, Google Spreadsheets.
  19655. 15:26:08But you can do the same thing with Office 365 as well.
  19656. 15:26:11And now you see the raw data as a spreadsheet.
  19657. 15:26:14But in Google Spreadsheets, if I go to File and then I go to Download,
  19658. 15:26:19notice I can download this as an Excel file, a PDF, and also
  19659. 15:26:23a CSV, comma separated values.
  19660. 15:26:25So let me go ahead and do that.
  19661. 15:26:27That gives me a file in my Downloads folder on my computer.
  19662. 15:26:30I'm going to now go back to my code editor here.
  19663. 15:26:34And what I'm going to go ahead and do is upload
  19664. 15:26:36this file, from my Downloads folder to VS Code,
  19665. 15:26:40so that we can actually see it within here.
  19666. 15:26:43And now you can see this open file.
  19667. 15:26:44And I'm going to shorten its name, just so it's a little easier to read.
  19668. 15:26:47I'm going to rename this using the MV command, to just Hogwarts.csv.
  19669. 15:26:52And then we can see, in the file, that there's two columns, timestamp column
  19670. 15:26:55house, where you have a whole bunch of time stamps
  19671. 15:26:57when people filled out the form, with someone very early in class.
  19672. 15:27:00And then everyone else just a moment ago.
  19673. 15:27:02And the second value, after each comma, is the name of the house.
  19674. 15:27:05Well, let me go ahead here and implement a program
  19675. 15:27:08in a file called Hogwarts.py, that processes this data.
  19676. 15:27:12So in Hogwarts.py, let's just write a program
  19677. 15:27:14that now reads a CSV, in this case not a phone book,
  19678. 15:27:17but everyone's sorting hat information.
  19679. 15:27:19And I'm going to go ahead and Import CSV.
  19680. 15:27:21And suppose I want to answer a reasonable question, ignoring
  19681. 15:27:25the fact that Google's GUI or graphical user interface, can do this for me.
  19682. 15:27:28I just want to count up who's going to be in which house.
  19683. 15:27:31So let me give myself a dictionary called houses, that's initially empty,
  19684. 15:27:36with curly braces.
  19685. 15:27:37And let me pre-create a few keys.
  19686. 15:27:39Let me say Gryffindor is going to be initialized to 0,
  19687. 15:27:44Hufflepuff will be initialized to 0 as well, Ravenclaw
  19688. 15:27:48will be initialized to 0.
  19689. 15:27:49And finally, Slytherin will be initialized to 0.
  19690. 15:27:53So here's another example of a dictionary, or a hash table,
  19691. 15:27:56just being a very general-purpose piece of data.
  19692. 15:27:58You can have keys and values.
  19693. 15:28:00The keys, in this case, are the houses.
  19694. 15:28:01The values are initially zero, but I'm going to use this,
  19695. 15:28:05instead of like four separate variables, to keep track of everyone's answer
  19696. 15:28:10to this form.
  19697. 15:28:11So I'm going to do this.
  19698. 15:28:12With opening Hogwarts.csv, in read mode, not append, I don't want to change it.
  19699. 15:28:19I just want to read it, as file as my variable name.
  19700. 15:28:22Let's go ahead and create a reader this time,
  19701. 15:28:26that is using the reader function in the CSV library, by opening that file.
  19702. 15:28:31I'm going to go ahead and ignore the first line of the file,
  19703. 15:28:33because, recall, that the first line is just timestamp and house.
  19704. 15:28:36I want to get the real data.
  19705. 15:28:37So this next function is just a little trick
  19706. 15:28:40for ignoring the first line of the file.
  19707. 15:28:43Then let's do this.
  19708. 15:28:44For every other row in the reader, that is line by line,
  19709. 15:28:48get the current person's house, which is in row bracket 1.
  19710. 15:28:51This is what the CSV reader library is doing for us.
  19711. 15:28:54It's handling all of the reading of this file.
  19712. 15:28:56It figures out where the comma is, and, for every row in the file,
  19713. 15:29:00it hands you back a list of size 2.
  19714. 15:29:02In bracket 0 is the time stamp, in bracket 1 is the house name.
  19715. 15:29:07So, in my code, I can say house equals row bracket 1.
  19716. 15:29:11I don't care about the time stamp for this program.
  19717. 15:29:13And then let's go into my dictionary called houses, plural, index
  19718. 15:29:17into it at the house location, by its name, and increment that 0 to 1.
  19719. 15:29:23And now, at the end of this block of code,
  19720. 15:29:26that has the effect of iterating over every line of the file,
  19721. 15:29:29updating my dictionary in four different places,
  19722. 15:29:31based on whether someone typed Gryffindor or Slytherin or anything
  19723. 15:29:35else.
  19724. 15:29:36And notice that I'm using the name of the house to index into my dictionary,
  19725. 15:29:40to essentially go up to this little cheat sheet and change the 0 to a 1,
  19726. 15:29:44the 1 to a 2, the 2 to a 3, instead of having
  19727. 15:29:46like four separate variables, which would just
  19728. 15:29:48be much more annoying to maintain.
  19729. 15:29:50Down at the bottom, let's just print out the results.
  19730. 15:29:52For each house in those houses, iterating over
  19731. 15:29:56the keys they're in by default in Python,
  19732. 15:29:58let's go ahead and print out an f-string that says,
  19733. 15:30:01the current house has the current count.
  19734. 15:30:05And count will be the result of indexing into houses, for that given house.
  19735. 15:30:11And let me close my quote.
  19736. 15:30:13So let's run this to summarize the data, Hogwarts.py, 140 of you
  19737. 15:30:18answered Gryffindor, 54 Hufflepuff, 72 Ravenclaw, and 80 of you Slytherin.
  19738. 15:30:22And that's just my now way of code, and this is, oh,
  19739. 15:30:25my God, so much easier than C, to actually analyze data in this way.
  19740. 15:30:28And one of the reasons that Python is so popular for data science and analytics,
  19741. 15:30:32more generally, is that it's actually really easy to manipulate data, and run
  19742. 15:30:36analytics like this.
  19743. 15:30:37And let me clean this up slightly.
  19744. 15:30:38It's a little annoying that I just have to know and trust
  19745. 15:30:41that the house name is in bracket 1 and timestamp is in bracket 0.
  19746. 15:30:46Let's clean this up.
  19747. 15:30:47There's something called a Dictionary Reader in the CSV library
  19748. 15:30:53that I can use instead.
  19749. 15:30:54Capital D, capital R, this means I can throw away this next thing,
  19750. 15:30:58because what a dictionary reader does is it
  19751. 15:31:01still returns to me every row from the file, one after the other,
  19752. 15:31:05but it doesn't just give me a list of size 2 representing each row.
  19753. 15:31:09It gives me a dictionary.
  19754. 15:31:10And it uses, as the keys in that dictionary, timestamp and house,
  19755. 15:31:15for every row in the file, which is just to say
  19756. 15:31:17it makes my code a little more readable, because instead
  19757. 15:31:20of doing this little trickery, bracket 1,
  19758. 15:31:23I can say quote unquote "Bracket House" with a capital H,
  19759. 15:31:26because it's capitalized in the Google Form itself.
  19760. 15:31:28So the code now is just minorly different,
  19761. 15:31:31but it's way more resilient, especially if I'm using Google Spreadsheets,
  19762. 15:31:34and I'm moving the columns around or doing something like that,
  19763. 15:31:36where the numbers might get messed up.
  19764. 15:31:38Now I can run this on Hogwarts.py again, and I get the same answers.
  19765. 15:31:41But I now don't have to worry about where those individual columns are.
  19766. 15:31:46All right, any questions on those capabilities there.
  19767. 15:31:51And that's a teaser of sorts, for some of the manipulation
  19768. 15:31:53we'll do in P set 6.
  19769. 15:31:56All right, so some final examples and flair, to intrigue
  19770. 15:32:00with what you can do with Python.
  19771. 15:32:01I'm going to actually switch over to a terminal window on my own Mac,
  19772. 15:32:05so that I can actually use audio a little more effectively.
  19773. 15:32:08So here's just a terminal window on Mac OS.
  19774. 15:32:10I before class have preinstalled some additional Python libraries,
  19775. 15:32:14that won't really work in VS Code in the cloud,
  19776. 15:32:16because they require audio that the browser won't necessarily support.
  19777. 15:32:20But I'm going to go ahead and write an example here
  19778. 15:32:22that involves writing a speech-based program, that actually does something
  19779. 15:32:26with speech.
  19780. 15:32:26And I'm going to go ahead and import a library,
  19781. 15:32:28that, again, I pre-installed, called Python text to speech,
  19782. 15:32:32and I'm going to go ahead and, per its documentation,
  19783. 15:32:34give myself a speech engine, by using that library's init function,
  19784. 15:32:39for initialize.
  19785. 15:32:40I'm then going to use this engine's save function
  19786. 15:32:43to do something fun, like Hello, world.
  19787. 15:32:45And then I'm going to go ahead and tell this engine to run and wait,
  19788. 15:32:49while it says those words.
  19789. 15:32:50All right, I'm going to save this file.
  19790. 15:32:52I'm not using VS Code at the moment.
  19791. 15:32:53I'm using another popular program that we used in CS50 back in my day,
  19792. 15:32:56called Vim, which is a command line program that's
  19793. 15:32:59just in this black and white window.
  19794. 15:33:01Let me go ahead now and run Python of Speech.py, and--
  19795. 15:33:05COMPUTER: Hello, world.
  19796. 15:33:07DAVID J. MALAN: All right, so it's a little computerized,
  19797. 15:33:09but it is speech that has been synthesized from this example.
  19798. 15:33:12Let's change it a little bit to be more interesting.
  19799. 15:33:14Let's do something like this.
  19800. 15:33:16Let's ask the user for their name, like what's your name question mark.
  19801. 15:33:20And then, let's use the little F string, and say, not Hello, world,
  19802. 15:33:24but Hello to that person's name.
  19803. 15:33:26Let me save my file, run Python of Speech.py, Enter.
  19804. 15:33:30David.
  19805. 15:33:31COMPUTER: Hello, David.
  19806. 15:33:33DAVID J. MALAN: All right, so we pronounce my name OK,
  19807. 15:33:36might struggle with different names, depending on the phonetics.
  19808. 15:33:38But that one seemed to be OK.
  19809. 15:33:40Let's do something else with Python, using similarly,
  19810. 15:33:42just a few lines of code.
  19811. 15:33:44Let me go into today's examples.
  19812. 15:33:49And I'm going to go into a folder called Detect, whoops, a folder called
  19813. 15:33:54Faces.py.
  19814. 15:33:56Sorry, Faces.
  19815. 15:33:57And in this folder, that I've written in advance,
  19816. 15:33:59are a few files, Detect.py, Recognize.py,
  19817. 15:34:02and two full of photos, Office.jpeg and Toby.jpeg.
  19818. 15:34:06If you're familiar with the show, here, for instance,
  19819. 15:34:09is the cast photo from The Office here.
  19820. 15:34:11So here's a photo as input.
  19821. 15:34:12Suppose I want to do something very Facebook-style,
  19822. 15:34:15where I want to analyze all of the faces,
  19823. 15:34:17or detect all of the faces in there.
  19824. 15:34:19Well, let me go ahead and show you a program
  19825. 15:34:21I wrote in advance, that's not terribly long.
  19826. 15:34:24Much of it is actually comments.
  19827. 15:34:25But let's see what I'm doing.
  19828. 15:34:27I'm importing the Pillow library, again, to get access to images.
  19829. 15:34:30I'm importing a library called face recognition, which I downloaded
  19830. 15:34:34and installed in advance.
  19831. 15:34:35But it does what it says.
  19832. 15:34:36According to its documentation, you go into that library
  19833. 15:34:39and you call a function called load image
  19834. 15:34:41file, to load something like Office.jpeg,
  19835. 15:34:43and then you can use the line of code like this.
  19836. 15:34:46Call a function called face locations, passing the images input,
  19837. 15:34:50and you get back a list of all of the faces in the image.
  19838. 15:34:53And then down here, a for loop, that iterates over all of those
  19839. 15:34:57face locations.
  19840. 15:34:58And inside of this loop, I just do a bit of trickery.
  19841. 15:35:01I figure out the top, right, bottom, and left corners of those locations.
  19842. 15:35:06And then, using these lines of code here,
  19843. 15:35:08I'm using that image library, to just draw a box, essentially.
  19844. 15:35:11And the code looks cryptic.
  19845. 15:35:12Honestly, I would have to look this up to write it again.
  19846. 15:35:14But per the documentation, this just draws a nice little box
  19847. 15:35:17around the image.
  19848. 15:35:18So let me go ahead and zoom out here, and run this now on Office.jpeg.
  19849. 15:35:24All right, it's analyzing, analyzing, and you can see in the sidebar here,
  19850. 15:35:29here's the original.
  19851. 15:35:30And here is every face that my, what, 10 lines of Python code
  19852. 15:35:35found, within that file.
  19853. 15:35:37What's a face?
  19854. 15:35:37Presumably the library is looking for something,
  19855. 15:35:40maybe without a mask, that has two eyes, a nose, and a mouth,
  19856. 15:35:43in some kind of arrangement, some kind of pattern.
  19857. 15:35:45So it would seem pretty reliable, at least on these fairly easy-to-read
  19858. 15:35:48faces here.
  19859. 15:35:49What if we want to look for someone specific,
  19860. 15:35:52for instance, someone that's always getting picked on.
  19861. 15:35:53Well, we could do something like this.
  19862. 15:35:55Recognize.py, which is taking two files as input, that image and the image
  19863. 15:35:59of one person in particular.
  19864. 15:36:01And if you're trying to find Toby in a crowd,
  19865. 15:36:03here I conflated the program, sorry, this is the version that
  19866. 15:36:06draws a box around the given face.
  19867. 15:36:08Here we have Toby as identified.
  19868. 15:36:10Why?
  19869. 15:36:10Because that program, Recognize.py, has a few more lines of code,
  19870. 15:36:14but long story short, it additionally loads as input Toby.jpeg,
  19871. 15:36:19in order to recognize that specific face.
  19872. 15:36:21And that specific face is a completely different photo,
  19873. 15:36:24but it looks similar enough to the person, that it all worked out OK.
  19874. 15:36:29Let's do one other that's a little sensitive to microphones.
  19875. 15:36:32Let me go into, how about my listen folder here, which is available
  19876. 15:36:37online, too.
  19877. 15:36:38And let's just run Python of Listen0.py.
  19878. 15:36:40I'm going to type in like David.
  19879. 15:36:43Oh, sorry, no, I'm going to--
  19880. 15:36:47Hello, world.
  19881. 15:36:52Oh, no, that's the wrong version.
  19882. 15:36:53[CHUCKLES] OK, I looked like an idiot.
  19883. 15:36:55OK, hello, there we go.
  19884. 15:36:58Hello to you, too.
  19885. 15:36:58And if I say goodbye, I'm talking to my laptop like an idiot, OK.
  19886. 15:37:02Now it's detecting what I'm saying here.
  19887. 15:37:05So this first version of the program is just using some relatively simple, if
  19888. 15:37:08elif elif, and it's just asking for input, forcing it to lowercase.
  19889. 15:37:12And that was my mistake with the first example.
  19890. 15:37:14And then, I'm just checking, is Hello in the user's words?
  19891. 15:37:17Is how are you in the user's words?
  19892. 15:37:19Didn't see that, but it's there.
  19893. 15:37:20Is goodbye in the user's words?
  19894. 15:37:21Now let's do a cooler version, using a library, just by looking at the effect.
  19895. 15:37:25Python of Listen1.py.
  19896. 15:37:27Hello, world.
  19897. 15:37:32Huh.
  19898. 15:37:33Let's do version 2 of this, that uses an audio speech-to-text library.
  19899. 15:37:40Hello, world.
  19900. 15:37:43OK, so now it's artificial intelligence.
  19901. 15:37:46Now let's do something a little more interesting.
  19902. 15:37:48The third version of this program that actually analyzes the words that are
  19903. 15:37:51said.
  19904. 15:37:53Hello, world, my name is David.
  19905. 15:37:55How are you?
  19906. 15:37:59OK, so that time, it not only analyzed what I said,
  19907. 15:38:02but it plucked my name out of it.
  19908. 15:38:04Let's do two final examples.
  19909. 15:38:07This one will generate a QR code.
  19910. 15:38:09Let me go ahead and write a program called
  19911. 15:38:11QR.py, that very simply does this.
  19912. 15:38:15Let me import a library called OS.
  19913. 15:38:17Let me import a library called QR code.
  19914. 15:38:19Let me grab an image here, that's QRcode.make.
  19915. 15:38:24And let me give you the URL of like a lecture video on YouTube, or something
  19916. 15:38:27like that, with this ID.
  19917. 15:38:31Let me just type this, so I don't get it wrong.
  19918. 15:38:36OK, so if I now use this URL here, of a video on YouTube, making
  19919. 15:38:41sure I haven't made any typos, I'm now going
  19920. 15:38:44to go ahead and do two lines of code in Python.
  19921. 15:38:46I'm going to first save that as a file called QR.png, which is
  19922. 15:38:49a two dimensional barcode, a QR code.
  19923. 15:38:52And, indeed, I'm going to use this format.
  19924. 15:38:53And I'm going to use the OS.system library to open QR.png automatically.
  19925. 15:39:00And if you'd like to take out your phone at this point,
  19926. 15:39:02you can see the result of my barcode, that's just been dynamically generated.
  19927. 15:39:08Hopefully from afar that will scan.
  19928. 15:39:13[UPROAR]
  19929. 15:39:16And I think that's an appropriate line to end on.
  19930. 15:39:18So that's it for CS50.
  19931. 15:39:20We will see you next time.
  19932. 15:39:22[APPLAUSE]
  19933. 15:39:25[MUSIC PLAYING]
  19934. 15:39:29[MUSIC PLAYING]
  19935. 15:40:43DAVID J. MALAN: This is CS50.
  19936. 15:40:45And this is week 7, the week, here, of Halloween.
  19937. 15:40:48Indeed, special thanks to CS50's own Valerie and her mom
  19938. 15:40:51for having created this very festive scenery, and all past ones as well.
  19939. 15:40:55Today, we pick up where we left off last time,
  19940. 15:40:58which, recall, we introduced Python.
  19941. 15:41:00And that was our big transition from C, where suddenly things
  19942. 15:41:03started to look new again, probably, syntactically.
  19943. 15:41:06But also, probably things hopefully started to feel easier.
  19944. 15:41:09Well, with that said, problem set 6 certainly added some challenges,
  19945. 15:41:13and you did some new things.
  19946. 15:41:14But hopefully you've begun to appreciate that with Python, just a lot more stuff
  19947. 15:41:18is easier to do.
  19948. 15:41:19You get more out of the box with the language itself.
  19949. 15:41:22And that's going to be so useful over the coming weeks
  19950. 15:41:24as we transition further to introducing something called databases today,
  19951. 15:41:29web programming next week and the week after.
  19952. 15:41:31So that by term's end, and perhaps even for your final project,
  19953. 15:41:34you really are building something from scratch
  19954. 15:41:37using all of these various tools somehow together.
  19955. 15:41:40So before we do that, though, today, let's consider
  19956. 15:41:42what we weren't really able to do last week, which was actually
  19957. 15:41:47create and store data ourselves.
  19958. 15:41:50In Python, we've played around with the CSV, comma-separated values library.
  19959. 15:41:56And you've been able to read in CSVs from disk,
  19960. 15:41:59so to speak, that is, from files in your programming environments.
  19961. 15:42:03But we haven't necessarily started saving data, persisting data ourselves.
  19962. 15:42:06And that's a huge limitation, because pretty much all of the examples
  19963. 15:42:09we've done thus far with a couple of exceptions
  19964. 15:42:11have involved my providing input at the keyboard or even vocally.
  19965. 15:42:14But then nothing happens to it.
  19966. 15:42:16It disappears the moment the program quits,
  19967. 15:42:18because it was only being stored in memory.
  19968. 15:42:20But today, we'll start to focus all the more on storing things on disk,
  19969. 15:42:24that is, storing things in files and folders
  19970. 15:42:27so that you can actually write programs that remember
  19971. 15:42:30what it is the human did last time.
  19972. 15:42:31And ultimately, you can actually make mobile or web apps
  19973. 15:42:34that actually begin to grow, and grow, and grow their data sets,
  19974. 15:42:37as might happen if you get more and more users, for instance, on a website.
  19975. 15:42:40To play, then, with this new capability of being able to write files,
  19976. 15:42:44let's go ahead and just collect some data.
  19977. 15:42:47In fact, those of you here in person, if you
  19978. 15:42:49want to pull up this URL on your phone or laptop,
  19979. 15:42:52that's going to lead you to a Google Form.
  19980. 15:42:54And that Google Form is going to ask you in just a moment for really
  19981. 15:42:59just your favorite TV show.
  19982. 15:43:00And it's going to ask you to categorize it
  19983. 15:43:02according to a genre, like comedy, or drama, or action, or musical,
  19984. 15:43:06or something like that.
  19985. 15:43:07And this is useful, because if you've ever
  19986. 15:43:09used a Google Form before, or Microsoft's equivalent with Office 365,
  19987. 15:43:12it's a really useful mechanism at just collecting data from users,
  19988. 15:43:15and then ultimately, putting it into a spreadsheet form.
  19989. 15:43:19So this is a screenshot of the form that those of you
  19990. 15:43:23here in person or tuning in on Zoom are currently filling out.
  19991. 15:43:26It's asking only two questions.
  19992. 15:43:27What's the title of your favorite TV show?
  19993. 15:43:29And what are one or more genres into which your TV show falls?
  19994. 15:43:34And I'll go ahead and pivot now to the view
  19995. 15:43:38that I'll be able to see as the person who created this form, which
  19996. 15:43:41is quite simply a Google spreadsheet.
  19997. 15:43:42Google Forms has this nice feature, if you've never noticed,
  19998. 15:43:45that allows you to export your data to a Google Spreadsheet.
  19999. 15:43:47And then from there, we can actually grab the file
  20000. 15:43:50and download it to my own Mac or your own PC
  20001. 15:43:52so that we can actually play around with the data that's come in.
  20002. 15:43:55So in fact, let me go ahead and slide over
  20003. 15:43:57to this, the live Google Spreadsheet.
  20004. 15:44:01And you'll see, probably, a whole bunch of familiar TV shows here,
  20005. 15:44:05all coming in.
  20006. 15:44:06And if we keep scrolling, and scrolling, and scrolling--
  20007. 15:44:09only 46, 47.
  20008. 15:44:10There we go, up to 50 plus already.
  20009. 15:44:12If you need that URL again here, if you're just tuning in,
  20010. 15:44:15you can go to this URL here.
  20011. 15:44:18And in just a moment, we'll have a bunch of data
  20012. 15:44:21with which we can start to experiment.
  20013. 15:44:24I'll give you a moment or so there.
  20014. 15:44:31All right.
  20015. 15:44:33Let me hang in there a little longer.
  20016. 15:44:35OK, we've got over 100 submissions.
  20017. 15:44:36Good.
  20018. 15:44:37Good, even more coming in now.
  20019. 15:44:40And we can see them coming in live.
  20020. 15:44:42Here, let me switch back to the spreadsheet.
  20021. 15:44:44The list is growing, and growing, and growing.
  20022. 15:44:46And in just a moment--
  20023. 15:44:48let me give Carter a moment to help me export it in real time.
  20024. 15:44:51Carter, just give me a heads up when it's reasonable for me
  20025. 15:44:54to download this file.
  20026. 15:44:58All right, and I'll begin to do this very slowly.
  20027. 15:45:00So I'm going to go up to the File menu, if you've never done this before.
  20028. 15:45:03Download-- you can download a whole bunch of formats, one in Excel.
  20029. 15:45:05But more simply, and the one we'll start to play with here,
  20030. 15:45:07is comma-separated values.
  20031. 15:45:08So CSV files we used this past week, why are they useful?
  20032. 15:45:12Now that you've played with them or used them in past real world,
  20033. 15:45:15what's the utility of a CSV file versus something like Excel, for instance?
  20034. 15:45:20Why CSV in the first place?
  20035. 15:45:24Any instincts?
  20036. 15:45:25Yeah?
  20037. 15:45:26AUDIENCE: Because it's just a text file?
  20038. 15:45:28DAVID J. MALAN: OK, so storage is compelling.
  20039. 15:45:29A simple text file with ASCII or Unicode text is probably pretty small.
  20040. 15:45:33I like that.
  20041. 15:45:33Other thoughts?
  20042. 15:45:35AUDIENCE: Structure of it?
  20043. 15:45:36DAVID J. MALAN: Yeah, well said.
  20044. 15:45:37It's just a simple text format, but using conventions
  20045. 15:45:40like commas you can represent the idea of columns using new lines,
  20046. 15:45:43backslash ends invisibly at the end of your lines,
  20047. 15:45:45you can create the idea of rows.
  20048. 15:45:47So it's a very simple way of implementing what
  20049. 15:45:49we might call a flat-file database.
  20050. 15:45:51It's a way of storing data in a flat, that is,
  20051. 15:45:54very simple file that's just pure ASCII or Unicode text.
  20052. 15:45:57And more compellingly, I dare say, is that with a CSV file,
  20053. 15:46:00it's completely portable.
  20054. 15:46:02Something is portable in the world of computing
  20055. 15:46:04if it means you can use it on a Mac or a PC running this operating system,
  20056. 15:46:07or this other one.
  20057. 15:46:08And portability is nice because if I were to download an Excel file,
  20058. 15:46:10there'd be a whole bunch of people in this room and online
  20059. 15:46:13who couldn't download it because they haven't bought Microsoft Excel
  20060. 15:46:15or installed it.
  20061. 15:46:16Or if they have a Mac, or if it's a .numbers file in the Mac world,
  20062. 15:46:21a PC user might not be able to download it.
  20063. 15:46:22So a CSV is indeed very portable.
  20064. 15:46:25So I'm going to go ahead and download, quite simply, the CSV
  20065. 15:46:28version of this file.
  20066. 15:46:29That's going to put it onto my own Mac's Downloads folder.
  20067. 15:46:32And let me go ahead here, and in just a moment, let me just simplify the name.
  20068. 15:46:36Because it actually downloads it at a pretty large name.
  20069. 15:46:40And give me just one moment here, and you'll see that, indeed,
  20070. 15:46:43on my Mac I have a file called favorites.csv.
  20071. 15:46:46I shortened the name real quick.
  20072. 15:46:48And now what I'm going to do is go over to VS Code, and in VS Code,
  20073. 15:46:54I'm going to open my File Explorer.
  20074. 15:46:55And if I minimize my window here for a moment, a handy feature of VS Code
  20075. 15:46:59is that you can just drag and drop a file, for instance, into your Explorer.
  20076. 15:47:03And voila, it's going to automatically upload it for you.
  20077. 15:47:06So let me go ahead and full screen here, close my Explorer,
  20078. 15:47:08temporarily close my Terminal window.
  20079. 15:47:10And you'll see here a CSV file, favorites.csv.
  20080. 15:47:14And the first row, by convention, has whatever
  20081. 15:47:16the columns were in Google Spreadsheets, or Office 365,
  20082. 15:47:20in Excel online, timestamp, comma, title, comma, genres.
  20083. 15:47:23Then, we have timestamps, which indicates
  20084. 15:47:25when people started submitting.
  20085. 15:47:27Looks like a couple of people were super eager to get
  20086. 15:47:29started an hour or two ago.
  20087. 15:47:30And then, you have the title next, after a comma.
  20088. 15:47:34But there's kind of a curiosity after that.
  20089. 15:47:37Sometimes I see the genre like comedy, comedy, comedy,
  20090. 15:47:40but sometimes it's like crime, comma, drama, or action, comma, crime, comma,
  20091. 15:47:45drama.
  20092. 15:47:45And those things are quoted.
  20093. 15:47:47And yet, I didn't do any quotes.
  20094. 15:47:49You probably didn't type any quotes.
  20095. 15:47:51Where are those quotes coming from in this CSV file?
  20096. 15:47:55Why are they there if we infer?
  20097. 15:47:56Yeah?
  20098. 15:47:57AUDIENCE: [INAUDIBLE]
  20099. 15:48:00DAVID J. MALAN: Yeah, so you have a corner case, if you will.
  20100. 15:48:03Because if you're using commas, as you described,
  20101. 15:48:05to separate your data into what are effectively columns, well,
  20102. 15:48:09you've painted yourself into a corner if your actual data
  20103. 15:48:12has commas in it itself.
  20104. 15:48:13So what Google has done, what Microsoft does, what Apple does
  20105. 15:48:16is, they quote any strings of text that themselves
  20106. 15:48:19have commas so that these are now English grammatical commas,
  20107. 15:48:23not CSV specific commas.
  20108. 15:48:26So it's a way of escaping your data, if you will.
  20109. 15:48:28And escaping just means to call out a symbol in a special way
  20110. 15:48:31so it's not misinterpreted as something else.
  20111. 15:48:33All right, so this is all to say that we now
  20112. 15:48:35have all of this data with which we can play in the form of what we'll
  20113. 15:48:39start calling a flat-file database.
  20114. 15:48:41So suppose I wanted to now start manipulating this data,
  20115. 15:48:44and I want to store it ultimately, indeed, in this CSV format.
  20116. 15:48:47How can I actually start to read this data,
  20117. 15:48:49maybe clean it up, maybe do some analytics on it
  20118. 15:48:52and actually figure out, what's the most popular show among those who submitted
  20119. 15:48:55here over the past few minutes?
  20120. 15:48:57Well, let me go ahead and close this.
  20121. 15:48:59Let me go ahead, then, and open up, for instance, just my Terminal window.
  20122. 15:49:04And let's code up a file called favorites.py.
  20123. 15:49:07And let's go ahead and iteratively start simple by just opening up this file
  20124. 15:49:11and printing out what's inside of it.
  20125. 15:49:13So you might recall that we can do this by doing something like import CSV
  20126. 15:49:16to give myself some CSV reading functionality.
  20127. 15:49:20Then, I can go ahead and do something like with open, the name of the file
  20128. 15:49:24that I want to open in read mode.
  20129. 15:49:27Quote, unquote, "r" means to read it.
  20130. 15:49:29And then, I can say as file, or whatever other name
  20131. 15:49:31for a variable to say that I want to open this file,
  20132. 15:49:35and essentially store some kind of reference to it in that variable
  20133. 15:49:37called file.
  20134. 15:49:38Then, I can give myself a reader, and I can say csv.reader,
  20135. 15:49:42passing in that file as input.
  20136. 15:49:43And this is the magic of that library.
  20137. 15:49:45It deals with the process of opening it, reading it, and giving you
  20138. 15:49:48back something that you can just iterate over, like with a for loop
  20139. 15:49:51I do want to skip the first row, and recall that I can do this.
  20140. 15:49:55Next, reader, is this little trick that just says, ignore the first row.
  20141. 15:49:59Because the first one is special.
  20142. 15:50:00It said timestamp, title, genres.
  20143. 15:50:02That's not your data, that was mine.
  20144. 15:50:04But this means now that I've skipped that first row.
  20145. 15:50:07Everything hereafter is going to be the title of a show
  20146. 15:50:10that you all like, so let me do this.
  20147. 15:50:11For row in the reader, let's go ahead and print out the title
  20148. 15:50:16of the show each of you typed in.
  20149. 15:50:18How do I get at the title of the show each of you typed in?
  20150. 15:50:22It's somewhere inside of row.
  20151. 15:50:24Row recalls a list.
  20152. 15:50:26So what do I want to type next in order to get
  20153. 15:50:28at the title of the current row just as a quick check here?
  20154. 15:50:34What do I want to type to get at the title of the row,
  20155. 15:50:36keeping in mind, again, that it was timestamp, title, genres?
  20156. 15:50:40Yeah?
  20157. 15:50:41AUDIENCE: [INAUDIBLE]
  20158. 15:50:42DAVID J. MALAN: So row bracket 1 would give me
  20159. 15:50:44the second column, 0 index, that is, the one in the middle with the title.
  20160. 15:50:47So this program isn't that interesting yet,
  20161. 15:50:49but it's a quick and dirty way to figure out, all right, what's my data
  20162. 15:50:52look like?
  20163. 15:50:53Let me actually just do a little bit of a check here
  20164. 15:50:55and see if it contains the data I think it does.
  20165. 15:50:57Let me maximize my Terminal window here.
  20166. 15:50:59Let me run Python of favorites.py, hitting Enter.
  20167. 15:51:03And you'll see now a purely textual list of all of the shows
  20168. 15:51:07you all seem to like here.
  20169. 15:51:09But what's noteworthy about it?
  20170. 15:51:12Specific shows aside, judgment aside as to people's
  20171. 15:51:15TV tastes, what's interesting or noteworthy about the data that
  20172. 15:51:19might create some problems for us if we start to analyze this data,
  20173. 15:51:23and figure out what's the most popular?
  20174. 15:51:25How many people like this or that?
  20175. 15:51:27What do you think?
  20176. 15:51:28Yeah?
  20177. 15:51:29AUDIENCE: User errors [INAUDIBLE].
  20178. 15:51:32DAVID J. MALAN: Yeah, there might be user errors,
  20179. 15:51:34or just stylistic differences that give the appearance that one show
  20180. 15:51:38is different from the other.
  20181. 15:51:39For instance, here.
  20182. 15:51:42Let's see if I can see an example on the screen here.
  20183. 15:51:45Yeah, so friends here is an all lowercase, Friends here is capitalized.
  20184. 15:51:49No big deal.
  20185. 15:51:50We can sort of mitigate that.
  20186. 15:51:51But this is just a tiny example of where data in the real world
  20187. 15:51:54can get messy fast.
  20188. 15:51:56And that probably wasn't even a typo.
  20189. 15:51:57It was just someone not caring as much to capitalize it, and that's fine.
  20190. 15:52:02Your users are going to type what they're going to type.
  20191. 15:52:05So let's see if we can't now begin to get at more specific data,
  20192. 15:52:08and maybe even clean some of this data up.
  20193. 15:52:10Let me go back into my file called favorites.py here,
  20194. 15:52:15and let's actually do something a little more user friendly for me.
  20195. 15:52:19Instead of a reader, recall that there was this dictionary reader that's
  20196. 15:52:23just a little more user friendly.
  20197. 15:52:25And it means I can type in dictionary reader here, passing in the same file.
  20198. 15:52:30But now, when I iterate over this reader variable, what is each row?
  20199. 15:52:36When using a DictReader instead of a reader, recall, and this
  20200. 15:52:39is just a peculiarity of the CSV library,
  20201. 15:52:43this gives me back, not a list of cells, but what instead,
  20202. 15:52:47which is marginally more user friendly for me?
  20203. 15:52:50Yeah?
  20204. 15:52:50AUDIENCE: [INAUDIBLE]
  20205. 15:52:52DAVID J. MALAN: Yeah.
  20206. 15:52:53I can now use open bracket, quotes, and the title.
  20207. 15:52:56Because what's coming back now is a dict object, that is,
  20208. 15:52:59a dictionary which has keys and values.
  20209. 15:53:02The keys of which are the column headings.
  20210. 15:53:04The values of which are the data I actually care about.
  20211. 15:53:06So this is just marginally better because, one, it's
  20212. 15:53:09just way more obvious to me, the author of this code, what it is I'm
  20213. 15:53:12getting at.
  20214. 15:53:13I don't remember what column the title was.
  20215. 15:53:15Was it 0?
  20216. 15:53:16Was it 1?
  20217. 15:53:16Was it 2?
  20218. 15:53:17That's something you're going to forget over time.
  20219. 15:53:18And God forbid someone changes the data by just dragging and dropping
  20220. 15:53:21the columns in Excel, or Apple Numbers, or Google Spreadsheets.
  20221. 15:53:24That's going to break all of your numeric indices.
  20222. 15:53:27And so a dictionary reader is arguably just
  20223. 15:53:29better design because it's more robust against changes
  20224. 15:53:32and potential errors like that.
  20225. 15:53:34Now the effect of this change isn't going to be really any different.
  20226. 15:53:37If I run Python of favorites.py, voila, I get all of the same results.
  20227. 15:53:42But I've now not made any assumptions as to where each of the columns
  20228. 15:53:46actually is numerically.
  20229. 15:53:48All right.
  20230. 15:53:48Well, let's go ahead and now filter out some duplicates.
  20231. 15:53:51Because there's a lot of commonality among some of the shows here, so let's
  20232. 15:53:55see if we can't filter out duplicates.
  20233. 15:53:58If I'm reading a CSV file top to bottom, what intuitively might be the logic
  20234. 15:54:04I want to implement to filter out duplicates?
  20235. 15:54:06It's not going to be quite as simple as a simple function that does it for me.
  20236. 15:54:10I'm going to have to build this.
  20237. 15:54:12But logically, if you're reading a file from top to bottom,
  20238. 15:54:15how might you go about, in Python or just any context,
  20239. 15:54:20getting rid of duplicate values?
  20240. 15:54:23Yeah, what do you think?
  20241. 15:54:25AUDIENCE: [INAUDIBLE]
  20242. 15:54:31DAVID J. MALAN: Sure.
  20243. 15:54:31I could use a list and I could add each title to the list,
  20244. 15:54:35but first check if I put this into the list before.
  20245. 15:54:38So let's try a little something like that.
  20246. 15:54:40Let me go ahead and create a variable at the top of my program here.
  20247. 15:54:43I'll call it titles, for instance, initialize to an empty list,
  20248. 15:54:46open bracket, close bracket.
  20249. 15:54:48And then, inside of my loop here, instead of printing it out,
  20250. 15:54:53let's start to make a decision.
  20251. 15:54:54So if the current row's title is in the titles list
  20252. 15:55:04I don't want to put it there.
  20253. 15:55:05And actually, let me invert the logic so I'm doing something proactively.
  20254. 15:55:08So if it's not the case that row bracket title is in titles,
  20255. 15:55:13then, go ahead and do something like titles.append the current row's title.
  20256. 15:55:21And recall that we saw .append a week or so ago,
  20257. 15:55:24where it just allows you to append to the current list.
  20258. 15:55:27And then, what can I do at the very end, after I'm all
  20259. 15:55:30done reading the whole file?
  20260. 15:55:31Why don't I go ahead and say, for title in titles,
  20261. 15:55:35go ahead and print out the current title?
  20262. 15:55:38So it's two loops now, and we can come back to the quality of that design.
  20263. 15:55:42But let me go ahead here and rerun Python of favorites.py.
  20264. 15:55:44Let me increase the size of my Terminal window so we can focus just on this,
  20265. 15:55:47and hit Enter.
  20266. 15:55:49And now, I'm just skimming.
  20267. 15:55:53I don't think I'm seeing duplicates, although I
  20268. 15:55:56am seeing some near duplicates.
  20269. 15:55:59For instance, there's Friends again.
  20270. 15:56:02And if we keep going, and going, and going, and going,
  20271. 15:56:05there's Friends again.
  20272. 15:56:06Oh, interesting, so that's curious that I seem to have multiple Friends,
  20273. 15:56:12and I have this one here, too.
  20274. 15:56:13So how might we clean this up further?
  20275. 15:56:16I like your instincts, and it's a step closer to it.
  20276. 15:56:18What are we going to have to do to really filter out
  20277. 15:56:20those near duplicates?
  20278. 15:56:22Any thoughts?
  20279. 15:56:24AUDIENCE: You could set everything to lower [INAUDIBLE]..
  20280. 15:56:29DAVID J. MALAN: Yeah.
  20281. 15:56:30What are the common mistakes to summarize?
  20282. 15:56:32We could ignore the capitalization altogether and maybe
  20283. 15:56:34just force everything to lowercase, or everything to uppercase.
  20284. 15:56:37Doesn't matter which, but let's just be consistent.
  20285. 15:56:39And for those of you who might have accidentally or instinctively hit
  20286. 15:56:42the spacebar at the beginning of your input or even at the end,
  20287. 15:56:44we can strip that off, too.
  20288. 15:56:46Stripping whitespace is a common thing just to clean up user input.
  20289. 15:56:49So let me go back into my code here, and let me go ahead
  20290. 15:56:53and tweak the title a little bit.
  20291. 15:56:55Let me say that the current title inside of this loop
  20292. 15:56:58is not going to be just the current row's title.
  20293. 15:57:01But let me go ahead and strip off, from the left and the right implicitly,
  20294. 15:57:05any whitespace.
  20295. 15:57:06If you read the documentation for the strip function, it does just that.
  20296. 15:57:09It gets rid of whitespace to the left, whitespace to the right.
  20297. 15:57:12And then, if I want to force everything to maybe uppercase,
  20298. 15:57:15I can just uppercase the entire string.
  20299. 15:57:18And remember, what's handy about Python is you can chain some of these function
  20300. 15:57:21calls together by just using dots again and again.
  20301. 15:57:24And that just takes whatever just happened,
  20302. 15:57:26like the whitespace got stripped off, then, it additionally
  20303. 15:57:29uppercases the whole thing as well.
  20304. 15:57:31So now, I'm going to just check whether this specific title is in titles.
  20305. 15:57:36And if not, I'm going to go ahead and append that title,
  20306. 15:57:40massaged into this different format, if you will.
  20307. 15:57:42So I'm throwing away some information.
  20308. 15:57:44I'm sacrificing all of the nuances of your grammar and input
  20309. 15:57:49to the form itself.
  20310. 15:57:50But at least I'm trying to canonicalize size, that is,
  20311. 15:57:52standardize what the data actually looks like.
  20312. 15:57:55So let me go ahead and run Python of favorites.py again and hit Enter.
  20313. 15:57:59Oh, and this is just user error.
  20314. 15:58:00Maybe you haven't seen this before.
  20315. 15:58:02This just looks like a mistake on my part.
  20316. 15:58:06I meant to say not even uppercase.
  20317. 15:58:08That's completely wrong.
  20318. 15:58:09The function is called upper, now that I think of it.
  20319. 15:58:11All right.
  20320. 15:58:12Let's go and increase the size of the Terminal window again.
  20321. 15:58:14Run Python of favorites.py.
  20322. 15:58:16And now, it's a little more overwhelming to look at because it's not sorted yet
  20323. 15:58:20and it's all capitalized.
  20324. 15:58:22But I don't think I'm seeing multiple Friends, so to speak.
  20325. 15:58:28There's one Friends up here and that's it.
  20326. 15:58:31I'm back up at my prompt already.
  20327. 15:58:33So we seem now to be filtering out duplicates.
  20328. 15:58:35Now, before we dive in further and clean this up further than this,
  20329. 15:58:38what else could we have done?
  20330. 15:58:40Well, it turns out that in Python 2 you often
  20331. 15:58:42do get a lot of functionality built into the language.
  20332. 15:58:44And I'm kind of implementing myself the idea of a set.
  20333. 15:58:47If you think back to mathematics, a set is typically
  20334. 15:58:49something with a bunch of values that has duplicates filtered out.
  20335. 15:58:53Recall that Python already has this for us.
  20336. 15:58:56And we saw it really briefly when I whipped up the dictionary
  20337. 15:58:59implementation a couple of weeks back.
  20338. 15:59:01So I could actually define my titles to be a set instead of a list,
  20339. 15:59:06and this would just modestly allow me to refine my code here, such
  20340. 15:59:11that I don't have to bother checking for duplicates anyway.
  20341. 15:59:14I can instead just say something like, titles.add
  20342. 15:59:18the current title, like this.
  20343. 15:59:21Marginally better design if you know that a set exists because you're just
  20344. 15:59:24getting more functionality out of this.
  20345. 15:59:26All right, so let's clean the data up further.
  20346. 15:59:28We've now gone ahead and fixed the problem of case sensitivity.
  20347. 15:59:31We threw away whitespace in case someone had hit the spacebar
  20348. 15:59:34with some of the input.
  20349. 15:59:35Let's go ahead now and sort these things by the titles themselves.
  20350. 15:59:39So instead of just printing out the titles in the same order
  20351. 15:59:42you all inputted them, but filtering out duplicates as we go, let me go ahead
  20352. 15:59:47and use another function in Python you might not have seen,
  20353. 15:59:49which is literally called sorted, and will
  20354. 15:59:52take care of the process of actually sorting titles for you.
  20355. 15:59:57Let me go ahead and increase the font size of my Terminal,
  20356. 15:59:59run Python of favorites.py, and hit Enter.
  20357. 16:00:01And now you can really see how many of these shows start with the word "the"
  20358. 16:00:05or do not.
  20359. 16:00:06Now it's a little easier to wrap our minds around,
  20360. 16:00:08just because it's at least sorted alphabetically.
  20361. 16:00:11But now you can really see some of the differences in people's inputs.
  20362. 16:00:15So far, so good.
  20363. 16:00:17But a few of you decided to stylize Avatar in three different ways here.
  20364. 16:00:21Brooklyn 99 is a couple of different ways here.
  20365. 16:00:24And I think if we keep going we'll see further and further variances that we
  20366. 16:00:28did not fix by focusing on whitespace and capitalization alone.
  20367. 16:00:31So already here, this is only, what, 100 plus, 200 rows.
  20368. 16:00:35Already real-world data starts to get messy quickly,
  20369. 16:00:38and that might not bode well when we actually
  20370. 16:00:40want to keep around real data from real users.
  20371. 16:00:41You can imagine an actual website or a mobile application
  20372. 16:00:44dealing with this kind of thing on scale.
  20373. 16:00:47Well, let's go ahead and do this.
  20374. 16:00:48Let's actually figure out the popularity of these various shows
  20375. 16:00:51by now iterating over my data, and keeping track of how many of you
  20376. 16:00:57inputted a given title.
  20377. 16:00:58We're going to ignore the problems like Brooklyn 99 and the Avatar.
  20378. 16:01:03Sorry, yeah, Avatar, where there was things
  20379. 16:01:07that were different beyond just whitespace and capitalization.
  20380. 16:01:12But let's go ahead and keep track of, now,
  20381. 16:01:14how many of you inputted each of these titles.
  20382. 16:01:17So how can I do this?
  20383. 16:01:18I'm still going to take this approach of iterating over
  20384. 16:01:21the CSV file from top to bottom.
  20385. 16:01:23We've used a couple of data structures thus far,
  20386. 16:01:25a list to keep track of titles, or a set to keep track of titles.
  20387. 16:01:29But what if I now want to keep around a little more information?
  20388. 16:01:32For each title, I want to keep around how many times I've seen it before.
  20389. 16:01:38I'm not doing that yet.
  20390. 16:01:39I'm throwing away the total number of times I see these shows.
  20391. 16:01:43How could I start to keep that around?
  20392. 16:01:45AUDIENCE: Use a dictionary.
  20393. 16:01:47DAVID J. MALAN: We could use a dictionary, and how?
  20394. 16:01:49Elaborate on that.
  20395. 16:01:50AUDIENCE: [INAUDIBLE]
  20396. 16:01:51DAVID J. MALAN: Perfect, really good instincts.
  20397. 16:01:53Using a dictionary, insofar as it lets us
  20398. 16:01:55store keys and values, that is, associate something with something
  20399. 16:01:58else.
  20400. 16:01:59This is why a dictionary or hash tables more
  20401. 16:02:01generally are such a useful, practical data structure.
  20402. 16:02:04Because they just let you remember stuff in some kind of structured way.
  20403. 16:02:08So if the keys are going to be the titles I've seen,
  20404. 16:02:11the values could be the number of times I've seen each of those titles.
  20405. 16:02:15And so it's kind of like just having a two-column table on paper.
  20406. 16:02:19For instance, if I were going to do this on a piece of paper,
  20407. 16:02:22I might just have two columns here, where
  20408. 16:02:24maybe this is the title that I've seen, and this is the count over here.
  20409. 16:02:29This is, in effect, a dictionary in Python.
  20410. 16:02:33It's two columns, keys on the left, values on the right.
  20411. 16:02:36And this, if I can implement in code, will actually
  20412. 16:02:38allow me to store this data, and then maybe do some simple arithmetic
  20413. 16:02:42to figure out which is the most popular.
  20414. 16:02:44So let's do this.
  20415. 16:02:45Let me go ahead and change my titles to not be a list, not be a set.
  20416. 16:02:49Let's have it be a dictionary instead, either doing this, or more succinctly,
  20417. 16:02:54two curly braces that are empty gives me an empty dictionary automatically.
  20418. 16:02:58What do I now want to do?
  20419. 16:03:00I think most of my code can stay the same.
  20420. 16:03:02But down here, I don't want to just blindly add titles
  20421. 16:03:06to the data structure.
  20422. 16:03:07I somehow need to keep track of the count.
  20423. 16:03:10And unfortunately, if I just do this-- let's do titles,
  20424. 16:03:14bracket, title, plus equals 1.
  20425. 16:03:18This is a reasonable first attempt at this.
  20426. 16:03:21Because what am I doing?
  20427. 16:03:22If titles is a dictionary and I want to look up the current title therein,
  20428. 16:03:28the syntax for that, like before, is titles, bracket, and then
  20429. 16:03:30the key you want to use to index into the dictionary.
  20430. 16:03:34It's not a number in this case, it's an actual word, a title.
  20431. 16:03:37And you're just going to increment it by one,
  20432. 16:03:39and then eventually I'll come back and finish my second loop
  20433. 16:03:42and do things in terms of the order.
  20434. 16:03:45But for now, let's just keep track of the total counts.
  20435. 16:03:48Let me go ahead and increase my Terminal window.
  20436. 16:03:51Let me do Python of favorites.py and hit Enter.
  20437. 16:03:54Huh.
  20438. 16:03:55How I Met Your Mother is giving me a key error.
  20439. 16:03:59What does that mean?
  20440. 16:04:02And why am I seeing this?
  20441. 16:04:04And in fact, just to give a little bit of a breadcrumb here,
  20442. 16:04:07let me zoom out here.
  20443. 16:04:09Let me open up the CSV file again real quickly.
  20444. 16:04:12And wow, we didn't even get past the second row in the file
  20445. 16:04:15or the first show in the file.
  20446. 16:04:17Notice that How I Met Your Mother, somewhat lowercased,
  20447. 16:04:20is the very first show in therein.
  20448. 16:04:22What's your instinct for why this is happening?
  20449. 16:04:24AUDIENCE: You don't have a starting point.
  20450. 16:04:27DAVID J. MALAN: I don't have a starting point.
  20451. 16:04:29I'm adding one to what?
  20452. 16:04:30I'm blindly indexing into the dictionary using a key, How I Met Your Mother,
  20453. 16:04:35that doesn't yet exist in the dictionary.
  20454. 16:04:37And so Python throws what's called a key error
  20455. 16:04:39because the key you're trying to use just doesn't exist yet.
  20456. 16:04:42So logically, how could we fix this?
  20457. 16:04:46We're close.
  20458. 16:04:47We got half of the problem solved, but I'm not handling the obvious, now,
  20459. 16:04:50case of nothing being there.
  20460. 16:04:52Yeah?
  20461. 16:04:52AUDIENCE: Creating a counter.
  20462. 16:04:54DAVID J. MALAN: Creating a--
  20463. 16:04:54AUDIENCE: Counter.
  20464. 16:04:55DAVID J. MALAN: Creating the counter itself.
  20465. 16:04:57So maybe I could do something like this.
  20466. 16:04:59Let me close my Terminal window and let me ask a question first.
  20467. 16:05:03If the current title is in the dictionary already, if title in titles,
  20468. 16:05:10that's going to give me a true-false answer it turns out.
  20469. 16:05:12Then, I can safely say, titles, bracket, title, plus equals 1.
  20470. 16:05:17And recall, this is just shorthand notation for the same thing as in C,
  20471. 16:05:22title plus 1.
  20472. 16:05:23Whoops, typo.
  20473. 16:05:24Don't do that.
  20474. 16:05:25That's the same thing as this but it's a little more succinct
  20475. 16:05:28just to say plus equals 1.
  20476. 16:05:30Else, if it's logically not the case that the current title is in the titles
  20477. 16:05:34dictionary, then I probably want to say titles, bracket, title equals?
  20478. 16:05:38Feel free to just shout it out.
  20479. 16:05:40AUDIENCE: Zero.
  20480. 16:05:41DAVID J. MALAN: Zero.
  20481. 16:05:42I just have to put some value there so that the key itself is also there.
  20482. 16:05:46All right.
  20483. 16:05:47So now that I've got this going on, let me go ahead
  20484. 16:05:49and undo my sorting temporarily.
  20485. 16:05:51And now let me go ahead and do this.
  20486. 16:05:54I can, as a quick check, let me go ahead and just run the code
  20487. 16:05:58as is, Python of favorites.py.
  20488. 16:06:00I'm back in business.
  20489. 16:06:02It's printing correctly, no key errors, but it's not sorted.
  20490. 16:06:05And I'm not seeing any of the counts.
  20491. 16:06:06Let me just quickly add the counts, and there's
  20492. 16:06:09a couple of ways I could do this.
  20493. 16:06:10I could, say, print out the title, and then, maybe, let's do something like--
  20494. 16:06:18how about just, comma, titles, bracket, title?
  20495. 16:06:22So I'm going to print two things at once,
  20496. 16:06:24both the current title in the dictionary,
  20497. 16:06:26and whatever its value is by indexing into it.
  20498. 16:06:29Let me increase my Terminal window.
  20499. 16:06:31Let me run Python of favorites.py, Enter, and OK.
  20500. 16:06:35Huh.
  20501. 16:06:37Huh.
  20502. 16:06:39None of you said a whole lot of TV shows, it seems.
  20503. 16:06:42What's the logical error here?
  20504. 16:06:47What did I do wrong if I look back at my code here?
  20505. 16:06:50Yeah?
  20506. 16:06:51Why so many 0s?
  20507. 16:06:52AUDIENCE: [INAUDIBLE]
  20508. 16:06:54DAVID J. MALAN: Exactly.
  20509. 16:06:55To summarize, I initialized the count to 0 the first time I saw it,
  20510. 16:07:00but I should have initialized it at least to 1 because I just saw it.
  20511. 16:07:03Or I should change my code a bit.
  20512. 16:07:05So for instance, if I go back in here, the simplest fix
  20513. 16:07:08is probably to initialize to 1, because on this iteration of the loop,
  20514. 16:07:11obviously, I'm seeing this title for the very first time.
  20515. 16:07:14Or I could change my logic a little bit.
  20516. 16:07:16I could do something like this instead.
  20517. 16:07:18If the current title is not in titles, then I could initialize it to 0.
  20518. 16:07:24And then I could get rid of the else, and now blindly index
  20519. 16:07:28into the titles dictionary.
  20520. 16:07:30Because now, on line 11, I can trust that lines 9 and 10
  20521. 16:07:34took care of the initialization for me if need be.
  20522. 16:07:37Which one is better?
  20523. 16:07:38I don't know.
  20524. 16:07:38This one's a little nicer, maybe because it's one line fewer.
  20525. 16:07:42But I think both approaches are perfectly reasonable and well-designed.
  20526. 16:07:45But the key thing, no pun intended, is that we
  20527. 16:07:47have to make sure the key exists before we presume to actually incrue.
  20528. 16:07:52Oh, this is wrong.
  20529. 16:07:54This is incorrect code.
  20530. 16:07:55What did I do wrong?
  20531. 16:07:58OK, yes.
  20532. 16:07:59There we go.
  20533. 16:07:59So otherwise, everyone would have liked this show once, and no matter
  20534. 16:08:03how many people said the same thing.
  20535. 16:08:04Now the code is as it should be.
  20536. 16:08:06So let me go ahead and open up my Terminal window again.
  20537. 16:08:08Let me run Python of favorites.py, and now we see more reasonable counts.
  20538. 16:08:13Some shows weren't that popular.
  20539. 16:08:14There's just 1s and maybe 2s.
  20540. 16:08:16But I bet if we sort these things we can start to see a little more detail.
  20541. 16:08:21So how else can we do this?
  20542. 16:08:23Well, turns out, when dealing with a dictionary like this--
  20543. 16:08:29let's go ahead and just sort the titles themselves.
  20544. 16:08:32So let's reintroduce the sorted function as I did before, but no other changes.
  20545. 16:08:37Let me go ahead now and run Python of favorites.py.
  20546. 16:08:40Now it's just a little easier to wrap your mind around it
  20547. 16:08:42because at least it's alphabetical.
  20548. 16:08:43But it's not sorted by value, it's sorted by key.
  20549. 16:08:47But sure enough, if we scroll down, there's something down here,
  20550. 16:08:51for instance, like, let's see, The Office.
  20551. 16:08:54That's definitely going to be a contender
  20552. 16:08:56for most popular, 15 responses.
  20553. 16:08:58But let's see what's actually going to bubble up to the top.
  20554. 16:09:01Unfortunately, the sorted function only sorts dictionaries by keys
  20555. 16:09:06by default, not by values.
  20556. 16:09:09But it turns out, in Python, if you read the documentation
  20557. 16:09:12for the sorted function, you can actually
  20558. 16:09:14pass in other arguments that tell it how to sort things.
  20559. 16:09:19For instance, if I want to do things in reverse order,
  20560. 16:09:22I can add a second parameter to the sorted function called reverse.
  20561. 16:09:27And it's a named parameter.
  20562. 16:09:28You literally say, reverse equals true, so
  20563. 16:09:30that the position of it in the comma-separated list doesn't matter.
  20564. 16:09:34If I now rerun this after increasing my Terminal window,
  20565. 16:09:37you'll see now that it's in the opposite order.
  20566. 16:09:39Now adventure and Anne with an E is at the bottom
  20567. 16:09:41of the output instead of the top.
  20568. 16:09:43How can I tell it to sort by values instead of by key?
  20569. 16:09:52Well, let's go ahead and do this.
  20570. 16:09:53Let me go ahead and define a function.
  20571. 16:09:56I'm just going to call it f to keep things simple.
  20572. 16:09:58And this f function is going to take a title as input.
  20573. 16:10:01And given a given title, it's going to return the value of that title.
  20574. 16:10:06So actually, maybe a better name for this would be get value,
  20575. 16:10:09and/or we could come up with something else as well.
  20576. 16:10:12The purpose of the get value function, to be clear,
  20577. 16:10:14is to take it as input a title and then return the corresponding value.
  20578. 16:10:19Why is this useful?
  20579. 16:10:20Well, it turns out that the sorted function in Python,
  20580. 16:10:23according to its documentation, also takes a key parameter,
  20581. 16:10:27where you can pass in, crazy enough, the name of a function
  20582. 16:10:31that it will use in order to determine what it should sort by, by the key,
  20583. 16:10:36or by the value, or in other cases, even other types of data as well.
  20584. 16:10:41So there's a curiosity here, though, that's very deliberate.
  20585. 16:10:44Key is the name of the parameter, just like reverse
  20586. 16:10:46was the name of this other parameter.
  20587. 16:10:48The value of it, though, is not a function call.
  20588. 16:10:51It's a function name.
  20589. 16:10:52Notice I am not doing this, no parentheses.
  20590. 16:10:55I'm instead passing in get value, the function I wrote, by its name.
  20591. 16:11:00And this is a feature of Python and certain other languages.
  20592. 16:11:03Just like variables, you can actually pass whole functions
  20593. 16:11:06around so that they can be called for you later on by someone else.
  20594. 16:11:10So what this means is that the sorted function written by Python,
  20595. 16:11:14they didn't know what you're going to want to sort by today.
  20596. 16:11:16But if you provide them with a function called get value, or anything else, now
  20597. 16:11:21their sorted function will use that function
  20598. 16:11:23to determine, OK, if you don't want to sort by the key of the dictionary, what
  20599. 16:11:27do you want to sort by?
  20600. 16:11:28This is going to tell it to sort by the value
  20601. 16:11:31by returning the specific value we care about.
  20602. 16:11:34So let me go ahead now and rerun this after increasing my Terminal, Python
  20603. 16:11:37of favorites.py, Enter.
  20604. 16:11:39Here we have now an example of all of the titles you all
  20605. 16:11:42typed in, albeit forced to uppercase and with any whitespace thrown out.
  20606. 16:11:47And now, The Office is an easy win over Friends,
  20607. 16:11:50versus Community, versus Game of Thrones, Breaking Bad, and then
  20608. 16:11:52a lot of variants thereafter.
  20609. 16:11:55So there's a lot of steps to go through.
  20610. 16:11:57This isn't that bad once you've done it once,
  20611. 16:11:58and you know what these functions are, and you
  20612. 16:12:00know that these parameters exist.
  20613. 16:12:02But it's a lot of work.
  20614. 16:12:03That's 17 lines of code just to analyze a CSV file
  20615. 16:12:07that you all created by way of those Google Form submissions.
  20616. 16:12:10But it took me a lot of work just to get simple answers out of it.
  20617. 16:12:13And indeed, that's going to be among the goals
  20618. 16:12:15for today, ultimately, is, how can we just make this easier?
  20619. 16:12:18It's one thing to learn new things in Python,
  20620. 16:12:20but if we can avoid writing code, or this much code,
  20621. 16:12:22that's going to be a good thing.
  20622. 16:12:24And so one other technique we can introduce here
  20623. 16:12:26that does allow us to write a little less code
  20624. 16:12:28is, we can actually get rid of this function.
  20625. 16:12:31It turns out, in Python, if you just need to make a function
  20626. 16:12:34but it's going to be used and then essentially thrown away,
  20627. 16:12:37it's not something you're going to be reusing in multiple places--
  20628. 16:12:40it's not like a library function that you want to keep around--
  20629. 16:12:42you can actually just do this.
  20630. 16:12:45You can change the value of this key parameter
  20631. 16:12:48to be what's called a lambda function, which
  20632. 16:12:51is a fancy way of saying a function that technically has no name.
  20633. 16:12:54It's an anonymous function.
  20634. 16:12:56Why does it have no name?
  20635. 16:12:57Well, it's kind of stupid that I invented this name on line 13.
  20636. 16:13:00I used it on line 16, and then I never again used it.
  20637. 16:13:04If there's only being used in one place, why bother giving it a name at all?
  20638. 16:13:07So if you instead, in Python, say lambda,
  20639. 16:13:10and then type out the name of the parameter
  20640. 16:13:13you want this anonymous function to take,
  20641. 16:13:15you can then say, go ahead and return this value.
  20642. 16:13:19Now let's notice the inconsistencies here.
  20643. 16:13:22When you use this special lambda keyword that says, hey Python,
  20644. 16:13:25give me an anonymous function, a function with no name,
  20645. 16:13:28it then says, Python, this anonymous function will take one parameter.
  20646. 16:13:31Notice there's no parentheses.
  20647. 16:13:34And that's deliberate, if confusing.
  20648. 16:13:35It just tightens things up a little bit.
  20649. 16:13:38Notice that there's no return keyword, which similarly tightens things
  20650. 16:13:42up a bit, albeit inconsistently.
  20651. 16:13:44But this line of code I've just highlighted
  20652. 16:13:47is actually identical in functionality to this.
  20653. 16:13:51But it throws away the word [INAUDIBLE].
  20654. 16:13:53It throws away the word get value.
  20655. 16:13:55It throws away the parentheses, and it throws away the return keyword just
  20656. 16:13:58to tighten things up.
  20657. 16:14:00And it's well suited for a problem like this
  20658. 16:14:02where I just want to pass in a tiny little function that
  20659. 16:14:05does something useful.
  20660. 16:14:06But it's not something I'm going to reuse.
  20661. 16:14:08It doesn't need multiple lines to take up space.
  20662. 16:14:10It's just a nice, elegant one liner.
  20663. 16:14:12That's all a lambda function does.
  20664. 16:14:14It allows you to create an anonymous function right then and there.
  20665. 16:14:17And then the function you're passing it to, like sorted, will use it as before.
  20666. 16:14:22Indeed, if I run Python of favorites.py after growing my Terminal window,
  20667. 16:14:26the result is exactly the same.
  20668. 16:14:28And we see at the bottom here all of those small results.
  20669. 16:14:31Are any questions, then, on this syntax, on these ideas?
  20670. 16:14:36The goal here has been to write a Python program that just starts
  20671. 16:14:39to analyze or clean up data like this.
  20672. 16:14:44Yeah?
  20673. 16:14:45AUDIENCE: [INAUDIBLE]
  20674. 16:14:48DAVID J. MALAN: Could you use the lambda if it's just returning immediately?
  20675. 16:14:51It's really meant for one line of code, generally.
  20676. 16:14:54So you don't use the return keyword.
  20677. 16:14:56You just say what it is you want to return.
  20678. 16:14:59AUDIENCE: [INAUDIBLE]
  20679. 16:15:03DAVID J. MALAN: Good question.
  20680. 16:15:04Could you do more in that one line if it's
  20681. 16:15:06got to be a more involved algorithm?
  20682. 16:15:08Yes, but you would just ultimately return the value in question.
  20683. 16:15:11In short, if it's getting at all sophisticated
  20684. 16:15:13you don't use the lambda function in Python.
  20685. 16:15:15You go ahead and actually just define a name for it,
  20686. 16:15:17even if it's a one-off name.
  20687. 16:15:19JavaScript, another language we'll look at in a few weeks,
  20688. 16:15:21makes heavier use, I dare say, of lambda functions.
  20689. 16:15:24And those can actually be multiple, multiple lines,
  20690. 16:15:27but Python does not support that instinct.
  20691. 16:15:30All right.
  20692. 16:15:31So let's go ahead and do one other thing.
  20693. 16:15:33Office was clearly popping out of the code here quite a bit.
  20694. 16:15:35Let's go ahead and write a slightly different program
  20695. 16:15:38that maybe just focuses on The Office for the moment,
  20696. 16:15:40just focuses on The Office.
  20697. 16:15:42So let me go ahead and throw most of this code away, up until this point
  20698. 16:15:46when I'm inside of my inner loop.
  20699. 16:15:48And let me go ahead, and I don't even want the global variable here.
  20700. 16:15:51All I want to do is focus on the current title.
  20701. 16:15:53How could I detect if someone likes The Office?
  20702. 16:15:56Well, I could say something like--
  20703. 16:15:59how about this?
  20704. 16:16:00So counter equals 0.
  20705. 16:16:01We'll just focus on The Office.
  20706. 16:16:03If title equals, equals The Office, I could then go ahead and say,
  20707. 16:16:09counter plus equals 1.
  20708. 16:16:12I don't need a key.
  20709. 16:16:13There's no dictionary involved now.
  20710. 16:16:15It's just a simple integer variable.
  20711. 16:16:17And then, down here I'll say something like,
  20712. 16:16:21number of people who like The Office is, whatever this value is.
  20713. 16:16:26And I'll put in counter in curly braces, and then I'll
  20714. 16:16:29turn this whole thing into an F string.
  20715. 16:16:31All right, let me go ahead and run this.
  20716. 16:16:32Python of favorites.py, Enter.
  20717. 16:16:35Number of people who like The Office is 15.
  20718. 16:16:37All right, so that's great.
  20719. 16:16:39But let's go ahead now and deliberately muddy the data a bit.
  20720. 16:16:42All of you were very nice in that you typed in The Office.
  20721. 16:16:46But you can imagine someone just typing Office,
  20722. 16:16:48for instance, maybe there, maybe there.
  20723. 16:16:51And many people might just write Office, you could imagine.
  20724. 16:16:53Didn't happen here, but suppose it did, and probably
  20725. 16:16:55would have if we had even more and more submissions over time.
  20726. 16:16:58Now let's go ahead and rerun this program, no changes to the code.
  20727. 16:17:02Now only 13 people like The Office.
  20728. 16:17:04So let's fix this.
  20729. 16:17:05The data is now as I mutated it to have a couple Offices, and many The Offices.
  20730. 16:17:11How could I change my Python code to now count both of those situations?
  20731. 16:17:16What could I change up here in order to improve this situation?
  20732. 16:17:20Any thoughts?
  20733. 16:17:23Yeah?
  20734. 16:17:24AUDIENCE: You write the title [INAUDIBLE]..
  20735. 16:17:27DAVID J. MALAN: Yeah, so I could just ask two questions like that.
  20736. 16:17:30If title equals The Office, or title equals, equals just
  20737. 16:17:34Office, for instance.
  20738. 16:17:35And I'm still don't have to worry about capitalization.
  20739. 16:17:38I don't have to worry about spaces because I at least threw that all away.
  20740. 16:17:41Now I can go ahead and rerun this code.
  20741. 16:17:43Let me go run it a third time.
  20742. 16:17:45OK, so we're back up to 15.
  20743. 16:17:47So I like that.
  20744. 16:17:50You could imagine this not scaling very well.
  20745. 16:17:54Avatar had three different permutations, and there were some others
  20746. 16:17:57if we dug deeper that there might have been more variants.
  20747. 16:17:59Could we do something a little more general purpose?
  20748. 16:18:01Well, we could do something like this.
  20749. 16:18:03If Office in the title--
  20750. 16:18:07this is kind of a cool thing you can do with Python.
  20751. 16:18:09It's very English-like, just ask the question, albeit tersely.
  20752. 16:18:12This, interesting, just got me into trouble.
  20753. 16:18:16Now, all of a sudden, we're up to 16.
  20754. 16:18:18Does anyone know what the other one is?
  20755. 16:18:21AUDIENCE: Someone put V Office.
  20756. 16:18:23DAVID J. MALAN: What Office?
  20757. 16:18:24AUDIENCE: Someone entered a V Office, [INAUDIBLE]..
  20758. 16:18:29DAVID J. MALAN: Oh, interesting.
  20759. 16:18:31Yes, so they hit The.
  20760. 16:18:33OK.
  20761. 16:18:33[APPLAUSE]
  20762. 16:18:36DAVID J. MALAN: OK.
  20763. 16:18:37Someone did that, sure.
  20764. 16:18:39So The V Office.
  20765. 16:18:42OK, this one's actually going to be hard to correct for.
  20766. 16:18:44I can't really think of a general--
  20767. 16:18:46well, this is actually a good example of data gets messy fast.
  20768. 16:18:51And you could imagine doing something where, OK, we
  20769. 16:18:53could have like 26 conditions if someone said The A Office, or The B Office,
  20770. 16:18:58right?
  20771. 16:18:58You could imagine doing that.
  20772. 16:18:59But then there's surely going to be other typos that are possible.
  20773. 16:19:02So that's actually a hard one to fix.
  20774. 16:19:04But it turns out we got lucky and now this is actually the accurate count.
  20775. 16:19:10But the data is itself messy.
  20776. 16:19:12Let me show another way that just adds another tool to our toolkit.
  20777. 16:19:15It turns out that there's this feature in many programming languages, Python
  20778. 16:19:20among them, called regular expressions.
  20779. 16:19:22And this is actually a really powerful technique
  20780. 16:19:24that we'll just scratch the surface of here.
  20781. 16:19:26But it's going to be really useful, actually, maybe toward final projects,
  20782. 16:19:29in web programming, any time you want to clean up data or validate data.
  20783. 16:19:34And actually, just to make this clear, give me a moment
  20784. 16:19:37before I switch screens here.
  20785. 16:19:39And let me open up a Google Form from scratch.
  20786. 16:19:43Give me just a moment to create something real quick.
  20787. 16:19:47If you've never noticed this before when creating a Google Form,
  20788. 16:19:50you can do a question.
  20789. 16:19:53And if you want the user to type in something
  20790. 16:19:55very specific as a short text answer like this,
  20791. 16:19:58you might know that there's toggles like this in Google's world,
  20792. 16:20:01like you can require it.
  20793. 16:20:02Or you can do response validation.
  20794. 16:20:04You could say, what's your email?
  20795. 16:20:07And then you could say something like, text is an email.
  20796. 16:20:12So here's an example in Google Forms how you can validate users' input.
  20797. 16:20:17But a feature most of you have probably never noticed, or cared about, or used,
  20798. 16:20:22is this thing called a regular expression, where
  20799. 16:20:24you can actually define a pattern.
  20800. 16:20:26And I could actually reimplement that same idea by doing something like this.
  20801. 16:20:30I can say, let the user type in anything represented by .star, then an at sign,
  20802. 16:20:36then something else, then a literal period, then, for instance,
  20803. 16:20:41something else.
  20804. 16:20:43So it's very cryptic, admittedly, at first glance.
  20805. 16:20:45But this means any character 0 more times.
  20806. 16:20:48This means any character 0 more times.
  20807. 16:20:51This means a literal period, because apparently
  20808. 16:20:54dot means any character in the context of these patterns.
  20809. 16:20:57Then this thing means any character 0 more times.
  20810. 16:21:01So I should actually be a little more nitpicky.
  20811. 16:21:04You don't want 0 or more times, you want 1 or more times.
  20812. 16:21:06So this with the plus means any character 1 or more time.
  20813. 16:21:10So there has to be something there.
  20814. 16:21:12And I think I want the same thing here 1 or more times, 1 or more times.
  20815. 16:21:16Or heck, if I want to restrict this form in some sense to edu addresses,
  20816. 16:21:21I could change that last thing to literally .edu.
  20817. 16:21:24And so long story short, even though this looks,
  20818. 16:21:26I'm sure, pretty cryptic, there's this mini language built into Python,
  20819. 16:21:31and JavaScript, and Java, and other languages that allows you to express
  20820. 16:21:35patterns in a standardized way.
  20821. 16:21:37And this pattern is actually something we can implement in code, too.
  20822. 16:21:41And let me switch back to Python for a second just
  20823. 16:21:43to do the same kind of idea.
  20824. 16:21:45Let me toggle back to my code here.
  20825. 16:21:48Let me put up, for instance, a summary of what it is you can do.
  20826. 16:21:52And here's just a quick summary of some of the available symbols.
  20827. 16:21:58A period may represent any character. .star or .asterisks means 0 or more
  20828. 16:22:04characters.
  20829. 16:22:05So the dot means anything, so it can be A or nothing.
  20830. 16:22:08It can be B or nothing.
  20831. 16:22:09It can be A, B, A, B, C. It can be any combination of 0 or more characters.
  20832. 16:22:14Change that to a plus and you now express one or more characters.
  20833. 16:22:18Question mark means something is optional.
  20834. 16:22:21Caret symbol means start matching at the beginning of the user's input.
  20835. 16:22:24Dollar sign means stop matching at the end of the user's input.
  20836. 16:22:30So we won't play with all of these just now.
  20837. 16:22:32But let me go over here and actually tackle this Office problem.
  20838. 16:22:36Let me go ahead and import a new library called the regular expression library,
  20839. 16:22:40import re.
  20840. 16:22:42And then, down here, let me say this.
  20841. 16:22:45If re.search, this pattern.
  20842. 16:22:50Let's just search for Office, quote, unquote, in the current title.
  20843. 16:22:55Then we're going to go ahead and increase the counter.
  20844. 16:22:58So it turns out that the regular expression library
  20845. 16:23:00has a function called search that takes as its first argument a pattern,
  20846. 16:23:04and then, as its second argument the string you
  20847. 16:23:07want to analyze for that pattern.
  20848. 16:23:09So it's sort of looking for a needle in this haystack, from left to right.
  20849. 16:23:13Let me go ahead now and run this version of the program, Enter.
  20850. 16:23:17And now I screwed up because I forgot my colon, but that's old stuff.
  20851. 16:23:21Enter.
  20852. 16:23:22Huh.
  20853. 16:23:24Number of people who like The Office is now 0.
  20854. 16:23:27So this seems like a big--
  20855. 16:23:28thank you-- big step backwards.
  20856. 16:23:30What did I do wrong?
  20857. 16:23:33Yeah?
  20858. 16:23:34AUDIENCE: [INAUDIBLE]
  20859. 16:23:35DAVID J. MALAN: Yeah.
  20860. 16:23:36I forced all my input to uppercase, so I probably need to do this.
  20861. 16:23:39So we'll come back to other approaches there.
  20862. 16:23:41Let me rerun it now.
  20863. 16:23:42OK, now we're back up to 16.
  20864. 16:23:45But I could even, let's say--
  20865. 16:23:47I could tolerate just The Office.
  20866. 16:23:50How about this, or how about something like, or The Office?
  20867. 16:23:55Let me do this instead.
  20868. 16:23:57And let me use these other special characters.
  20869. 16:23:59This caret sign means the beginning of the string.
  20870. 16:24:02This dollar sign weirdly represents the end of the string.
  20871. 16:24:06I'm adding in some parentheses just like in math, just to add another symbol
  20872. 16:24:09here, the or symbol here.
  20873. 16:24:11And this is saying start matching at the beginning of the user string.
  20874. 16:24:15Check if the beginning of the string is Office, or the beginning of the string
  20875. 16:24:20is The Office.
  20876. 16:24:21And then, you better be at the end of the string.
  20877. 16:24:23So they can't keep typing words before or after that input.
  20878. 16:24:26Let me go ahead and rerun the program.
  20879. 16:24:29And now we're down to 15, which used to be our correct answer,
  20880. 16:24:32but then we noticed The V Office.
  20881. 16:24:36How can we deal with that?
  20882. 16:24:38It's going to be messier to deal with that.
  20883. 16:24:41How about if I tolerate any character represented by dot
  20884. 16:24:46in between The and Office?
  20885. 16:24:48Now if I rerun it, now I really have this expressive capability.
  20886. 16:24:53So this is only to say, there are so many ways in languages, in general,
  20887. 16:24:57to solve problems.
  20888. 16:24:58And some of these tools are more sophisticated than others.
  20889. 16:25:01This is one that you've actually probably glanced at but never used
  20890. 16:25:04in the context of Google Forms for years if you're
  20891. 16:25:06in the habit of creating these for student groups or other activities.
  20892. 16:25:09But it's now something you can start to leverage.
  20893. 16:25:11And we're just scratching the surface of what's actually possible with this.
  20894. 16:25:14But let's now do one final example just using some Python code here.
  20895. 16:25:18And let's actually write a program that's
  20896. 16:25:20a little more general purpose that allows me to search for any given title
  20897. 16:25:25and figure out its popularity.
  20898. 16:25:27So let me go ahead and simplify this.
  20899. 16:25:29Let's get rid of our regular expressions.
  20900. 16:25:31Let's go ahead and continue capitalizing the title.
  20901. 16:25:35And let's go ahead to--
  20902. 16:25:36at the beginning of this program, and first ask the user for the title
  20903. 16:25:41they want to search for.
  20904. 16:25:42So title equals, let's ask the user for input,
  20905. 16:25:45which is essentially the same thing as our CS50 get_string function.
  20906. 16:25:48Ask them for the title.
  20907. 16:25:50And then whatever they type in, let's go ahead and strip whitespace
  20908. 16:25:53and uppercase the thing again.
  20909. 16:25:56And now, inside of my loop, I could say something like this.
  20910. 16:26:01If the current row's title after stripping whitespace and forcing
  20911. 16:26:08it to uppercase, too, equals the user's title, then, go ahead
  20912. 16:26:12and maybe increment a counter.
  20913. 16:26:14So I still need that counter back.
  20914. 16:26:16So let me go ahead and define this maybe in here, counter equals 0.
  20915. 16:26:21And then, at the very end of this program,
  20916. 16:26:24let me go ahead and print out just the popularity
  20917. 16:26:26of whatever the human typed in.
  20918. 16:26:28So again, the only difference is I'm asking the human for some input
  20919. 16:26:31this time.
  20920. 16:26:32I'm initializing my counter to 0, then I'm
  20921. 16:26:34searching for their title in the CSV file
  20922. 16:26:38by doing the same massaging of the data by forcing it to uppercase
  20923. 16:26:41and getting rid of the whitespace.
  20924. 16:26:43So now, when I run Python of favorites.py, Enter,
  20925. 16:26:47I could type in the office all lowercase even, and now we're down to 13.
  20926. 16:26:5513, why?
  20927. 16:27:00Oh, that's correct.
  20928. 16:27:02Because I'm the one that went in and removed those The keywords a bit ago.
  20929. 16:27:05If we fixed those, we would be back up to 15.
  20930. 16:27:08If we added support for The V Office, we would be up to 16 as well.
  20931. 16:27:12All right, any questions then on these various manipulations?
  20932. 16:27:15And if you're feeling like, oh, my god, this
  20933. 16:27:17is so much Python code just to do simple things, that's the point.
  20934. 16:27:20And indeed, even though it's a powerful language
  20935. 16:27:22and can solve these kinds of problems, we had to write almost 20 lines of code
  20936. 16:27:26just to ask a single question like this.
  20937. 16:27:28But any questions on how we did this, or on any of these building
  20938. 16:27:32blocks along the way?
  20939. 16:27:36Anything here?
  20940. 16:27:37No?
  20941. 16:27:37All right.
  20942. 16:27:37That was a lot.
  20943. 16:27:38Let's take a five-minute break here.
  20944. 16:27:40When we come back, we'll do it better.
  20945. 16:27:42So we are back.
  20946. 16:27:43And the rest of today is ultimately about, how
  20947. 16:27:45can we store, and manipulate, and change, and retrieve data
  20948. 16:27:50more efficiently than we might by just writing raw code?
  20949. 16:27:53This isn't to say that you shouldn't use Python to do the kinds of things
  20950. 16:27:56that we just did.
  20951. 16:27:57And in fact, it might be super common if you're getting a lot of messy input
  20952. 16:28:02from users that you might want to clean it up.
  20953. 16:28:04And maybe the best way to do that is to write a program so that step-by-step
  20954. 16:28:07you can make all of the requisite changes and fixes
  20955. 16:28:09like we did with The Office, for instance, again and again,
  20956. 16:28:12and reuse that code, especially if more and more submissions are
  20957. 16:28:15coming through.
  20958. 16:28:16But another theme of today, ultimately, is
  20959. 16:28:18that sometimes there are different, if not better tools for the same job.
  20960. 16:28:22And in fact, now at this point in the term,
  20961. 16:28:24as we begin to introduce not just Python, but in a moment
  20962. 16:28:27a language called SQL, and next week, a language called JavaScript,
  20963. 16:28:31and the week after that, synthesizing a whole lot of these languages
  20964. 16:28:34together is to just kind of paint a picture of how
  20965. 16:28:37you might decide what the trade-offs are between using this tool, or this tool,
  20966. 16:28:41or this other tool.
  20967. 16:28:42Because undoubtedly you can solve problems moving forward
  20968. 16:28:45in many different ways with many different tools.
  20969. 16:28:48So let's give you another tool, one with which
  20970. 16:28:50you can implement a proper relational database.
  20971. 16:28:53What we just saw in the form of CSV files
  20972. 16:28:56are what we might call flat-file databases.
  20973. 16:28:59Again, just a very simple file, flat in that there's no hierarchy to it.
  20974. 16:29:02It's just rows and columns.
  20975. 16:29:04And that is all ultimately storing ASCII or Unicode text.
  20976. 16:29:09A relational database, though, is something that's actually
  20977. 16:29:12closer to a proper spreadsheet program.
  20978. 16:29:16A CSV is an individual sheet, if you will,
  20979. 16:29:18from a spreadsheet when you export it.
  20980. 16:29:20If you had multiple sheets in a spreadsheet,
  20981. 16:29:22you would have to export multiple CSVs.
  20982. 16:29:24And that gets annoying quickly in code if you
  20983. 16:29:26have to open up this CSV, this CSV, all of which
  20984. 16:29:29represent different sheets or tabs in a proper spreadsheet.
  20985. 16:29:32A relational database is more like a spreadsheet program
  20986. 16:29:36that you, a programmer, now can interact with.
  20987. 16:29:39You can write data to it.
  20988. 16:29:41You can read data from it, and you can have multiple sheets, a.k.a.,
  20989. 16:29:45tables storing all of your data.
  20990. 16:29:47So whereas Excel and numbers in Google spreadsheet
  20991. 16:29:49are meant to be reused really by humans with their mouse and their keyboard,
  20992. 16:29:52clicking, and pointing, and manipulating things graphically,
  20993. 16:29:55a relational database using a language called
  20994. 16:29:57SQL is one in which the programmer has similar capabilities,
  20995. 16:30:02but doing so in code.
  20996. 16:30:04Specifically, using a language called SQL, and at a scale
  20997. 16:30:08that's much grander than spreadsheets alone.
  20998. 16:30:11In fact, if you try on your Mac or PC to open a spreadsheet that's
  20999. 16:30:13got tens of thousands of rows, it'll probably
  21000. 16:30:16work fine, hundreds of thousands of rows, millions of rows, no way.
  21001. 16:30:20At some point your Mac or PC is going to struggle
  21002. 16:30:22to open particularly large data sets.
  21003. 16:30:24And that, too, is where proper databases come
  21004. 16:30:26into play and proper languages for databases come
  21005. 16:30:29into play, when it's all about scale.
  21006. 16:30:31And indeed, most any mobile app or web app today that you or someone else
  21007. 16:30:34might write should probably plan on lots of data if it's successful.
  21008. 16:30:38So we need the right tools for that problem.
  21009. 16:30:41So fortunately, even though we're about to learn yet another language,
  21010. 16:30:44it only does four things fundamentally, known by this silly acronym, CRUD.
  21011. 16:30:49SQL, this language for databases, supports the ability
  21012. 16:30:53to create data, read data, update data, and delete data.
  21013. 16:30:57That's it.
  21014. 16:30:58There's a few more keywords that exist in this language called SQL
  21015. 16:31:02that we'll soon see.
  21016. 16:31:03But at the end of the day, even if you're
  21017. 16:31:04starting to feel like this is a lot very quickly,
  21018. 16:31:07it all boils down to these four basic operations.
  21019. 16:31:10And the four commands in SQL, if you will,
  21020. 16:31:12functions in a sense that implement those four ideas happen to be these.
  21021. 16:31:17They're almost the same but with some slight variance.
  21022. 16:31:19The ability to create or insert data is the C. The ability to select data
  21023. 16:31:24is the R, or read.
  21024. 16:31:26Update is the same.
  21025. 16:31:27Delete is the same, but drop is also a keyword as well.
  21026. 16:31:30So we'll see these and a few other keywords
  21027. 16:31:32in SQL that, at the end of the day, just allow you to create, read, and update
  21028. 16:31:35data using verbs, if you will, like these.
  21029. 16:31:39So to do that, what's the syntax going to be?
  21030. 16:31:43Well, we won't get into the weeds too quickly on this.
  21031. 16:31:45But here's a representative syntax of how
  21032. 16:31:47you can create using this language called SQL, in your very
  21033. 16:31:51own database, a brand new table.
  21034. 16:31:53This is so easy in Excel, and Google Spreadsheets, and Apple Numbers.
  21035. 16:31:56You want a new sheet, you click the plus button.
  21036. 16:31:58You get a new tab.
  21037. 16:31:59You give it a name, and boom, you're done.
  21038. 16:32:00In the world of programming, though, if you want to create the analogue of that
  21039. 16:32:05spreadsheet in the computer's memory, you create something called a table,
  21040. 16:32:08like a sheet, that has a name, and then in parentheses has one or more columns.
  21041. 16:32:13But unlike Google Spreadsheets, and Apple Numbers, and Excel,
  21042. 16:32:17you have to decide as the programmer what types of data
  21043. 16:32:20you're going to be storing in each of these columns.
  21044. 16:32:22Now even though Excel, and Google Spreadsheets,
  21045. 16:32:24and Numbers does allow you to format or present data in different ways,
  21046. 16:32:28it's not strongly typed data like it is, for instance, when we were using C.
  21047. 16:32:33And heck, even in Python there's underlying data types.
  21048. 16:32:35Even if you don't have to type them explicitly,
  21049. 16:32:37databases are going to want to know, are you storing integers?
  21050. 16:32:40Are you storing real numbers or floats?
  21051. 16:32:41Are you storing text?
  21052. 16:32:42Why?
  21053. 16:32:43Because especially as your data scales, the more hints
  21054. 16:32:46you give the database about your data, the more performance it can be,
  21055. 16:32:49the faster it can help you get at and store that data.
  21056. 16:32:52So types are about to be important again,
  21057. 16:32:54but there's not going to be that many of them, fortunately.
  21058. 16:32:57Now how can I go about converting, for instance, some real data,
  21059. 16:32:59like that from you, my favorites.csv file,
  21060. 16:33:02into a proper relational database?
  21061. 16:33:04Well, it turns out that using SQL I can do this
  21062. 16:33:07in VS Code on my own Mac, or PC, or in the cloud
  21063. 16:33:10here by just importing the CSV into a database.
  21064. 16:33:13We'll see eventually how to do this manually.
  21065. 16:33:15For now, I'm going to use more of an automated process.
  21066. 16:33:17So let me go over to VS Code here.
  21067. 16:33:20Let me type ls to see where we left off before.
  21068. 16:33:22I had two files favorites.csv, which I downloaded from Google Spreadsheets.
  21069. 16:33:26Recall that I made a couple of changes.
  21070. 16:33:27We deleted a couple of Thes from the file for The Office.
  21071. 16:33:31But this is the same file as before, and then we
  21072. 16:33:33have favorites.py, which we'll set aside for now.
  21073. 16:33:36I'm going to go ahead now and run a command SQLite3.
  21074. 16:33:40So in the world of relational databases, there's
  21075. 16:33:43many different products out there, many different software that
  21076. 16:33:48implements the SQL language.
  21077. 16:33:50Microsoft has their own.
  21078. 16:33:51There's something called MySQL that's been very popular for years.
  21079. 16:33:55Facebook, for instance, used it early on.
  21080. 16:33:57PostgreSQL, Microsoft Access Server, Oracle,
  21081. 16:34:00and maybe a whole bunch of other product names
  21082. 16:34:02you might have encountered over time, which
  21083. 16:34:04is to say there's many different types of tools, and servers,
  21084. 16:34:08and software in which you can use SQL.
  21085. 16:34:10We're going to use a very lightweight version of the SQL language
  21086. 16:34:13today called SQLite.
  21087. 16:34:14This is the version of SQL that's generally
  21088. 16:34:17used on iPhones and Android devices these days.
  21089. 16:34:19If you download an app that stores data like your own contacts,
  21090. 16:34:22typically is stored using SQLite.
  21091. 16:34:24Because it's fairly lightweight, but you can still store hundreds,
  21092. 16:34:28thousands, even tens of thousands of pieces of data
  21093. 16:34:31even using this lightweight version thereof.
  21094. 16:34:33SQLite3 is like version 3 of this tool.
  21095. 16:34:36We're going to go ahead and run SQLite3 with a file called favorites.db.
  21096. 16:34:41It's conventional in the world of SQLite to name your file something.db.
  21097. 16:34:45I'm going to create a database called favorites.db.
  21098. 16:34:47Once I'm inside of the program, now I'm going to go ahead and enter CSV Mode.
  21099. 16:34:52Again, not something you have to memorize,
  21100. 16:34:54just something you can look up as needed.
  21101. 16:34:55And then, I'm going to import favorites.csv
  21102. 16:34:59into a table, that is, a sheet, if you will, called favorites as well.
  21103. 16:35:05Now I'm going to hit Enter and I'm going to go ahead and exit the program
  21104. 16:35:09altogether and type ls.
  21105. 16:35:10Now I have three files in my current directory--
  21106. 16:35:13the CSV file, the Python file from before, and now favorites.db.
  21107. 16:35:17But if I did this right, all of the data you all typed into the CSV file
  21108. 16:35:21has now been loaded into a proper database where I can now use
  21109. 16:35:25this SQL language to access it instead.
  21110. 16:35:28So let's go ahead again and run SQLite3 of favorites.db, which now exists.
  21111. 16:35:33And now, at the SQLite prompt I can start
  21112. 16:35:35to play around and see what this data is.
  21113. 16:35:38For instance, I can look, by typing .schema,
  21114. 16:35:41at what the schema is of my data, what's the design.
  21115. 16:35:44Now no thought was put into the design of this data at the moment
  21116. 16:35:47because I automated the whole process.
  21117. 16:35:49Once we start creating our own databases we'll
  21118. 16:35:52give more thought to the data types and the columns that we have.
  21119. 16:35:55But we can see what SQLite presumed I wanted just
  21120. 16:35:59by importing the data by default.
  21121. 16:36:01What the import command did for me a moment ago is essentially the syntax.
  21122. 16:36:06It automated the process of creating a table, if it doesn't exist,
  21123. 16:36:09called favorites.
  21124. 16:36:11And then notice, in parentheses it gave me three columns--
  21125. 16:36:14timestamp, title, and genres, which were inferred, obviously, from the CSV.
  21126. 16:36:18All three of which have been decreed to be text.
  21127. 16:36:21Again, once we're more comfortable we'll create our own tables,
  21128. 16:36:24choose our own types and column names.
  21129. 16:36:26But for now, I just automated the whole process just
  21130. 16:36:28to get us started by using this built-in import command as well.
  21131. 16:36:33All right.
  21132. 16:36:34So what now can I begin to do?
  21133. 16:36:36Well, if I wanted to, for instance, start playing around with data therein,
  21134. 16:36:42I might execute a couple of different commands.
  21135. 16:36:48Let me find the right one here-- one of which would be select.
  21136. 16:36:53Select being one of our most versatile tools
  21137. 16:36:56to select data from this database.
  21138. 16:36:58So if I have these three columns here-- timestamp,
  21139. 16:37:01title, and genres, suppose I want to select all of the titles.
  21140. 16:37:04Doing that earlier in Python required importing the CSV library,
  21141. 16:37:09opening the file, creating a reader or a DictReader, iterating over every row,
  21142. 16:37:14adding every title to a dictionary or just printing it out,
  21143. 16:37:16and dot, dot, dot.
  21144. 16:37:17There was a dozen or so lines of code when we first began.
  21145. 16:37:20Now, how about this?
  21146. 16:37:22Select title from favorites, semicolon, done.
  21147. 16:37:26So now, with this particular language, the output is very textual
  21148. 16:37:30and it's simulating what it looks like if it were more graphical by creating
  21149. 16:37:34this table, so to speak.
  21150. 16:37:36Select title from favorites is a distillation
  21151. 16:37:39in a different language called SQL of all the lines of code
  21152. 16:37:42I wrote early on when we first started playing with favorites.py.
  21153. 16:37:46SQL is therefore optimized for reading, and creating, and updating,
  21154. 16:37:50and ultimately, deleting data.
  21155. 16:37:52So here's perhaps a better tool for the job once you have the data.
  21156. 16:37:56Tossing it into a more powerful, versatile format
  21157. 16:37:59might allow you now to get more work done more quickly
  21158. 16:38:02without having to reinvent the wheel.
  21159. 16:38:04Someone else has figured out how to select data like this.
  21160. 16:38:06What more can I do here?
  21161. 16:38:09Well, let me go ahead and pull up, in a moment, just a little bit
  21162. 16:38:12of a cheat sheet here.
  21163. 16:38:14Give me one second to find this.
  21164. 16:38:19So suppose I want to now select data a little more powerfully.
  21165. 16:38:23So here's what I just did in a canonical way.
  21166. 16:38:25So select typically works like this.
  21167. 16:38:27You select columns from a specific table, semicolon.
  21168. 16:38:31Unfortunately, stupid semicolons are back.
  21169. 16:38:33Select columns from table then, is the generic form of what I just did.
  21170. 16:38:38More specifically, I selected one column called title from favorites.
  21171. 16:38:42Favorites is the name of the table.
  21172. 16:38:43Semicolon ends my thought.
  21173. 16:38:45Suppose I wanted to get two things, like the genres that each of you inputted.
  21174. 16:38:48I could instead do select title, comma, genres from favorites,
  21175. 16:38:53and then, a semicolon, and Enter.
  21176. 16:38:55It's going to look a little ugly on my screen
  21177. 16:38:57because some of these titles and--
  21178. 16:38:59OK, one of you really went all out with Community.
  21179. 16:39:02You can see that it's just wrapping in an ugly way,
  21180. 16:39:06but it's just now showing me two columns.
  21181. 16:39:08If we scroll up to the very top again, the left most of one,
  21182. 16:39:12Black Mirror went all out, too.
  21183. 16:39:13Thank you.
  21184. 16:39:14And now, OK, we're going to have to clean some of these up.
  21185. 16:39:17Game of Thrones, good comedy, yes.
  21186. 16:39:22Keep going, keep going, keep going.
  21187. 16:39:24So now we've selected two of the columns that we care about.
  21188. 16:39:28There it is.
  21189. 16:39:28OK, so it's crazy wide because of all of those genres.
  21190. 16:39:31But it allows me to select exactly the data I want.
  21191. 16:39:34Let's go back to the titles, though, and perhaps start playing around
  21192. 16:39:37with some modifiers here.
  21193. 16:39:39For instance, it turns out, using SQL there's a lot of functionality
  21194. 16:39:43built into the language.
  21195. 16:39:45You've got a lot of functions, similar to Excel or Google Spreadsheets
  21196. 16:39:48where you can have formulas.
  21197. 16:39:49SQL provides you with some of the same heuristics that
  21198. 16:39:51allow you to apply operations like these on entire columns.
  21199. 16:39:55For instance, you can take averages, count the total,
  21200. 16:39:58get the distinct values, force things to lowercase, uppercase, min,
  21201. 16:40:01and max, and so forth.
  21202. 16:40:02So let's try distinct, for instance.
  21203. 16:40:04Let me go back to my Terminal, and let's say, select,
  21204. 16:40:08how about the distinct titles from the favorites table?
  21205. 16:40:14Enter.
  21206. 16:40:14I didn't bother selecting the genres because I
  21207. 16:40:16want it to be a little prettier.
  21208. 16:40:18And you can see here that we have just the distinct titles,
  21209. 16:40:23except for issues of formatting.
  21210. 16:40:25So whitespace is going to be an issue again.
  21211. 16:40:27Capitalization is going to be a thing again.
  21212. 16:40:29So there's a trade-off.
  21213. 16:40:30One of the things I was doing in Python was forcing everything to uppercase
  21214. 16:40:34and then getting rid of whitespace.
  21215. 16:40:36But we could combine some of these.
  21216. 16:40:37I could do something like force every title to uppercase,
  21217. 16:40:40then get the distinct value.
  21218. 16:40:41And that's actually going to get rid of some of those values as well.
  21219. 16:40:44And again, I did it all in one simple line that was fast.
  21220. 16:40:47So let me pull up at the bottom of the screen again.
  21221. 16:40:49I selected distinct upper titles from favorites,
  21222. 16:40:53and that did everything for me at once in just one breath.
  21223. 16:40:56Suppose I want to get the total number of counts of titles.
  21224. 16:40:58How about select count of all of those titles from favorites?
  21225. 16:41:05Semicolon, Enter, and now you get back a mini table
  21226. 16:41:09that contains just your answer, 158 in this case.
  21227. 16:41:13So that's the total number of, not distinct,
  21228. 16:41:15but total titles that we had in the file.
  21229. 16:41:18And we could continue to manipulate the data further using, again,
  21230. 16:41:21functions like these here.
  21231. 16:41:23But there's also additional filtration we can do.
  21232. 16:41:26We can also qualify our selections by saying where some condition is true.
  21233. 16:41:32So just as in Scratch, and C, and Python, you have Boolean expressions,
  21234. 16:41:35you can have the same in SQL as well, where I can filter my data where
  21235. 16:41:41something is true or false.
  21236. 16:41:44Like allows me to do approximations.
  21237. 16:41:46If I want to get something that's like The Office
  21238. 16:41:48but not necessarily T-H-E, space, Office,
  21239. 16:41:51I could do pattern matching using like here.
  21240. 16:41:54Order by, limit, and grouped by are other commands I can execute, too.
  21241. 16:41:58So let me go back and do a couple of these here.
  21242. 16:42:01How about, let me just get, oh, I don't know, all of the titles from favorites
  21243. 16:42:07but limit it to 10 results.
  21244. 16:42:10That might be one thing that's helpful to see if you just care about some
  21245. 16:42:13of the data at the top there instead.
  21246. 16:42:15How about, select all of the titles from favorites, where the title itself
  21247. 16:42:21is like, quote, unquote, "Office?"
  21248. 16:42:25And this will give me only two answers.
  21249. 16:42:28Those are the two rows, recall, that I mutated by getting rid of the word The.
  21250. 16:42:32Notice that like allows me too tolerate uppercase and lowercase.
  21251. 16:42:37Because if I instead just use the equal sign,
  21252. 16:42:40and in SQL a single equal sign does, in fact, mean equality.
  21253. 16:42:46For comparison's sake, it's not doing assignment.
  21254. 16:42:48This is not how you assign data in SQL.
  21255. 16:42:51I got back no answers there.
  21256. 16:42:53So indeed, the equal sign is giving me literal answers
  21257. 16:42:56that searches just for what I typed in.
  21258. 16:42:59How could I get all of these?
  21259. 16:43:00Well, similar in spirit to regular expressions but not quite as powerful
  21260. 16:43:04in SQL, I could do something like this.
  21261. 16:43:06I can select the title from favorites where the title is like, quote,
  21262. 16:43:10unquote, "Office."
  21263. 16:43:12But I can add, a bit weirdly, percent signs to the left and the right.
  21264. 16:43:17So the language SQL supports the same notion of pattern matching
  21265. 16:43:23but much more limited out of the box.
  21266. 16:43:24If we want more powerful regular expressions
  21267. 16:43:26we probably do want to use Python instead.
  21268. 16:43:28But the percent sign here means 0 or more characters
  21269. 16:43:32on the left, 0 or more characters on the right.
  21270. 16:43:34So this will just grab any title that contains O-F-F-I-C-E in it in that
  21271. 16:43:39order.
  21272. 16:43:40And now I get all 16, it would seem, of those results, again.
  21273. 16:43:44How do I know it's 16?
  21274. 16:43:45Well, I can just get the count of those titles
  21275. 16:43:48and get back that answer instead as well.
  21276. 16:43:51So again, it takes some getting used to, the vocabulary
  21277. 16:43:54and the syntax that you can use.
  21278. 16:43:56There's these building blocks and others.
  21279. 16:43:58But SQL is really designed, again, for creating, reading, updating,
  21280. 16:44:00and deleting data.
  21281. 16:44:01For instance, I've never really been a fan of Friends, for instance.
  21282. 16:44:06So right now if I do select, how about title from favorites
  21283. 16:44:12where title like, quote, unquote, Friends with the percent signs?
  21284. 16:44:18We can see that there's a whole bunch of them.
  21285. 16:44:20That's how many exactly.
  21286. 16:44:21Let's just do a quick count.
  21287. 16:44:23So that's nine of them.
  21288. 16:44:25Well, delete from favorites.
  21289. 16:44:28OK, you and me, delete from favorites, where title like Friends, Enter.
  21290. 16:44:35Nothing seems to happen, but bye-bye Friends.
  21291. 16:44:39[APPLAUSE]
  21292. 16:44:40DAVID J. MALAN: Thank you.
  21293. 16:44:44So now we've actually changed the data.
  21294. 16:44:46And this is what's compelling about a proper database.
  21295. 16:44:50Yes, you could technically write Python code that not only reads the CSV file,
  21296. 16:44:54but also writes it.
  21297. 16:44:55You can change using quote, unquote, "A" for append,
  21298. 16:44:58or quote, unquote, "W" for write, instead of quote, unquote,
  21299. 16:45:01"R" for read alone.
  21300. 16:45:02But it's definitely a little more involved to do that in Python.
  21301. 16:45:05But with SQL, you can update the data in real time.
  21302. 16:45:07And if I were actually running a web application here or a database
  21303. 16:45:11for a mobile app, that change, theoretically,
  21304. 16:45:13would be reflected everywhere on your own devices
  21305. 16:45:15if you're somehow talking to this application.
  21306. 16:45:17So that's the direction we're headed.
  21307. 16:45:19This other thing has been bothering me.
  21308. 16:45:20So select, how about title from favorites, where title equals,
  21309. 16:45:27what was it?
  21310. 16:45:28The V Office, was it?
  21311. 16:45:31Yeah, it was that one.
  21312. 16:45:33How about we update favorites by setting title
  21313. 16:45:37equal to The Office, where title equals quote, unquote, "The V Office"
  21314. 16:45:44semicolon?
  21315. 16:45:45And now, if I select the same thing again
  21316. 16:45:47I can go up and down with my arrow keys quickly.
  21317. 16:45:50Now there is no The V Office.
  21318. 16:45:52We've actually changed that value.
  21319. 16:45:54How about genres?
  21320. 16:45:55Select genres from favorites, where the title is title
  21321. 16:46:01equals Game of Thrones, semicolon.
  21322. 16:46:04These were kind of long, and I don't really agree with all of that.
  21323. 16:46:08So how about we update favorites, set genres equal to, sure,
  21324. 16:46:14action, adventure, sure, drama?
  21325. 16:46:17OK, so it's a decent list.
  21326. 16:46:19Fantasy, sure, thriller, war.
  21327. 16:46:22OK, anything really but comedy, I would say.
  21328. 16:46:26Let's go ahead and hit Enter now.
  21329. 16:46:28And now, if I select genres again, same query, now we've canonicalized that.
  21330. 16:46:33We've thrown data away.
  21331. 16:46:34So whether or not that is right is probably
  21332. 16:46:36a bit subjective and argumentative.
  21333. 16:46:38But I have at least cleaned up my data, which is, again, the U in CRUD.
  21334. 16:46:42Create, read, update, delete, you can do it that easily.
  21335. 16:46:46Beware using delete.
  21336. 16:46:47Beware worse using drop, whereby you can drop an entire table.
  21337. 16:46:51But via these kinds of commands, can we actually now
  21338. 16:46:54manipulate our data much more rapidly and with single thoughts.
  21339. 16:46:58And in fact, if you're an aspiring statistician, or data scientist,
  21340. 16:47:01or analyst in the real world, SQL is such a commonly used language
  21341. 16:47:05because it allows you to really dive into data quickly, and ask
  21342. 16:47:08questions of the data, and get back answers quite quickly.
  21343. 16:47:11And this is a simple data set.
  21344. 16:47:12You can do this with much larger data sets as we soon will, too.
  21345. 16:47:17Or any questions on what we've seen of SQL thus far?
  21346. 16:47:20Only scratched the surface, but again, it
  21347. 16:47:22boils down to creating, reading, updating, and deleting data.
  21348. 16:47:28Questions here?
  21349. 16:47:30All right.
  21350. 16:47:30Well, let's consider the design of this data.
  21351. 16:47:33Recall that if I do .schema, that shows me the design of my table,
  21352. 16:47:37the so-called schema of my data.
  21353. 16:47:39This is OK.
  21354. 16:47:40It gets the job done, and frankly, everything the user typed in
  21355. 16:47:42was arguably text, including the timestamp, which is the date and time.
  21356. 16:47:46But so the data set itself is somewhat simple.
  21357. 16:47:49But if we look at the data set itself, especially genres, let's do this.
  21358. 16:47:54Select genres from favorites.
  21359. 16:47:57And let me point out one other thing stylistically, too.
  21360. 16:47:59I am very deliberately capitalizing all of the special SQL keywords,
  21361. 16:48:04and I'm lowercasing all of the column names and the table names.
  21362. 16:48:08This is a convention, and honestly, it just helps you read,
  21363. 16:48:11I think, the code when you're co-mingling your names for columns
  21364. 16:48:14and tables with proper SQL keywords.
  21365. 16:48:17But I could just as easily do select genres from favorites,
  21366. 16:48:23but again, the SQL specific keywords don't quite jump out as much.
  21367. 16:48:26So stylistically, we would recommend this, selecting genres
  21368. 16:48:29from favorites, semicolon.
  21369. 16:48:31So here is where--
  21370. 16:48:34oh.
  21371. 16:48:36OK, that was not intended.
  21372. 16:48:38I accidentally made every show, including
  21373. 16:48:40The Office about action, adventure, drama, fantasy, thriller, and war.
  21374. 16:48:45How did I do that accidentally?
  21375. 16:48:49What did I do wrong?
  21376. 16:48:50AUDIENCE: [INAUDIBLE]
  21377. 16:48:55DAVID J. MALAN: Yeah.
  21378. 16:48:56So beware, this is funny.
  21379. 16:48:57I think I did say beware around this time.
  21380. 16:48:59So the SQL database took me-- literally, I updated favorites,
  21381. 16:49:03setting genres equal to that, semicolon, end of thought.
  21382. 16:49:06I really wanted to say where title equals,
  21383. 16:49:08quote, unquote, "Game of Thrones."
  21384. 16:49:11Unfortunately, there isn't an undo command or time machine
  21385. 16:49:14with a SQL database, so the best we can do here
  21386. 16:49:17is, let's actually get rid of favorites.db.
  21387. 16:49:21Let's run SQLite of favorites.db again, which now will be recreated.
  21388. 16:49:27Let me change myself into CSV mode.
  21389. 16:49:29Let me import, into my favorites table, the CSV file.
  21390. 16:49:35And now, Friends is back, for better or for worse,
  21391. 16:49:39but so are all of our genres.
  21392. 16:49:43If I now reload the file and do select, star, from--
  21393. 16:49:46sorry.
  21394. 16:49:47Select genres from favorites, that was the result I was getting.
  21395. 16:49:51It's much messier, but that's because some of these are quite long.
  21396. 16:49:53But now we're back to the original data.
  21397. 16:49:55Lesson here, be sure to back up your work.
  21398. 16:49:58All right.
  21399. 16:49:58So what more can we now do with this data?
  21400. 16:50:02Well, I don't love the design of the genres table for a couple of reasons.
  21401. 16:50:05One, we didn't have any sort of validation,
  21402. 16:50:08but user input is going to be messy.
  21403. 16:50:10There's just a lot of redundancy in here.
  21404. 16:50:13Let's go ahead and do this.
  21405. 16:50:15Let me select all the comedies you all typed in.
  21406. 16:50:17So select title from favorites, where genres equals,
  21407. 16:50:23quote, unquote, "comedy."
  21408. 16:50:25OK, so there's all of the shows that are explicitly comedies.
  21409. 16:50:31But I think there might actually be others.
  21410. 16:50:34Let me scroll back up here.
  21411. 16:50:36Comedy, drama.
  21412. 16:50:37What was a comedy and a drama?
  21413. 16:50:39How about let's search for the-- oops, let me copy paste comedy, comma, drama.
  21414. 16:50:44OK, so The Office, in this case, was considered comedy and drama, Billions,
  21415. 16:50:49It's Always Sunny in Philadelphia, and Gilmore Girls as well.
  21416. 16:50:52But notice that I get many more when I just search for comedy.
  21417. 16:50:56So the catch here is that, because I have all of these genres implemented
  21418. 16:51:01the way Google did, as a comma-separated list,
  21419. 16:51:04it's actually really hard and messy to get at any show, all of the shows
  21420. 16:51:08that are somewhere described as comedy.
  21421. 16:51:12Because if I search for quote, unquote, "comedy," the only answers
  21422. 16:51:15I'm going to get are this one, whatever that show is, this one, whatever
  21423. 16:51:18that show is, this one.
  21424. 16:51:20But I'm not going to get this one.
  21425. 16:51:22I'm not going to get this one.
  21426. 16:51:23Why?
  21427. 16:51:24If I'm searching for, where genres equals, quote, unquote, "comedy,"
  21428. 16:51:28why am I missing those other shows?
  21429. 16:51:32Why am I missing?
  21430. 16:51:33Yeah?
  21431. 16:51:33AUDIENCE: [INAUDIBLE]
  21432. 16:51:36DAVID J. MALAN: Exactly.
  21433. 16:51:37It's not just a comedy, it's a comedy and a drama,
  21434. 16:51:39and a comedy or a news show, and so forth.
  21435. 16:51:42So I have to search for these commas, so this gets messy quickly, right?
  21436. 16:51:45Let me copy this so I can do this.
  21437. 16:51:47Let me search for where genres equals comedy.
  21438. 16:51:51How about, or genres equals comedy, drama, or genres
  21439. 16:51:58equals this whole thing, comedy, news, talk show?
  21440. 16:52:01I'm going to get more and more results.
  21441. 16:52:03But that's not going to scale well.
  21442. 16:52:05What could I do instead of enumerating with ors
  21443. 16:52:08all of the different permutations of genres, do you think?
  21444. 16:52:11AUDIENCE: [INAUDIBLE]
  21445. 16:52:15DAVID J. MALAN: Yeah.
  21446. 16:52:15So I could use the keyword is, similar in Python to the word in.
  21447. 16:52:19I could use the like keyword so that so long
  21448. 16:52:22as the genres is like comedy somewhere in there,
  21449. 16:52:27that's going to give me all of them, so long as the word comedy is in there.
  21450. 16:52:31But let me go ahead and just open the form from earlier.
  21451. 16:52:37Let me see if I can open this real quick before I toggle over.
  21452. 16:52:40If we look back at the form, recall that there
  21453. 16:52:42were all of those radio buttons asking for the specific genres
  21454. 16:52:47into which something fell.
  21455. 16:52:49And if I open this, let me full screen here and now open the original form.
  21456. 16:52:55You'll see all of the genres here, none of which
  21457. 16:52:58are that worrisome except for a corner case is jumping out at me.
  21458. 16:53:04Where might the like keyword alone get me into trouble?
  21459. 16:53:08It's not with comedy.
  21460. 16:53:09I'm OK with comedy.
  21461. 16:53:11AUDIENCE: Music and musical?
  21462. 16:53:13DAVID J. MALAN: Yeah, music and musical are deliberately on the list here.
  21463. 16:53:16Because, one, they're separate genres.
  21464. 16:53:19But if I just search for something that's like music,
  21465. 16:53:21I'm going to accidentally suck in all of the musicals, which
  21466. 16:53:24might not be what I intend.
  21467. 16:53:25If music is a music video or whatever, and musical is actually
  21468. 16:53:28a different type of show, I don't want to just do that.
  21469. 16:53:31So it seems just very messy.
  21470. 16:53:33I could probably hack something together with-- maybe add some commas in there,
  21471. 16:53:37or something like this.
  21472. 16:53:37But this is just not a good design for the data.
  21473. 16:53:40Google has done it this way because it's just
  21474. 16:53:43simple to actually keep the user's data all in a single column,
  21475. 16:53:47and just as they did, separate it by commas.
  21476. 16:53:49But this is a real messy way to use CSV is
  21477. 16:53:54by putting comma-separated values in your comma-separated values.
  21478. 16:53:58Arguably, the folks at Google probably just did this
  21479. 16:54:00because it's just simpler.
  21480. 16:54:01And they didn't want to give people multiple sheets
  21481. 16:54:03or complicate things using some other weirder character than commas alone.
  21482. 16:54:07But I bet there's a better way for us to do this.
  21483. 16:54:09And let me go ahead and do this.
  21484. 16:54:11Let me go back into my code here.
  21485. 16:54:13And in just a moment, I'm going to grab a program
  21486. 16:54:15that I wrote in advance that's going to use Python to open up the CSV file,
  21487. 16:54:19iterate over all of the rows, and load the data into two tables this time,
  21488. 16:54:24two tables, one called shows, and one called genres,
  21489. 16:54:27so as to actually separate these two things out.
  21490. 16:54:30Give me just a moment to grab the code.
  21491. 16:54:33And when I run this, I'll only have to run it once.
  21492. 16:54:36Let me go ahead and run Python in a moment,
  21493. 16:54:38and I'll reveal the results in a sec.
  21494. 16:54:41This is going to be version 8 of the code online.
  21495. 16:54:44When I do this, let me go ahead and open up this file.
  21496. 16:54:47Give me a second to move it into this directory.
  21497. 16:54:51Version 8, OK.
  21498. 16:54:53So here we have version 8 of this that's available online
  21499. 16:54:56that's going to do the following.
  21500. 16:54:58And I'll gloss over some of the details just so
  21501. 16:55:00that we don't get stuck in the weeds of some of this code.
  21502. 16:55:04I'm going to be using, at the top of this program,
  21503. 16:55:06as we'll soon see, a CS50 library, not for the sake of get_string,
  21504. 16:55:11or get_int, or get_float, but because there's some built-in SQL
  21505. 16:55:14functionality that we didn't discuss a couple of weeks back with the CS50
  21506. 16:55:17library itself.
  21507. 16:55:18But inside of the CS50 library we'll see there is a special function called
  21508. 16:55:22SQL that gives you the ability using this weird URL-like looking thing,
  21509. 16:55:26technically called a URI, that allows me to open a file called favorites.db.
  21510. 16:55:31And long story short, all of the subsequent code
  21511. 16:55:33is going to iterate over this favorites.csv file that we downloaded.
  21512. 16:55:37And it's going to import it into the SQLite database,
  21513. 16:55:41but it's going to use two tables instead of just one.
  21514. 16:55:44So give me just a moment to run this, and then I'll
  21515. 16:55:46reveal the actual results.
  21516. 16:55:48This is going to be run on favorites.csv.
  21517. 16:55:56And taking a look here, give me just a moment.
  21518. 16:56:04Oh, give me a sec.
  21519. 16:56:08Come on.
  21520. 16:56:10Come on.
  21521. 16:56:11This program should not be taking this long.
  21522. 16:56:14Sorry.
  21523. 16:56:15Let's open this real fast.
  21524. 16:56:20Whoops, not that file.
  21525. 16:56:24OK.
  21526. 16:56:24Let me just skim this code real quick to see where we've gone wrong.
  21527. 16:56:27[INAUDIBLE] reader.
  21528. 16:56:30Reader, title, show ID in certain two shows.
  21529. 16:56:35[INAUDIBLE] genres split, DB execute.
  21530. 16:56:40All right.
  21531. 16:56:41This is me debugging in real time.
  21532. 16:56:42All those times we encourage you to use print, this is me actually using print.
  21533. 16:56:48We'll see how quickly I can recover from this.
  21534. 16:56:50Python of favorites version 8.
  21535. 16:56:54OK, so here's me debugging in real time.
  21536. 16:56:57It's printing it.
  21537. 16:56:58Oh, maybe I just didn't wait long enough.
  21538. 16:56:59OK, so here we go.
  21539. 16:57:01What I'm doing is printing out the dictionary that represents
  21540. 16:57:05each row that you all typed in.
  21541. 16:57:06And we're actually making progress.
  21542. 16:57:08All right.
  21543. 16:57:09I was too impatient and didn't wait long enough.
  21544. 16:57:11So in a moment--
  21545. 16:57:12there we go.
  21546. 16:57:13All right, so all we have to do sometimes is wait.
  21547. 16:57:15Let me go ahead now and open this file using SQLite3.
  21548. 16:57:19So in SQLite3 I now have a different version of favorites.db.
  21549. 16:57:23I named it number 8 for consistency.
  21550. 16:57:25Once I've run the program I can do .schema to look inside of it.
  21551. 16:57:28And here's what the two tables in this database are going to look like.
  21552. 16:57:32I've created a table called shows, this time to represent all of the TV shows
  21553. 16:57:36that are favorites, that has two columns.
  21554. 16:57:39One is called ID, one is called Title.
  21555. 16:57:42But now I'm going to start taking out for a spin some
  21556. 16:57:44of the other features of SQL.
  21557. 16:57:45And besides there being text, it turns out there's a data type called integer.
  21558. 16:57:50Besides there being a data type called text,
  21559. 16:57:52there's also a special key phrase that you can specify
  21560. 16:57:55that the title can never be null.
  21561. 16:57:57Think back to our use of null in C. Think back
  21562. 16:58:00to the keyword none in Python.
  21563. 16:58:02This is a database constraint that allows you to ensure that none of you
  21564. 16:58:06can't have of favorite TV show.
  21565. 16:58:07If you submit the form, you have to have typed in a title for it
  21566. 16:58:11to end up in our database here.
  21567. 16:58:13And you'll notice one other new feature.
  21568. 16:58:16It turns out, on this table I'm defining what's
  21569. 16:58:18called a primary key, specifically to be the ID column.
  21570. 16:58:22More on that in just a moment.
  21571. 16:58:23Meanwhile, the second table my code has created for me, as we'll soon see,
  21572. 16:58:28gives me a column called show ID, and then, a genre,
  21573. 16:58:33the value of which is text that can also not be null.
  21574. 16:58:36And then more on this in a moment.
  21575. 16:58:38This table has what we're going to call a foreign key,
  21576. 16:58:41specifically the show ID column that references shows ID.
  21577. 16:58:45So before we get into the weeds of this, this
  21578. 16:58:48is now a way of creating the relation in relational database.
  21579. 16:58:52If I have two tables now, not just one, they can somehow
  21580. 16:58:56be linked together by a common column.
  21581. 16:59:00In other words, the shows column--
  21582. 16:59:03shows table is going to give me a table with two columns--
  21583. 16:59:06an ID and a title.
  21584. 16:59:08Every title you gave me, I'm going to assign a unique value.
  21585. 16:59:12The genre's table, meanwhile, is going to associate individual genres
  21586. 16:59:16singular with that same idea.
  21587. 16:59:19And the result of this, to pop back to the Terminal here, is, let's do this.
  21588. 16:59:26Select star from shows of this new database,
  21589. 16:59:30and you'll see that I've given, indeed, all of the shows you all typed
  21590. 16:59:34in unique identifiers.
  21591. 16:59:36I didn't filter out duplicates or do anything beyond just forcing everything
  21592. 16:59:39to uppercase.
  21593. 16:59:39So there's going to be some duplicates here because I didn't
  21594. 16:59:42want to get rid of anyone's data.
  21595. 16:59:44But you'll see that, indeed, I've given everyone
  21596. 16:59:47a unique identifier, from the very first person who
  21597. 16:59:49typed How I Met Your Mother, all the way down to input number 158.
  21598. 16:59:53Meanwhile, if I do select star from genres, which is now a table, not just
  21599. 17:00:01a column in the original data, now you'll
  21600. 17:00:03see a much better design for this data.
  21601. 17:00:08Notice what I've done here.
  21602. 17:00:09Let me go all the way to the top and you'll see two columns, one of which
  21603. 17:00:12is called show ID, the other of which is called genre.
  21604. 17:00:16And again, I wrote some code to do this because I
  21605. 17:00:18had to take Google's messy output where everything was separated by commas.
  21606. 17:00:22I had to tear away the commas and then put each genre into this table
  21607. 17:00:25by itself.
  21608. 17:00:27Even though we haven't introduced the syntax via which
  21609. 17:00:29we can reconstitute the data and reassociate
  21610. 17:00:32your genres with your titles, why, at a glance,
  21611. 17:00:35might this be a better design now?
  21612. 17:00:38Even though I've doubled the number of tables from one to two,
  21613. 17:00:42why is this probably on the direction toward a better design?
  21614. 17:00:46What might your instincts be?
  21615. 17:00:51Why is this cleaner?
  21616. 17:00:53Again, first time with SQL, why is it better, perhaps,
  21617. 17:00:56that we've done this with our genre's table?
  21618. 17:00:59Can I come to you?
  21619. 17:01:00Why might this be better?
  21620. 17:01:02Yeah.
  21621. 17:01:02Oh, just because we had the conversation before about the commas.
  21622. 17:01:06AUDIENCE: [INAUDIBLE]
  21623. 17:01:07DAVID J. MALAN: Exactly.
  21624. 17:01:08It's as simple as that.
  21625. 17:01:09We've cleaned up the data by giving every genre, every word in the genres
  21626. 17:01:14column in the original Google Spreadsheet
  21627. 17:01:16its own cell in this table, if you will.
  21628. 17:01:19And now notice show ID might appear multiple times.
  21629. 17:01:22Whoever typed in How I Met Your Mother, they only associated one genre with it.
  21630. 17:01:26And so we see that show ID 1 is a comedy.
  21631. 17:01:29But whoever typed in--
  21632. 17:01:30I forget the name of the second show offhand.
  21633. 17:01:32But that person, whoever was assigned show ID 2 checked off
  21634. 17:01:37a whole bunch of the genre's boxes.
  21635. 17:01:39That happened again with show ID 3, 4.
  21636. 17:01:42Persons 5, 6, 7 only checked one box.
  21637. 17:01:46And so you can see now that we've associated the data with what we
  21638. 17:01:50might call a one-to-many relationship.
  21639. 17:01:53A one-to-many relationship, whereby for every one show in the show's table,
  21640. 17:01:58it can now have many genres associated with it, each of which
  21641. 17:02:02is represented by a separate row here.
  21642. 17:02:06So again, if I go ahead and select star from shows--
  21643. 17:02:10let's limit it to the first 10 just to focus on a subset of the data.
  21644. 17:02:14How I Met Your Mother, The Sopranos was the second input there.
  21645. 17:02:17It would seem that now that I've created the data in this way,
  21646. 17:02:20I could ideally somehow search the data, but a little more correctly.
  21647. 17:02:25I don't have to worry about the commas.
  21648. 17:02:26I don't have to worry about the hackish approach of music
  21649. 17:02:29being a substring of musical.
  21650. 17:02:30But how can I actually get back at this data?
  21651. 17:02:33Well, let's go ahead and do this.
  21652. 17:02:35Suppose I did want to get back maybe all of the comedies.
  21653. 17:02:39All of the comedies, no matter whether the person checked just the comedy
  21654. 17:02:42box or multiple boxes instead.
  21655. 17:02:44How now, given that I have two tables, could I
  21656. 17:02:48go about selecting only the titles of comedies?
  21657. 17:02:53I've actually made the problem a little harder,
  21658. 17:02:55but again, SQL is going to give me a solution for this.
  21659. 17:02:58The problem is that if I want to search for comedies,
  21660. 17:03:00I have to check the genres table first.
  21661. 17:03:03And then what's that going to give me?
  21662. 17:03:04If I search the genres table for comedies,
  21663. 17:03:08what's that going to give me back potentially?
  21664. 17:03:11Yeah?
  21665. 17:03:12AUDIENCE: Show ID.
  21666. 17:03:13DAVID J. MALAN: Maybe show ID.
  21667. 17:03:14So let me try that.
  21668. 17:03:15Let me do select show ID from genres, where the genre in a given row
  21669. 17:03:21equals quote, unquote, "comedy."
  21670. 17:03:22No commas, no like, no percent signs.
  21671. 17:03:25Because literally, that column now is singular words, like comedy, or drama,
  21672. 17:03:30or the like.
  21673. 17:03:31Let me go ahead and hit Enter here.
  21674. 17:03:33OK, so I got back a whole bunch of ID numbers.
  21675. 17:03:36Now this could very quickly get annoying.
  21676. 17:03:38It looks like show ID 1, 2, 4, 5, 6, 7, 9, and so forth, are all comedies.
  21677. 17:03:43So I could do something really crazy like, select title from shows,
  21678. 17:03:49where ID equals 1, or ID equals 2.
  21679. 17:03:54This is not going to scale very well, but this
  21680. 17:03:57is why SQL is especially powerful.
  21681. 17:03:59You can actually compose one SQL question from multiple ones.
  21682. 17:04:04So let's do this.
  21683. 17:04:05Why don't I select the title where the ID of the show
  21684. 17:04:09is in the following list of IDs?
  21685. 17:04:13Select show ID from genres, where the specific genre is, quote, unquote,
  21686. 17:04:20"comedy."
  21687. 17:04:20So I've got two SQL queries.
  21688. 17:04:23One is deliberately nested inside of parentheses.
  21689. 17:04:27That's going to give me back that whole list of show IDs.
  21690. 17:04:30But that's exactly what I want to then look up
  21691. 17:04:32the titles for by selecting title from shows where the ID of the show
  21692. 17:04:36is in that big, tall list.
  21693. 17:04:38And so now if I hit Enter, I get back only those shows
  21694. 17:04:44that were somehow flagged as comedy, whether you in the audience
  21695. 17:04:47checked one box for comedy, two boxes, or all of the boxes.
  21696. 17:04:51Somehow we teased out comedy, again, just
  21697. 17:04:54by using that Python script, which loaded this data not
  21698. 17:04:56into one big table, but instead, two.
  21699. 17:04:59And if we want to clean this up, let's do a couple of things.
  21700. 17:05:01Let's, outside of the parentheses, do order by title.
  21701. 17:05:05This is a way of sorting the data in SQL very easily.
  21702. 17:05:08Now we have a whole list of the same titles that are now sorted.
  21703. 17:05:13And what was the keyword with which I could filter out duplicates?
  21704. 17:05:17Yeah, distinct.
  21705. 17:05:18So let's try this.
  21706. 17:05:19Same query, but let's select only the distinct titles from that whole query.
  21707. 17:05:24And notice, I've very deliberately done it this way.
  21708. 17:05:27And to this day, any time I'm using SQL, I
  21709. 17:05:28don't just start at the beginning and type out my whole thought,
  21710. 17:05:31and just get it right on the first try.
  21711. 17:05:33I very commonly start with the subquery, if you
  21712. 17:05:35will, the thing in parentheses, just to get myself
  21713. 17:05:38one step toward what I care about.
  21714. 17:05:39Then I add to it.
  21715. 17:05:40Then I add to it.
  21716. 17:05:41Then I add to it, just like we've encouraged in Python and C,
  21717. 17:05:43taking baby steps in order to get to the answer you actually care about,
  21718. 17:05:47like this one now.
  21719. 17:05:48And other than this mistake, which we didn't
  21720. 17:05:51fix because I re-imported the data after accidentally changing everyone's genre,
  21721. 17:05:55we now have an alphabetized list of all of the same data.
  21722. 17:06:00But now it's better designed, because we have it split across these two tables.
  21723. 17:06:06Oh, thank you.
  21724. 17:06:06OK, just thanks.
  21725. 17:06:10What questions do we have, if any here?
  21726. 17:06:14Questions on this approach?
  21727. 17:06:18Yeah?
  21728. 17:06:20AUDIENCE: [INAUDIBLE]
  21729. 17:06:25DAVID J. MALAN: Oh, now that we have a database,
  21730. 17:06:27how do we transfer it to a CSV?
  21731. 17:06:29There are ways to do that.
  21732. 17:06:31And in fact, there's a command within SQLite
  21733. 17:06:33that allows you to export your data back to a CSV file.
  21734. 17:06:36If you want to email it to someone and you
  21735. 17:06:38want them to be able to open it in Excel, or Google Spreadsheets, or Apple
  21736. 17:06:41Numbers, or the like, you can go in the other direction.
  21737. 17:06:44Generally though, once you're in the world of SQL
  21738. 17:06:47you're probably storing your data there long term.
  21739. 17:06:49And you're probably updating it, maybe deleting it, adding to it,
  21740. 17:06:52and so forth.
  21741. 17:06:53For instance, the one command I did not show earlier
  21742. 17:06:55is, suppose someone forgot a show.
  21743. 17:06:58Let's see, did I see this in the output?
  21744. 17:07:00All right, so Curb Your Enthusiasm.
  21745. 17:07:02Saw that last night.
  21746. 17:07:03It was just, yeah.
  21747. 17:07:04Did anyone see it last night?
  21748. 17:07:06No?
  21749. 17:07:07All right, well, just the one person that checked that box, so you and me.
  21750. 17:07:10What's another show that didn't make the list?
  21751. 17:07:12How about Seinfeld?
  21752. 17:07:13It's now on Netflix, apparently.
  21753. 17:07:14So insert into shows.
  21754. 17:07:20What do we want to insert?
  21755. 17:07:21Well, we want to insert maybe an ID and a title.
  21756. 17:07:25But I don't actually care what the ID is,
  21757. 17:07:27so I'm just going to insert a title.
  21758. 17:07:28And the value I'm going to give to that title
  21759. 17:07:31is going to be, quote, unquote, "Seinfeld."
  21760. 17:07:34And then, let me go ahead and hit semicolon.
  21761. 17:07:37Nothing seems to happen, but let me rerun the big query
  21762. 17:07:39from before looking for comedies.
  21763. 17:07:41And unfortunately, Seinfeld has not yet been flagged as a comedy,
  21764. 17:07:45so let's get this right, too.
  21765. 17:07:47What intuitively I'm going to have to do to associate, now,
  21766. 17:07:50Seinfeld with my comedies?
  21767. 17:07:53I just inserted into the show's table.
  21768. 17:07:55What more needs to happen before we can flag Seinfeld as a comedy?
  21769. 17:07:59AUDIENCE: [INAUDIBLE]
  21770. 17:08:00DAVID J. MALAN: Say again?
  21771. 17:08:01AUDIENCE: [INAUDIBLE]
  21772. 17:08:02DAVID J. MALAN: Yeah.
  21773. 17:08:03So I need to insert into the genres table two things now,
  21774. 17:08:08a show ID, like this, and then, the name of the genre,
  21775. 17:08:13which presumably is comedy.
  21776. 17:08:14What values do I want to insert?
  21777. 17:08:16Well, the show ID, I better grab that.
  21778. 17:08:18Oh, I don't even know what it is.
  21779. 17:08:19I'm going to have to figure out what that is.
  21780. 17:08:21So I could do this in a couple of ways.
  21781. 17:08:23Let me do a one-time thing.
  21782. 17:08:24Select star from shows, where title equals,
  21783. 17:08:28quote, unquote, "Seinfeld" semicolon 159.
  21784. 17:08:32So now I could do, insert into genres a show ID
  21785. 17:08:37and a genre name, the values 159, and, quote, unquote, "comedy" semicolon,
  21786. 17:08:45Enter.
  21787. 17:08:46And now, if I scroll back in my history and execute that really big query
  21788. 17:08:50again, looking for all distinct comedies,
  21789. 17:08:52now Seinfeld has made the list.
  21790. 17:08:54But I did this manually so I didn't actually capitalize it.
  21791. 17:08:57Let's clean that up.
  21792. 17:08:58Let's do update.
  21793. 17:09:00Let's do update my shows.
  21794. 17:09:03Set title equals to Seinfeld semicolon.
  21795. 17:09:08No?
  21796. 17:09:09OK, thank you, where title equals, quote, unquote, "Seinfeld."
  21797. 17:09:13Let's not make that mistake again.
  21798. 17:09:14Enter.
  21799. 17:09:15And now, if I execute that really big query, now Seinfeld is,
  21800. 17:09:18indeed, considered a comedy.
  21801. 17:09:21So where are we going with this?
  21802. 17:09:23Well, thus far we've been doing all of this pretty manually.
  21803. 17:09:25And this is absolutely what an analyst, a data scientist type person
  21804. 17:09:28might do if just manipulating a pretty large data set just
  21805. 17:09:30to get at interesting answers that might be across one,
  21806. 17:09:33two, or even many more tables.
  21807. 17:09:34Eventually, in a few weeks, we're going to start to automate all of this
  21808. 17:09:37by writing code in Python that generates SQL to do this.
  21809. 17:09:41If you go to most any website on the internet today,
  21810. 17:09:44and you, for instance, log in, odds are you're typing a username and password,
  21811. 17:09:48clicking Submit.
  21812. 17:09:49What's then happening?
  21813. 17:09:50Well, the website might not be implemented in Python
  21814. 17:09:53but it's probably implemented in some language, Python, JavaScript, Java,
  21815. 17:09:56Ruby, something else.
  21816. 17:09:58And that language is probably using something like a relational database
  21817. 17:10:03to use SQL to get your username, get your password,
  21818. 17:10:07and compare the two against what you've typed in.
  21819. 17:10:09And actually, it's hopefully not getting your actual password,
  21820. 17:10:11but something called the hash thereof.
  21821. 17:10:13But there's probably a database involved doing that.
  21822. 17:10:15When you buy something on Amazon.com and you click Check Out,
  21823. 17:10:18odds are there's some code on Amazon's server
  21824. 17:10:22that's looking at what it is you added to your shopping cart,
  21825. 17:10:25and then maybe using a for loop of some sort, in Python or another language.
  21826. 17:10:29It's doing a whole bunch of SQL inserts to store in their database what
  21827. 17:10:33it is you bought.
  21828. 17:10:34There's other types of databases, too, but SQL databases,
  21829. 17:10:37or relational databases are quite popular.
  21830. 17:10:39So let's go ahead and write one other program here
  21831. 17:10:42in Python that now merges these two languages together, whereby
  21832. 17:10:46I'm going to use SQL inside of a Python program
  21833. 17:10:50so I can implement my logic of my program in Python,
  21834. 17:10:53step-by-step, line-by-line.
  21835. 17:10:55But when I want to get at some data I can actually talk to a SQL database.
  21836. 17:10:59So let me go ahead and open favorites.py.
  21837. 17:11:05And let me go ahead and throw away some of what we did earlier and really
  21838. 17:11:10just now add a SQL to the mix.
  21839. 17:11:13From the CS50 library, let's import the SQL function.
  21840. 17:11:16This will be useful to use because most third-party libraries
  21841. 17:11:19that deal with SQL and Python are more complicated than they need to be.
  21842. 17:11:22So I think you'll find this library easier to use.
  21843. 17:11:25Let's then do the following.
  21844. 17:11:27Create a variable called db for database.
  21845. 17:11:29But I could call it anything I want.
  21846. 17:11:30Let's use that you URI, which is a fancy way of saying something
  21847. 17:11:34that looks like a URL, but that actually opens up a database on disk, that is,
  21848. 17:11:43in the current folder.
  21849. 17:11:44Let's now ask the user for a title by prompting them for a, quote, unquote,
  21850. 17:11:47"title" like this.
  21851. 17:11:49And let's strip off any whitespace just so that the data is not messy.
  21852. 17:11:53And then, let's go ahead and do this.
  21853. 17:11:56And this is the new logic.
  21854. 17:11:57I'm going to go ahead now and write a line of code that uses Python
  21855. 17:12:01to talk to the original favorites.db.
  21856. 17:12:05So again, I'm not using the two-table database, which is in favorites8.db.
  21857. 17:12:09I'm using the original that we imported from your own data,
  21858. 17:12:12and I'm going to do the following.
  21859. 17:12:14I'm going to use db.execute to execute a SQL command inside of Python.
  21860. 17:12:19I'm going to select the count of shows from the favorites
  21861. 17:12:28table, where the title the user typed in is like this question mark.
  21862. 17:12:35And why I'm doing that is as follows.
  21863. 17:12:37Just like in C, when we had percent S, in SQL for now,
  21864. 17:12:40the analogue is going to be a question mark.
  21865. 17:12:42So same idea, different syntax.
  21866. 17:12:44Instead of percent S, it's just a question mark.
  21867. 17:12:46And using a comma outside of this first string, using CS50's execute
  21868. 17:12:51function I can pass in a SQL string, a command,
  21869. 17:12:54then any arguments I want to plug into the question marks therein.
  21870. 17:12:59So the goal at hand is to actually write a program that's
  21871. 17:13:01going to search favorites.csv, a.k.a., favorites.db for the total number
  21872. 17:13:07of people that liked a particular show.
  21873. 17:13:10So this is going to select the count of people from the favorites table
  21874. 17:13:14where the title they typed in is like whatever the user has just now typed
  21875. 17:13:18in.
  21876. 17:13:19This db execute function returns a list.
  21877. 17:13:22It returns a list of rows.
  21878. 17:13:23And you would only know that by my telling you or reading
  21879. 17:13:25the documentation.
  21880. 17:13:26And therefore, if I want to get back to the total count,
  21881. 17:13:29I'm going to go ahead and grab the first row from those rows.
  21882. 17:13:34Because it's only going to give me back the count.
  21883. 17:13:36And then I'm going to go ahead and print out that row's first value.
  21884. 17:13:41But it's going to be a little weird.
  21885. 17:13:43Technically the column is going to be called "count" star, quote, unquote,
  21886. 17:13:46which is a little weird.
  21887. 17:13:47Let me add one more feature to the mix.
  21888. 17:13:49You can actually give nicknames to columns
  21889. 17:13:51that are coming back, especially if they are the result of functions like this.
  21890. 17:13:55I can just call that column counter, in all lowercase.
  21891. 17:13:59That means I can now say get back the counter key inside of this dictionary.
  21892. 17:14:06So just to recap, what have we done?
  21893. 17:14:08We've imported the CS50 library SQL function.
  21894. 17:14:11We've, with this line of code, opened the favorites.db
  21895. 17:14:14file that you and I created earlier by importing your CSV into SQLite.
  21896. 17:14:20I'm now just asking the user for a title they want to search for.
  21897. 17:14:23I'm now executing this SQL query on that database,
  21898. 17:14:27plugging in whatever the human typed in as their title
  21899. 17:14:30in order to get back a total count.
  21900. 17:14:32And I'm giving the count a nickname, an alias of counter,
  21901. 17:14:36just so it's more self-explanatory.
  21902. 17:14:39This function, db execute, no matter what, always returns a list of rows,
  21903. 17:14:43even if there's only one row inside of it.
  21904. 17:14:45So this line of code just gives me the first and only row.
  21905. 17:14:48And then, this goes inside of that row, which it turns out is a dictionary,
  21906. 17:14:53and gives me the key counter and the value it corresponds to.
  21907. 17:14:59So what, to be clear, is this doing?
  21908. 17:15:00Let's go ahead and run this manually in my Terminal window first.
  21909. 17:15:03Let me run SQLite3 on favorites--
  21910. 17:15:07Well, let's do this.
  21911. 17:15:08On favorites.db, let me import the data again.
  21912. 17:15:12So mode csv.import in from favorites.csv into a favorites table.
  21913. 17:15:20So I've just recreated the same data set that you all
  21914. 17:15:22gave me earlier in favorites.db.
  21915. 17:15:25If I were to do this manually, let's search for The Office again.
  21916. 17:15:27Select, count star from favorites, where title like, and let's
  21917. 17:15:34just manually type it in for now, The Office.
  21918. 17:15:37We'll search for the one with the word The, semicolon.
  21919. 17:15:40I get back 12.
  21920. 17:15:41But technically, notice what I get back.
  21921. 17:15:44I technically get back a miniature table containing one column and one row.
  21922. 17:15:50What if I want to rename that column?
  21923. 17:15:52That's where the as keyword comes in.
  21924. 17:15:54So select count star as counter.
  21925. 17:15:56Notice what happens, Enter.
  21926. 17:15:58I just get back-- same simple table, but I've
  21927. 17:16:01renamed the column to be counter just because it's a little more
  21928. 17:16:03self-explanatory as to what it is.
  21929. 17:16:05So what am I doing with this line of code?
  21930. 17:16:08This line of code is returning to me that miniature temporary table
  21931. 17:16:12in the form of a list of dictionaries.
  21932. 17:16:16The list contains one row, as we'll see, and it
  21933. 17:16:20contains one column, as we'll see, the key for which is counter.
  21934. 17:16:26So let's now run the code itself.
  21935. 17:16:27I'm going to get out of SQLite3 and I'm going to run Python of favorites.py.
  21936. 17:16:32Enter.
  21937. 17:16:33I'm being prompted for a title.
  21938. 17:16:34I'm going to type in The Office and cross my fingers, and there's that 12.
  21939. 17:16:39Why is it 12?
  21940. 17:16:40Well, there's a typo again because I re-imported the CSV.
  21941. 17:16:42I had deleted two of the Thes, so we're back at the original data set.
  21942. 17:16:46So there's 12 total that have, quote, unquote, "The Office"
  21943. 17:16:51in the title like that.
  21944. 17:16:53So what have we done?
  21945. 17:16:54We've combined some Python with some SQL,
  21946. 17:16:57but we've relegated all of the complexity of searching for something,
  21947. 17:17:00the selecting of something, gotten rid of all
  21948. 17:17:02of the with keyword, the open keyword, the for loop,
  21949. 17:17:04the reader the DictReader, and all of that.
  21950. 17:17:06And it's just one line of SQL now, using the best of both worlds.
  21951. 17:17:11All right, any questions on what we've just done here or how any of this
  21952. 17:17:17works?
  21953. 17:17:20Any questions here?
  21954. 17:17:21Yeah?
  21955. 17:17:22AUDIENCE: [INAUDIBLE]
  21956. 17:17:26DAVID J. MALAN: When does this function return more than one row?
  21957. 17:17:29Was that the question?
  21958. 17:17:30AUDIENCE: Yeah.
  21959. 17:17:31DAVID J. MALAN: Yeah.
  21960. 17:17:31So let's do that by changing the problem at hand.
  21961. 17:17:33This program was designed just to select the total count.
  21962. 17:17:36Let's go ahead and select, for instance, all
  21963. 17:17:41of the ways you all typed in The Office by selecting the title this time.
  21964. 17:17:49If I do this in SQLite3, let me go ahead and do this again
  21965. 17:17:53after increasing my Terminal window.
  21966. 17:17:55Let's do it manually.
  21967. 17:17:56Select title from favorites, where the title is like,
  21968. 17:18:00quote, unquote, "The Office," semicolon.
  21969. 17:18:04I get back all of these different rows, and we didn't even notice this one.
  21970. 17:18:07There's actually another little typo in there
  21971. 17:18:09with some capitalization of the E, and the C, and the E. That
  21972. 17:18:12would be an example of a query that gives me back therefore
  21973. 17:18:16for multiple rows.
  21974. 17:18:17So let's now change my Python program.
  21975. 17:18:19If I now, in my Python program, do this, I get back a whole bunch of rows
  21976. 17:18:24containing all of those titles.
  21977. 17:18:26I can now do, for row in rows, I can print out the current row's title,
  21978. 17:18:31and now manipulate all of those things together.
  21979. 17:18:34Let me keep both on the screen.
  21980. 17:18:36Let me run Python of favorites.py.
  21981. 17:18:37And that for loop now should iterate, what, 10 or more times,
  21982. 17:18:41once for each of those titles.
  21983. 17:18:43And indeed, if I type in The Office again, Enter.
  21984. 17:18:47Whoops.
  21985. 17:18:50Row title.
  21986. 17:18:51What did I do wrong?
  21987. 17:18:52Oh, I should not be renaming title to counter this time.
  21988. 17:18:55So that's just a dumb mistake on my part.
  21989. 17:18:57Let me rerun it again.
  21990. 17:18:58And now I should see after typing in The Office,
  21991. 17:19:01Enter, a whole bunch of The Offices.
  21992. 17:19:03And because I'm using like, even the missed
  21993. 17:19:05capitalizations are coming through, because like is case insensitive.
  21994. 17:19:08It doesn't matter if it's uppercase or lowercase.
  21995. 17:19:11Whereas had I used the equal sign I would get back only the same ones
  21996. 17:19:15capitalized correctly.
  21997. 17:19:17All right, any questions on this next?
  21998. 17:19:20All right, so let's transition to a larger, juicier data
  21999. 17:19:25set, and consider some of the issues that
  22000. 17:19:26arise when actually now using SQL and skating toward a world in which we're
  22001. 17:19:31using SQL for mobile apps, web apps, and generally speaking,
  22002. 17:19:34very large data sets.
  22003. 17:19:36So let's start with a larger data set just like that.
  22004. 17:19:39Give me just a moment to switch screens over to what we have for you today,
  22005. 17:19:45which is an actual relational database that we've created out
  22006. 17:19:48of a real-world data set from IMDb.
  22007. 17:19:51So InternetMovieDatabase.com is a website
  22008. 17:19:54where you can search for TV shows, and movies, and actors,
  22009. 17:19:57and so forth, all using their database behind the scenes.
  22010. 17:20:00IMDb wonderfully makes their data set available as not CSV files,
  22011. 17:20:04but TSV files, tab-separated values.
  22012. 17:20:08And so what we did is, before class we downloaded those TSV files.
  22013. 17:20:11We wrote a Python program similar to my favorites8.py file
  22014. 17:20:15earlier that read in all of those TSV files,
  22015. 17:20:19created some SQL tables in an IMDb database
  22016. 17:20:24for you in SQLite that has multiple tables and multiple columns.
  22017. 17:20:28So let's go and wrap our minds around what's actually in this data set.
  22018. 17:20:32Let me go back to VS Code here, and in just a moment,
  22019. 17:20:36I'm going to go ahead and copy the file, which we've named shows.db.
  22020. 17:20:40And I'm going to go ahead and increase my Terminal and do SQLite3 of shows.db.
  22021. 17:20:45Whenever playing around with a SQLite database for the first time,
  22022. 17:20:48typing .schema is perhaps a good place to start to give you a sense
  22023. 17:20:51of what's in there.
  22024. 17:20:52And things just escalated quickly.
  22025. 17:20:54There's a lot in this data set, because, indeed, there's
  22026. 17:20:56going to be tens of hundreds of thousands of rows in this data set,
  22027. 17:21:01and also problem set 7, where we'll look at the movie side of things
  22028. 17:21:04and not just the TV shows.
  22029. 17:21:06So what is the schema that we have created for you
  22030. 17:21:09from IMDb's actual real-world data?
  22031. 17:21:12One, there's a table called shows.
  22032. 17:21:14And notice we've just added whitespace by hitting Enter a bunch of times
  22033. 17:21:17to make it a little more stylistically readable.
  22034. 17:21:19The shows table has an ID column, a title column, a year,
  22035. 17:21:23and the total number of episodes for a given show.
  22036. 17:21:26And the types of those columns are integer, text, numeric, and integer.
  22037. 17:21:31So it turns out there's actually a few different data
  22038. 17:21:33types that are worth being aware of when it comes to creating tables themselves.
  22039. 17:21:39In fact, in SQLite there's five data types, and only five,
  22040. 17:21:43fortunately, one of which is, indeed, integer, negative or positive,
  22041. 17:21:46numeric, which is kind of a catchall for dates and times,
  22042. 17:21:50things that are numeric but are not just integers,
  22043. 17:21:52and not just real numbers, for instance.
  22044. 17:21:54Real number is what we've generally thought of as float up until now.
  22045. 17:21:58Text, of course, is just text, but notice
  22046. 17:22:00that you don't have to worry about how big it is.
  22047. 17:22:02Like in Python, it will size to fit.
  22048. 17:22:04And then there's BLOB, which is binary large object, which
  22049. 17:22:07is for just raw 0s and 1s, like for files or things like that.
  22050. 17:22:10But we'll generally use the other four of these.
  22051. 17:22:12And so, indeed, when we imported this data for you
  22052. 17:22:16we decided that every show would be given an ID, which is just an integer.
  22053. 17:22:21Every show has, of course, a title, which should not be null.
  22054. 17:22:24Otherwise, why is it in the database?
  22055. 17:22:26Every show has a year, which is numeric according
  22056. 17:22:30to that definition a moment ago.
  22057. 17:22:31And the total number of episodes for a show is going to be an integer.
  22058. 17:22:34What now is with these primary keys that we mentioned earlier, too?
  22059. 17:22:38A primary key is the column that uniquely identifies all of the data.
  22060. 17:22:43In our case, with the favorites, I automatically
  22061. 17:22:46gave each of your submissions a unique ID so that even if two or more of you
  22062. 17:22:50typed in The Office, your submission still
  22063. 17:22:52had a unique identifier, a number that allowed me to then correlate it
  22064. 17:22:57with your genres, just as we saw a moment ago.
  22065. 17:23:01In this version of IMDb, there's also genres.
  22066. 17:23:04But they don't come from us, they come from IMDb.com.
  22067. 17:23:07And so a genre has a show ID, and a genre just like our database.
  22068. 17:23:11But these are real-world genres with a bit more filtration.
  22069. 17:23:15Notice, though, just like my version, there's a foreign key.
  22070. 17:23:19A foreign key is the appearance of another table's primary key
  22071. 17:23:25in its own table.
  22072. 17:23:27So when you have a table like genres, which is somehow
  22073. 17:23:30cross referencing the original shows table, if shows have a primary key
  22074. 17:23:36called ID, and those same numbers appear in the genres table
  22075. 17:23:40under the column called show ID, by definition, show ID is a foreign key.
  22076. 17:23:45It's the same numbers but it's foreign in the sense
  22077. 17:23:47that the number is being used in this table,
  22078. 17:23:50even though it's officially defined primarily in this other table.
  22079. 17:23:54This is what we mean by relational databases.
  22080. 17:23:57You have multiple tables with some column in common, numbers typically.
  22081. 17:24:02And those numbers allow you to line the two tables up in such a way
  22082. 17:24:06that you can reconnect the shows with their genres,
  22083. 17:24:09just like we did with our smaller data set a moment ago.
  22084. 17:24:12This logic is extended further.
  22085. 17:24:14Notice that the IMDb database we've created for you has a stars table,
  22086. 17:24:18like TV show stars, the actors therein.
  22087. 17:24:22And that table, interestingly, has no mention of people
  22088. 17:24:25and no mention of shows, per se.
  22089. 17:24:27It only has a column called show ID, which is an integer,
  22090. 17:24:31and a person ID, which is an integer.
  22091. 17:24:33Meanwhile, if we scrolled down to the bottom,
  22092. 17:24:39you will see a table called people.
  22093. 17:24:42And we have decided in IMDb's world that every person in the TV show world
  22094. 17:24:48will have a unique identifier that's a number, a name that's text, a birth
  22095. 17:24:52date, which is numeric, and then, again, specifying that ID
  22096. 17:24:56is going to be their primary key.
  22097. 17:25:00So what's going on here?
  22098. 17:25:02Well, it turns out that TV stars and writers are both types of people.
  22099. 17:25:07So using this relational database, notice the road we're going down.
  22100. 17:25:13We're factoring out commonalities.
  22101. 17:25:15And if a person can be different things in life,
  22102. 17:25:17well, we're defining them first and foremost as people.
  22103. 17:25:20And then, notice these two tables are almost the same.
  22104. 17:25:23The stars table has a show ID, which is a number,
  22105. 17:25:26and a person ID, which is a number, which
  22106. 17:25:28allows us via this middleman table, if you will, to link people with TV shows.
  22107. 17:25:36Similarly, the writers table allows us to connect shows with people, too,
  22108. 17:25:41by just recording those numbers.
  22109. 17:25:43So if we go into this data set, let's do the following.
  22110. 17:25:46Let's do select star from people semicolon.
  22111. 17:25:49So a huge amount of data is coming back.
  22112. 17:25:52This is hundreds of thousands of rows now based on the ID numbers alone.
  22113. 17:25:56So this is real-world data now flying across the screen.
  22114. 17:25:59There's a lot of people in the TV show business, not just actors and writers,
  22115. 17:26:03but others as well.
  22116. 17:26:05It's still going.
  22117. 17:26:06There's a lot of data there.
  22118. 17:26:07So my god, if you had to do anything manual in this data
  22119. 17:26:09set it's probably not going to work out very well.
  22120. 17:26:12And actually, we're up to, what, a million people in this data
  22121. 17:26:14set, plus, which would mean this probably isn't even
  22122. 17:26:17going to open very well in Excel, or Google Spreadsheets, or Apple Numbers.
  22123. 17:26:20SQL probably is the better approach here.
  22124. 17:26:23Let's search for someone specific, like select star
  22125. 17:26:25from people, where name equals Steve Carell, for instance, sticking
  22126. 17:26:31with comedies.
  22127. 17:26:32All right, so there's Steve Carell.
  22128. 17:26:33He is person number 136,797, born in 1962.
  22129. 17:26:39And that's as much data as we have on Steve Carell here.
  22130. 17:26:41How do we figure out what shows, for instance, he's in?
  22131. 17:26:44Well, let's see, select star from shows, semicolon.
  22132. 17:26:48There's a crazy number of shows out there in the IMDb database.
  22133. 17:26:52And you can see it here again flying across the screen.
  22134. 17:26:55Feels like we're going to have to employ some techniques in order
  22135. 17:26:58to get at all of Steve Carell's shows.
  22136. 17:27:02So how are we going to do that?
  22137. 17:27:04Well, god, this is a lot of data here.
  22138. 17:27:07And in fact, yeah, we have, what, 15 million
  22139. 17:27:10shows plus in this data set, too.
  22140. 17:27:12So doing things efficiently is now going to start to matter.
  22141. 17:27:15So let's actually do this.
  22142. 17:27:17Let me select a specific show.
  22143. 17:27:18Select star from shows where title equals, quote, unquote, "The Office."
  22144. 17:27:23And there presumably shouldn't be typos in this data
  22145. 17:27:26because it comes from the real website IMDb.com.
  22146. 17:27:28Let's get back to show.
  22147. 17:27:30Turns out there's been a lot of The Offices out in the world.
  22148. 17:27:33The one that started in 2005 is the one that we want,
  22149. 17:27:37presumably the most popular with 188 episodes.
  22150. 17:27:40How can we get just that?
  22151. 17:27:41Maybe we could do and year equals, how about 2005?
  22152. 17:27:46All right, so now we've got back just the ID of The Office
  22153. 17:27:50that we care about.
  22154. 17:27:51And let's do this, too.
  22155. 17:27:52Let me turn on a timer within SQLite just
  22156. 17:27:55to get a sense of running time now.
  22157. 17:27:57Let me do that again.
  22158. 17:27:58Select star from shows, where title equals The Office,
  22159. 17:28:01and year equals 2005.
  22160. 17:28:03And let's keep it simple.
  22161. 17:28:04Let's just do titles for now.
  22162. 17:28:05Enter.
  22163. 17:28:06All right, so not terribly long.
  22164. 17:28:08It found it pretty fast, but it looks like it took how much real time?
  22165. 17:28:120.02 seconds, not bad for just a title.
  22166. 17:28:15But just to plant a seed, it turns out that we can probably
  22167. 17:28:18speed even this up.
  22168. 17:28:19Let me do this.
  22169. 17:28:20Let me create something called an index, which is another use of the C
  22170. 17:28:23in CRUD for creating something.
  22171. 17:28:25And I'm going to call this title index.
  22172. 17:28:28And I'm going to create it on the shows table,
  22173. 17:28:32specifically on the title column.
  22174. 17:28:34And we'll see in a moment what this is going to do for me.
  22175. 17:28:37Enter.
  22176. 17:28:38Took a moment, like 0.349 seconds, to create something called an index.
  22177. 17:28:42But now watch, if I select star from shows searching for The Office again,
  22178. 17:28:46previously it took me 0.021 seconds.
  22179. 17:28:49Not bad, but now, wow.
  22180. 17:28:53Literally no time at all, or so low that it wasn't really measurable.
  22181. 17:28:56And I'll do it again just to get a sense of things.
  22182. 17:28:58Still quite low.
  22183. 17:29:00Now even though 0.021 seconds, not crazy long, imagine now having a lot of data,
  22184. 17:29:05a lot of users running a real website or real mobile app.
  22185. 17:29:07Every millisecond we can start to shave off is going to be compelling.
  22186. 17:29:11So what is it we just did?
  22187. 17:29:13Well, we actually just created something called an index.
  22188. 17:29:17And this is a nice way to tie in, now, some
  22189. 17:29:19of our week 5 discussion of data structures,
  22190. 17:29:21and our week 3 discussion of running times.
  22191. 17:29:23An index in a database is some kind of fancy data
  22192. 17:29:26structure that allows the database to do better than linear search.
  22193. 17:29:31Literally, as you just saw, these tables are crazy long or tall right now,
  22194. 17:29:35very linear, that is.
  22195. 17:29:37And so when I first searched for The Office,
  22196. 17:29:39it was literally doing linear search, top to bottom, looking at as many as,
  22197. 17:29:43what, a million plus rows.
  22198. 17:29:44That's relatively slow.
  22199. 17:29:46It's not that slow, 0.021 seconds.
  22200. 17:29:48But that's relatively slow just theoretically, algorithmically,
  22201. 17:29:52doing anything linearly.
  22202. 17:29:53But if you instead create an index using syntax
  22203. 17:29:57like this, which I just did, creating an index on the title column of the show's
  22204. 17:30:03table, that's like giving the database a clue in advance saying,
  22205. 17:30:06hey, I know I'm going to search on this column in this table a lot.
  22206. 17:30:10Do something with data structures to speed things up.
  22207. 17:30:12And so if you think back to our discussion of data structures,
  22208. 17:30:15maybe it's using a tree.
  22209. 17:30:17Maybe it's using a trie or a hash table, some fancier two-dimensional data
  22210. 17:30:21structure is generally going to lift the data up creating right maybe a tree
  22211. 17:30:25structure.
  22212. 17:30:26So it's just much faster to find data, especially
  22213. 17:30:28if it's sorting it now based on title, and not
  22214. 17:30:31just storing it in one long list.
  22215. 17:30:33And in fact, in the world of relational databases,
  22216. 17:30:35the type of structure that's often used in a database
  22217. 17:30:37is something called a B-tree.
  22218. 17:30:39It's not a binary tree.
  22219. 17:30:40Different use of the letter B, but it looks a little something like the trees
  22220. 17:30:44we've seen.
  22221. 17:30:45It's not binary because some of the nodes
  22222. 17:30:47might have more than two children or fewer,
  22223. 17:30:50but it's a very wide but relatively shallow tree.
  22224. 17:30:53It's not very tall.
  22225. 17:30:55And the upside of that is that if your data is stored in this tree,
  22226. 17:30:59the database can find it more quickly.
  22227. 17:31:01And the reason it took half a second, a third of a second to build the index
  22228. 17:31:06is because SQLite needed to take some non-zero amount of time
  22229. 17:31:10to just build up this tree in memory.
  22230. 17:31:12And it has algorithms for doing so based on alphabetization or other techniques.
  22231. 17:31:17But you spend a bit of time up front, a third of a second.
  22232. 17:31:20And then thereafter, wow.
  22233. 17:31:22Every subsequent query, if I keep doing it again and again,
  22234. 17:31:25is going to be crazy low, 0.000, maybe 0.001.
  22235. 17:31:29But an order of magnitude, a factor of 10 or 100 faster than it
  22236. 17:31:33previously was earlier.
  22237. 17:31:36So we have these indexes which allow us to get at data faster.
  22238. 17:31:39But what if we want to actually get data that's
  22239. 17:31:42now across these multiple tables?
  22240. 17:31:44How can we do that?
  22241. 17:31:45And how might these indices or indexes help further?
  22242. 17:31:48Well, it turns out there is a way that we've seen already
  22243. 17:31:52indirectly to join two tables together.
  22244. 17:31:54Previously, when I selected the ID of The Office,
  22245. 17:31:58and then I searched for it in the other table using select in a nested query,
  22246. 17:32:03I was joining two tables together.
  22247. 17:32:05And it turns out there's a couple of ways to do this.
  22248. 17:32:08Let's go ahead now and, for instance, find all of Steve Carell's TV shows.
  22249. 17:32:11Not just The Office but all of them, too.
  22250. 17:32:14Unfortunately, if we look at our schema, shows up here have no mention of TV--
  22251. 17:32:21oh, shows over here has no mention of the TV stars in them.
  22252. 17:32:27And people have no mention of shows.
  22253. 17:32:30We somehow need to use this table here to connect the two.
  22254. 17:32:34And this is called a join table, in the sense that using two integer columns--
  22255. 17:32:40it joins the two tables together logically.
  22256. 17:32:43And so if you're savvy enough with SQL, you can do what I did with my hands
  22257. 17:32:47earlier and like recombine tables by using these common IDs,
  22258. 17:32:51these integers together.
  22259. 17:32:52So let me do this.
  22260. 17:32:53Let me go ahead and figure out, step-by-step, Steve Carell's shows.
  22261. 17:32:58So how am I going to do this?
  22262. 17:32:59Well, if I select star from people, where name equals Steve Carell,
  22263. 17:33:04fortunately, there's only one of them.
  22264. 17:33:06So this gives me back his name, his ID, and his birth year.
  22265. 17:33:12But it's really only his ID that I care about.
  22266. 17:33:14Why?
  22267. 17:33:15Because in order to get back his shows, I need to link person ID with show ID.
  22268. 17:33:20So I need to know his ID number.
  22269. 17:33:22So what could I do with this?
  22270. 17:33:24Well, remember the schema and the stars table.
  22271. 17:33:29I've just gotten, from the people table, Steve Carell's ID.
  22272. 17:33:33I bet by transitivity I could now use his person ID, his ID,
  22273. 17:33:38to get back all of his show IDs.
  22274. 17:33:41And then once I've got all of his show IDs, I can take it one step further
  22275. 17:33:44and get back all of his shows' titles.
  22276. 17:33:46So the answer is actually English words and not just random, seemingly,
  22277. 17:33:50integers.
  22278. 17:33:51So let me go ahead and do this.
  22279. 17:33:52Let me, again, get Steve Carell's ID number, but not star.
  22280. 17:33:57Star represents everything.
  22281. 17:33:58It's a wildcard character in SQL.
  22282. 17:34:00Let me just select the ID of Steve Carell.
  22283. 17:34:03And that gives me back 136,797.
  22284. 17:34:06And it's only giving me back one value.
  22285. 17:34:08The thing called ID is just the column heading up above.
  22286. 17:34:12Now, suppose I want to select all of the show IDs
  22287. 17:34:16that Steve Carell is affiliated with.
  22288. 17:34:18Let me select Show ID from stars, where the person ID in stars
  22289. 17:34:25happens to equal Steve Carell's ID.
  22290. 17:34:28So again, I'm building up my answer in reverse and taking these baby steps.
  22291. 17:34:32On the right, in parentheses, I'm getting Steve Carell's ID.
  22292. 17:34:36On the left, I am now selecting all of the show IDs
  22293. 17:34:40that have some connection with that person ID in the stars table.
  22294. 17:34:44This answer, too, is not going to be that illuminating.
  22295. 17:34:47It's just a whole bunch of integers that have no meaning to me as a human.
  22296. 17:34:50But let's take this one step further.
  22297. 17:34:53And even though my code is getting long, I
  22298. 17:34:54could hit Enter and format it nicely, especially
  22299. 17:34:57if I were doing this in a code file.
  22300. 17:34:59But I'm just doing it interactively for now.
  22301. 17:35:00Let's now select all of the titles from the shows table,
  22302. 17:35:04where the ID of the show is in this following previous query.
  22303. 17:35:13So again, the query is getting long.
  22304. 17:35:15But notice, it's the third and last step.
  22305. 17:35:17Select title from the shows table, where the ID of the show
  22306. 17:35:21is in the list of all of the show IDs that
  22307. 17:35:23came back from the stars table searching for Steve Carell's person ID.
  22308. 17:35:27How did we get that person ID?
  22309. 17:35:28Let me scroll to the end.
  22310. 17:35:30Well, I selected, in my innermost parentheses, Steve Carell's own ID.
  22311. 17:35:36So now, when I hit Enter, voila.
  22312. 17:35:38I get all of Steve Carell's TV shows up until now.
  22313. 17:35:41And if I want to tidy this up further, I can use the same tricks as before.
  22314. 17:35:44Order by title, semicolon.
  22315. 17:35:47Now I've got it all alphabetized as before.
  22316. 17:35:50So again, with SQL comes the ability to search--
  22317. 17:35:53I mean, look how quickly we do this, 0.094 seconds
  22318. 17:35:56to search across three different tables to get back this answer.
  22319. 17:35:59But my data is now all neatly designed in individual tables,
  22320. 17:36:04which is going to be important now that the data set is so large.
  22321. 17:36:07But let me take this one step further.
  22322. 17:36:09Let me go ahead and do this.
  22323. 17:36:12Let me go ahead and point out that with this query,
  22324. 17:36:16notice that I'm searching on--
  22325. 17:36:20let's say I'm searching on a person ID here.
  22326. 17:36:24And at the end here, I'm searching on a name column here.
  22327. 17:36:27So let me actually go ahead and do this.
  22328. 17:36:30Let me go ahead and see if we can't speed this up.
  22329. 17:36:34This query at the moment takes 0.092 seconds.
  22330. 17:36:38Let's see if we can't speed this up further by just quickly creating
  22331. 17:36:41a few more of those B-trees in the databases memory.
  22332. 17:36:44Create an index called person index, and I'm going to do this on the stars table
  22333. 17:36:49on the person ID column.
  22334. 17:36:51Enter.
  22335. 17:36:52It's taking a moment, taking a moment.
  22336. 17:36:53That's almost a full second because that's a big table.
  22337. 17:36:56Let's create another index called show index on the stars table.
  22338. 17:37:00Why?
  22339. 17:37:00Because I want to search by the show ID also.
  22340. 17:37:03That was part of my big query.
  22341. 17:37:05Takes a moment.
  22342. 17:37:06OK, just more than about 2/3 of a second.
  22343. 17:37:09Now let's create one last one, another index called name index,
  22344. 17:37:11but I could call these things anything I want, on the people table.
  22345. 17:37:14Why?
  22346. 17:37:14Because I'm also searching on the name column.
  22347. 17:37:16So in short, I'm creating indexes on each
  22348. 17:37:19of the columns that are somehow involved in my search query,
  22349. 17:37:22going from one table to the other.
  22350. 17:37:25Now let's go back to the previous query, which, recall, took--
  22351. 17:37:32I think I erased it, 0.091.
  22352. 17:37:35All right.
  22353. 17:37:36Well, it was roughly this order of magnitude.
  22354. 17:37:37We're not seeing the data now.
  22355. 17:37:39But let me go ahead and run my original big query once.
  22356. 17:37:42And boom, we're down to almost nothing.
  22357. 17:37:45So again, creating these indexes in memory
  22358. 17:37:48has the effect of rapidly speeding up our computation time.
  22359. 17:37:52Now if you've ever used, for instance, the my.harvard course shopping tool
  22360. 17:37:56here on campus, or Yale's analogue, you might wonder, why is the thing so slow?
  22361. 17:38:00This could be one of the reasons why large data sets with thousands of rows,
  22362. 17:38:04thousands of courses tend to be slow, if,
  22363. 17:38:07and I'm only conjecturing, if the database isn't properly indexed.
  22364. 17:38:10If you're building your own web application
  22365. 17:38:12and you're finding that users are waiting and waiting,
  22366. 17:38:14and things are spinning and spinning, what might be among the problems?
  22367. 17:38:17Well, it could absolutely just be bad algorithms and bad code that you wrote.
  22368. 17:38:21Or it might be that you haven't thought about, well,
  22369. 17:38:23what column should be optimized for searches and filtration
  22370. 17:38:27like I've done here in order to speed up subsequent queries?
  22371. 17:38:31Again, from the outside in, we can only conjecture.
  22372. 17:38:33But ultimately, this is just one of the things that
  22373. 17:38:36explains performance problems as well.
  22374. 17:38:39All right, let's point out just a couple of final syntactic things,
  22375. 17:38:42and then we'll consider, bigger picture, some problems
  22376. 17:38:45that might arise in this world.
  22377. 17:38:47If these nested, nested queries start to get a little much,
  22378. 17:38:52there are other ways, just so you've seen it,
  22379. 17:38:54that you can execute similar logic in SQL.
  22380. 17:38:57For instance, if I know in advance that I
  22381. 17:38:59want to connect Steve Carell to his show IDs and to their titles,
  22382. 17:39:04we can do something more like this.
  22383. 17:39:06Select title from the people table, joined with the stars table on people
  22384. 17:39:17ID equals stars.personID.
  22385. 17:39:20So what am I doing?
  22386. 17:39:21New syntax.
  22387. 17:39:21And again, this is not something you'll have to memorize or ingrain right away.
  22388. 17:39:25But just so you've seen other approaches, select title from people
  22389. 17:39:29join stars.
  22390. 17:39:30This is an explicit way to say, take the people table in one hand, the stars
  22391. 17:39:35table in the other hand, and somehow join them
  22392. 17:39:37as I keep doing with my fingertips here.
  22393. 17:39:39How to join them?
  22394. 17:39:40Join them so that the people, the ID column in the people table lines up
  22395. 17:39:45with the person ID in the stars table.
  22396. 17:39:48But that's not quite everything.
  22397. 17:39:50I could also say, join further on the shows table,
  22398. 17:39:54where the stars show ID equals the shows ID column.
  22399. 17:40:00So what am I doing here?
  22400. 17:40:01That's saying, go further and join the stars table with the show's table,
  22401. 17:40:11joining the show ID column with the ID column.
  22402. 17:40:14Again, this starts to get a little messy to think about.
  22403. 17:40:17But now I can just say, where name equals, quote, unquote, "Steve Carell."
  22404. 17:40:21I can do in one query what previously took me three nested queries
  22405. 17:40:24and get back the same answers.
  22406. 17:40:25And I can still add in my order by title to get back the result.
  22407. 17:40:30And if I do this a little more neatly, let me type this out a little
  22408. 17:40:35differently.
  22409. 17:40:36Let me type this out by adding a new line-- ah, I can't do that here.
  22410. 17:40:41I'm going to leave it alone for now.
  22411. 17:40:43We can type it on multiple lines in other contexts.
  22412. 17:40:46And let me do one last thing.
  22413. 17:40:49Do I want to show that?
  22414. 17:40:50I'm going to show it, but this is not something
  22415. 17:40:52you should ingrain just yet either.
  22416. 17:40:53Select title from people, stars, and shows.
  22417. 17:40:56If you know in advance that you want to do something with all three tables,
  22418. 17:41:00you can just enumerate them, one table name after the other.
  22419. 17:41:03And then you can say where people.ID equals stars.personID.
  22420. 17:41:08And now I'm hitting Enter so that it formats
  22421. 17:41:10a little more readably on my screen.
  22422. 17:41:12And stars.showID equals shows.ID, and lastly, name equals Steve Carell.
  22423. 17:41:20In short, you specify that you want to select data from all three
  22424. 17:41:25of these tables.
  22425. 17:41:26And then you tell the database how to combine foreign keys with primary keys,
  22426. 17:41:31that is, the columns that have those integers in common.
  22427. 17:41:35If I hit Enter now, I get the same exact results, ever
  22428. 17:41:38more so if I also add in an order by title.
  22429. 17:41:41Oops.
  22430. 17:41:43All right.
  22431. 17:41:43That's why I didn't want to do this earlier.
  22432. 17:41:45I have to go back through my history multiple times to actually get back
  22433. 17:41:48the multi-line query this time.
  22434. 17:41:49All right.
  22435. 17:41:50That was a lot all at once.
  22436. 17:41:52But this is only to say that, even as we make the design of the data
  22437. 17:41:56more sophisticated, and we put some of it over here, some of it
  22438. 17:41:59over here, some of it over here so as to avoid duplication of data, weird hacks
  22439. 17:42:03like putting commas in the data, we can still get back all of the answers
  22440. 17:42:07that we might want across these several tables.
  22441. 17:42:09And using indexes, we can significantly speed up these processes
  22442. 17:42:13so as to handle 10 times as many, a 100 times as many users
  22443. 17:42:17on the same actual database.
  22444. 17:42:19There is going to be a downside.
  22445. 17:42:20And thinking back to our discussion of algorithms and data
  22446. 17:42:22structures in past weeks, what might be a downside of creating these indexes?
  22447. 17:42:27Because as of now, I created four separate indexes on the name column,
  22448. 17:42:31the title column, and some other columns, too.
  22449. 17:42:34Why wouldn't I just go ahead and index everything
  22450. 17:42:37if it's clearly speeding things up?
  22451. 17:42:39Memory, so space.
  22452. 17:42:41Any time you're starting to benefit time wise in computer science,
  22453. 17:42:44odds are you're sacrificing space, or vice versa.
  22454. 17:42:47And probably indexing absolutely everything is a little dumb
  22455. 17:42:50because you're going to waste way more space than you might actually need.
  22456. 17:42:54So figuring out where the right inflection point is
  22457. 17:42:56is part of the process of designing and just getting better at these things.
  22458. 17:43:01Now unfortunately, a whole lot of things can go wrong in this world,
  22459. 17:43:06and they continue to in the real world with people using SQL databases.
  22460. 17:43:10And in fact, here on out, if you're reading
  22461. 17:43:12something technical about SQL databases, and websites being hacked in some form,
  22462. 17:43:16and passwords leaking out, unfortunately, all too often
  22463. 17:43:20it is because of what are called SQL injection attacks.
  22464. 17:43:22And just to give you a sense now to counterbalance,
  22465. 17:43:24maybe [INAUDIBLE] enthusiasm for like, oh, that
  22466. 17:43:26was neat how we can do things so quickly.
  22467. 17:43:28With great power comes responsibility in this world, too.
  22468. 17:43:32And so many people introduce bugs into their code
  22469. 17:43:34by not quite appreciating how it is the data is getting into your application.
  22470. 17:43:42So what do I mean by that?
  22471. 17:43:43Here, for instance, is a typical login screen for Yale.
  22472. 17:43:46And here's the analogue for Harvard where you're prompted,
  22473. 17:43:49every day probably, for your username and your password,
  22474. 17:43:51your email address and your password here.
  22475. 17:43:53Suppose, though, that behind this login page,
  22476. 17:43:57whether Harvard's or Yale's, there's some website.
  22477. 17:44:00And that website is using SQL underneath the hood
  22478. 17:44:03to store all of the Harvard or Yale people's
  22479. 17:44:06usernames, passwords, ID numbers, courses, transcripts,
  22480. 17:44:09all of that stuff.
  22481. 17:44:10So there's a SQL database underneath the website.
  22482. 17:44:12Well, what might go wrong with this process?
  22483. 17:44:15Unfortunately, there's some special syntax in SQL
  22484. 17:44:18just like there is in C and Python.
  22485. 17:44:19For instance, there are comments in SQL, too.
  22486. 17:44:22If you do two hyphens, dash, dash, that's a comment in SQL.
  22487. 17:44:26And if you, the programmer, aren't sufficiently distrustful of your users,
  22488. 17:44:31such that you defend against potentially adversarial attacks,
  22489. 17:44:34you might do something like this.
  22490. 17:44:36Suppose that I somewhat maliciously or curiously log in
  22491. 17:44:41by typing my username, [email protected], and then maybe
  22492. 17:44:44a single quote and a dash, dash.
  22493. 17:44:46Why?
  22494. 17:44:47Because I'm trying to suss out if there is a vulnerability here
  22495. 17:44:50to a SQL injection attack.
  22496. 17:44:51Do not do this in general.
  22497. 17:44:53But if I were the owner of the website trying to see if I've made any mistake,
  22498. 17:44:56I might try using potentially dangerous characters in my input.
  22499. 17:45:00Dangerous how?
  22500. 17:45:01Because single quote is used for quoting things in SQL, as we've seen--
  22501. 17:45:05single quotes or double quotes.
  22502. 17:45:07Dash, dash, I claim now, is used for commenting.
  22503. 17:45:10But let's now imagine what the code underneath the hood
  22504. 17:45:13might be for something like Yale's login or Harvard's login.
  22505. 17:45:17What if it's code that looks like this?
  22506. 17:45:19So let me read it from left to right.
  22507. 17:45:21Suppose that they are using something like CS50's own execute function,
  22508. 17:45:26and they've got some SQL typed into the website that
  22509. 17:45:28says select star from users, where username equals this,
  22510. 17:45:32and password equals that.
  22511. 17:45:34And they're plugging in username and password.
  22512. 17:45:37So what am I doing here?
  22513. 17:45:38Well, when the user types their username password, hits Enter,
  22514. 17:45:41I probably want to select that user from my database
  22515. 17:45:44to see if the username and passwords match.
  22516. 17:45:46So the underlying SQL might be, select star
  22517. 17:45:49from users, where username equals question mark,
  22518. 17:45:51and password equals question mark.
  22519. 17:45:52Users is the table.
  22520. 17:45:53One column is username.
  22521. 17:45:54One column is password.
  22522. 17:45:56All right.
  22523. 17:45:57And if we get back one row, presumably [email protected]
  22524. 17:46:02exists with that password.
  22525. 17:46:04We should let him proceed from there on out.
  22526. 17:46:06So that's some pseudo code, if you will, for this scenario.
  22527. 17:46:10What if, though, this code is not as well written as it currently
  22528. 17:46:14is, and isn't using question marks?
  22529. 17:46:16So the question mark syntax is a fairly common SQL thing,
  22530. 17:46:20where the question marks are used as placeholders,
  22531. 17:46:22just like in printf, percent S was.
  22532. 17:46:24But this function, db.execute from CS50's library
  22533. 17:46:28and third-party libraries as well, is also
  22534. 17:46:30doing some good stuff with these question marks,
  22535. 17:46:33and defending against the following attack.
  22536. 17:46:35Suppose that you were not using a third-party library like ours
  22537. 17:46:38and you were just manually constructing your SQL queries like this.
  22538. 17:46:41You were to do something like this instead using an f-string in Python.
  22539. 17:46:45You're comfortable with format strings now.
  22540. 17:46:47You've gotten into the habit of using curly braces and plugging in values.
  22541. 17:46:50Suppose that you, the aspiring programmer,
  22542. 17:46:52is just using techniques that you've been taught.
  22543. 17:46:55So you have an f-string with select star from users,
  22544. 17:46:58where username equals, quote, unquote, "username" in curly braces.
  22545. 17:47:01And password equals, quote, unquote, "password" in curly braces.
  22546. 17:47:06As of what, two weeks ago, this was perfectly
  22547. 17:47:09legitimate technique in Python to plug in values into a string.
  22548. 17:47:14But notice if you are using single quotes yourself
  22549. 17:47:18and the user has typed in single quotes to their input, what
  22550. 17:47:24could go wrong here?
  22551. 17:47:25Where are we going with this if you're just blindly plugging user input
  22552. 17:47:29into your own prepared string of text?
  22553. 17:47:33Yeah?
  22554. 17:47:34AUDIENCE: [INAUDIBLE]
  22555. 17:47:40DAVID J. MALAN: Yeah.
  22556. 17:47:40Worst case, they could insert what is actually SQL code into your database
  22557. 17:47:46as follows.
  22558. 17:47:47Generally speaking, if you're using special syntax like single quotes
  22559. 17:47:50to surround the user's input, you'd better
  22560. 17:47:52hope that they don't have an apostrophe in their name.
  22561. 17:47:54Or you better hope that they don't type a single quote as well.
  22562. 17:47:57Because what if their single quote finishes your single quote instead,
  22563. 17:48:01and then the rest of this is somehow ignored?
  22564. 17:48:03Well, let's consider how this might happen.
  22565. 17:48:04Let me go ahead in here.
  22566. 17:48:05This got a little blurry here, but let me
  22567. 17:48:08plug in here-- wow, that looks awful.
  22568. 17:48:10Let me fix the red.
  22569. 17:48:13Just change this to white so it's more readable.
  22570. 17:48:15What happens if the user does this instead?
  22571. 17:48:22They type in, like I did into the screenshot,
  22572. 17:48:24'[email protected],' single quote, dash, dash.
  22573. 17:48:28What has just happened logically, even though we've
  22574. 17:48:30only just begun with SQL today?
  22575. 17:48:32Well, select star from users, where username equals [email protected], end
  22576. 17:48:37quote.
  22577. 17:48:38What's bad about the rest of this?
  22578. 17:48:42Dash, dash, I claim, means a comment, which
  22579. 17:48:45means my color coding is going to be a little blurry again.
  22580. 17:48:47But everything after the dash, dash is just ignored.
  22581. 17:48:50The logic, then, of the SQL query, then, is
  22582. 17:48:52to just say, select [email protected] from the database,
  22583. 17:48:56not even checking the password anymore.
  22584. 17:48:58Therefore, you will get back at least one row.
  22585. 17:49:01So length of rows will equal 1, and so presumably the rest of the pseudo code
  22586. 17:49:06logs the user in, gives them access to my my.harvard account,
  22587. 17:49:09or whatever it is.
  22588. 17:49:10And they've pretended to be me simply by using a single quote and a dash,
  22589. 17:49:15dash in the username field.
  22590. 17:49:17Again, please don't go start doing this later today
  22591. 17:49:19on Harvard, Yale, or other websites.
  22592. 17:49:21But it could be as simple as that.
  22593. 17:49:23Why?
  22594. 17:49:23Because the programmer practiced what they
  22595. 17:49:25were taught, which was just to use curly braces to plug in,
  22596. 17:49:29in f-strings, values.
  22597. 17:49:30But if you don't understand how the user's input is going to be used,
  22598. 17:49:33and if you don't distrust your users fundamentally, for every good person
  22599. 17:49:37out there there's going to be, unfortunately,
  22600. 17:49:39some adversary who just wants to try to find fault in your code or hack
  22601. 17:49:44into your data set.
  22602. 17:49:45This is what's known as a SQL injection attack,
  22603. 17:49:48because the user can type something that happens to be or look like SQL,
  22604. 17:49:52and trick your database into doing something it didn't intend to,
  22605. 17:49:56like, for instance, logging the user in.
  22606. 17:50:00Worst case, they could even do something else.
  22607. 17:50:02Maybe the user types a semicolon, then the word drop, or the word update.
  22608. 17:50:06You could imagine doing semicolon update table grades, where
  22609. 17:50:10name equals Malan, and set the grade equal to A instead of B,
  22610. 17:50:14or something like that.
  22611. 17:50:16The ability to inject SQL into the database
  22612. 17:50:18means you can do anything you want with the data set, either constructively,
  22613. 17:50:22or worse, destructively.
  22614. 17:50:25And now, just a quick, little cartoon that should now make sense.
  22615. 17:50:34OK, to, like, one of us, two of us.
  22616. 17:50:38Awkwardly somewhat funny.
  22617. 17:50:39All right, so let's move on to one last condition.
  22618. 17:50:41There's one other problem that can go awry here.
  22619. 17:50:44Oh, and I should explain this.
  22620. 17:50:45So this is an allusion to the son, Robert, having typed in semicolon.
  22621. 17:50:50The word drop, table, students, and doing some of the same technique.
  22622. 17:50:54This is humor that only CS people would understand
  22623. 17:50:56because it's the mom realizing, oh, her son's doing a SQL injection
  22624. 17:51:00attack onto the database.
  22625. 17:51:01Less funny when you explain it, but once you notice the syntax, that's all this
  22626. 17:51:04is an allusion to.
  22627. 17:51:06All right.
  22628. 17:51:06So one final threat, now that you are graduating
  22629. 17:51:10to the world of proper databases and away from CSV files alone.
  22630. 17:51:14Things can go wrong when using databases,
  22631. 17:51:17and honestly, even using CSV files if you have multiple users.
  22632. 17:51:21And thus far, you and I have had the luxury
  22633. 17:51:22in almost every program we've written that it's just me using my code.
  22634. 17:51:25It's just you using your code.
  22635. 17:51:27And even if your teaching fellow or TA is using it, probably
  22636. 17:51:30not at the same time.
  22637. 17:51:31But the world gets interesting if you start putting your code on phones,
  22638. 17:51:36on websites, such that now you might have two users literally trying
  22639. 17:51:40to log in at the same time, literally clicking a button
  22640. 17:51:42at the same, or nearly the same time.
  22641. 17:51:44What happens, then, if a computer is trying
  22642. 17:51:47to handle requests from two different people at once,
  22643. 17:51:50as might happen all the time on a website?
  22644. 17:51:52You might get what are called race conditions.
  22645. 17:51:54And this is a problem in computing in general, not just with SQL, not just
  22646. 17:51:58with Python, really just any time you have shared data,
  22647. 17:52:02like a database, as follows.
  22648. 17:52:04This apparently is one of the most liked Instagram posts ever.
  22649. 17:52:08It is literally just a picture of an egg.
  22650. 17:52:11Has anyone clicked on this egg?
  22651. 17:52:12Like, a couple?
  22652. 17:52:13Oh, OK.
  22653. 17:52:14Wow.
  22654. 17:52:14All right, so yes.
  22655. 17:52:15So go search for this photo if you'd like to add to the likes on Instagram.
  22656. 17:52:19The account is world_record_egg.
  22657. 17:52:21This is just a screenshot of Instagram of that picture of an egg.
  22658. 17:52:24If you're in the habit of using Instagram,
  22659. 17:52:25or like any social media site, there's some equivalent of a like button
  22660. 17:52:28or a heart button these days.
  22661. 17:52:30And that's actually a really hard problem.
  22662. 17:52:32Such a simple idea to count the number of likes something
  22663. 17:52:35has, but that means someone has to click on it.
  22664. 17:52:38Your code has to detect the click.
  22665. 17:52:40Your code has to update the database, and then do it again and again,
  22666. 17:52:43even if multiple people are perhaps right now clicking on that same egg.
  22667. 17:52:48And unfortunately, bad things can happen if two people try to do something
  22668. 17:52:53at the same time on a computer.
  22669. 17:52:55How might this happen?
  22670. 17:52:57So here's some more code, half pseudocode, half Python code here,
  22671. 17:53:01as follows.
  22672. 17:53:01Suppose that what happens when you, literally, right now, maybe click
  22673. 17:53:05on the like button on the Instagram post.
  22674. 17:53:08Suppose that code, like the following, is executed on Facebook servers.
  22675. 17:53:13db.execute of select likes from posts where ID equals question mark.
  22676. 17:53:19All right.
  22677. 17:53:20So what am I assuming here?
  22678. 17:53:22I'm assuming that that photograph has a unique ID.
  22679. 17:53:24It's some big integer, whatever it was, randomly assigned.
  22680. 17:53:28I'm assuming that when you click on the heart
  22681. 17:53:30the unique ID is somehow sent to Instagram servers
  22682. 17:53:33so that their code can call it ID.
  22683. 17:53:36And I'm assuming that Instagram is using its SQL database
  22684. 17:53:39and selecting, from a posts table, the current number of likes
  22685. 17:53:43of that egg for that given ID number.
  22686. 17:53:46Why?
  22687. 17:53:47Because I need to know how many likes it already has if I want to add one to it
  22688. 17:53:50and then update the database.
  22689. 17:53:51I need to select the data, then I need to update the data here.
  22690. 17:53:55All right.
  22691. 17:53:55So in some Python code here, let's store, in a variable called
  22692. 17:53:59likes, whatever comes back in the first row from the likes column.
  22693. 17:54:03Again, this is new syntax specific to our library,
  22694. 17:54:06but a common way of getting back first row and the column called
  22695. 17:54:09likes therein.
  22696. 17:54:10So at this point in the story, likes is storing
  22697. 17:54:12the total number of likes, in the millions or whatever it is,
  22698. 17:54:14of that particular egg.
  22699. 17:54:15Then I do this.
  22700. 17:54:17Execute update posts, set the number of likes
  22701. 17:54:21equal to this value, where the ID of the post equals this value.
  22702. 17:54:25What do I want to update the likes to?
  22703. 17:54:27Whatever likes currently is plus 1, and then plugging in the ID.
  22704. 17:54:31So a simple idea, right?
  22705. 17:54:33I'm checking the value of the likes, and maybe it's 10.
  22706. 17:54:37I'm changing 10 to 11 and then updating the table.
  22707. 17:54:40But a problem can arise if two people have
  22708. 17:54:43clicked on that egg at roughly the same time, or literally, the same time.
  22709. 17:54:48Why is that?
  22710. 17:54:49Well, in the world of databases and servers,
  22711. 17:54:52and the Instagrams of the world have thousands of physical servers nowadays.
  22712. 17:54:56So they can support millions, billions even, of users nowadays.
  22713. 17:55:00What can go wrong?
  22714. 17:55:02Well, typically code like this is not what we'll call atomic.
  22715. 17:55:05To be atomic means that it all executes together or not at all.
  22716. 17:55:09Rather, code typically is executed, as you might imagine, line by line.
  22717. 17:55:14And if your code is running on a server that multiple people have access to,
  22718. 17:55:18which is absolutely the case for an app like Instagram,
  22719. 17:55:20if you and I click on the heart at roughly the same time,
  22720. 17:55:23for efficiency, the computer, the server, owned by Instagram,
  22721. 17:55:27might execute this line of code for me.
  22722. 17:55:29Then it might execute this line of code for you.
  22723. 17:55:31Then this line of code for me, then this line of code for you,
  22724. 17:55:34then this line of code for me, then this line of code for you.
  22725. 17:55:37That is to say, our queries might get intermingled chronologically.
  22726. 17:55:41Because it'd be a little obnoxious if, when you're using Instagram,
  22727. 17:55:44I'm blocked out while you're interacting with the site.
  22728. 17:55:47It'd be a lot nicer for efficiency and fairness if somehow they
  22729. 17:55:50do a little bit of work for me, a little bit of work for you,
  22730. 17:55:52and back and forth, and back and forth, equitably on the server.
  22731. 17:55:55So that's what typically happens by default. These lines of code
  22732. 17:55:58get executed independently.
  22733. 17:56:00And they can happen in alternating order with other users.
  22734. 17:56:05You can get them combined like this.
  22735. 17:56:07Same order top to bottom, but other things might happen in between.
  22736. 17:56:11So suppose that the number of likes at the very beginning was 10.
  22737. 17:56:15And suppose that Carter and I both click on that egg at roughly the same time.
  22738. 17:56:19And suppose this line of code gets executed for me,
  22739. 17:56:21and that gives me a value in likes, ultimately, of 10.
  22740. 17:56:25Suppose, then, that the computer takes a break from dealing with my request,
  22741. 17:56:28does the same code for Carter, and gets back
  22742. 17:56:31what value for the current number of likes?
  22743. 17:56:33Also 10 for Carter.
  22744. 17:56:34Because mine has not been recorded yet.
  22745. 17:56:36At this point in the story, somewhere in the computer's memory
  22746. 17:56:39there's a likes variable for me, storing 10.
  22747. 17:56:41There's a likes variable storing 10 for Carter.
  22748. 17:56:44Then this line of code executes for me.
  22749. 17:56:46It updates the database to be likes plus 1, which stores 11 in the database.
  22750. 17:56:50Then Carter's code is executed, updating the same row in the database
  22751. 17:56:55to 11, unfortunately.
  22752. 17:56:59Because his value of likes happened to be the same value of mine.
  22753. 17:57:03And so the metaphor here, that if we had a refrigerator on stage we would
  22754. 17:57:06actually act out, is something that was taught to me years ago in an operating
  22755. 17:57:10systems class, whereby the most similar analogue in the real world would be
  22756. 17:57:15if you've got a mini fridge in your dorm room.
  22757. 17:57:17And one of you and your roommates comes home, opens the fridge, and realizes,
  22758. 17:57:23oh, we're out of milk, was how the story went in my day.
  22759. 17:57:26So you close the refrigerator, and you walk across the street, go to CVS,
  22760. 17:57:30and get in line to buy some milk.
  22761. 17:57:31Meanwhile, your roommate comes home.
  22762. 17:57:33They, too, inspect the state of your refrigerator, a.k.a., a variable,
  22763. 17:57:38open the door, and realizes, oh, we're out of milk.
  22764. 17:57:40I'll go get more milk.
  22765. 17:57:41Close the fridge, go across the street, and head
  22766. 17:57:43to maybe a different store, or the line is long enough
  22767. 17:57:45that you don't see each other at the store.
  22768. 17:57:47So long story short, you both eventually get home, open the door, and damn it,
  22769. 17:57:51now there's milk from your other roommate
  22770. 17:57:52there because you both made a decision on this
  22771. 17:57:56based on the state of a variable that you independently examined.
  22772. 17:58:01And you didn't somehow communicate.
  22773. 17:58:03Now in the real world, this is absolutely solvable.
  22774. 17:58:05How would you fix this or avoid this problem in the real world?
  22775. 17:58:09Literally, own roommate, own fridge.
  22776. 17:58:11AUDIENCE: Text your roommate [INAUDIBLE]..
  22777. 17:58:13DAVID J. MALAN: Perfect.
  22778. 17:58:14Let them know, so somehow communicate.
  22779. 17:58:15And in fact, the terminology here would be multiple threads
  22780. 17:58:18can somehow intercommunicate by having shared state,
  22781. 17:58:20like the iMessage thread on your phone.
  22782. 17:58:22You could leave a note.
  22783. 17:58:23You could, more dramatically, lock the refrigerator somehow,
  22784. 17:58:26thereby making the milk purchasing process atomic.
  22785. 17:58:30The fundamental problem is that for efficiency, again,
  22786. 17:58:33computers tend to intermingle logic that needs
  22787. 17:58:37to happen when it's happening across multiple users just for fairness' sake,
  22788. 17:58:41for scheduling sake.
  22789. 17:58:42You need to make sure that all three of these lines of code
  22790. 17:58:45execute for me, and then for Carter, and then for you
  22791. 17:58:48if you want to ensure that this count is correct.
  22792. 17:58:51And for years, when social media was first getting off the ground,
  22793. 17:58:54this was a super hard problem.
  22794. 17:58:56Twitter used to go down all of the time, and tweets,
  22795. 17:58:59and retweets were a thing that were similarly happening
  22796. 17:59:01with a very high frequency.
  22797. 17:59:02These are hard problems to solve.
  22798. 17:59:04And thankfully, there are solutions.
  22799. 17:59:06And we won't get into the weeds of how you might use these things,
  22800. 17:59:08but know that there are solutions in the form of things
  22801. 17:59:11called locks, which I use that word deliberately with the fridge.
  22802. 17:59:14Software locks can allow you to protect a variable so no one else can
  22803. 17:59:18look at it until you're done with it.
  22804. 17:59:20There are things called transactions, which
  22805. 17:59:23allow you to do the equivalent of sending a message to, or really locking
  22806. 17:59:26out your roommate from accessing that same variable, too,
  22807. 17:59:29but for slightly less amount of time.
  22808. 17:59:32There are solutions to these problems.
  22809. 17:59:34So for instance, in Python, the same code now in green
  22810. 17:59:37might look a little something like this.
  22811. 17:59:39When you know that something has to happen all at once,
  22812. 17:59:42altogether, you first begin a transaction, and you do your thing,
  22813. 17:59:46and then you commit the transaction at the very end.
  22814. 17:59:49Here, too, though, there's going to be a downside.
  22815. 17:59:51Typically, the more you use transactions in this way,
  22816. 17:59:55potentially the higher the probability is
  22817. 17:59:56that you're going to box someone out or make Carter's request a little slower.
  22818. 18:00:00Why?
  22819. 18:00:01Because we can't interact at the same time.
  22820. 18:00:02Or you might make his request fail if he tries to update
  22821. 18:00:05something that's already been updated.
  22822. 18:00:07So you generally want to have as few lines of code
  22823. 18:00:10together in between these transactions so that you get in and you get out.
  22824. 18:00:13And you go to CVS and you get back really fast so as to not
  22825. 18:00:16cause these kind of performance things.
  22826. 18:00:17So things indeed escalated quickly today.
  22827. 18:00:20The original goal was just to solve problems using a different language
  22828. 18:00:23more effectively than Python.
  22829. 18:00:24But as soon as you have these more powerful techniques,
  22830. 18:00:27a whole new set of problems arises.
  22831. 18:00:28Takes practice to get comfortable with.
  22832. 18:00:30But ultimately, this is all leading us toward the introduction next week
  22833. 18:00:34of web programming with HTML, CSS, and some JavaScript.
  22834. 18:00:37The week after, bringing Python and SQL back into the mix.
  22835. 18:00:40So that by term's end, we've really now used
  22836. 18:00:42all of these different languages for what they're best at.
  22837. 18:00:45And over the next few weeks, the goal is to make sure you're understanding
  22838. 18:00:48and comfortable with what each of these things is good and bad for.
  22839. 18:00:51Let's go ahead and wrap here.
  22840. 18:00:52I'll stick around for questions.
  22841. 18:00:53We'll see you next time.
  22842. 18:00:56[MUSIC PLAYING]
  22843. 18:02:13SPEAKER 1: All right.
  22844. 18:02:15This is CS50, and this is already week 8.
  22845. 18:02:19And if we think back to the past several weeks now,
  22846. 18:02:21recall that things started pretty interestingly, pretty interactively,
  22847. 18:02:24in like week 0, when we were using Scratch,
  22848. 18:02:27because with Scratch we had a GUI, a graphical user interface.
  22849. 18:02:29So even as we explored variables and loops and conditionals and all of that,
  22850. 18:02:33you had kind of a fun environment in which to express those ideas.
  22851. 18:02:36And then in week 1, we sort of took a lot
  22852. 18:02:37of that away, when we introduced C, and a terminal window, and a command line,
  22853. 18:02:41because now, all of your programs became very textual, very keyboard-based,
  22854. 18:02:46and gone was the mouse, the animations, the menus, and so forth.
  22855. 18:02:49And so now, fast forward to week 8, we're
  22856. 18:02:51going to bring those kinds of user interface, UI, elements back,
  22857. 18:02:54in the form of web programming.
  22858. 18:02:56And this goes beyond just laying out websites.
  22859. 18:02:58This will, to this week and next week, combine elements of the back-end server
  22860. 18:03:03stuff that we've been doing for the past several weeks,
  22861. 18:03:05using Python, using SQL, and now introducing
  22862. 18:03:07a couple of other languages, on the so-called client side,
  22863. 18:03:10on your own Mac, your own PC, your own phone, that's going
  22864. 18:03:13to talk to those back-end services.
  22865. 18:03:15So indeed, at this end of CS50, does everything rather
  22866. 18:03:18come together into a user interface that's just super familiar.
  22867. 18:03:22All of us are on our phones, desktops, laptops, every day.
  22868. 18:03:24And increasingly, even the mobile apps that you all are using
  22869. 18:03:28are implemented, not necessarily in languages like Swift or Java,
  22870. 18:03:32if you're familiar with those, but with languages
  22871. 18:03:34called HTML, CSS, and JavaScript, which we'll focus on here today.
  22872. 18:03:38But before we do that, let's provide a foundation on which these apps can run,
  22873. 18:03:43because indeed, we'll start to look underneath the hood of how the internet
  22874. 18:03:46itself works, albeit quickly, so that we have kind of a mental model for where
  22875. 18:03:51all of this code is running, how you can troubleshoot issues, and how,
  22876. 18:03:54really, ultimately, after CS50, you can learn, by just
  22877. 18:03:56poking around other actual websites.
  22878. 18:03:59So the internet, we're all on it.
  22879. 18:04:00Literally, right now, what is it, in your own words?
  22880. 18:04:05What is the internet?
  22881. 18:04:07It's this utility nowadays, that we all rather take for granted.
  22882. 18:04:10How would you describe it?
  22883. 18:04:11AUDIENCE: Big storage.
  22884. 18:04:12SPEAKER 1: OK, big storage, and indeed, that's
  22885. 18:04:14how the cloud is described, which is kind of an abstraction if you will,
  22886. 18:04:18for a whole lot of wires and cables and hardware.
  22887. 18:04:21And the internet, other formulations of the term, how else?
  22888. 18:04:24AUDIENCE: Bunch of data that we can reach.
  22889. 18:04:26SPEAKER 1: OK, a bunch of data that we can all
  22890. 18:04:28reach, by way of being interconnected somehow with wires or wirelessly.
  22891. 18:04:32And so really, the internet, too, is a hardware thing.
  22892. 18:04:35There's a whole lot of servers out there, that are somehow interconnected,
  22893. 18:04:38via physical cables, via internet service providers,
  22894. 18:04:41via wireless connectivity, and the like.
  22895. 18:04:43And once you start to have networks of networks of networks,
  22896. 18:04:46do you get the internet.
  22897. 18:04:47Indeed, Harvard has its own network and Yale has its own network,
  22898. 18:04:50and your own home probably has its own network.
  22899. 18:04:52But once you start connecting those networks,
  22900. 18:04:54do you get the interconnected network that is the internet as we now know it?
  22901. 18:04:58So there's this whole alphabet soup that goes
  22902. 18:05:01with the internet, some of whose acronyms and terms
  22903. 18:05:03you've probably seen before.
  22904. 18:05:04But let's at least peel back some of those layers
  22905. 18:05:06and consider what some of the building blocks are.
  22906. 18:05:08So here's a picture of the internet before it was known as the internet,
  22907. 18:05:11back in 1969, when it was something called
  22908. 18:05:14ARPANET, from the Advanced Research Projects Agency.
  22909. 18:05:17And the intent, originally, was just to Interconnect a few universities here
  22910. 18:05:20in Utah and California, literally servers, or computers, in each
  22911. 18:05:25of those areas, somehow interconnected with wires,
  22912. 18:05:27so that people could start to share data.
  22913. 18:05:29A year later, it expanded to include MIT and Harvard and others.
  22914. 18:05:33And now fast forward to today, you have a huge number
  22915. 18:05:36of systems around the world that are on this same network.
  22916. 18:05:39And, in fact, if I just pull up a web page
  22917. 18:05:41here, that's sort of constantly changing,
  22918. 18:05:44a visualization of the internet as it might now be today, this here,
  22919. 18:05:48in the abstract, all of these lines and interconnections
  22920. 18:05:52represent just how interconnected the world is today.
  22921. 18:05:56And it just means that there's all the more servers, all the more cabling,
  22922. 18:05:59all of the more hardware giving us this underlying infrastructure.
  22923. 18:06:02But if we focus, really, on just these nodes, these individual dots,
  22924. 18:06:07whether back in 1970, or now in 2021, each of these dots you can think of as,
  22925. 18:06:11yes, a server, but a certain type of server, namely known as a router.
  22926. 18:06:15And a router, as the name implies, just routes
  22927. 18:06:17data left to right, top to bottom, from one point to another.
  22928. 18:06:21And so there's all these servers here on campus at Harvard, on Yale's campus,
  22929. 18:06:25in Comcast's network, Verizon's network, your own home network,
  22930. 18:06:28you have your own routers out there, whose purpose in life
  22931. 18:06:31is to take in data and then decide, should I send it this way,
  22932. 18:06:34or this way, or this way, so to speak, assuming there are
  22933. 18:06:36multiple options with multiple cables.
  22934. 18:06:38You, in your home, probably have just one cable coming in or going out.
  22935. 18:06:41But certainly, if you're a place like Harvard or Yale or Comcast or the like,
  22936. 18:06:46there's probably a whole bunch of interconnections
  22937. 18:06:49that the data can then travel across ultimately.
  22938. 18:06:51So how do we get data among these routers?
  22939. 18:06:54For instance, if you want to send an email to someone
  22940. 18:06:57at Stanford, in California, from here, on the East Coast,
  22941. 18:07:00or if you want to visit www.stanford.edu, how does your laptop,
  22942. 18:07:04your phone, your desktop, actually get data from point A to point B?
  22943. 18:07:08Well, essentially, your laptop or phone knows
  22944. 18:07:12when it boots up at the beginning of the day, what the local router is, what
  22945. 18:07:16the address of that local router is.
  22946. 18:07:17So if you want to send an email from my laptop over here,
  22947. 18:07:20my laptop is essentially going to hand it to the nearest Harvard router.
  22948. 18:07:23And then, from there, I don't know, I don't care
  22949. 18:07:25how it gets the rest of the distance.
  22950. 18:07:27But hopefully, within some small number of steps later,
  22951. 18:07:29Harvard's router is going to send it to maybe Boston's router
  22952. 18:07:32is going to send it to California's router is going
  22953. 18:07:34to send it to Stanford's router, until finally it reaches Stanford's email
  22954. 18:07:37server.
  22955. 18:07:38And we can depict this, actually, how about a bit playfully.
  22956. 18:07:41Thankfully, the course's staff kindly volunteered
  22957. 18:07:44to create a visualization for this, using a familiar technology.
  22958. 18:07:48So here we have some of our TFs and TAs and CAs present and past.
  22959. 18:07:52Let me go ahead and full screen this window here.
  22960. 18:07:55Give me just a moment to pull it up on my screen here.
  22961. 18:07:58And we'll consider what happens if we want to send a packet of information
  22962. 18:08:03from one person or router, namely Phyllis in this case,
  22963. 18:08:07in the bottom right hand corner, up to Brian, in this case,
  22964. 18:08:10in the top left hand corner.
  22965. 18:08:11So each of the staff members here represents exactly one
  22966. 18:08:14of these routers on the internet.
  22967. 18:08:17[MUSIC PLAYING]
  22968. 18:08:44[APPLAUSE]
  22969. 18:08:46The applause is appreciated.
  22970. 18:08:47It actually took us a significant number of attempts
  22971. 18:08:49to get that ultimately right.
  22972. 18:08:51So when, what was it the staff were all passing here?
  22973. 18:08:54Here we have just, physically, what it was the staff were passing around.
  22974. 18:08:57So Phyllis started with an envelope, inside of which
  22975. 18:08:59was that email, presumably, on the East Coast,
  22976. 18:09:01and she wanted to send it to Brian on the West Coast, top left hand corner.
  22977. 18:09:05And so she had all of these different options, different connections,
  22978. 18:09:08between her and point B, namely Brian.
  22979. 18:09:11She could go up, down, in her case, and then each of those subsequent routers
  22980. 18:09:14could go up, down, left, or right, until it finally reaches Brian.
  22981. 18:09:17And long story short, there's algorithms that
  22982. 18:09:19figure out how you decide to send a packet up, down,
  22983. 18:09:22left, or right, so to speak.
  22984. 18:09:24But they do so by taking an input, and in the form of input is this envelope.
  22985. 18:09:29And there's at least a couple of things on the outside of this,
  22986. 18:09:32because all of these routers and, in turn, all of our Macs and PCs
  22987. 18:09:35and phones these days, speak something called
  22988. 18:09:38TCP/IP, a set of acronyms you've probably
  22989. 18:09:41seen somewhere on your phone, your Mac or PC,
  22990. 18:09:44in print somewhere, which refers to two protocols, two conventions,
  22991. 18:09:48that computers use to inter-communicate these days.
  22992. 18:09:51Now what's a protocol?
  22993. 18:09:52A protocol is like a set of rules, that you behave.
  22994. 18:09:54In healthier times, I might extend my hand and someone
  22995. 18:09:57like Carter might extend his hand, thereby interacting with me, based
  22996. 18:10:00on a human protocol of like literally physically shaking hands.
  22997. 18:10:03Nowadays, we have mask protocols, whereby what you need to do
  22998. 18:10:07is wear a mask indoors.
  22999. 18:10:08But that, too, is just a set of rules that we all follow and adhere to,
  23000. 18:10:11that's somewhere standardized and documented.
  23001. 18:10:13So computers use protocols all the time to govern
  23002. 18:10:16how they are sending information and receiving information.
  23003. 18:10:19And TCP and IP are two such protocols that standardize this as follows.
  23004. 18:10:24What TCP/IP tells someone like Phyllis to do,
  23005. 18:10:27if she wants to send an email to Brian, is put the email in a virtual envelope,
  23006. 18:10:31so to speak.
  23007. 18:10:31But on the outside of that virtual envelope, put Brian's unique address.
  23008. 18:10:37And I'll describe this as destination on the middle of the envelope,
  23009. 18:10:41just like in our human world, you would write the destination
  23010. 18:10:44address on the envelope.
  23011. 18:10:45And then she's going to put her own source address in the top left hand
  23012. 18:10:49corner, just like you, the sender, would put your own source
  23013. 18:10:51address in the human world.
  23014. 18:10:53But, instead of these addresses being like something Kirkland Street,
  23015. 18:10:56Cambridge, Massachusetts 02138, USA, you probably know that computers
  23016. 18:11:01on the internet have unique addresses of their own, known as IP addresses.
  23017. 18:11:05And an IP address is just a numeric identifier
  23018. 18:11:08on the internet, that allows computers, like Phyllis and Brian,
  23019. 18:11:11to address these envelopes to and from each other.
  23020. 18:11:14And you've probably seen the format at some point.
  23021. 18:11:16Typically, the format of IP addresses is something dot something
  23022. 18:11:20dot something dot something.
  23023. 18:11:22Each of those somethings, represented here with a hash symbol,
  23024. 18:11:24is a number from 0 through 255.
  23025. 18:11:29And, based on that little hint, if each of these hashes
  23026. 18:11:32represents a number from 0 to 255, each of those hashes
  23027. 18:11:36is represented with how many bytes or bits?
  23028. 18:11:39Eight bits or one byte, which is to say, we can extrapolate from there,
  23029. 18:11:43an IP address must use 32 bits or 4 bytes,
  23030. 18:11:47if we rewind now to some of the primitives we looked at in week 0.
  23031. 18:11:50And what that means is, at least at a glance,
  23032. 18:11:52it looks like we have 4 billion some odd IP addresses available to us.
  23033. 18:11:57Now, unfortunately, there's a huge number
  23034. 18:11:58of humans in the world these days, all of whom have, many of whom
  23035. 18:12:01have multiple devices, certainly in places like this, where you have
  23036. 18:12:05a laptop, and a phone, and you have other internet of things-type devices,
  23037. 18:12:08all of which need to be addressed.
  23038. 18:12:10So there's another type of IP address that's
  23039. 18:12:12starting to be used more commonly.
  23040. 18:12:14This is version 4 of IP.
  23041. 18:12:16There's also version 6 which, instead of 32 bits,
  23042. 18:12:19uses 128 bits, which gives us a crazy number of possible addresses
  23043. 18:12:23for computers, so we can at least handle all of the additional devices we now
  23044. 18:12:27have today.
  23045. 18:12:28So this is to say, what ultimately is going on this envelope
  23046. 18:12:31is the destination address, that is Brian's IP address, and the source
  23047. 18:12:35address, that is Phyllis's IP address, so that this packet can go from point A
  23048. 18:12:40to point B, and if need be, back, by just flipping
  23049. 18:12:43the source and the destination.
  23050. 18:12:44But on the internet, you presumably know that there's not just email servers.
  23051. 18:12:49There's web servers, there's chat servers, video servers, game servers.
  23052. 18:12:53Like there's all of these different functions on the internet nowadays.
  23053. 18:12:56And so, when Brian receives that envelope,
  23054. 18:12:58how does he know it's an email, versus a web page, versus a Skype call,
  23055. 18:13:05versus something else altogether.
  23056. 18:13:07Well, it turns out that we can look at the other part
  23057. 18:13:10of this acronym, the TCP in TCP/IP.
  23058. 18:13:14And what TCP allows us to do, for instance,
  23059. 18:13:17is specify a couple of things.
  23060. 18:13:18One, the type of service whose data is in this envelope, that is,
  23061. 18:13:23it does this with a numeric identifier.
  23062. 18:13:26And I'm going to go ahead and write down a colon, and the word port, P-O-R-T.
  23063. 18:13:31And I'm going to write that in the source address, too, colon and port.
  23064. 18:13:35So technically, now, what's on this envelope
  23065. 18:13:37is not just the addresses, but also a unique number
  23066. 18:13:40that represents what kind of service is being sent from point A to point B,
  23067. 18:13:45whether it's email, or web traffic, or Skype, or something else.
  23068. 18:13:48These numbers are standardized, and here are just two of the most common ones,
  23069. 18:13:53not even in the context of email, but in the context of the web.
  23070. 18:13:56Port 80 is typically used whenever an envelope contains
  23071. 18:13:59a web page, or a request therefor, or the number 443,
  23072. 18:14:03when that request is actually encrypted, using that thing you probably
  23073. 18:14:07know, in URLs, known as HTTPS, where the S literally means secure.
  23074. 18:14:11More on what the HTTP means later.
  23075. 18:14:13If it's email, the number might be 25 or 465, or 587.
  23076. 18:14:16These are the kinds of things you Google if you ultimately care about.
  23077. 18:14:19But if you've ever had to configure, like, Outlook or even Gmail
  23078. 18:14:24to talk to another account, you might very well
  23079. 18:14:26have seen these numbers, by typing in something like SMTP.Gmail.com
  23080. 18:14:30and then a number, which is only to say these numbers are omnipresent.
  23081. 18:14:33But they're typically not things you and I
  23082. 18:14:35have to care about, because servers and computers nowadays
  23083. 18:14:38automate much of this process.
  23084. 18:14:40But that's all it takes, ultimately, for Phyllis to get this message to Brian.
  23085. 18:14:45But what if it's a really big message?
  23086. 18:14:47If it's a short email, It might fit perfectly in one single packet,
  23087. 18:14:50so to speak.
  23088. 18:14:50But suppose that Phyllis wants to send Brian a picture of a cat,
  23089. 18:14:54like this, or worse, a video of a cat.
  23090. 18:14:56It would be kind of inequitable if no one else could do anything
  23091. 18:15:00on the internet, just because Phyllis wants
  23092. 18:15:03to send Brian a really big picture, a really big video of a cat.
  23093. 18:15:06It would be nice if we could kind of time-share the interconnections,
  23094. 18:15:10across these routers, so that we can give a little bit of time
  23095. 18:15:13to Phyllis, a little bit of time to someone else,
  23096. 18:15:15a little bit of time to someone else, so that eventually, Phyllis' entire cat
  23097. 18:15:18gets through the internet.
  23098. 18:15:19But in terms of fairness, she doesn't monopolize the bandwidth
  23099. 18:15:25of the network in question.
  23100. 18:15:27And this, then, allows us to do one other feature of TCP/IP,
  23101. 18:15:31which is fragmentation, where we can temporarily,
  23102. 18:15:35and Phyllis's computer would do this automatically, fragment
  23103. 18:15:37the big packet in question, or the big file in question,
  23104. 18:15:41and then use, not just a single envelope, but maybe a second, a third,
  23105. 18:15:46and a fourth, or more.
  23106. 18:15:48If we do that, though, we're probably going
  23107. 18:15:50to need one other piece of information, just logically, on these envelopes.
  23108. 18:15:54Like, if you were implementing this, chopping up this picture of a cat
  23109. 18:15:57into four parts, like, intuitively, what might you
  23110. 18:16:00want to put virtually on the outside of this envelope now?
  23111. 18:16:03Yeah.
  23112. 18:16:04AUDIENCE: The order.
  23113. 18:16:05SPEAKER 1: The order of them, somehow.
  23114. 18:16:06So probably something like part one of four, part two of four,
  23115. 18:16:10part three of four, and so forth.
  23116. 18:16:12So I'm going to write one more thing in like the memo line of the envelope
  23117. 18:16:14here.
  23118. 18:16:15I put some kind of sequence number, that's
  23119. 18:16:17just a little bit of a clue to Brian, to know
  23120. 18:16:20in what order to reassemble these things.
  23121. 18:16:22And even more powerfully than that, this actually
  23122. 18:16:25gives us this simple primitive of just using INTs on these envelopes,
  23123. 18:16:29in these packets.
  23124. 18:16:30If Brian receives envelopes like these, with numbers like these in the memo
  23125. 18:16:35field, what other feature does TCP apparently
  23126. 18:16:39enable Brian and Phyllis to implement?
  23127. 18:16:42This is a bit subtle.
  23128. 18:16:44But it's not just the ordering of the packets.
  23129. 18:16:46What else might be useful about putting numbers on these things,
  23130. 18:16:50might you think?
  23131. 18:16:52What might be useful here?
  23132. 18:16:54Yeah, in back.
  23133. 18:16:55AUDIENCE: How about if you like missed.
  23134. 18:16:56SPEAKER 1: If you missed something that was intended to be sent,
  23135. 18:16:58if I heard that correct.
  23136. 18:16:59So short answer, exactly, yes, TCP, because of this simple little integer
  23137. 18:17:04that we're including, can quote unquote "guarantee" delivery.
  23138. 18:17:06Why?
  23139. 18:17:07Because if Brian receives one out of four, two out of four,
  23140. 18:17:10four out of four, but not three out of four,
  23141. 18:17:12he now knows, predictably, that he needs to ask Phyllis, somehow,
  23142. 18:17:16to resend that packet.
  23143. 18:17:17And so this is why pretty much always, if you receive an email,
  23144. 18:17:21you either receive the whole thing, or nothing at all.
  23145. 18:17:24Like sentences and words and paragraphs should never really
  23146. 18:17:27be missing from an email.
  23147. 18:17:29Or if you download a photograph on the web,
  23148. 18:17:31it shouldn't just have a blank hole in the middle,
  23149. 18:17:33just because that packet of information happened to be lost.
  23150. 18:17:36TCP, if it is the protocol being used to transmit data from point A to point B,
  23151. 18:17:40ensures that it either all gets there, or ultimately, none of it at all.
  23152. 18:17:44So this is an important property, but, just as a teaser there's
  23153. 18:17:48other protocols out there.
  23154. 18:17:49There's something called UDP, which is an alternative to TCP,
  23155. 18:17:52that doesn't guarantee delivery.
  23156. 18:17:54And just as a taste of why you might ever not want to guarantee delivery,
  23157. 18:17:58maybe you're watching like a streaming video, like a sports event online.
  23158. 18:18:03You probably don't necessarily want the thing
  23159. 18:18:05to buffer and buffer and buffer, just because you have a slow connection,
  23160. 18:18:08because you're going to start to miss things.
  23161. 18:18:10And then you're going to be the only one in the world watching
  23162. 18:18:12the game that ended 20 minutes ago, when everyone else is sort of up to speed.
  23163. 18:18:15Similarly for a voice call, it would be really annoying
  23164. 18:18:18if our voice is constantly buffered.
  23165. 18:18:19So UDP might be a good protocol for making sure
  23166. 18:18:22that, even if the person on the other end sounds a little crappy, at least
  23167. 18:18:25you can hear them.
  23168. 18:18:26It's not pausing and resending and resending,
  23169. 18:18:29because that would really slow down that sort of human interaction.
  23170. 18:18:33So, in short, IP handles the addressing of these packets,
  23171. 18:18:36and standardizes numbers that every computer, your own included, gets,
  23172. 18:18:40and TCP handles the standardization of like what services
  23173. 18:18:44can be used, between points A and point B. All right, this is great,
  23174. 18:18:50but presumably, when Phyllis sends a message to Brian,
  23175. 18:18:54she doesn't really know and probably shouldn't
  23176. 18:18:56care what his IP address is, right?
  23177. 18:18:58These days it's, like, I don't know most of the phone numbers
  23178. 18:19:01that my friends have.
  23179. 18:19:02I instead look them up in some way.
  23180. 18:19:04And, indeed, when you visit a website, what do you type in?
  23181. 18:19:07It's typically not something dot something dot something dot
  23182. 18:19:10something, where each of those somethings is a number.
  23183. 18:19:12What do you typically type in to a browser?
  23184. 18:19:14So a domain name, right?
  23185. 18:19:15Something like Stanford.edu, Harvard.edu, Yale.edu, gmail.com,
  23186. 18:19:20or any other such domain name.
  23187. 18:19:22And so, thankfully, there's another system
  23188. 18:19:24on the internet, one more acronym for today, called DNS, domain name system.
  23189. 18:19:29And pretty much every network on the internet, Harvard's, Yale's, Comcast's,
  23190. 18:19:33your own home network, somewhere, somehow has a DNS server.
  23191. 18:19:37You probably didn't have to configure it yourself.
  23192. 18:19:39Someone else did, your campus, your job, your internet service provider.
  23193. 18:19:44But there is some server connected somehow to the network you're on,
  23194. 18:19:48via wires or wirelessly, that just has a really big table in its memory,
  23195. 18:19:52a big spreadsheet, if you will, or, if you prefer,
  23196. 18:19:55a hash table, that has at least two columns of keys and values
  23197. 18:19:59respectively.
  23198. 18:20:00Where on the left hand side is what we'll
  23199. 18:20:02call domain name, something like Harvard.edu,
  23200. 18:20:04Yale.edu, an IP address on the right hand side, that is to say,
  23201. 18:20:08a DNS server's purpose in life is just to translate domain names
  23202. 18:20:13to IP addresses.
  23203. 18:20:14And vice versa, if you want to go in the other direction,
  23204. 18:20:17and technically, just to be precise, it translates fully qualified domain names
  23205. 18:20:22to IP addresses.
  23206. 18:20:23And we'll see what those are in just a moment.
  23207. 18:20:25But again, all of this just kind of happens magically
  23208. 18:20:27when you turn on your phone or your laptop
  23209. 18:20:29today, because all of these things are pre-configured for us nowadays.
  23210. 18:20:33So how can we actually start to see some of these things in action?
  23211. 18:20:38Well, let's go ahead and poke around, for instance, at a couple of URLs here.
  23212. 18:20:44Let's see what we can actually do now with these basic primitives.
  23213. 18:20:48If we now have the ability to move data from point A to point B,
  23214. 18:20:52and what can be in that envelope could be, yes, an email,
  23215. 18:20:55but today, onward, it's really going to be web content.
  23216. 18:20:58There's going to be content that you're requesting,
  23217. 18:21:00like give me today's home page.
  23218. 18:21:01And there's content you're sending, which
  23219. 18:21:03would be the contents of that actual home page.
  23220. 18:21:05And so, just to go one level deeper, now that we have these packets that
  23221. 18:21:10are getting from point A to point B using TCP/IP, let's
  23222. 18:21:14put something specific inside of them, not just an email and a bunch of text,
  23223. 18:21:19but something called HTTP, which stands for hypertext transfer protocol.
  23224. 18:21:24You've seen this for decades now, probably,
  23225. 18:21:25in the form of URLs, so much so that you probably don't even type it nowadays.
  23226. 18:21:29Your browser just adds it for you automatically,
  23227. 18:21:31and you just type in Harvard.edu, or Yale.edu, or the like.
  23228. 18:21:35But HTTP is just a final protocol that we'll
  23229. 18:21:38talk about here, that just standardizes how web browsers and web
  23230. 18:21:42servers inter-communicate.
  23231. 18:21:44So this is a distinction now between the internet and the web.
  23232. 18:21:47The internet is really like the low-level plumbing,
  23233. 18:21:50all of the cables, all of a technology that just moves packets
  23234. 18:21:53from left to right, right to left, top to bottom, that gets data from point A
  23235. 18:21:57to point B. You can do anything you want on top of that internet nowadays,
  23236. 18:22:01email and web and video and chat and gaming, and all of that.
  23237. 18:22:06So HTTP, or the web, is just one application
  23238. 18:22:09that is conceptually on top of, built on top of the internet.
  23239. 18:22:13Once you take for granted that there is an internet,
  23240. 18:22:15you can do really interesting things with it,
  23241. 18:22:17just like in our physical world, once you have electricity,
  23242. 18:22:19you can just assume you can do really interesting things with that, too,
  23243. 18:22:22without even knowing or caring how it works.
  23244. 18:22:25But now that you'll be programming for the web,
  23245. 18:22:28it's useful to understand how some of these things indeed work.
  23246. 18:22:32So let's take a peek at the format of the things that
  23247. 18:22:36go inside of these messages.
  23248. 18:22:37These days, it's usually actually HTTPS that's
  23249. 18:22:39in play, where, again, the S just means secure.
  23250. 18:22:42More on that later, but the HTTP is what standardizes what kinds of messages
  23251. 18:22:47go inside of these envelopes.
  23252. 18:22:48And wonderfully, it's just textual information, typically.
  23253. 18:22:52There is a simple text format that humans decided on years ago,
  23254. 18:22:56that goes inside of these envelopes, that tells a browser how
  23255. 18:23:00to request information from a server, and how to respond from the server
  23256. 18:23:04to that client with information.
  23257. 18:23:06So here's, for instance, a canonical URL, https://www.example.com.
  23258. 18:23:12What might you see at the end of this?
  23259. 18:23:14You might sometimes see a slash.
  23260. 18:23:15Browsers nowadays kind of simplify things and don't show it to you.
  23261. 18:23:18But slash, as we'll see, just represents like the default
  23262. 18:23:21folder, the root of the web server's hard drive,
  23263. 18:23:24like whatever the base is of it.
  23264. 18:23:26It's like C colon backslash on Windows, or it's my computer on Mac OS.
  23265. 18:23:32But a URL can have more than that.
  23266. 18:23:34It can have slash path, where path is just a word,
  23267. 18:23:36or multiple words, that sort of describe a longer part of the URL.
  23268. 18:23:40That path could actually be a specific file, we'll see,
  23269. 18:23:43like something called file.html.
  23270. 18:23:45More on HTML in just a bit, or it can even be slash folder,
  23271. 18:23:48maybe with another slash, or maybe it can be /folder/file.html.
  23272. 18:23:52Now these days Safari, and even Chrome to some extent, and other browsers,
  23273. 18:23:57are in the habit of trying to hide more and more of these details
  23274. 18:24:00from you and me.
  23275. 18:24:02Ultimately, though, it'll be useful to understand
  23276. 18:24:05what URLs you're at, because it maps directly to the code,
  23277. 18:24:08that we're ultimately going to write.
  23278. 18:24:10But this is only to say that all this stuff in yellow
  23279. 18:24:13refers to, presumably, a specific file and/or folder on the web
  23280. 18:24:18server, on which you're programming.
  23281. 18:24:20All right, what's this?
  23282. 18:24:21Example.com, this is the domain name, as we described it earlier.
  23283. 18:24:26Example.com is the so-called domain name.
  23284. 18:24:28This whole thing, www.example.com, is the fully qualified domain name.
  23285. 18:24:33And what the WW is referring to is specifically the name
  23286. 18:24:37of a specific server in that domain.
  23287. 18:24:40So back in the day, there was a www.example.com web server.
  23288. 18:24:44There might have been a mail.example.com mail server.
  23289. 18:24:48There might have been a chat.example.com chat server.
  23290. 18:24:51Nowadays, this hostname, or subdomain, depending on the context,
  23291. 18:24:56can actually refer to a whole bunch of servers, right?
  23292. 18:24:58When you go to www.facebook.com, that's not one server,
  23293. 18:25:01that's thousands of servers nowadays.
  23294. 18:25:03So long story short, there's technology that
  23295. 18:25:05somehow get your data to one of those servers,
  23296. 18:25:08but this whole thing is what we meant by fully qualified domain name.
  23297. 18:25:11This thing here, hostname, in the context of an email
  23298. 18:25:13address it might alternatively be called a subdomain.
  23299. 18:25:16This thing here, top level domain, you probably
  23300. 18:25:20know that dot com means commercial, although anyone can buy it these days.
  23301. 18:25:23Dot org is similar, dot net.
  23302. 18:25:25Some of them are a bit restricted, dot mil is just for the US military,
  23303. 18:25:29dot edu is just for accredited educational institutions.
  23304. 18:25:31But there are hundreds, if not more, top level domains
  23305. 18:25:35nowadays, some more popular than others.
  23306. 18:25:37CS50's tools, for instance, use CS50.io.
  23307. 18:25:41IO sort of connotes input-output.
  23308. 18:25:44It actually belongs, though, to a small island nation, a country,
  23309. 18:25:49whose country code is .io, and you see other two letter top level domains that
  23310. 18:25:55are country specific.
  23311. 18:25:56Indeed, it's something.uk, something.jp, and the like typically
  23312. 18:26:00refer to countries.
  23313. 18:26:01But some of them have been rather co-opted, .tv as well,
  23314. 18:26:04because they have these meanings in English as well.
  23315. 18:26:06Lastly, this is what we'll call the protocol.
  23316. 18:26:08That specifies how the server uses this URL to get data from point A
  23317. 18:26:13to point B. So what is inside of this envelope?
  23318. 18:26:16Let's now start poking around a little bit more.
  23319. 18:26:18What is inside of this envelope?
  23320. 18:26:20It's essentially, for our purposes today, one of two verbs,
  23321. 18:26:23either GET or POST.
  23322. 18:26:25And if any of you have dabbled with HTML or made your own website,
  23323. 18:26:28you might have seen some of these terms before.
  23324. 18:26:30But these two verbs describe just how to send information
  23325. 18:26:34from you to the server.
  23326. 18:26:36Long story short, more on this next week,
  23327. 18:26:39GET means put any user input in the URL, POST means hide it,
  23328. 18:26:43so that things you're searching for, credit card numbers you're typing in,
  23329. 18:26:46usernames and passwords you're inputting, don't show up in the URL,
  23330. 18:26:49and are therefore visible to anyone with access
  23331. 18:26:51to your computer and your search history,
  23332. 18:26:53but rather they're somehow provided elsewhere, deeper into that envelope.
  23333. 18:26:57But for now, we'll focus almost entirely on GET,
  23334. 18:27:00which is perhaps the most common one that we're always going to use.
  23335. 18:27:03And what we're going to do is this.
  23336. 18:27:05Let me switch over just to a blank screen here.
  23337. 18:27:07And if we assume that little old me is this laptop here,
  23338. 18:27:11and I'm connected to the cloud, and in that cloud is some server that I
  23339. 18:27:16want to request the web page of, Harvard.edu or Yale.edu,
  23340. 18:27:20it's really going to be a two-step process.
  23341. 18:27:22There's going to be a request, that goes from point A to point B,
  23342. 18:27:27and then, hopefully, the server that hears
  23343. 18:27:29that request is going to reply with what we'll typically call a response.
  23344. 18:27:34And other terms that are relevant here, is my laptop
  23345. 18:27:37is the so-called client, Harvard.edu, Yale.edu, whatever
  23346. 18:27:40it is, is the so-called server.
  23347. 18:27:42And just like in a restaurant, where you might request something to eat,
  23348. 18:27:45the server might bring it to you.
  23349. 18:27:47It's, again, that kind of bidirectional relationship.
  23350. 18:27:49One request, one response, for each such web page we request.
  23351. 18:27:54All right, so what's inside these envelopes, and what do we actually see?
  23352. 18:27:58Well, this arrow, this line I just drew from left to right,
  23353. 18:28:01representing the request, technically looks a little more like this.
  23354. 18:28:05When you visit a web page, using your browser,
  23355. 18:28:08on your phone, laptop, or desktop, what's going inside that envelope,
  23356. 18:28:11and the textual message your Mac or PC or phone is automatically generating,
  23357. 18:28:14looks a little something like this.
  23358. 18:28:16The verb GET, the URL, or rather the path that you want to get,
  23359. 18:28:20slash represents the default page on the website.
  23360. 18:28:22HTTP/1.1 is just some mention of what version of HTTP you're speaking.
  23361. 18:28:27Now we're up to version 2, and version 3, but 1.1 is quite common.
  23362. 18:28:31And the envelope contains some mention of the host that was typed in,
  23363. 18:28:35the fully qualified domain name.
  23364. 18:28:37This is because single servers can actually host many different websites.
  23365. 18:28:42If you're using Squarespace or Wix or one of these popular hosting websites
  23366. 18:28:46nowadays, you don't get your own personal server, most likely.
  23367. 18:28:49You're on the same server as dozens, hundreds of other customers.
  23368. 18:28:52But when your customers, your users' browsers,
  23369. 18:28:56include a little mention of your specific, fully qualified domain
  23370. 18:29:00name in the envelope, Squarespace and Wix just
  23371. 18:29:02know to send it to your web page or my web page or some other customer
  23372. 18:29:06altogether.
  23373. 18:29:07Dot dot dot, there's some other stuff there.
  23374. 18:29:09But that's really the essence of what's in these requests.
  23375. 18:29:12Hopefully, then, when your browser requests this web page from the server,
  23376. 18:29:16what comes back?
  23377. 18:29:17Well, hopefully, a response that looks like this, HTTP/1.1,
  23378. 18:29:21so the same version, some status code, like a number 200,
  23379. 18:29:25and then literally a short phrase like OK, which means exactly that, like, OK,
  23380. 18:29:30this request was satisfied.
  23381. 18:29:31Then it contains some other information, like the type of content
  23382. 18:29:35that's coming back.
  23383. 18:29:35And we'll see that this, too, is standardized.
  23384. 18:29:37Text/HTML means here comes some HTML, which is just a text language.
  23385. 18:29:41It could instead be image/jpeg or Image/png, or video/mp4,
  23386. 18:29:48there are these different content types, otherwise known as MIME types,
  23387. 18:29:51that uniquely identify types of files, that come back,
  23388. 18:29:54similar in spirit to file extensions, but a little more
  23389. 18:29:57standardized this way.
  23390. 18:29:59Then there's some more stuff, dot dot dot.
  23391. 18:30:00But in general, what you see here, are a familiar pattern, keys and values.
  23392. 18:30:05These keys and values are otherwise known as HTTP headers.
  23393. 18:30:09And your browser has been sending these every time you visit a website.
  23394. 18:30:14And, indeed, we can see this right now ourselves.
  23395. 18:30:16Let me go over, in just a second, to Chrome on my computer,
  23396. 18:30:20though you can do this kind of thing with most any browser today.
  23397. 18:30:23I'll go ahead and visit HTTP://Harvard.edu, Enter.
  23398. 18:30:28And, voila, I'm at Harvard's home page for today.
  23399. 18:30:31The content often changes.
  23400. 18:30:32But this is what it looks like right now.
  23401. 18:30:34Well, I typed in the URL, but notice it changed a little bit.
  23402. 18:30:38It actually sent me to HTTPS and added the www,
  23403. 18:30:41even though I didn't type that.
  23404. 18:30:42But it turns out we can poke around at what my browser is actually doing.
  23405. 18:30:46Let me open another page.
  23406. 18:30:47I'm going to start to use incognito mode this time, not because I
  23407. 18:30:50care that people know I'm visiting Harvard.edu,
  23408. 18:30:52but because it throws away any history that I just did.
  23409. 18:30:56So that every request is going to look like a brand new one,
  23410. 18:30:58and that's just useful diagnostically, because we're always
  23411. 18:31:01going to see fresh information.
  23412. 18:31:02My browser is not going to remember what I previously already requested.
  23413. 18:31:06But I'm going to go up to View, developer,
  23414. 18:31:09developer tools, which is something that all of you have, if you use Chrome.
  23415. 18:31:13And there's something analogous for Firefox and Edge
  23416. 18:31:15and Safari and other browsers.
  23417. 18:31:17Developer tools is going to open up these tabs down here.
  23418. 18:31:20I don't really care what's new, so I'm going to close the bottom thing there.
  23419. 18:31:23And I'm going to hover over the Network tab for just a moment.
  23420. 18:31:26And now I'm going to go and say HTTP://Harvard.edu, so
  23421. 18:31:31the shorter version.
  23422. 18:31:32I'm going to hit Enter, and a whole bunch of stuff
  23423. 18:31:36just flew across the screen.
  23424. 18:31:37And it's still coming in.
  23425. 18:31:38And if I zoom in down here, my God, visiting Harvard.edu, still going,
  23426. 18:31:43is downloading, what 17, 18, 19 megabytes, 20 megabytes,
  23427. 18:31:48millions of bytes of information, over 111 HTTP requests.
  23428. 18:31:53In other words, a bit of a simplification, but my browser,
  23429. 18:31:56unbeknownst to me, sent one envelope initially with the request.
  23430. 18:31:59Then the server said, OK, by the way, there's
  23431. 18:32:01110 other things you need, 112 other things you need to get.
  23432. 18:32:05So my computer went back and forth, requesting even more content for me.
  23433. 18:32:09Why?
  23434. 18:32:10Well, inside of Harvard's web page is a whole bunch of images,
  23435. 18:32:13and maybe sound files and videos and other stuff,
  23436. 18:32:16that all need to be downloaded and to compose
  23437. 18:32:18what is ultimately the web page.
  23438. 18:32:20But I don't care about like 100 plus of these things.
  23439. 18:32:22Let's focus on the very first one first.
  23440. 18:32:25The very first request I sent was up here.
  23441. 18:32:27And I'm going to click on this row, under the Network tab.
  23442. 18:32:30And then I'm going to see a bit of diagnostic information.
  23443. 18:32:33To an average person using the web, they needn't care about this,
  23444. 18:32:36just as you probably didn't care about it until right now.
  23445. 18:32:39And even then, perhaps not.
  23446. 18:32:41But if I scroll down to request headers, you will see,
  23447. 18:32:44if I click View source, literally everything that was in the request
  23448. 18:32:48my Mac just sent to Harvard.edu.
  23449. 18:32:51Two of the lines are familiar, get/http1.1, host:harvard.edu,
  23450. 18:32:56and then other stuff that, for now, it's not that interesting for us.
  23451. 18:32:59But let's look at the response that came back from the server.
  23452. 18:33:03I'm going to scroll up now and see response headers, view source.
  23453. 18:33:08And this is interesting.
  23454. 18:33:09It is not OK.
  23455. 18:33:11There's no 200, there's no word OK.
  23456. 18:33:14Curiously, harvard.edu has moved permanently.
  23457. 18:33:18What does that mean?
  23458. 18:33:18Well, there's a whole bunch of stuff here
  23459. 18:33:20that's not that interesting for us.
  23460. 18:33:22But this line, location, is interesting.
  23461. 18:33:24This is an HTTP header, a standardized key value pair,
  23462. 18:33:28that's part of the HTTP protocol, that is, conventions.
  23463. 18:33:32And if I highlight just this one, it's telling me,
  23464. 18:33:34mm-mmm, Harvard is not at HTTP://Harvard.edu,
  23465. 18:33:38Harvard's website is now, and perhaps forever, at HTTPS://www.harvard.edu.
  23466. 18:33:44So what's the value here?
  23467. 18:33:47Probably someone at Harvard wants you to use a secure connection.
  23468. 18:33:50So they redirected you from HTTP to HTTPS.
  23469. 18:33:53Maybe the marketing people want you to be at www instead of just Harvard.edu.
  23470. 18:33:57Why?
  23471. 18:33:57Just to standardize things, but there are technical reasons
  23472. 18:34:00to use a hostname, and not just the raw domain name.
  23473. 18:34:03And all this other stuff is sort of uninteresting for our purposes,
  23474. 18:34:06now, because a browser that receives a 301 response knows,
  23475. 18:34:11by design, by the definition of HTTP, to automatically redirect the user.
  23476. 18:34:16And that's why, in my browser, all of this happened in like a split second,
  23477. 18:34:20because I didn't really know or care about all of those headers.
  23478. 18:34:22But that's why and how I ended up at this URL here.
  23479. 18:34:26My browser was told to go elsewhere via that new location.
  23480. 18:34:29And the browser just followed those breadcrumbs,
  23481. 18:34:32if you will, at which point it downloaded all of the other images
  23482. 18:34:35and files, and so forth, that compose this particular page.
  23483. 18:34:39Well, let me zoom out.
  23484. 18:34:40And let me actually go into VS Code, if only
  23485. 18:34:42because it's a little more pleasant to do things in just a terminal window,
  23486. 18:34:45without actually using a full-fledged browser.
  23487. 18:34:49So now let's just use an equivalent program.
  23488. 18:34:51It's called Curl, for connecting to a URL, that's
  23489. 18:34:54going to allow me to play with websites and just see those headers,
  23490. 18:34:57without bothering to download all the images and text
  23491. 18:34:59and so forth from the website.
  23492. 18:35:01It's going to allow me to do something like this.
  23493. 18:35:03Let me go ahead and run, for instance, Curl-I-xget, which is just the command
  23494. 18:35:10line arguments that says simulate a GET request textually,
  23495. 18:35:14as though you're a browser.
  23496. 18:35:15And let's go to HTTP://Harvard.edu Enter.
  23497. 18:35:20Now, by way of how Curl, works, I'm just seeing the headers.
  23498. 18:35:23It didn't bother downloading the whole website.
  23499. 18:35:25And you see exactly the same thing, 301 moved permanently.
  23500. 18:35:28Location is, indeed, this one here.
  23501. 18:35:31So that's kind of interesting.
  23502. 18:35:33But let's follow it manually now.
  23503. 18:35:34Let's now do what it's telling me to do.
  23504. 18:35:37Let's go to the location, with HTTPS and the www and hit Enter.
  23505. 18:35:42And now, what's a good sign with this output?
  23506. 18:35:46Most of it's irrelevant.
  23507. 18:35:47AUDIENCE: Migrate?
  23508. 18:35:48SPEAKER 1: 200 OK, that means I'm seeing, presumably,
  23509. 18:35:51if I were using a real browser, the actual content of the web page.
  23510. 18:35:55Looks like Harvard's version of HTTP is even newer than the one I'm using.
  23511. 18:35:58It's using HTTP version 2, which is fine.
  23512. 18:36:01But 200 is indeed indicative of things being OK.
  23513. 18:36:04Well, what if I try visiting some bogus URL,
  23514. 18:36:07like Harvard.edu, when this file does not exist, something completely random,
  23515. 18:36:14probably doesn't exist, and hit Enter.
  23516. 18:36:17What do you see now, that's perhaps familiar, in the real world?
  23517. 18:36:20Yeah.
  23518. 18:36:21AUDIENCE: Error 404.
  23519. 18:36:23SPEAKER 1: Yeah, error 404.
  23520. 18:36:24All of us have seen this probably endlessly,
  23521. 18:36:26from time to time, when you screw up by mis-typing a URL,
  23522. 18:36:29or someone deletes the web page in question.
  23523. 18:36:31But all that is is a status code that a browser
  23524. 18:36:34is being sent from the server, that's a little clue as to what
  23525. 18:36:37the actual problem is, underneath the hood.
  23526. 18:36:40So instead of getting back, for instance,
  23527. 18:36:42something like OK, or moved permanently, what I've just gotten back, quite
  23528. 18:36:45simply, is 404 not found.
  23529. 18:36:47Well, it turns out there's other types of status codes
  23530. 18:36:51that you'll start to see over time, as you start to program for the web.
  23531. 18:36:55200 is OK.
  23532. 18:36:56301 is moved permanently.
  23533. 18:36:57302, 304, 307 are all similar in spirit.
  23534. 18:37:01They're related to redirecting the user from one place to another.
  23535. 18:37:04401, 403, unauthorized or forbidden.
  23536. 18:37:08If you ever mess up your password, or you
  23537. 18:37:11try visiting a URL you're not supposed to look at,
  23538. 18:37:13you might see one of these codes, indicating that you just
  23539. 18:37:15don't have authorization for those.
  23540. 18:37:17404 not found, 418, I'm a teapot, was an April Fool's joke
  23541. 18:37:21by the tech community years ago.
  23542. 18:37:24500 is bad.
  23543. 18:37:25And, unfortunately, all of you are probably
  23544. 18:37:27on a path now to creating HTTP 500 errors, once,
  23545. 18:37:30next week, we start writing code, because all of us
  23546. 18:37:33are going to screw up.
  23547. 18:37:34We're going to have typos, logical errors, and this is on the horizon,
  23548. 18:37:37just like segfaults were in the world of C, but solvable with the right skills.
  23549. 18:37:42503 service unavailable, means maybe the server is overloaded,
  23550. 18:37:45or something like that.
  23551. 18:37:46And there's other codes there.
  23552. 18:37:47But those are perhaps some of the most common ones.
  23553. 18:37:51Has anyone, we can get away with this here, less so in New Haven,
  23554. 18:37:54has anyone ever visited SafetySchool.org?
  23555. 18:38:01HTTP://SafetySchool.org, dare we do this, Enter.
  23556. 18:38:08Oh, look at that.
  23557. 18:38:09Where did we end up?
  23558. 18:38:10[LAUGHTER]
  23559. 18:38:11OK, so--
  23560. 18:38:13[APPLAUSE]
  23561. 18:38:17--so this has been like a joke for like 10 or 20 years.
  23562. 18:38:20Someone out there has been paying for the domain name,
  23563. 18:38:22safetyschool.org, just for this two second demonstration.
  23564. 18:38:26But we can now infer, how did this work?
  23565. 18:38:28The person who bought that domain name and somehow configured
  23566. 18:38:31DNS to point to their web server, the IP address of their web server,
  23567. 18:38:35what is their web server presumably spitting out,
  23568. 18:38:37whenever a browser requests the page?
  23569. 18:38:41What status code, perhaps?
  23570. 18:38:42Well, we can simulate this.
  23571. 18:38:44Let me go over to VS Code.
  23572. 18:38:46Let me go back over here.
  23573. 18:38:48Let me increase my terminal window.
  23574. 18:38:49Let me do Curl-I-xget HTTP://safetyschool.org Enter,
  23575. 18:38:58and that's all this website does.
  23576. 18:39:00There's not even an actual website there.
  23577. 18:39:02No HTML, no CSS languages we're about to see.
  23578. 18:39:04It literally just exists on the internet to do that redirect there.
  23579. 18:39:09In fairness, there are others.
  23580. 18:39:13Let me actually do another one here.
  23581. 18:39:15Instead of safetyschool.org, turns out someone,
  23582. 18:39:19some years ago, bought HarvardSucks.org Enter.
  23583. 18:39:25And when we do this, you'll see that, oh, they don't need us to be secure,
  23584. 18:39:30but I do need the www.
  23585. 18:39:31Let's do this one, Enter.
  23586. 18:39:34That one is not found.
  23587. 18:39:36This demo actually worked for so many years.
  23588. 18:39:38But someone has stopped paying for the Squarespace account
  23589. 18:39:41recently, apparently.
  23590. 18:39:42So--
  23591. 18:39:43[APPLAUSE]
  23592. 18:39:46OK, so, fortunately, we did save the YouTube video
  23593. 18:39:52to which this thing refers.
  23594. 18:39:53And so, just to put this into context, since it's
  23595. 18:39:56been quite a few years, Harvard and Yale, of course,
  23596. 18:39:58have this long-standing rivalry.
  23597. 18:40:00There is this tradition of pranking each other.
  23598. 18:40:02And, honestly, hands down, one of the best pranks ever done in this rivalry
  23599. 18:40:06was by Yale to Harvard.
  23600. 18:40:09It's about a three-minute retrospective.
  23601. 18:40:10It's one of the earliest videos, I dare say, on YouTube,
  23602. 18:40:13so the quality is representative of that.
  23603. 18:40:15But let me go ahead and full screen my page here.
  23604. 18:40:18And what used to live at HarvardSucks.org is this video here.
  23605. 18:40:22If we could dim the lights for about three minutes.
  23606. 18:40:25[VIDEO PLAYBACK]
  23607. 18:40:26[MUSIC PLAYING]
  23608. 18:40:48[CHEERING]
  23609. 18:40:53- Actually we're going all the way to the top.
  23610. 18:40:55And you pass it down.
  23611. 18:40:57- This is for you, Yale.
  23612. 18:40:59- We love you, Yale.
  23613. 18:41:01- We're here to trip up Harvard.
  23614. 18:41:04- Go Harvard!
  23615. 18:41:05- Go Harvard!
  23616. 18:41:06- Pass from the top one, pass it down.
  23617. 18:41:08- Pass them down.
  23618. 18:41:09- It's nice to say the ERA sucks.
  23619. 18:41:12- Let's go Harvard.
  23620. 18:41:14- Where does?
  23621. 18:41:16- You see that [BEEP]?
  23622. 18:41:17Where they're passing.
  23623. 18:41:19It's going to have to happen.
  23624. 18:41:22- It's actually going to happen.
  23625. 18:41:25I can't [BEEP] believe this.
  23626. 18:41:26- What do you think of Yale?
  23627. 18:41:28- They don't think good.
  23628. 18:41:30- Hah-hah.
  23629. 18:41:33- Because they don't have it.
  23630. 18:41:34Doesn't run out of stuff.
  23631. 18:41:35- OK.
  23632. 18:41:35- Is there another stuff?
  23633. 18:41:37- Probably that's going to be legible, very small.
  23634. 18:41:40- Garbage.
  23635. 18:41:43- I know, but--
  23636. 18:41:44- Well, what houses?
  23637. 18:41:45- Says, are we in boats now?
  23638. 18:41:47- How many extras?
  23639. 18:41:48- How many extra are there?
  23640. 18:41:49- Sometimes.
  23641. 18:41:50- Yeah.
  23642. 18:41:52[CHEERING]
  23643. 18:41:53- OK.
  23644. 18:41:54- You guys are from Harvard, right?
  23645. 18:41:55- No, vote for.
  23646. 18:41:56Full timer.
  23647. 18:41:57- Yeah, these are '05s.
  23648. 18:41:58- Just make sure everyone has one.
  23649. 18:42:00- They're probably crummy.
  23650. 18:42:01- We're still passing.
  23651. 18:42:02- All the cards needed.
  23652. 18:42:03- Oh, no.
  23653. 18:42:03My bad.
  23654. 18:42:03- Yeah.
  23655. 18:42:05All right, cue it up.
  23656. 18:42:07[CHEERING]
  23657. 18:42:08Go, Harvard.
  23658. 18:42:14[APPLAUSE]
  23659. 18:42:18- Hold up your signs.
  23660. 18:42:21[BEEP]
  23661. 18:42:23- You suck.
  23662. 18:42:23You suck.
  23663. 18:42:24You suck.
  23664. 18:42:24You suck.
  23665. 18:42:25You suck.
  23666. 18:42:25You suck.
  23667. 18:42:26You suck.
  23668. 18:42:27You suck.
  23669. 18:42:28You suck.
  23670. 18:42:29You suck.
  23671. 18:42:30You suck.
  23672. 18:42:31You suck.
  23673. 18:42:32You suck.
  23674. 18:42:32You suck.
  23675. 18:42:33You suck.
  23676. 18:42:35[SCREAMING]
  23677. 18:42:35- What do you think of Yale, sir?
  23678. 18:42:38- Going to be, do one more time.
  23679. 18:42:41- One more time.
  23680. 18:42:42One more time.
  23681. 18:42:44[SCREAMING]
  23682. 18:42:48- Oh, there it goes again.
  23683. 18:42:50- Oh.
  23684. 18:42:56- Harvard sucks.
  23685. 18:42:57Harvard sucks.
  23686. 18:42:58Harvard sucks.
  23687. 18:42:59Harvard sucks.
  23688. 18:43:01Harvard sucks.
  23689. 18:43:02Harvard sucks.
  23690. 18:43:03Harvard sucks.
  23691. 18:43:04[END PLAYBACK]
  23692. 18:43:08SPEAKER 1: All right, so thanks to our friends at Yale for that one.
  23693. 18:43:13Let's go ahead here and consider, in just a moment, what further is deeper
  23694. 18:43:17down inside of the envelope, because we now
  23695. 18:43:18have the ability to get data from, oh, OK, YouTube autoplay again.
  23696. 18:43:24Got to stop doing that.
  23697. 18:43:25Let's consider for just a moment that, let's consider for just a moment
  23698. 18:43:30that we now have this ability to get data from point A to point B.
  23699. 18:43:33And we have the ability to specify in those envelopes what
  23700. 18:43:37it is we want from the website.
  23701. 18:43:38We want to get the home page.
  23702. 18:43:40We want to get back the HTML.
  23703. 18:43:41But what is that HTML?
  23704. 18:43:43In fact, we don't yet have the language with which the web pages themselves
  23705. 18:43:46are written, namely HTML and CSS.
  23706. 18:43:48But let's go ahead and take a five minute break here.
  23707. 18:43:50And when we come back, we'll learn those two languages.
  23708. 18:43:54All right, we are back.
  23709. 18:43:56So we've got three languages to look at today.
  23710. 18:43:58But two of them are not actually programming languages.
  23711. 18:44:00What makes something a programming language, like C or Python and SQL,
  23712. 18:44:05is that there are these constructs via which you can express conditionals.
  23713. 18:44:08You might have variables, you might have looping constructs.
  23714. 18:44:10You have the ability, ultimately, to express logic.
  23715. 18:44:13HTML and CSS aren't so much about logic as they are about structure,
  23716. 18:44:16and the aesthetics of a page.
  23717. 18:44:18And so we're going to create the skeleton of a web page using
  23718. 18:44:21this pair of languages, HTML and CSS.
  23719. 18:44:23And then toward the end of the today, we'll
  23720. 18:44:24introduce an actual programming language,
  23721. 18:44:26that actually is pretty similar in spirit and syntactically
  23722. 18:44:30to both C and Python, but that's going to allow us to make these web pages not
  23723. 18:44:34just static, things that you look at, but interactive applications as well.
  23724. 18:44:38And then next week again, in week 9, will we reintroduce Python and SQL,
  23725. 18:44:42tie all of this together, so that you can actually have a browser or a phone
  23726. 18:44:46talking to a back-end server, and creating
  23727. 18:44:49the experience that you and I now take for granted for most any app or website
  23728. 18:44:53today.
  23729. 18:44:53Well, let's go ahead and do this.
  23730. 18:44:55Let's quickly whip up something in this language called HTML.
  23731. 18:44:58I'm in VS Code here.
  23732. 18:44:59I'm going to go ahead and create a file quite simply called, Hello.html.
  23733. 18:45:04The convention is typically to end your file names in dot html.
  23734. 18:45:07And I'm going to go ahead and bang this out real quick.
  23735. 18:45:09But then we'll more slowly step through what the constructs are herein.
  23736. 18:45:12So I'm going to say doctype html open bracket html,
  23737. 18:45:17and then notice I'm going to do open bracket slash html close bracket.
  23738. 18:45:22And I'm leveraging a feature of VS Code and programming environments more
  23739. 18:45:25generally, to do a bit of autocomplete.
  23740. 18:45:27So you'll see that there's this symmetry to much of what I'm going to type,
  23741. 18:45:30but I'm not typing all of these things.
  23742. 18:45:32VS Code is automatically generating the end of my thought for me, if you will.
  23743. 18:45:37Let me go ahead and say, Open the head tag.
  23744. 18:45:41Open the title tag.
  23745. 18:45:42I'll say something cute like, Hello, title.
  23746. 18:45:44And then down here, I'm going to create the body of this web page
  23747. 18:45:47and say something like Hello, body.
  23748. 18:45:49And let me specify at the very top, that all of this is really in English,
  23749. 18:45:53Lang equals en.
  23750. 18:45:54So at this moment, I have a file in my VS Code environment called Hello.html.
  23751. 18:46:00VS Code as we're using it, of course, is cloud-based.
  23752. 18:46:03We're using it in a browser, even though you can also
  23753. 18:46:05download it and run it on a Mac and PC.
  23754. 18:46:07So we are in this weird situation where I'm
  23755. 18:46:10using the cloud to create a web page, and I
  23756. 18:46:12want that web page to also live in the cloud, that is, on the internet.
  23757. 18:46:17But the thing about VS Code, or really any website
  23758. 18:46:21that you might use in a browser, by default that website is using probably
  23759. 18:46:24TCP port number 80 or TCP port number 443,
  23760. 18:46:29which is HTTP and HTTPS respectively.
  23761. 18:46:32But here I am, sort of a programmer myself,
  23762. 18:46:34trying to create my own website on an existing website.
  23763. 18:46:39So it's a bit of a weird situation.
  23764. 18:46:40But that's OK, because what's nice about TCP
  23765. 18:46:43is that you and I can just pick port numbers to use and run our own web
  23766. 18:46:47server, on a web server.
  23767. 18:46:49That is, we can control the environment entirely,
  23768. 18:46:51by just running our own web server via this command, HTTP-server,
  23769. 18:46:57in my terminal window.
  23770. 18:46:58This is a command that we preinstalled in VS Code here.
  23771. 18:47:01And you'll notice a pop-up just came up.
  23772. 18:47:03Your application running on port 8080 is available.
  23773. 18:47:05That's a commonly used TCP port number, when 80 is already used,
  23774. 18:47:09and 443 is already used, you can run your own server
  23775. 18:47:11on your own port, 8080 in this case.
  23776. 18:47:14I've opened that tab in advance, and if I go into another browser tab here,
  23777. 18:47:18here I see a so-called directory listing of the web server I'm running.
  23778. 18:47:22So I don't see any of my other files.
  23779. 18:47:24I don't see anything belonging to VS Code itself.
  23780. 18:47:27I only see the file that I've created in my current directory, called
  23781. 18:47:30Hello.html.
  23782. 18:47:31And so if I click on this file now, I should see Hello, body.
  23783. 18:47:36I don't see the title.
  23784. 18:47:37But that's because the title of a web page
  23785. 18:47:39nowadays is typically embedded in the tab.
  23786. 18:47:41And if I'm full screen in my browser, there are no tabs.
  23787. 18:47:44So let me minimize the window a bit.
  23788. 18:47:45And now you can see just in this single browser window, in my own URL
  23789. 18:47:50here, that Hello, body, is in the top left hand corner.
  23790. 18:47:52And if I zoom in, there's Hello, title.
  23791. 18:47:54So what have I done here?
  23792. 18:47:56I have gone ahead and created my own web page in HTML,
  23793. 18:48:01in a file called Hello.html.
  23794. 18:48:04And then I have opened up a web server of my own,
  23795. 18:48:09configured it to listen on TCP port 8080,
  23796. 18:48:11which just says to the internet, hey, listen for requests from web browsers,
  23797. 18:48:14not on the standard port number, 80 or 443, listen on 8080.
  23798. 18:48:18And this means I can develop a website using a web-based tool, like this one
  23799. 18:48:22here, which is increasingly common today.
  23800. 18:48:24All right, so now let's consider what it is I actually just typed out.
  23801. 18:48:28HTML is characterized really by just two features, two vocab words, tags
  23802. 18:48:32and attributes.
  23803. 18:48:33Most of what I just typed were tags, but there was at least one attribute
  23804. 18:48:36already.
  23805. 18:48:37Here's the same source code that I typed out in HTML, from top to bottom.
  23806. 18:48:41Let's consider what this is.
  23807. 18:48:43The very first line of code here, doctype html,
  23808. 18:48:46is the only anomalous one.
  23809. 18:48:47It's the only one that starts with an open bracket, a less than sign,
  23810. 18:48:51and an exclamation point.
  23811. 18:48:52There's no more exclamation points thereafter, for now.
  23812. 18:48:55This is the document type declaration, which is a fancy way of saying,
  23813. 18:48:58it's just got to be there nowadays.
  23814. 18:49:00It's like a little breadcrumb at the beginning of a file that
  23815. 18:49:02says to the browser, you are about to see a file written in HTML version 5.
  23816. 18:49:08That line of code has changed over time, over the years.
  23817. 18:49:11The most recent version of it is nice and succinct like this,
  23818. 18:49:13and it's just a clue to the browser as to what version of HTML
  23819. 18:49:16is being used by you, the programmer.
  23820. 18:49:18All right, what comes after that?
  23821. 18:49:20Well, after that, and I've highlighted two things in yellow,
  23822. 18:49:23this is what we're going to start calling an open tag,
  23823. 18:49:26or a start tag, open bracket HTML then something, close bracket,
  23824. 18:49:30is the so-called start or open tag.
  23825. 18:49:32Then the corresponding close or end tag is down here.
  23826. 18:49:35And it's almost the same.
  23827. 18:49:37You use the same tag number, you use the same angled brackets.
  23828. 18:49:40But you do add a slash, and you don't repeat yourself
  23829. 18:49:43with any of the things called attributes,
  23830. 18:49:46because, what is this thing here?
  23831. 18:49:47Lang equals quote unquote "en," means the language
  23832. 18:49:50of my page is written in the English language.
  23833. 18:49:53The humans have standardized two and three letter codes
  23834. 18:49:56for every human language, right now.
  23835. 18:49:59And so this is just a clue to the browser for like automatic translation
  23836. 18:50:03and accessibility purposes, what language the web page
  23837. 18:50:06itself is written in.
  23838. 18:50:07Not the tags, but the words, like Hello, title and Hello, body,
  23839. 18:50:10which while minimalist, are indeed in English.
  23840. 18:50:13So when you close a tag, you close the name of it with the slash
  23841. 18:50:16and the angle brackets.
  23842. 18:50:17You don't repeat the attribute.
  23843. 18:50:19That would just be annoying to have to type everything again.
  23844. 18:50:21But notice the pattern here.
  23845. 18:50:23It's new syntax.
  23846. 18:50:24But this is another example of key value pairs in computing.
  23847. 18:50:27The key is Lang, the value is E-N for English.
  23848. 18:50:31The attribute is called Lang, the value is
  23849. 18:50:34called, it is E-N. So again, it's just key value pairs,
  23850. 18:50:38in just yet another context.
  23851. 18:50:39Probably the browser's using a hash table underneath the hood,
  23852. 18:50:41to keep track of this stuff, like a two column table, with keys and values.
  23853. 18:50:44Again, humans keep using the same paradigm in different languages.
  23854. 18:50:48What's inside of that?
  23855. 18:50:49The nesting is important visually, not to the computer,
  23856. 18:50:52but to us, the humans, because it implies
  23857. 18:50:54that there's some hierarchy here.
  23858. 18:50:55And, indeed, what is inside of the HTML tag here?
  23859. 18:50:59Well, we have what we'll call the head tag.
  23860. 18:51:02The head tag says, hey, browser, here comes the head of the page.
  23861. 18:51:06And then the body tag says, hey, browser,
  23862. 18:51:08here comes the body of the page.
  23863. 18:51:09The body is like 99% of the user's experience, the big rectangular window.
  23864. 18:51:13The head is really just the address bar and other such stuff at top,
  23865. 18:51:17like the title that we saw a moment ago.
  23866. 18:51:20Just to introduce the vernacular, then, the HTML tag, otherwise known
  23867. 18:51:24as an element, has two children, the head child and the body child,
  23868. 18:51:29which is to say that head and body are now siblings.
  23869. 18:51:31So you can use the same kind of family tree terminology that we used,
  23870. 18:51:35when talking about trees, weeks ago.
  23871. 18:51:37If we look at the head tag, how many children does it seem to have?
  23872. 18:51:41I'm seeing one, and, indeed, at least if we
  23873. 18:51:44ignore all the white space, the spaces or tabs or new line characters,
  23874. 18:51:48there's just one child, a title element.
  23875. 18:51:51And an element is the terminology that includes the start tag and the end tag,
  23876. 18:51:55and everything in between.
  23877. 18:51:56So this is the title element.
  23878. 18:51:58And the title element has one child, which is just pure text,
  23879. 18:52:01otherwise known as a text node.
  23880. 18:52:03Recall, node, from our discussions of data structures weeks ago.
  23881. 18:52:06If we jump then to the body, which is the other child of the HTML tag,
  23882. 18:52:10it too has one child, which is just another chunk of text, a text node,
  23883. 18:52:14that says, quote unquote "Hello, body."
  23884. 18:52:17What's nice about this indentation, even though the browser technically
  23885. 18:52:21is not going to care, is that it implies this kind of structure.
  23886. 18:52:25And this is where we connect, like weeks 5 and now weeks 8, here
  23887. 18:52:28is the tree structure we began to talk about, even in our world of C.
  23888. 18:52:33It's not a binary tree, even though this one happens
  23889. 18:52:35to have no more than two children.
  23890. 18:52:37It's an arbitrary tree that can have 0 or any number of children.
  23891. 18:52:40But if we have a special node here that refers to the document,
  23892. 18:52:43the root node, so to speak, is HTML, drawn with a rectangle
  23893. 18:52:47here, just for discussion's sake.
  23894. 18:52:48It has two children, head and body, also rectangles.
  23895. 18:52:51Head has a title child, and then it and body
  23896. 18:52:54have text nodes, which I've drawn with ovals instead.
  23897. 18:52:57Which is only to say that when your browser, Chrome, Safari, whatever,
  23898. 18:53:01downloads a web page, opens up that envelope,
  23899. 18:53:03and sees the contents that have come back from the server,
  23900. 18:53:06it essentially reads the code that someone wrote,
  23901. 18:53:10the HTML code, top to bottom, left to right,
  23902. 18:53:12and creates in the browser's memory, in your Mac or your PC
  23903. 18:53:16or your phone's memory or RAM, this kind of data structure.
  23904. 18:53:20That's what's going on underneath the hood.
  23905. 18:53:22And that's why aesthetically, it's just nice, as a human,
  23906. 18:53:24to indent things stylistically, because it's very clear then
  23907. 18:53:27to you, and to other programmers, what the structure actually is.
  23908. 18:53:32So that's it for like the fundamentals of HTML.
  23909. 18:53:36We'll see a bunch of tags and a bunch of examples now.
  23910. 18:53:38But HTML is just tags and attributes.
  23911. 18:53:40And it's the kind of thing that you look them up when you need to.
  23912. 18:53:43Eventually, many of them get ingrained.
  23913. 18:53:45I constantly check the reference guides or stack overflow
  23914. 18:53:47if I'm trying to figure out, how do I lay something out.
  23915. 18:53:50It's really just these building blocks that
  23916. 18:53:52allow you to assemble the structure of a web page.
  23917. 18:53:55This one is being super simple, but it's just tags and attributes.
  23918. 18:53:58Any questions on this framework, before we
  23919. 18:54:01start to add more tags, more vocabulary, if you will?
  23920. 18:54:05In the middle, yeah.
  23921. 18:54:06AUDIENCE: What would happen if we put the title tag?
  23922. 18:54:09SPEAKER 1: If we put the hello tag around body, that's a good question.
  23923. 18:54:13Let's try it.
  23924. 18:54:13So let me actually go to this, and say open bracket title,
  23925. 18:54:20whoops, sometimes you don't want it to finish your thought for you.
  23926. 18:54:23But it did that time.
  23927. 18:54:24I've gone ahead and changed the file.
  23928. 18:54:27Let me go and open up, give me a second to open my terminal window,
  23929. 18:54:30and go back to the URL that has my page.
  23930. 18:54:34Give me a second.
  23931. 18:54:36There's my Hello.html.
  23932. 18:54:38Let me zoom in on this.
  23933. 18:54:39Let me zoom in on this.
  23934. 18:54:41And let me go ahead now and click on Hello.html.
  23935. 18:54:45And in this case, it looks like we don't actually see anything.
  23936. 18:54:49So the browser is hiding it.
  23937. 18:54:50Technically speaking, browsers tend to be pretty generous.
  23938. 18:54:54And half the time, when you make mistakes in HTML,
  23939. 18:54:56it will display, it might display--
  23940. 18:54:58not display as you intend it.
  23941. 18:54:59It might not display the same on Macs or PCs or Chrome or on Firefox.
  23942. 18:55:03There is a tool, though, that we'll see, that
  23943. 18:55:05can help answer this question for you.
  23944. 18:55:07For instance, if I go to Validator.w3.org,
  23945. 18:55:11W3 is the World Wide Web Consortium, a group
  23946. 18:55:13of people that standardize this kind of stuff,
  23947. 18:55:15I can click on Validate by direct input, and just
  23948. 18:55:17copy paste my sample HTML into this box, and click Check.
  23949. 18:55:21And I should see, hopefully, that indeed, it's
  23950. 18:55:24an error, what you proposed that I do.
  23951. 18:55:25The browser just did its best to do something,
  23952. 18:55:27which was to show me nothing at least, rather than the incorrect information.
  23953. 18:55:30But if I revert that change, and let me undo what we just did,
  23954. 18:55:34let me copy my original code back into this text box, and click Check,
  23955. 18:55:39now you can see, conversely, my code is now correct.
  23956. 18:55:41And there's automated tools to check that.
  23957. 18:55:43But we'll encourage you, for problem sets and projects,
  23958. 18:55:45to use that particular manual tool.
  23959. 18:55:48All right, so let's go ahead and enhance this a little bit
  23960. 18:55:51by introducing a whole bunch of tags, just
  23961. 18:55:53to give you a sense of some of the building blocks here.
  23962. 18:55:55So I'm going to go ahead and create a new file called Paragraphs.html.
  23963. 18:56:01And I'm just going to do a bunch of copy/paste just to start things off,
  23964. 18:56:04so I'm not constantly typing all this darn stuff again and again,
  23965. 18:56:07because I want everything to be the same here,
  23966. 18:56:09except I'm going to change my title to be Paragraphs for this demo.
  23967. 18:56:12And inside of the body, I need a whole bunch of paragraphs of text.
  23968. 18:56:16And I don't really want to come up with some text.
  23969. 18:56:18So let me go to some random website here and grab lorem ipsum text,
  23970. 18:56:21which if you're involved in like student newspaper or just design,
  23971. 18:56:25this is placeholder text, kind of looks like Latin, but technically isn't.
  23972. 18:56:28Here, though, I have a handy way of just getting three long paragraphs
  23973. 18:56:32in something that looks like Latin.
  23974. 18:56:33And I've put those, notice, inside of the body.
  23975. 18:56:36And they're indeed long.
  23976. 18:56:37Look how long the made-up words here are.
  23977. 18:56:40So let me go now into my browser tab here.
  23978. 18:56:46Let me reload this page, and you'll see two files have now appeared,
  23979. 18:56:50Paragraphs.html, which is my new one, and Hello.html.
  23980. 18:56:53Let me click on Paragraphs.html, and what clearly seems to be wrong?
  23981. 18:56:58Yeah.
  23982. 18:56:58AUDIENCE: One paragraph.
  23983. 18:57:00SPEAKER 1: Yeah, it's obviously one massive paragraph, instead of three.
  23984. 18:57:03So that's interesting, but it's just a little hint as to how pedantic HTML is.
  23985. 18:57:07It will only do what you say.
  23986. 18:57:09And each of these tags tells the browser to start doing something,
  23987. 18:57:12and then maybe stop doing something, like, hey, browser, here comes my HTML.
  23988. 18:57:15Hey, browser, here comes the head of my page.
  23989. 18:57:17Hey, browser, here comes the title of my page, Hello, title.
  23990. 18:57:20Hey, browser, that's it for the title.
  23991. 18:57:22That's it for the head, here comes the body tag.
  23992. 18:57:24So it's kind of having this conversation between the browser,
  23993. 18:57:27between the HTML and the browser, doing literally what it says.
  23994. 18:57:30So if you want a paragraph, you're probably
  23995. 18:57:32going to want to use the P tag for paragraph.
  23996. 18:57:35And I'm going to go ahead and add this to my code.
  23997. 18:57:38I'm going to keep things neat, even though the browser won't care,
  23998. 18:57:41by indenting things here.
  23999. 18:57:43Let me create another paragraph tag here, and close it
  24000. 18:57:47right after that one, indenting again, and I'm
  24001. 18:57:49keeping everything nice and orderly.
  24002. 18:57:51Let me do one more here.
  24003. 18:57:53Let me indent that, and then let me add it to the end of my page here.
  24004. 18:57:58So again, a little tedious, but now I have three paragraphs of text that say,
  24005. 18:58:02hey, browser, start a paragraph.
  24006. 18:58:04Hey, browser, stop that paragraph.
  24007. 18:58:05Start, stop, and so forth.
  24008. 18:58:07Let me go back to the browser window here.
  24009. 18:58:09Let me hit Command R or Control R to reload the page.
  24010. 18:58:13And voila, now I have three cleaner paragraphs, all right?
  24011. 18:58:16So there's a P tag for paragraphs.
  24012. 18:58:18So now we have that particular building block.
  24013. 18:58:20What if I want to add, for instance, some headings to this page?
  24014. 18:58:23Well, that's something that's possible, too.
  24015. 18:58:25Let me go ahead and create a new file called Headings.html.
  24016. 18:58:29Let me copy and paste that same code as before.
  24017. 18:58:31But now, let's preface each paragraph with maybe H1.
  24018. 18:58:36And I'm going to just write the word one.
  24019. 18:58:38And here I'm going to say H2, two.
  24020. 18:58:41And down here I might say H3, three.
  24021. 18:58:44So this is another tag, another three tags, H1, H2, H3.
  24022. 18:58:49As you might have inferred by the file name I chose,
  24023. 18:58:51this just gives you headings, like in a book, different chapters or sections
  24024. 18:58:55or subsections, or in an academic paper, you
  24025. 18:58:57have different hierarchies to the text that you're writing.
  24026. 18:59:00So now that I've added an H1 tag, and the word one, H2 tag, the word
  24027. 18:59:04two, H3 tag and the word three, let's go back to the browser,
  24028. 18:59:07reload the page again, and voila, once the page
  24029. 18:59:12reloads, I'll do it with the manual button, reload the page.
  24030. 18:59:17Oh, what am I doing wrong?
  24031. 18:59:19Yeah.
  24032. 18:59:20AUDIENCE: Not in headings file.
  24033. 18:59:21SPEAKER 1: Right, I'm not in the headings file.
  24034. 18:59:23So let me go back a page.
  24035. 18:59:24Now there's Headings.html.
  24036. 18:59:26Let me click on that.
  24037. 18:59:27OK, now we see some evidence of this.
  24038. 18:59:29Again, it's nonsensical content.
  24039. 18:59:30But you can kind of see that H1 is apparently big and bold,
  24040. 18:59:33H2 is slightly less big, but still bold.
  24041. 18:59:36H3 is the same but a little smaller.
  24042. 18:59:38And it goes all the way down to H6.
  24043. 18:59:40After that, you should probably reorganize your thoughts.
  24044. 18:59:42But there are six different hierarchies here,
  24045. 18:59:44as you might use for chapters, sections, subsections, and so forth, all right?
  24046. 18:59:48So those are headings, as an HTML tag, in our vocabulary.
  24047. 18:59:53What's a common thing, too, well, let me go to VS Code again, let me go ahead
  24048. 18:59:59and get some boilerplate here, create a file called List.html.
  24049. 19:00:04Let's create a simple list inside of my body,
  24050. 19:00:07and I'll give this a title of List.
  24051. 19:00:10And let me fix the title of this one to be Headings, as well.
  24052. 19:00:13So in List.html, suppose I want to have a list of things, foo, bar, and baths,
  24053. 19:00:19they're like a computer scientist's go-to words,
  24054. 19:00:21just like a mathematician might say xyz.
  24055. 19:00:23Foo, bar, baths is in List.html.
  24056. 19:00:26Let me go back to my browser, hit the Back button.
  24057. 19:00:29There's List.html, and, hopefully, I'll see foo, bar, and baths, one
  24058. 19:00:33on each line like a nice little list, but, of course, I do not.
  24059. 19:00:37And this is not English.
  24060. 19:00:38Chrome thinks it might be Arabic.
  24061. 19:00:41But that's curious, too, because the Lang attribute
  24062. 19:00:44should be overriding that.
  24063. 19:00:45So Google is trying to override it.
  24064. 19:00:48All right, what's the obvious explanation
  24065. 19:00:49why we're seeing foo, bar, and baths on the same line, and not
  24066. 19:00:52three separate ones?
  24067. 19:00:53AUDIENCE: We didn't tell it.
  24068. 19:00:55SPEAKER 1: We didn't tell it to do that.
  24069. 19:00:57So we need paragraph tags, or maybe something else.
  24070. 19:00:59Turns out there is something else.
  24071. 19:01:00There is a UL tag, for an unordered list in HTML,
  24072. 19:01:04inside of which you can have LI tags, for list item,
  24073. 19:01:08inside of which you can put your words.
  24074. 19:01:10So there's my foo, there's my bar, there's my baths.
  24075. 19:01:13And, again, notice that VS Code is finishing my thought for me.
  24076. 19:01:16But notice the hierarchy, open UL, open LI, close LI, open LI,
  24077. 19:01:21close LI, open LI, close LI, close UL.
  24078. 19:01:24So it's sort of done in reverse order here.
  24079. 19:01:27Let me go back to my browser, reload the same page, List.html, and voila,
  24080. 19:01:33a default bulleted list, that still seems to be in Arabic.
  24081. 19:01:36What if I want this list to be numbered?
  24082. 19:01:38Well, you can probably guess.
  24083. 19:01:39If you don't want an unordered list, but an ordered list, what tag should I use?
  24084. 19:01:43AUDIENCE: OL.
  24085. 19:01:44SPEAKER 1: OL, sure, so let's try that.
  24086. 19:01:46Not always that easy as just guessing, but in this case,
  24087. 19:01:49OL is going to do the trick.
  24088. 19:01:51Let me go back to my other browser.
  24089. 19:01:52Let me reload the page, and now it's going to automatically number for me.
  24090. 19:01:55It's a tiny thing, but this is actually useful
  24091. 19:01:58if you have a very long list of data, and maybe you
  24092. 19:02:00might add some things in the middle, the beginning, or the end.
  24093. 19:02:02It would just be annoying to have to go and renumber it.
  24094. 19:02:04The computer is doing it for us by, instead, just
  24095. 19:02:07numbering from top to bottom here.
  24096. 19:02:10All right, what about another type of layout,
  24097. 19:02:12not just paragraphs, not just lists, but what about tabular data?
  24098. 19:02:14You've got some research data you want to present,
  24099. 19:02:17some financial data you want to present, a phone book that you want to present.
  24100. 19:02:20How might we go about laying out data, a la a table?
  24101. 19:02:23Well, let me create a file called Table.html,
  24102. 19:02:26and I'll just copy paste where we started earlier.
  24103. 19:02:28Let me start to close some of these other files.
  24104. 19:02:31And in Table.html, this is going to be a bit more HTML,
  24105. 19:02:34but I'm going to go ahead and do this.
  24106. 19:02:36Table and close table, tables can have table headings.
  24107. 19:02:40So T head is the name of that tag, and tables can have T bodies, table bodies.
  24108. 19:02:45So I'm going to add that tag.
  24109. 19:02:47And this is a common technique, sort of start your thought,
  24110. 19:02:49finish your thought, and then go back and fill in what's in between.
  24111. 19:02:52What do I want to put in this table?
  24112. 19:02:54How about a bunch of names and numbers.
  24113. 19:02:58So, for instance, like left column name, right column number.
  24114. 19:03:02So let's create a table row, with what's called the TR tag.
  24115. 19:03:05Let's create a table heading with the TH tag, and let's say name here.
  24116. 19:03:10Let's create another table heading called number here.
  24117. 19:03:14And all of that, to be clear, is in one table row.
  24118. 19:03:17Meanwhile, in the table body, let me create another table row,
  24119. 19:03:21but this time, it's not a heading.
  24120. 19:03:23Now I'm in the guts of my table.
  24121. 19:03:24Let's do table data, which is synonymous with like the cell of the table,
  24122. 19:03:28in like an Excel spreadsheet or Google spreadsheet.
  24123. 19:03:30In this TD, I'm going to say like Carter's name,
  24124. 19:03:33and then lets grab Carter's number from our past demo, 617-495-1000.
  24125. 19:03:39Then let's put me into the mix, and I'll go ahead and copy paste here,
  24126. 19:03:43which often is not good.
  24127. 19:03:44But we'll see that there's a lot of shared structure with HTML.
  24128. 19:03:47Let me go ahead and do mine, 949-468-2750, and now save this page.
  24129. 19:03:53So we're getting to be a lot of indentation.
  24130. 19:03:56I'm using four spaces by default. Some people use two spaces by default.
  24131. 19:03:59So long as you're consistent, that's considered good style.
  24132. 19:04:02But let me go back to my browser here, and hit back.
  24133. 19:04:04That then brings me to my directory listing again.
  24134. 19:04:07Here's Table.html, and this is not that interesting yet.
  24135. 19:04:10But you can see that there's two columns, name and number.
  24136. 19:04:13Because it's a table heading, TH, the browser made it boldfaced for me.
  24137. 19:04:18In there, in the table, are two rows below that, Carter and David.
  24138. 19:04:22It's a little, oh, I forgot my number one, sorry about that.
  24139. 19:04:25One and one, it's not the prettiest table, right?
  24140. 19:04:28I feel like I kind of want to separate things
  24141. 19:04:30a little more, maybe put some borders or the like.
  24142. 19:04:32But with HTML alone, I'm really focusing on the structure alone.
  24143. 19:04:36So we'll make this prettier soon.
  24144. 19:04:37But for now, this is how you might lay out tabular data.
  24145. 19:04:41All right, let me pause here just to see if there's any questions.
  24146. 19:04:44But, again, the goal right now is just to kind of throw at you
  24147. 19:04:46some basic building blocks, that, again, can be easily looked up in a reference.
  24148. 19:04:49But we're going to start stylizing these things soon, too.
  24149. 19:04:53Yeah, in the middle.
  24150. 19:04:54AUDIENCE: How to indent?
  24151. 19:04:55SPEAKER 1: How do you indent paragraphs?
  24152. 19:04:57Really good question.
  24153. 19:04:58For that, we'll probably going to want something
  24154. 19:04:59called CSS, Cascading Style Sheets.
  24155. 19:05:01So let me come back to that, in just a little bit.
  24156. 19:05:03For the stylization of these things, beyond the basics, like big and bold,
  24157. 19:05:06we're going to need a different language altogether.
  24158. 19:05:10All right, well, let's now create what the web
  24159. 19:05:13is full of, which is like photographs and images and the like.
  24160. 19:05:17Let me go ahead and create a new file called Image.html, and let me go ahead
  24161. 19:05:22and change the title here to be, say, Image.
  24162. 19:05:25And then, in the body of this page, let's go ahead and put an image.
  24163. 19:05:29The interesting thing about an image is that it's actually not
  24164. 19:05:31going to have a start tag and an end tag, because that's kind of illogical.
  24165. 19:05:35Like, how can you start an image and then eventually finish it?
  24166. 19:05:38It's either there or it isn't.
  24167. 19:05:39So some tags do not have end tags.
  24168. 19:05:42So let me do image, IMG, source equals Harvard.jpeg.
  24169. 19:05:49And let me go ahead, and, in my terminal window,
  24170. 19:05:51I actually came with a photo of Harvard.
  24171. 19:05:54Let me grab this for just a second.
  24172. 19:05:57Let me grab Harvard.jpeg and put it into my directory,
  24173. 19:06:01pretend that I downloaded that in advance.
  24174. 19:06:03And so I'm referring to now a file called
  24175. 19:06:06Harvard.jpeg, that apparently is in the same folder as my Image.html file.
  24176. 19:06:12If this image were on the internet, like Harvard server,
  24177. 19:06:15I could also say like HTTPS://www.Harvard.edu/FolderName,
  24178. 19:06:21whatever it is, /Harvard.jpeg, but if you've in advance uploaded a file
  24179. 19:06:25to your own, the Scode environment, like I did before class,
  24180. 19:06:28by dragging and dropping this whole file, this photo of Harvard,
  24181. 19:06:32you can just refer to it relatively, so to speak.
  24182. 19:06:35This would be the same thing as saying ./Harvard.jpeg,
  24183. 19:06:38go to the current directory and get the file called Harvard.jpeg.
  24184. 19:06:41But that's unnecessary to type.
  24185. 19:06:43For accessibility purposes, though, for someone who's vision-impaired,
  24186. 19:06:47it's ideal if we also give this an alternative text, something
  24187. 19:06:51like Harvard University, in the so-called Alt tag,
  24188. 19:06:55and this is so that screen readers will recite
  24189. 19:06:57what it is the photo is, for folks who can't see it.
  24190. 19:06:59And if you're just on a slow connection, sometimes you'll
  24191. 19:07:02see the text of what you're about to see,
  24192. 19:07:04before the image itself downloads, especially on a mobile device.
  24193. 19:07:07So let's now go back to my open browser tab, and let's look in the directory.
  24194. 19:07:12I now have Harvard.jpeg, which I downloaded in advance, and Image.html.
  24195. 19:07:16Let me click on Image.html, and here we have
  24196. 19:07:20a really big picture of Memorial Hall, the building we're currently in.
  24197. 19:07:25Suffice it to say I should probably fix this and maybe make it only so wide.
  24198. 19:07:29But to do that, we're going to probably want to use this other language, CSS.
  24199. 19:07:33There are some historical attributes that you can still
  24200. 19:07:36use to control width and height, and so forth.
  24201. 19:07:39But we're going to do it the better way, so to speak,
  24202. 19:07:41with a language designed for just that.
  24203. 19:07:44How about a video, though.
  24204. 19:07:45I also came prepared with, let me grab another file here,
  24205. 19:07:50let me grab a file called Halloween.mp4, which is an MPEG file.
  24206. 19:07:55And let me go ahead and change this now to be a file called Video.html.
  24207. 19:08:02I'll change my title to be Video.
  24208. 19:08:04And let's go ahead and now introduce another tag, a video tag,
  24209. 19:08:07open bracket video, and then let me go ahead and close that tag proactively.
  24210. 19:08:13And then inside of the video tag, you can say the source of the video
  24211. 19:08:17is going to be specifically Halloween.mp4, the type of this file,
  24212. 19:08:22I know, is Video/mp4, because I looked up its content type or MIME type.
  24213. 19:08:27And the video tag actually has a few attributes.
  24214. 19:08:29I can have this thing autoplay.
  24215. 19:08:31I can have it loop forever.
  24216. 19:08:33I can mute it, so that there's no sound, which is necessary nowadays.
  24217. 19:08:36Most browsers, to prevent ads, don't autoplay videos, if they have sound.
  24218. 19:08:41So if you mute your video, it will autoplay, but presumably not
  24219. 19:08:44annoy users.
  24220. 19:08:45And let me set the width of this thing to be like, oh, 1280 pixels wide.
  24221. 19:08:49But I can make it any size I want.
  24222. 19:08:51So I know this just from having looked up the syntax for this tag.
  24223. 19:08:55But notice one curiosity.
  24224. 19:08:57Sometimes attributes don't have values.
  24225. 19:08:59They're empty attributes.
  24226. 19:09:01They're just single words, autoplay, loop, muted,
  24227. 19:09:04and that kind of makes sense for any attribute that
  24228. 19:09:06really does what it says.
  24229. 19:09:08Like, it doesn't make sense to say muted equals something.
  24230. 19:09:11Like it's either muted or not.
  24231. 19:09:12The attribute is there or not.
  24232. 19:09:14Similarly, for these others, as well.
  24233. 19:09:16So let me go back to my other browser tab, reload the directory listing.
  24234. 19:09:19There is both my mp4 and also Video.html,
  24235. 19:09:24which is the web page that embeds it.
  24236. 19:09:26And this is actually a video that was just on Harvard's website yesterday,
  24237. 19:09:29and it was amazing.
  24238. 19:09:30So we included it in this demo here.
  24239. 19:09:35This is the video that was on Harvard.edu last night, same photo.
  24240. 19:09:41But you can see here that an image alone probably
  24241. 19:09:44would not have the same effect.
  24242. 19:09:45This is actually a movie, a small video file that's now looping.
  24243. 19:09:48Now there's some artifacts here, like there's a white border around the top.
  24244. 19:09:51I feel like it'd be nice to fill the screen.
  24245. 19:09:53But again, we'll come back to a language that can allow us to do exactly that.
  24246. 19:09:58Well, it's not just videos like this, that you
  24247. 19:10:00might want to put into a web page.
  24248. 19:10:01Let me create another file called iFrame.html.
  24249. 19:10:06If you've ever poked around with, if you have your own YouTube account,
  24250. 19:10:09or if you had your own blog or WordPress site, or Wix or Squarespace,
  24251. 19:10:12you might have been in the habit of embedding videos
  24252. 19:10:14in websites, using like embedded YouTube players.
  24253. 19:10:17Well, this is possible, too, using what's called an inline frame,
  24254. 19:10:21an iFrame.
  24255. 19:10:22And an iFrame is just a tag that is literally iFrame.
  24256. 19:10:25It has source equals, and then a URL, and if it
  24257. 19:10:28happens to be a YouTube video, there's a certain URL format you need to follow,
  24258. 19:10:32per YouTube's documentation.
  24259. 19:10:33So you might do www.youtube.com, embed, and then here's an ID of a video.
  24260. 19:10:41So this is essentially what we do, if we want to embed CS50's own lecture
  24261. 19:10:47videos, in the course's website, or the video player does literally this.
  24262. 19:10:50If I want to allow full screen, I can add this attribute, too,
  24263. 19:10:53that I know exists, by just having checked the documentation.
  24264. 19:10:56And if I now go back to my browser here, reload my directory listing,
  24265. 19:11:00there's iFrame.html.
  24266. 19:11:02It's not going to fill the screen, because I
  24267. 19:11:03haven't customized the aesthetics yet.
  24268. 19:11:05But it does seem to embed a tiny little video there for you to play with later,
  24269. 19:11:10if you'd like.
  24270. 19:11:10So we could change the width, change the height, get rid of that margin,
  24271. 19:11:13and so forth.
  24272. 19:11:14But an iFrame is a way of embedding someone else's web page in your web
  24273. 19:11:19page, if they allow it, so as to create all
  24274. 19:11:21the more of an interactive experience for them on, say, your site.
  24275. 19:11:25All right, well, the web is, of course, known for things like links.
  24276. 19:11:28Let's go ahead and create a file called Link.html.
  24277. 19:11:32And if we want to create a web page that actually links from itself somewhere
  24278. 19:11:35else, let's go ahead and do this, something very simple like visit
  24279. 19:11:40Harvard.edu period.
  24280. 19:11:44Now, in like Facebook, Instagram, a lot of websites nowadays, if you just type
  24281. 19:11:48in a domain name, or a fully qualified domain name,
  24282. 19:11:50it automatically becomes a link.
  24283. 19:11:52That's because those websites have code in them that automatically
  24284. 19:11:56detects something that looks like a URL, and turns it into a proper link.
  24285. 19:12:00HTML itself does not do that for you.
  24286. 19:12:02And so if I go back to my web page here, click on Link.html,
  24287. 19:12:06if you type visit Harvard.edu period, that's
  24288. 19:12:09all you're literally going to see.
  24289. 19:12:11But instinctively, even if you've never written HTML before, what should
  24290. 19:12:15we probably do here to solve this problem?
  24291. 19:12:19What could we do to solve this problem.
  24292. 19:12:20What do I probably want to add.
  24293. 19:12:22Yeah.
  24294. 19:12:22AUDIENCE: Surround your--
  24295. 19:12:24SPEAKER 1: Yeah, so I want to surround the URL with some kind of link text.
  24296. 19:12:27And you wouldn't necessarily know this until someone told you,
  24297. 19:12:30or you looked it up, but the tag for creating a link is somewhat weirdly
  24298. 19:12:33called the A tag for anchor.
  24299. 19:12:35It has an attribute called HREF for hyper-reference,
  24300. 19:12:39which is like a link in the virtual world to a URL.
  24301. 19:12:42So let me type in Harvard's full and proper URL here.
  24302. 19:12:45Then I'm going to close the tag.
  24303. 19:12:48And then I can still say Harvard.edu, and make that what the human sees.
  24304. 19:12:53But the place they're going to go should be a full URL protocol and all,
  24305. 19:12:58HTTP or HTTPS, and all.
  24306. 19:13:00Now if I go back here and reload the page,
  24307. 19:13:03now it automatically gets underlined.
  24308. 19:13:05It happens to be purple by default. Why?
  24309. 19:13:07Because we visited Harvard.edu a few minutes ago.
  24310. 19:13:09So my browser, by default, is indicating in purple that I've been there before.
  24311. 19:13:12But now I have a link that I can click on,
  24312. 19:13:14and if I hover over it but don't click, you'll see that, in most browsers,
  24313. 19:13:18there's a little clue as to where you will go if you click subsequently
  24314. 19:13:22on this link.
  24315. 19:13:24And without going too far down a rabbit hole,
  24316. 19:13:26but to tie together our discussion of cybersecurity recently,
  24317. 19:13:29what if I were to do something like this.
  24318. 19:13:32Right now you have the beginnings of a phishing attack of sorts,
  24319. 19:13:37P-H-I-S-H-I-N-G, whereby you can create clearly a web page, or, heck,
  24320. 19:13:42even an email using HTML, that tells the user they're going to go one place,
  24321. 19:13:46but they're really going to go someplace else altogether.
  24322. 19:13:49And that is the essence of phishing attacks these days.
  24323. 19:13:52If you've ever gotten a bogus email pretending to be from PayPal
  24324. 19:13:55or your bank or some other website, odds are
  24325. 19:13:57they've just written HTML that says whatever they want,
  24326. 19:14:00but the underlying tags might do something very different.
  24327. 19:14:04And so having the instinct to look in the bottom left hand corner,
  24328. 19:14:06or be a little suspicious when you're just told blindly to click on a link,
  24329. 19:14:10it's this easy to socially engineer people, that is,
  24330. 19:14:13deceive them, by just saying one thing and linking to another.
  24331. 19:14:18Well, what if I want to link my page to another page I already created?
  24332. 19:14:22Well, if I want to link to that photo of Harvard,
  24333. 19:14:25I can just do HREF = equals quote unquote and the name of a file,
  24334. 19:14:28in my same account, that is itself a web page.
  24335. 19:14:32So this is how you can create relative links, multi-page web
  24336. 19:14:35pages, multi-page websites, yourself.
  24337. 19:14:38So if I now reload this page, hover over Harvard.edu,
  24338. 19:14:41you'll see in the bottom left hand corner a very long URL.
  24339. 19:14:45But that's because I'm in code spaces right now, VS Code,
  24340. 19:14:48and it's appending automatically to the end of my current URL
  24341. 19:14:51the file name, Image.html.
  24342. 19:14:53But this should work.
  24343. 19:14:54When I click on this, I go immediately to that
  24344. 19:14:57file we created earlier, with a crazy, big version of the image.
  24345. 19:15:01But that's just a way that one page on a website
  24346. 19:15:03can link to another page on a website.
  24347. 19:15:07Let's do one other thing here, making things more responsive,
  24348. 19:15:11because, in fact, that wasn't a particularly responsive website.
  24349. 19:15:14Responsive means responding to the size of the user's device, which
  24350. 19:15:17is so important when someone might be on a screen like this,
  24351. 19:15:20or on a screen like this these days.
  24352. 19:15:22There are special tags we can use to tell the browser to modify its display,
  24353. 19:15:26based on the hardware.
  24354. 19:15:28So let me create a file called Responsive.html.
  24355. 19:15:32I'm going to copy/paste some starting point here, call this title Responsive.
  24356. 19:15:36And let me go ahead and just grab, let me grab some of that lorem ipsum text
  24357. 19:15:40from before, just so that we have a sizable paragraph to play with here.
  24358. 19:15:46And let me go ahead and grab this text here.
  24359. 19:15:50And I'm just going to paste this into the body of this page.
  24360. 19:15:53And that's it.
  24361. 19:15:54So I just have a big paragraph, at the moment, inside of my body.
  24362. 19:15:57Let me go back to my browser.
  24363. 19:15:59Let me open up this file, called Responsive.html,
  24364. 19:16:02to make the point that it is not yet responsive.
  24365. 19:16:05Let me go ahead and click on Responsive.html.
  24366. 19:16:07That looks fine.
  24367. 19:16:08But here's another trick you can do, using Chrome or Edge or other browsers
  24368. 19:16:12these days.
  24369. 19:16:12You can pretend to be another device.
  24370. 19:16:14Let me go to View, developer, developer tools again.
  24371. 19:16:19Last time we used this to use the Network tab, which
  24372. 19:16:21was kind of interesting, because we could see what the underlying network
  24373. 19:16:24traffic is.
  24374. 19:16:25But notice, we can also click on this icon, in Chrome, at least,
  24375. 19:16:29that looks like a mobile phone.
  24376. 19:16:31I can turn my laptop into what looks like a mobile device by clicking this.
  24377. 19:16:36I'm going to click the dot dot dot menu over here, and just move the dock.
  24378. 19:16:39Instead of on the bottom, where it might be by default,
  24379. 19:16:41I'm going to move it to the right hand side.
  24380. 19:16:43So that now on the left, you see what looks more
  24381. 19:16:45like the shape of a vertical phone.
  24382. 19:16:47And, in fact, if I go to my dimensions here,
  24383. 19:16:49I'll choose something like iPhone X, so a few years back.
  24384. 19:16:53Here's what that same website might look like on an iPhone X. You know,
  24385. 19:16:57that looks pretty damn small, to be able to read it.
  24386. 19:17:01And that's because the website has not automatically
  24387. 19:17:03responded to the fairly narrow dimensions of the iPhone
  24388. 19:17:07in question, or Android device, or whatnot.
  24389. 19:17:09So let me go ahead and do this.
  24390. 19:17:11Let me go back into my code.
  24391. 19:17:13And let me go into the head of the page, and for the first time,
  24392. 19:17:16add another tag up here.
  24393. 19:17:18This word is now all over the internet, but there
  24394. 19:17:20is a metatag that is called, that allows you
  24395. 19:17:23to specify the name of some kind of configuration detail here,
  24396. 19:17:27or property, if you will.
  24397. 19:17:28Viewport is the technical term for the rectangular region
  24398. 19:17:31that the human sees in a browser.
  24399. 19:17:32It's essentially the body of the page. but only the part the human
  24400. 19:17:35is currently seeing.
  24401. 19:17:37And you can specify the content of the viewport
  24402. 19:17:39should have an initial scale of 1.
  24403. 19:17:41So it shouldn't be zoomed in or out.
  24404. 19:17:43And the width that the browser should assume
  24405. 19:17:46should be equal to the device's width.
  24406. 19:17:48These are sort of magical statements that you just have to know
  24407. 19:17:51or copy/paste or transcribe, that just express, to the browser,
  24408. 19:17:55assume that the width of the page is the same thing as the width of the device.
  24409. 19:17:59Don't assume the luxury of a big laptop or desktop computer.
  24410. 19:18:03Now, making only that change, let me go back to my pretend iPhone
  24411. 19:18:08here, using Chrome's developer tools.
  24412. 19:18:10Let me reload the page.
  24413. 19:18:13And now, it's not very effective on this screen, if I were showing you this on,
  24414. 19:18:18is there--
  24415. 19:18:20well, there we go.
  24416. 19:18:21Let's do this.
  24417. 19:18:22There we go.
  24418. 19:18:23So if I zoom in to 100%, this would be on an actual physical device, much more
  24419. 19:18:28readable than it would have been a moment ago,
  24420. 19:18:30even though I realized that demo was not necessarily persuasive.
  24421. 19:18:33But it's as simple as telling the browser
  24422. 19:18:34to resize the thing to the width of the page.
  24423. 19:18:38All right, let me pause here to see if there's any questions, because that
  24424. 19:18:41feels like enough HTML tags.
  24425. 19:18:43We'll add just a couple of more in.
  24426. 19:18:45But for the most part, like HTML tags are
  24427. 19:18:47things you Google and figure out over time, just to build up your vocabulary.
  24428. 19:18:51The basic building blocks are tags, attributes.
  24429. 19:18:54Some attributes have values.
  24430. 19:18:55Some do not.
  24431. 19:18:56And that's sort of the structure of HTML in essence.
  24432. 19:19:00Questions on any of these, though.
  24433. 19:19:01Yeah.
  24434. 19:19:02AUDIENCE: Do attributes have an order?
  24435. 19:19:03SPEAKER 1: Do attributes have an order?
  24436. 19:19:05No, attributes can be in any order, from left to right.
  24437. 19:19:08I tend to be a little nit-picky, and so I alphabetize them,
  24438. 19:19:11if only because then I can easily spot if something's missing,
  24439. 19:19:14if it's not there alphabetically.
  24440. 19:19:16Most people on the internet don't seem to do that.
  24441. 19:19:21Yeah, in the middle.
  24442. 19:19:23Version.
  24443. 19:19:23Yeah, good question.
  24444. 19:19:24I mentioned that HTML is starting to replace
  24445. 19:19:26other languages for user interfaces.
  24446. 19:19:28And it's not just HTML alone.
  24447. 19:19:30It's HTML with CSS, with JavaScript, both of which we'll get a taste of here
  24448. 19:19:34today.
  24449. 19:19:35That rather has been the trend for portability,
  24450. 19:19:37and the ability for companies, for individual programmers,
  24451. 19:19:40to write one version of an app and have it
  24452. 19:19:42work on Android devices and iPhones and Macs and PCs, and the like.
  24453. 19:19:47It is very expensive.
  24454. 19:19:48It is very time-consuming to learn a language like Java
  24455. 19:19:51and write an Android app, learn another language called Swift
  24456. 19:19:54and make an iOS app, not to mention make them look and behave
  24457. 19:19:56the same, not to mention fix a bug in one
  24458. 19:19:59and then remember to fix it in the other.
  24459. 19:20:00I mean, this is just very painful and time-consuming and costly.
  24460. 19:20:05So this standardization on HTML, CSS, and JavaScript,
  24461. 19:20:09even for mobile apps and web apps, has been increasingly compelling,
  24462. 19:20:13because it solves problems like that.
  24463. 19:20:16All right, so let's go ahead and now do something that's finally interactive.
  24464. 19:20:19All of these pages thus far are really just tastes
  24465. 19:20:22of static content, content that does not change.
  24466. 19:20:25Well, let's go ahead and do this.
  24467. 19:20:27Let me introduce one other format of URLs, which looks
  24468. 19:20:31a little something like it did before.
  24469. 19:20:33So slash path, but it could actually be something like this,
  24470. 19:20:36slash path question mark, key equals value.
  24471. 19:20:40You might not have noticed, or cared to notice,
  24472. 19:20:42the URLs in your URL bar every day.
  24473. 19:20:44But these things are everywhere.
  24474. 19:20:46Often when you type into a search engine like Google
  24475. 19:20:49a search query, whatever you just typed ends up in the URL.
  24476. 19:20:52When you click on a link that contains some information,
  24477. 19:20:55there might be a question mark, and then some keys and values.
  24478. 19:20:57There might be an ampersand and more keys and values.
  24479. 19:21:00Here, again, is that very common programming paradigm
  24480. 19:21:02of just associating keys with values.
  24481. 19:21:05We can see this as follows.
  24482. 19:21:07Let me actually go to google.com, in a browser
  24483. 19:21:11here, and let me search for something the internet is filled with, cats.
  24484. 19:21:16Enter, notice now that my URL changed from google.com
  24485. 19:21:20to google.com slash search question mark,
  24486. 19:21:23Q equals cats, ampersand and then a bunch of stuff
  24487. 19:21:27that I don't understand or know.
  24488. 19:21:28So let's just delete it for now, and leave it with the essence of that URL.
  24489. 19:21:33And that still works.
  24490. 19:21:34If I zoom out here, years ago you would get pictures of cats.
  24491. 19:21:37Now you get videos of the movie.
  24492. 19:21:41And then that top query there, is Cats a bad movie.
  24493. 19:21:44But we can also, of course, click on Images.
  24494. 19:21:46And there are the adorable cat, creepy cats.
  24495. 19:21:49All right, this didn't used to happen when we searched for cats.
  24496. 19:21:52But anyhow, the point is that the URL changed to include the user's input.
  24497. 19:21:57And this is such a simple, but such a powerful thing.
  24498. 19:22:00This is how humans provide input to servers.
  24499. 19:22:04They don't manually create the URLs, like I sort of just did.
  24500. 19:22:07But when you fill out a form on the web and you hit Enter,
  24501. 19:22:10typically the URL suddenly changes to include
  24502. 19:22:13whatever you typed in, in the URL, assuming
  24503. 19:22:16the form is using the verb GET.
  24504. 19:22:18That's not ideal.
  24505. 19:22:20If you're typing in a username, a password,
  24506. 19:22:22a credit card information, because you don't want the next person to sit down
  24507. 19:22:25at your laptop to see literally everything you typed in,
  24508. 19:22:27saved in your history.
  24509. 19:22:29So there's another verb, POST, that can hide all of that.
  24510. 19:22:32And it's just sent a little differently.
  24511. 19:22:33But things like this are typically sent via GET,
  24512. 19:22:36and what that means underneath the hood is that your browser is just
  24513. 19:22:39making a request like this, Get/search?
  24514. 19:22:43Q equals, whatever you typed in, the host that you visited, and so forth.
  24515. 19:22:47And hopefully what comes back is a page full of search results, including cats.
  24516. 19:22:52And what's interesting here now is, if I go back to VS Code on my own computer,
  24517. 19:22:57and let me go ahead and create a file called, how about Search.html.
  24518. 19:23:04In Search.html, I'm going to start with some copy/paste from before,
  24519. 19:23:09change my title to search.
  24520. 19:23:11And in the body of this page, I'm going to introduce a form tag.
  24521. 19:23:14And in this form tag, I'm going to have a couple of inputs.
  24522. 19:23:18And the types of inputs are going to be text, and the type of the input
  24523. 19:23:25is going to be submit.
  24524. 19:23:28And this isn't that interesting yet, but let's see
  24525. 19:23:30what is happening in the page itself.
  24526. 19:23:32Let me go back to my directory listing.
  24527. 19:23:34Let me click on Search.html.
  24528. 19:23:36I seem to have the beginning of my own search engine.
  24529. 19:23:39It's not very interesting.
  24530. 19:23:40It's just a text box and a submit button.
  24531. 19:23:43But let's finish my thoughts here.
  24532. 19:23:45So let's specifically give this text box a name of Q,
  24533. 19:23:49which, if you roll back to the late '90s when Larry and Sergey of Google fame
  24534. 19:23:53created Google.com, Q represented query, the query that the human's typing in.
  24535. 19:23:58So the name of this text box shall be text,
  24536. 19:24:01shall be Q. The form is going to use what method?
  24537. 19:24:05Technically it uses GET by default, but I'll
  24538. 19:24:07be explicit and say method equals quote unquote "get."
  24539. 19:24:10Stupidly, it's lowercase in HTML, even though what's in the envelope is indeed
  24540. 19:24:14uppercase, by convention.
  24541. 19:24:16The action of this form, specifically, would ideally go to my own server.
  24542. 19:24:21But we don't really have time today to implement Google itself.
  24543. 19:24:24So we're just going to send the user's request to google.com/search.
  24544. 19:24:28So I'm creating a form, the action of which
  24545. 19:24:31is to send the data to Google's slash search path, using the GET method.
  24546. 19:24:35It's going to send an input called Q, whenever I click this Submit button.
  24547. 19:24:41Let me go back to the browser, reload the page.
  24548. 19:24:44Nothing seems to have changed yet, but, if I search for, let me zoom out,
  24549. 19:24:48so we can see the URL bar.
  24550. 19:24:50Right now I'm in Search.html.
  24551. 19:24:53If I zoom out and search for cats now and click Submit,
  24552. 19:24:57I'm whisked away to google.com.
  24553. 19:24:59But notice that the URL is parameterized, with those key value
  24554. 19:25:02pairs, that key value pair.
  24555. 19:25:04And I get back a whole bunch of cat results.
  24556. 19:25:06And I can very easily now make this a little prettier.
  24557. 19:25:08Right now, it's not ideal that like the human has to move their cursor
  24558. 19:25:11and click in the box.
  24559. 19:25:13And it's a little obnoxious that autocomplete is enabled.
  24560. 19:25:15If I don't want to search for cats anymore,
  24561. 19:25:17well, according to HTML's documentation, I can say something like this.
  24562. 19:25:21Autocomplete equals off, to turn off autocomplete, auto focus
  24563. 19:25:25to automatically put the cursor inside of that text box.
  24564. 19:25:28If I want some explanatory text, I can put placeholder text like quote unquote
  24565. 19:25:32"query."
  24566. 19:25:33And now if I go back to this page and reload,
  24567. 19:25:35now it's a little more user-friendly.
  24568. 19:25:37You see query in kind of gray text.
  24569. 19:25:39The cursor is already there and blinking.
  24570. 19:25:41I don't have to even move my cursor.
  24571. 19:25:43I can search for dogs now, and you didn't see any autocomplete at all.
  24572. 19:25:46Hit enter to submit, and now I'm searching for,
  24573. 19:25:48there we go, adorable dogs, instead.
  24574. 19:25:51So what have I done?
  24575. 19:25:52I've implemented the front end of Google.com, just not the back end.
  24576. 19:25:56To implement the back end, we're obviously
  24577. 19:25:58going to need like a really big database, maybe something like SQL.
  24578. 19:26:01We're going to need some code that like searches the database for dogs or cats,
  24579. 19:26:05or anything else.
  24580. 19:26:06We're going to need Python for something like that.
  24581. 19:26:08And in fact, that's the direction we're steering next week,
  24582. 19:26:09when we implement that back end.
  24583. 19:26:11But today it's all about this front end.
  24584. 19:26:14Or any question, then, about forms, these URL parameters, before we now
  24585. 19:26:20transition to making things look a little prettier, with CSS?
  24586. 19:26:24And then we'll end by making things a little more functional,
  24587. 19:26:27with JavaScript.
  24588. 19:26:29Anything at all?
  24589. 19:26:31No?
  24590. 19:26:31All right, so let's start to answer a couple of the questions that
  24591. 19:26:35came up, by making these pages a little more aesthetically interesting.
  24592. 19:26:40Let's go ahead now and introduce to the mix one other language, as follows.
  24593. 19:26:45Let me go ahead and create a file called Home.html,
  24594. 19:26:48as though I'm making a home page for the very first time.
  24595. 19:26:51And in this page, I'm going to give a title of Home.
  24596. 19:26:53And I'm just going to have like three things.
  24597. 19:26:55First I'm going to have maybe a paragraph of text up here
  24598. 19:27:00at the top, that says something welcoming for my home page,
  24599. 19:27:03like my name, John Harvard, for instance, or John Harvard's home page.
  24600. 19:27:06Then in the middle of the page, I'm going to have some text like,
  24601. 19:27:10welcome to my home page exclamation point!
  24602. 19:27:12And at the bottom of the page, I'm going to have a final paragraph that
  24603. 19:27:16says something like copyright, the copyright symbol, John
  24604. 19:27:19Harvard, or something like that.
  24605. 19:27:21All right, so it's like a web page with three different structural areas,
  24606. 19:27:25made with text.
  24607. 19:27:26This isn't that interesting.
  24608. 19:27:27If I open this page called Home.html, let me go ahead
  24609. 19:27:32and create three quick paragraphs, a first paragraph for John Harvard.
  24610. 19:27:35Inside the middle, I'm going to say something like welcome to my home page
  24611. 19:27:39exclamation point!
  24612. 19:27:40And at the bottom, whoops, at the bottom,
  24613. 19:27:42a little footer that says something like copyright,
  24614. 19:27:45a little simple copyright symbol, and John Harvard's name.
  24615. 19:27:50All right, now let me reload the page.
  24616. 19:27:52And there we go.
  24617. 19:27:53It's a very simple, very underwhelming web page that has three main sections.
  24618. 19:27:57Let's start to now stylize this in an interesting way,
  24619. 19:28:00so that it's a little more aesthetically pleasing.
  24620. 19:28:02First, these aren't really paragraphs.
  24621. 19:28:04They're sort of like areas of the page, divisions, like the header is up here.
  24622. 19:28:08There's like the main part of my screen.
  24623. 19:28:09And then there's the footer of my screen.
  24624. 19:28:11So paragraphs isn't quite right, if these aren't really
  24625. 19:28:13paragraphs of texts.
  24626. 19:28:15I might more properly call them divs or divisions
  24627. 19:28:17of the page, which is a very commonly used tag in HTML, which just has
  24628. 19:28:21this generic rectangular region to it.
  24629. 19:28:24It does not do anything aesthetically, no bold facing, no size changes.
  24630. 19:28:28It just creates an invisible rectangular region, inside of which
  24631. 19:28:32you can start to style the text.
  24632. 19:28:34Or I can take this one step further.
  24633. 19:28:36There's some other tags in HTML, known as semantic tags, that literally
  24634. 19:28:40have names that describe the types of your page, which
  24635. 19:28:42is all the more compelling these days for accessibility, too,
  24636. 19:28:45for screen readers, for search engines, because now, a screen reader, a search
  24637. 19:28:49engine can realize that footer is probably a little fluffy.
  24638. 19:28:52The header might be a little interesting.
  24639. 19:28:54The main part of the page is probably the juicy part,
  24640. 19:28:57that I want users to be able to search for or read aloud, substantively.
  24641. 19:29:01So let's start to stylize this page somehow.
  24642. 19:29:04Let's introduce a style attribute in HTML,
  24643. 19:29:08inside of which is going to be text like this, font size colon
  24644. 19:29:13large, text align colon center.
  24645. 19:29:16On Main, I'm going to add a style attribute and say font size
  24646. 19:29:20medium, text align center.
  24647. 19:29:24And then on the footer, I'm going to say style equals font size
  24648. 19:29:27small, text align center.
  24649. 19:29:32What's going on here?
  24650. 19:29:34Well, in blue is the language we promised,
  24651. 19:29:36called CSS, for Cascading Style Sheets.
  24652. 19:29:39We're not really seeing the Cascading Style Sheet of it yet.
  24653. 19:29:42But in blue here, notice is another very common paradigm.
  24654. 19:29:46It's different syntax now, but how would you
  24655. 19:29:48describe what you're looking at here in blue?
  24656. 19:29:52This is another example of what kind of programming convention?
  24657. 19:29:56AUDIENCE: Key value.
  24658. 19:29:57SPEAKER 1: Yeah, it's just more key value pairs, right?
  24659. 19:30:00It'd be nice if the world standardized how you write key value pairs,
  24660. 19:30:03because we've now seen equal signs and arrows and colons and semicolons,
  24661. 19:30:07and all this.
  24662. 19:30:07But it's just different languages, different choices.
  24663. 19:30:10The key here is font-size, the value is large.
  24664. 19:30:13The other key is text-align, the colon, the value is center.
  24665. 19:30:16The semicolon just separates one key value pair from another.
  24666. 19:30:20Just like in the URL, the ampersand did, in the context of HTTP.
  24667. 19:30:24The designers of CSS used semicolons instead.
  24668. 19:30:27Strictly speaking, this semicolon isn't necessary.
  24669. 19:30:30I tend to include it just for symmetry, but it doesn't matter,
  24670. 19:30:32because there's nothing after that.
  24671. 19:30:34This is a bit of a weird example.
  24672. 19:30:36This is the co-mingling of CSS inside of JavaScript.
  24673. 19:30:41So as of now, you can use the CSS language inside of the quote marks
  24674. 19:30:46in the value of a style attribute.
  24675. 19:30:49We did something a little similarly last two weeks,
  24676. 19:30:52a week plus ago, when we included some SQL inside of Python.
  24677. 19:30:57So again, languages can kind of cross barriers together.
  24678. 19:30:59But we're going to clean this up, because this
  24679. 19:31:01is going to get messy quickly, certainly for large web pages, the size
  24680. 19:31:04of Harvard's or Yale's, or the like.
  24681. 19:31:07So let's see what this looks like.
  24682. 19:31:09Let me go back to my browser window here, reload the page.
  24683. 19:31:13And it's not that different.
  24684. 19:31:14But it's indeed centered, and it's indeed large, medium, and small text.
  24685. 19:31:19And let me make one refinement.
  24686. 19:31:20The copyright symbol actually can be expressed,
  24687. 19:31:22but there's no key on my US keyboard here.
  24688. 19:31:25I can actually magically say ampersand hash 169 semicolon,
  24689. 19:31:30using what's called an HTML entity.
  24690. 19:31:33It turns out there are numeric codes, with this weird syntax, that
  24691. 19:31:36allow you to specify symbols that exist in Macs and PCs and phones,
  24692. 19:31:40but that don't exist on most keyboards.
  24693. 19:31:42If I reload the page now, now it's a proper copyright symbol.
  24694. 19:31:46So minor aesthetic, but it introduces us to these HTML entities.
  24695. 19:31:50So even if you've never seen CSS before, you
  24696. 19:31:53can probably find something kind of dumb about what
  24697. 19:31:56I did here, like poor design.
  24698. 19:31:58It is correct, if my goal was small, medium, and large, bottom up, what
  24699. 19:32:02looks like a bad design, perhaps, even if you've never
  24700. 19:32:07seen this language before.
  24701. 19:32:08Yeah.
  24702. 19:32:09AUDIENCE: Same
  24703. 19:32:09SPEAKER 1: Yeah, I've used the same style three times,
  24704. 19:32:12like copy/paste, or typing the exact same thing again and again.
  24705. 19:32:14It has rarely been a good thing.
  24706. 19:32:17Well, here's where we can take advantage of the design of CSS,
  24707. 19:32:21because it supports what we might call inheritance,
  24708. 19:32:24whereby children inherit the properties, the key value pairs of their parents
  24709. 19:32:29or ancestors.
  24710. 19:32:30And what that means is, I can do this.
  24711. 19:32:32Let me get rid of this text align.
  24712. 19:32:34Let me get rid of this text align.
  24713. 19:32:36Let me get rid of this one.
  24714. 19:32:37I could get rid of the semicolon, too, but I'll leave it for now.
  24715. 19:32:40And let me add all of that style to the parent element, the body,
  24716. 19:32:46so that it sort of cascades down to the header, the main, and the footer tags
  24717. 19:32:51as well.
  24718. 19:32:52And let me close my quotes there, too.
  24719. 19:32:54Now, if I go back to my browser and hit reload, nothing changes.
  24720. 19:32:58But it's a little better designed, right?
  24721. 19:33:00Because if I want to change the text alignment to maybe be right aligned,
  24722. 19:33:03I can now reload the page, and voila, now it's over there.
  24723. 19:33:06I change it in one place, not in three different places.
  24724. 19:33:08So that would seem to be marginally better design.
  24725. 19:33:11And could we do this any more differently?
  24726. 19:33:14Well, it's not that elegant that it's all just in line with my HTML.
  24727. 19:33:20This generally tends to be bad practice, where
  24728. 19:33:22you co-mingle your HTML and your CSS, especially since some of you
  24729. 19:33:26might be really good at laying out the structure of web pages
  24730. 19:33:28and the content and the data, and you might have a horrible sense of design
  24731. 19:33:31or just not care about the aesthetics.
  24732. 19:33:32You might work with a designer, an artist,
  24733. 19:33:34who's much better at all of these fine tunings aesthetically.
  24734. 19:33:37Wouldn't it be nice if you could work on the HTML, they could work on the CSS.
  24735. 19:33:41And you don't have to somehow like literally
  24736. 19:33:43edit the same lines of code as each other.
  24737. 19:33:46Well, just like we can move stuff into header files in C,
  24738. 19:33:50or packages in Python, we can do the same in CSS.
  24739. 19:33:53So I'm actually going to go ahead and do this.
  24740. 19:33:55Let me get rid of all of these style attributes,
  24741. 19:33:58and let me now start to practice a convention of not co-mingling CSS
  24742. 19:34:03with my HTML.
  24743. 19:34:05Let me instead move it into the head of the page, in a style tag,
  24744. 19:34:10instead of an attribute.
  24745. 19:34:11This is one of the rare examples where there
  24746. 19:34:14are attributes that have the same names of tags as vice versa.
  24747. 19:34:16It's not very common, but this one does exist.
  24748. 19:34:19Here's a slightly different syntax for expressing the same key value pairs.
  24749. 19:34:22If I want to apply CSS properties, that is, key value pairs,
  24750. 19:34:26to the header of the page, I say header, and then I use curly braces,
  24751. 19:34:31and inside of those I say font-size large, text-align center.
  24752. 19:34:38Then, if I want to apply some properties to the main section of the page,
  24753. 19:34:42I again do font-size, say, medium, and then I can do text-align center.
  24754. 19:34:47Then, lastly, on the footer of the page, I
  24755. 19:34:49can assign some properties like font-size small, and then text-align
  24756. 19:34:55center semicolon.
  24757. 19:34:57And I don't have to do anything more in my HTML.
  24758. 19:35:00It all just represents the structure of my page.
  24759. 19:35:03But, because of this style tag in the head of the page,
  24760. 19:35:06the browser knows in advance that the moment it
  24761. 19:35:08encounters a header tag, a main tag, or a footer tag,
  24762. 19:35:10it should apply those properties, those styles.
  24763. 19:35:14If I reload the page, other than it being recentered now,
  24764. 19:35:17there's no other changes.
  24765. 19:35:18All we're doing is sort of iteratively improving the design here.
  24766. 19:35:21But now everything's in the top of the file.
  24767. 19:35:24But there's still a bad design here.
  24768. 19:35:26What could I now do that would be smarter?
  24769. 19:35:30Similar problem to before.
  24770. 19:35:32Yeah.
  24771. 19:35:33AUDIENCE: Create it.
  24772. 19:35:33SPEAKER 1: OK, create a new file with just the CSS.
  24773. 19:35:35I like that.
  24774. 19:35:36Let's go there in just one second.
  24775. 19:35:37But even as we're here, there's still a redundancy
  24776. 19:35:40we can probably chip away at.
  24777. 19:35:41Yeah, get rid of the text-align center in three different places, which
  24778. 19:35:45doesn't seem necessary, and perhaps someone
  24779. 19:35:47else, if I get rid of text-align center, what should I add to my style tag
  24780. 19:35:53in order to bring it back, but apply it to everything in the page?
  24781. 19:35:56And the page, if I scroll down, looks like this, in HTML.
  24782. 19:35:59Yeah.
  24783. 19:36:00AUDIENCE: The body.
  24784. 19:36:01SPEAKER 1: Yeah, so the body tag.
  24785. 19:36:02So let me go ahead and say body.
  24786. 19:36:04And then in here, put text-align center.
  24787. 19:36:07And that, now, if I reload the page, has no visual effect,
  24788. 19:36:10but it's just better design, because now I
  24789. 19:36:12factored out that kind of commonality.
  24790. 19:36:14And so, just to make clear what we've been doing here,
  24791. 19:36:16these are all, again, CSS properties, these key value pairs.
  24792. 19:36:19And there's different types of ways of using them.
  24793. 19:36:22And there's this whole taxonomy.
  24794. 19:36:24What we've been doing thus far are what we're going to call type selectors,
  24795. 19:36:27where the type is the name of a tag.
  24796. 19:36:30And so it turns out there's other ways, though, to do this.
  24797. 19:36:33And let's head in this direction.
  24798. 19:36:35Let's go ahead and maybe write our CSS slightly differently,
  24799. 19:36:38because you know what would be nice.
  24800. 19:36:40I bet, after today, once I start creating other files for my home page,
  24801. 19:36:44or John Harvard's home page, I might want
  24802. 19:36:46to have centered text on other pages.
  24803. 19:36:48And I might want to have large text or medium text or small text.
  24804. 19:36:52It'd be nice if I could reuse these properties again and again,
  24805. 19:36:55and kind of create my own library, maybe even
  24806. 19:36:57ultimately putting it in a separate file.
  24807. 19:36:59So let me do this.
  24808. 19:37:00Instead of explicitly applying text-align center to the body,
  24809. 19:37:04let me create a new noun, or an adjective,
  24810. 19:37:07rather, for myself, called centered.
  24811. 19:37:09It has to start with a dot, because what I'm doing
  24812. 19:37:12is inventing my own class, so to speak.
  24813. 19:37:14This has nothing to do with classes in Java or Python.
  24814. 19:37:17Class here is this aesthetic feature.
  24815. 19:37:20And, actually, let me rename these, to be dot large,
  24816. 19:37:22dot medium, and dot small.
  24817. 19:37:26What this is doing for me is it's inventing new words,
  24818. 19:37:29well-named words, that I can now use in this file,
  24819. 19:37:33or potentially in other web pages I make, as follows.
  24820. 19:37:36I can now say, if I want to center the whole body,
  24821. 19:37:39I can say class equals centered.
  24822. 19:37:41On the header tag, I can say class equals large.
  24823. 19:37:45On the main tag I can say class equals medium.
  24824. 19:37:48On the footer tag, I can say class equals small.
  24825. 19:37:50But let me take this one step further.
  24826. 19:37:53As you suggested, why don't I go ahead now
  24827. 19:37:56and let me actually get rid of-- let me grab all of the CSS,
  24828. 19:37:59copy it to my clipboard.
  24829. 19:38:01Let me get rid of the style tag here, and create a new file called Home.css,
  24830. 19:38:08and let me just save all of that same text in a separate file ending in .css,
  24831. 19:38:13nothing else, no HTML whatsoever.
  24832. 19:38:15But let me go back to my Home.html page, and this
  24833. 19:38:18is one of the most annoyingly named tags, because it doesn't really
  24834. 19:38:21mean what it does, Link HREF Home.css rel equals stylesheet.
  24835. 19:38:30So ideally we would have used the link tag for links in web pages,
  24836. 19:38:33but this is link in the sort of conceptual sense.
  24837. 19:38:36We're linking this file to this other one, so that they work together,
  24838. 19:38:39using this hyper-reference, Home.css, the relationship
  24839. 19:38:43of that file to this one is that of stylesheet.
  24840. 19:38:46A stylesheet is a file containing a whole bunch
  24841. 19:38:48of stylizations, a whole bunch of properties, as we just did.
  24842. 19:38:52So here, too, it's underwhelming the effect.
  24843. 19:38:54If I reload the page, nothing changed.
  24844. 19:38:57But now, I not only have a better design here,
  24845. 19:39:01because I can now use those same classes in my second page that I might make,
  24846. 19:39:06my third page, my fourth page, my bio, my resume page, whatever it is I'm
  24847. 19:39:11making on my website here, I can reuse those styles by just
  24848. 19:39:15including one line of code, instead of copying and pasting all of that style
  24849. 19:39:19stuff into file after file after file.
  24850. 19:39:21And heck, if the rest of the world is really
  24851. 19:39:24impressed by my centered class, and my large and medium and small classes,
  24852. 19:39:28I could bundle this up, let other people on the internet download it,
  24853. 19:39:31and I have my own library, my own CSS library, that other people can use.
  24854. 19:39:35Why should you ever invent a centered class again,
  24855. 19:39:37if I already did it for you, stupid and small as this one is.
  24856. 19:39:41But it would be nice now to package this up
  24857. 19:39:43in a way that's usable by other people as well.
  24858. 19:39:47So this is perhaps the best design, when it comes to CSS.
  24859. 19:39:51Use classes where you can, use external stylesheets where you can,
  24860. 19:39:56but don't use the style attribute where we began, which while explicit,
  24861. 19:40:00starts to get messy quickly, especially for large files.
  24862. 19:40:06All right, any questions, then, on this.
  24863. 19:40:11No, all right, so that's class selectors.
  24864. 19:40:13When you specify dot something, that means
  24865. 19:40:16you're selecting all of the tags in the page, that have that particular class,
  24866. 19:40:20and applying those properties.
  24867. 19:40:21So there's a couple of others here, just to give you
  24868. 19:40:23a taste now of what's possible.
  24869. 19:40:25There's so much more that you can actually do with HTML and CSS together.
  24870. 19:40:29Let me go ahead and open up a few examples that I did here in advance.
  24871. 19:40:33Let me go ahead and open up VS Code.
  24872. 19:40:35And let me go ahead and copy my source eight directory.
  24873. 19:40:43Give me one second to grab the source eight directory for today's lectures,
  24874. 19:40:47so that I can now go into my browser, go into some
  24875. 19:40:51of the pre-made examples in source eight,
  24876. 19:40:53and let me open up paragraphs one here.
  24877. 19:40:57So here's something, it's a little subtle.
  24878. 19:41:00But does anyone notice how this is stylized?
  24879. 19:41:04This is just some generic lorem ipsum text again.
  24880. 19:41:07But what's noteworthy stylistically, a book might do this.
  24881. 19:41:12Yeah?
  24882. 19:41:13AUDIENCE: They're bigger.
  24883. 19:41:14SPEAKER 1: Yeah, the first paragraph's a little bigger.
  24884. 19:41:15Why?
  24885. 19:41:16Who knows, it's just a stylistic thing at the beginning of the chapter.
  24886. 19:41:18The first paragraph is bigger.
  24887. 19:41:19How did we do that?
  24888. 19:41:21Well, we can actually explore this in a couple of ways.
  24889. 19:41:23One, I can obviously go into VS Code and show you the code.
  24890. 19:41:26But, now, that we're using Chrome and we're using these developer tools,
  24891. 19:41:29let's again go into them.
  24892. 19:41:30View developer, developer tools, and now notice,
  24893. 19:41:33let me turn off the mobile feature, and let me move the dock back
  24894. 19:41:37to the bottom, just so that it's fully wide.
  24895. 19:41:39We looked at the Network tab before.
  24896. 19:41:41We looked at the mobile button before.
  24897. 19:41:44Now let me click on Elements.
  24898. 19:41:45What's nice about the Elements tab is you can see a pretty printed
  24899. 19:41:49version of the web page's HTML, nicely color-coded, syntax highlighted
  24900. 19:41:54for you, so that you can now henceforth learn from, look at, the source
  24901. 19:41:58code, the HTML source code, of any web page on the internet.
  24902. 19:42:02Notice that my own web page here, it's not that interesting.
  24903. 19:42:05There's a bunch of paragraph tags of lorem ipsum text.
  24904. 19:42:08But notice what I did.
  24905. 19:42:09The very first one, I gave an ID to.
  24906. 19:42:12This is something that you, as a web designer, can do.
  24907. 19:42:14You can give an ID attribute to any tag in a page,
  24908. 19:42:18to give it a unique identifier.
  24909. 19:42:20The onus is on you, not to reuse the word, anywhere else.
  24910. 19:42:22If you reuse it, you've screwed up.
  24911. 19:42:24It's incorrect behavior.
  24912. 19:42:26But I chose an ID of first, just so that I
  24913. 19:42:30have some way of referring to the very first paragraph in this file.
  24914. 19:42:34If I look in the head of the page, and the style tag here,
  24915. 19:42:37notice that I have hash first.
  24916. 19:42:40So just as I use dot for classes, the world of CSS
  24917. 19:42:43uses a hash symbol to represent IDs, unique IDs.
  24918. 19:42:46And what this is telling the browser, whatever element has the first ID,
  24919. 19:42:51F-I-R-S-T, without the hash, apply font-size larger to it.
  24920. 19:42:57And that's why the first paragraph, and only the first paragraph,
  24921. 19:43:00is actually stylized.
  24922. 19:43:01If I actually go into VS Code now, and let
  24923. 19:43:04me go into my source eight directory.
  24924. 19:43:06Let me open up Paragraphs1.html.
  24925. 19:43:09Here is the actual file.
  24926. 19:43:10If I want to change the color of that first paragraph to green, for instance,
  24927. 19:43:14I can do color colon: green.
  24928. 19:43:16Let me close the developer tools, reload the page.
  24929. 19:43:19And now that page is green as well.
  24930. 19:43:22You don't have to just use words.
  24931. 19:43:24You can use hexadecimal.
  24932. 19:43:27What was the hex code for green in RGB?
  24933. 19:43:31Like no red, lots of green, no blue.
  24934. 19:43:34So you could do 00 FF 00, using a hash, which, coincidentally,
  24935. 19:43:38is the same symbol, but it has nothing to do with IDs.
  24936. 19:43:41This is just how Photoshop and web pages represent colors.
  24937. 19:43:44Let's go back here and reload.
  24938. 19:43:46It's the same, although it's a slightly different version of green.
  24939. 19:43:48This is pure green here.
  24940. 19:43:50If I want to change it to red, that would be, let's see, RGB FF 00 00,
  24941. 19:43:56and here I can go and reload.
  24942. 19:43:58Now it's first paragraph red.
  24943. 19:43:59This actually gets pretty tedious quickly.
  24944. 19:44:01Like, if you're a web designer trying to make a website for the first time,
  24945. 19:44:04it actually might be fun to tinker with the website,
  24946. 19:44:06before you open up your editor and you start making changes
  24947. 19:44:09and save and reload.
  24948. 19:44:10That's just more steps.
  24949. 19:44:11So notice what you can do with developer tools,
  24950. 19:44:14too, in Chrome and other browsers.
  24951. 19:44:16When I highlight over this paragraph, under the Elements tab,
  24952. 19:44:19notice that, one, it gets highlighted in blue.
  24953. 19:44:22If I move my cursor, it doesn't get highlighted.
  24954. 19:44:24If I move it, it gets highlighted.
  24955. 19:44:26So it's showing me what that tag represents.
  24956. 19:44:29But notice over here on the right, you can also
  24957. 19:44:32see all of the stylizations of that particular element.
  24958. 19:44:35Some of them are built-in.
  24959. 19:44:37The italicized ones here at the bottom means user agent stylesheet.
  24960. 19:44:40That means this is what Google makes all paragraphs look like by default.
  24961. 19:44:44But in non-italicized here, you see hash first,
  24962. 19:44:48which is my code, that I just changed.
  24963. 19:44:50And if I want to start tinkering with colors, I can do like 00 00 FF Enter.
  24964. 19:44:55I changed it to blue.
  24965. 19:44:57But notice, if I go back to VS Code, I didn't change my original VS Code code.
  24966. 19:45:02This is now purely client side.
  24967. 19:45:04And this is a key detail.
  24968. 19:45:05When I drew that picture earlier of the browser going,
  24969. 19:45:08making a request to the cloud, the server in the cloud and the response
  24970. 19:45:11coming back, the browser, your Mac, your PC, your phone,
  24971. 19:45:14has a copy of all the HTML and CSS, so you can change it here,
  24972. 19:45:18however you actually want.
  24973. 19:45:20And, for instance, you can do this with any website.
  24974. 19:45:22Let's go, say, on a field trip here, to how about Stanford.edu.
  24975. 19:45:29So here's Stanford's website as of today.
  24976. 19:45:31Let's go ahead here and let's see, there's
  24977. 19:45:34their admissions page, campus life, and so forth.
  24978. 19:45:36Let me go ahead and view developer tools on Stanford's page,
  24979. 19:45:41developer tools, elements, you can see all of their HTML.
  24980. 19:45:45And notice it's collapsed, so here is their header.
  24981. 19:45:48Here's their main part, and I'm using my keyboard shortcuts
  24982. 19:45:51to just open and close the tags, to dive in deeper and deeper.
  24983. 19:45:54Suppose you want to kind of mess with Stanford,
  24984. 19:45:56you can actually like right click on any element of a page,
  24985. 19:45:58or control click, Inspect, and that's going to jump you automatically
  24986. 19:46:03to the tag in the Elements tab that shows you that link.
  24987. 19:46:07And notice, if I hover over this LI, notice Stanford's using a list,
  24988. 19:46:11as an unordered list from left to right.
  24989. 19:46:13But it doesn't have to be a bulleted list top to bottom.
  24990. 19:46:16They've used CSS to change it to be a list, from news, events, academics,
  24991. 19:46:20research, health care, campus admission, about.
  24992. 19:46:22Well, so much for admission, that's gone.
  24993. 19:46:25So now, if I close developer tools, now it's gone from Stanford's website.
  24994. 19:46:29But, of course, what have I really done.
  24995. 19:46:32I've just like mutated my own local copy.
  24996. 19:46:35So this is not hacking, even though this might
  24997. 19:46:37be how they do it in TV and the movies.
  24998. 19:46:38It's still there if I reload the page.
  24999. 19:46:40But it's a wonderfully powerful way to, one, just iterate quickly, and try
  25000. 19:46:44different things stylistically, figure out
  25001. 19:46:46how you want to design something, and two, just learn
  25002. 19:46:48how Stanford did something.
  25003. 19:46:50So, for instance, if I right click or control click on admission again,
  25004. 19:46:53go to inspect, and let me go to the LI tag.
  25005. 19:46:56Let me keep going up, up, up, up, up to the UL tag.
  25006. 19:47:00There's going to be a lot going on here.
  25007. 19:47:02But notice, they have applied all of these CSS properties
  25008. 19:47:06to that particular UL tag.
  25009. 19:47:08But notice, here, this is how, it's something like this.
  25010. 19:47:11And we'd have to read more to learn how this works, list style type none,
  25011. 19:47:15this is how they probably got rid of the bullets.
  25012. 19:47:18And what you can do is just tinker.
  25013. 19:47:19Like, all right, well, what does this do?
  25014. 19:47:21Well, let me uncheck it.
  25015. 19:47:22All right, didn't really change anything, font weights, uncheck this,
  25016. 19:47:26there we go.
  25017. 19:47:26So now the margin is changed, the padding around it has changed.
  25018. 19:47:30Let's get rid of this.
  25019. 19:47:31We can just start turning things on and off, just
  25020. 19:47:34to get a sense of how the web page works.
  25021. 19:47:35I'm not really learning anything here so far.
  25022. 19:47:37Let me go to the LI here for, let's go to the admissions one here.
  25023. 19:47:43Margin, there we go, OK.
  25024. 19:47:47So when there's a display property in CSS,
  25025. 19:47:50that's apparently effectively changing things from vertical to horizontal,
  25026. 19:47:53if I turn that off, now Stanford's links all look like this.
  25027. 19:47:56And there are those bullets.
  25028. 19:47:57So again, just default styles, that they've somehow overridden,
  25029. 19:48:00and a good web designer just knows ultimately
  25030. 19:48:03how to do these kinds of things.
  25031. 19:48:06All right, how about a couple of final building blocks,
  25032. 19:48:08before we'll take one more break.
  25033. 19:48:09And then we'll dive in with JavaScript to manipulate this stuff
  25034. 19:48:12programmatically.
  25035. 19:48:13Let me go ahead and open up, how about Paragraphs2 here.
  25036. 19:48:17Let me close this tab, let me go into Paragraphs2, which is premade.
  25037. 19:48:21And this one looks the same, except, when
  25038. 19:48:25I go ahead and inspect this first paragraph,
  25039. 19:48:27notice that I was able to get rid of the ID
  25040. 19:48:29somehow, which is just to say, there's many,
  25041. 19:48:32many ways to solve problems in HTML and CSS,
  25042. 19:48:34just like there is in C and Python.
  25043. 19:48:36Let me look in the head and the style of the page now.
  25044. 19:48:39This is what we might call another type of selector,
  25045. 19:48:45that allows us to specify the paragraph tag,
  25046. 19:48:49that itself happens to be the first child only.
  25047. 19:48:52So you can apply CSS to a very specific child, namely first child.
  25048. 19:48:56There's also syntax for last child, if just the first one
  25049. 19:48:58is supposed to look a little different.
  25050. 19:49:00So, here, I've just gotten out of the business
  25051. 19:49:02of creating my own unique identifier and, instead, I'm
  25052. 19:49:05using this type of selector as well.
  25053. 19:49:08Well, what more can we do?
  25054. 19:49:09Let me go into another example here, called Link1.html,
  25055. 19:49:14and here we have a very simple page that just says visit Harvard.
  25056. 19:49:17But notice it's purple by default, because we've
  25057. 19:49:19been to Harvard.edu before.
  25058. 19:49:21Let's see if we can't maybe stylize Harvard's links
  25059. 19:49:24to be a little different.
  25060. 19:49:25Let me go into Link version 2, now, which looks like this.
  25061. 19:49:30And now Harvard is very red.
  25062. 19:49:33How did I do that?
  25063. 19:49:33Well, let me right click on it, click Inspect,
  25064. 19:49:36and I can start to poke around.
  25065. 19:49:37It looks like my HTML is not at all noteworthy.
  25066. 19:49:40It's just very simple HTML, anchor tag with an HREF.
  25067. 19:49:43So let's look at the style.
  25068. 19:49:45Let me zoom out.
  25069. 19:49:46And we can look at it in two different ways.
  25070. 19:49:48We can literally look at the style, contents here,
  25071. 19:49:51or we can look at Chrome's pretty version of it, over here.
  25072. 19:49:55It looks like my style sheet, in the style tag,
  25073. 19:49:59has changed the color to be red, and the text decoration, which is a new thing,
  25074. 19:50:04but it's another CSS property, to none.
  25075. 19:50:06Notice, if I turn that off, links on the internet
  25076. 19:50:08are underlined by default, which tends to be
  25077. 19:50:10good for familiarity, for visibility, for accessibility.
  25078. 19:50:13But, if it's very obvious what is text and what is a link,
  25079. 19:50:18maybe you change text decoration to none.
  25080. 19:50:21But maybe, watch this, maybe the link comes, the line comes back
  25081. 19:50:25when you hover over it.
  25082. 19:50:26Well, let's look at how I did this in style.
  25083. 19:50:29Notice that I have stylization, and I put my curly braces on the same line
  25084. 19:50:34here, as tends to be convention in CSS.
  25085. 19:50:36Color is red, text decoration is none.
  25086. 19:50:38But, whenever an anchor tag is hovered over,
  25087. 19:50:42you can change the text decoration to be back to the default, underline.
  25088. 19:50:47So, again, just little ways of playing around with the aesthetics of the page,
  25089. 19:50:51once you understand that, really, there's
  25090. 19:50:52just different types of selectors.
  25091. 19:50:54And you might have to remind yourself, look them up occasionally,
  25092. 19:50:56as to what the syntax is.
  25093. 19:50:57But it's just another way of scoping your properties to specific tags.
  25094. 19:51:02Let's look at version 3 of this here, which adds Yale to the mix.
  25095. 19:51:06If I go to Link3.html, maybe I want to have Harvard links red,
  25096. 19:51:11Yale links blue.
  25097. 19:51:12How might I have done this?
  25098. 19:51:14Well, let's right click, and click Inspect.
  25099. 19:51:17And here we might have two links, with a couple of techniques,
  25100. 19:51:21just to, again, emphasize, you can do this so many different ways.
  25101. 19:51:24I gave my Harvard link an ID of Harvard, my Yale link an ID of Yale.
  25102. 19:51:30In my CSS, if we go to the head of the page, I then did this.
  25103. 19:51:34The tag with the Harvard ID, a.k.a.
  25104. 19:51:37#Harvard, should be red, #Yale should be blue,
  25105. 19:51:41and then any anchor tag should have no text decoration,
  25106. 19:51:45unless you hover over it, at which point it should be underlined.
  25107. 19:51:48And so, if I hover over Harvard, it's red underlined, Yale,
  25108. 19:51:52it's blue underlined.
  25109. 19:51:53If I want to get rid of the IDs, I can do this a slightly different way.
  25110. 19:51:56Let me go into Link4.
  25111. 19:51:57Same effect, but notice, I got rid of the IDs now.
  25112. 19:52:00How else can I express myself?
  25113. 19:52:02Well, let's look at the CSS here.
  25114. 19:52:03The anchor tag has no text decoration by default,
  25115. 19:52:06unless you're hovering over it.
  25116. 19:52:08And this is kind of cool.
  25117. 19:52:09This is what we would call, on our list here,
  25118. 19:52:11an attribute selector, where you select tags using CSS notation,
  25119. 19:52:16based on an attribute.
  25120. 19:52:18So this is saying, go ahead and find any anchor tag
  25121. 19:52:21who's HREF value happens to equal this URL, and make it red.
  25122. 19:52:26Do the same for Yale, and make it blue.
  25123. 19:52:28Now, this might not be ideal, because if there's something after the slash,
  25124. 19:52:31these equal signs don't work, because if it's
  25125. 19:52:33a different Harvard or different Yale link, this is a little too precise.
  25126. 19:52:37So let me look at version 5 here, of Link.html.
  25127. 19:52:40Look at this style, and I did this a little smarter.
  25128. 19:52:43This is new syntax.
  25129. 19:52:44And, again, just the kind of thing you look up.
  25130. 19:52:46Star equals means, change any anchor tag who's HREF contains anywhere in it
  25131. 19:52:54Harvard.edu to red, and do the same thing for Yale, based on star equals.
  25132. 19:52:59So star here connotes wildcard.
  25133. 19:53:01So search for Harvard.edu or Yale.edu anywhere in the HREF,
  25134. 19:53:04and if it's there, colorize the link.
  25135. 19:53:07And, again, we could do this all day long, with diminishing returns,
  25136. 19:53:11to actually achieve the same kind of stylizations in different ways.
  25137. 19:53:15And as projects just get larger and larger,
  25138. 19:53:17you just have more and more decisions to make.
  25139. 19:53:19And so you have certain conventions you start to adopt.
  25140. 19:53:21And, indeed, if I may, you have the introduction
  25141. 19:53:25of what are called frameworks, ultimately.
  25142. 19:53:28If you're a full-time web developer, or you're
  25143. 19:53:30working for a company doing the same, you might have internal conventions
  25144. 19:53:33that you adhere to.
  25145. 19:53:34For instance, the company might say, always use classes, don't use IDs.
  25146. 19:53:38Or always use attribute selectors, or don't use this.
  25147. 19:53:41And it wouldn't be necessarily as draconian as that.
  25148. 19:53:44But they might have a style guide of sorts.
  25149. 19:53:46But, what many people, and many companies, do nowadays,
  25150. 19:53:49is they do not come up with all of their own CSS properties.
  25151. 19:53:53They start with something off the shelf, a framework, typically a free and open
  25152. 19:53:57source framework, that just gives them a lot of pretty stylizations
  25153. 19:54:00for free, just by using a third party library.
  25154. 19:54:04And one of the most popular ones nowadays
  25155. 19:54:05is something called Bootstrap, that CS50 uses
  25156. 19:54:07on all of its websites, super-popular in industry as well.
  25157. 19:54:11It's at getbootstrap.com, and this is just to give you a taste of it,
  25158. 19:54:17a website that documents the library that they offer.
  25159. 19:54:20And there's so much documentation here, but let me just go to things like,
  25160. 19:54:24how about components.
  25161. 19:54:26It just gives you, out of the box, the CSS with which you
  25162. 19:54:30can create little alerts.
  25163. 19:54:31If you've ever noticed on CS50's website,
  25164. 19:54:33little colorful warnings at the top of the page, or call
  25165. 19:54:36outs, to draw your attention to things.
  25166. 19:54:37How did we do that?
  25167. 19:54:38It's probably a paragraph tag or a div tag,
  25168. 19:54:41and maybe we changed the font color.
  25169. 19:54:43We changed the background color.
  25170. 19:54:44Or it's a lot of stuff we could absolutely do from scratch,
  25171. 19:54:47but, you know what, why would we reinvent
  25172. 19:54:49the wheel if we can just use Bootstrap.
  25173. 19:54:51So, for instance, let me just scroll down.
  25174. 19:54:53If you've ever seen on CS50's website a yellow warning alert like this,
  25175. 19:54:57let me just zoom in on this.
  25176. 19:55:00We are just using HTML like this.
  25177. 19:55:03We're using a div tag, which, again, is an invisible division,
  25178. 19:55:06a rectangular region of the page.
  25179. 19:55:07But we're using classes called alert and another class called alert warning.
  25180. 19:55:12Those are classes that the folks at Bootstrap invented.
  25181. 19:55:17They associated certain text colors and background
  25182. 19:55:19colors and padding and margin and like other aesthetics with,
  25183. 19:55:23so all we have to do is use those classes.
  25184. 19:55:25Role equals alert, just makes clear to like a screen reader that this
  25185. 19:55:28is an alert, that should probably be recited,
  25186. 19:55:30and whatever's in between the open tag and close tag,
  25187. 19:55:33is what the human would see.
  25188. 19:55:35How do you use something like Bootstrap?
  25189. 19:55:37Well, you just read the documentation.
  25190. 19:55:39Under Getting Started, there is a link tag you copy/paste into your own.
  25191. 19:55:44So let me do this.
  25192. 19:55:45So in Table.html, we had code like this.
  25193. 19:55:49Let me actually read Bootstrap's documentation really fast.
  25194. 19:55:52And they tell me...
  25195. 19:55:53copy/paste this code.
  25196. 19:55:55I'm going to put this into the head of my page.
  25197. 19:55:57And it's quite long, but notice, it's a link tag,
  25198. 19:55:59which I used earlier for my own CSS file, the HREF of which
  25199. 19:56:03is this CDN link, content delivery network, that's
  25200. 19:56:06referring to a specific version of Bootstrap that's available on this day.
  25201. 19:56:09And the file that I'm including is called Bootstrap.min.css.
  25202. 19:56:13This is an actual file I can visit with my browser.
  25203. 19:56:17If I open this in a separate tab, this is the CSS
  25204. 19:56:20that Bootstrap has made freely available to us.
  25205. 19:56:23Crazy long, no white space.
  25206. 19:56:25That's because it's been minimized, just to not
  25207. 19:56:27waste space by adding lots of white space and comments.
  25208. 19:56:29But this contains a whole lot, hundreds, of CSS properties
  25209. 19:56:33that we can reuse, thanks to classes that they invented.
  25210. 19:56:36If I want to use some JavaScript code, I can also copy this script tag.
  25211. 19:56:40But we'll come back to that before long.
  25212. 19:56:41Let me now just make a couple of tweaks to this table.
  25213. 19:56:45If I go into my browser from before, this
  25214. 19:56:48is what it looked like previously, where name and number were
  25215. 19:56:51bold, but centered, and then Carter and David were on the left,
  25216. 19:56:54and the numbers were to the right.
  25217. 19:56:55It's fine.
  25218. 19:56:56It's not that pretty, but it'd be nice if it were a little prettier than that.
  25219. 19:56:59So if we add Bootstrap into it, notice one thing happens first,
  25220. 19:57:03when I reload the page.
  25221. 19:57:04No longer are Chrome's default styles used.
  25222. 19:57:08Now Bootstrap's default styles are used, which
  25223. 19:57:10is a way of enforcing similarity across Chrome, Edge, Firefox,
  25224. 19:57:14Safari, and others.
  25225. 19:57:15Notice it went from a serif font to a sans serif
  25226. 19:57:18font, and something cleaner like this.
  25227. 19:57:19It still looks pretty ugly, but let me go into Bootstrap's documentation.
  25228. 19:57:24Let me go under their content tab, for tables.
  25229. 19:57:30And if I just kind of start skimming this,
  25230. 19:57:32these are some good looking tables, right?
  25231. 19:57:34Like, there's some underlining here, some bolder font.
  25232. 19:57:38There's a dark line.
  25233. 19:57:39If I keep going, ooh, that's getting pretty, too,
  25234. 19:57:41if I want to have a colorful table, like I could figure all of this stuff
  25235. 19:57:44out myself if I want some dark mode here,
  25236. 19:57:47if I want to have alternating highlights, and so forth.
  25237. 19:57:51There's so many different stylizations of tables that I could do myself.
  25238. 19:57:54But I care about making a phone book, not about reinventing these wheels.
  25239. 19:57:58So if I read the documentation closely, it turns out that all I need to do
  25240. 19:58:02is add Bootstrap's table class to my table tag,
  25241. 19:58:06and watch with a simple reload, what my now Table.html file looks like.
  25242. 19:58:11Much nicer, right?
  25243. 19:58:13Might not be what you want, but, my God, with like two lines of code,
  25244. 19:58:16I just really prettied things up.
  25245. 19:58:18And so here, then, is the value of using something like a framework.
  25246. 19:58:21It allows you to actually create much prettier, much more
  25247. 19:58:27user-friendly websites than you might otherwise be able to make on your own,
  25248. 19:58:32certainly quickly.
  25249. 19:58:34In fact, let's iterate one more time on one other example,
  25250. 19:58:37before we introduce a bit of that code.
  25251. 19:58:39Let me go ahead and open up Search.html from before,
  25252. 19:58:44which, recall, looks like this, and Search.html on my browser
  25253. 19:58:49was this very simple Google search.
  25254. 19:58:52And suppose I want to reinvent Google.com's UI a bit more.
  25255. 19:58:56Here's a screenshot of Google.com on a typical day.
  25256. 19:58:59It's got an about link, a store link, Gmail images, these weird dots,
  25257. 19:59:03sign in, their logo.
  25258. 19:59:05It's not appearing well on the screen here,
  25259. 19:59:07but there's a big text box in the middle, and then two buttons,
  25260. 19:59:09Google search, and I'm feeling lucky.
  25261. 19:59:12Well, could I maybe go about implementing this UI myself,
  25262. 19:59:15using some HTML, some CSS, and maybe Bootstrap's help,
  25263. 19:59:19just so I don't have to figure out all of these various stylizations?
  25264. 19:59:23Well, here's my starting point.
  25265. 19:59:24In Search.html, let's go and add in Bootstrap, first and foremost,
  25266. 19:59:29so that we have access to all of their classes that are reusable now.
  25267. 19:59:34And let me go ahead and figure out how to do this.
  25268. 19:59:37Well, just like Stanford's site had like its NAV navigation bar, using a UL,
  25269. 19:59:43but they changed it from being a bulleted list to being left to right,
  25270. 19:59:46I bet I can do something like this myself.
  25271. 19:59:48So let me go into the body of my page and, first,
  25272. 19:59:50based on Bootstrap's documentation, let me add a div called
  25273. 19:59:54a div with a class of container fluid.
  25274. 19:59:57Container fluid is just a class that comes
  25275. 19:59:59with Bootstrap that says, make your web page fluid, that is,
  25276. 20:00:03grow to fill the window.
  25277. 20:00:04So that way it's going to resize nicely.
  25278. 20:00:07I'm going to go ahead and fix my indentation here.
  25279. 20:00:09If you haven't discovered this yet, if you
  25280. 20:00:11highlight multiple lines in VS Code, you can
  25281. 20:00:13hit Tab and indent them all at once.
  25282. 20:00:15So now, I have all of that inside of this div.
  25283. 20:00:17Now, just like in Stanford's site, let's create an unordered list that has maybe
  25284. 20:00:23an LI, called with a class of NAV item, and then in here, whoops, in here,
  25285. 20:00:32let me go ahead and say, A HREF=https://about.google,
  25286. 20:00:42which is the real URL of Google's about page.
  25287. 20:00:44And I'll put the about text in there.
  25288. 20:00:46Then I'm going to close my LI tag here, and I want to do one other thing,
  25289. 20:00:50because I'm using Bootstrap.
  25290. 20:00:52Bootstrap's documentation, if I read it closely,
  25291. 20:00:54says to add a class to your links, called like NAV link, and text dark,
  25292. 20:00:59to make it dark, like black or dark gray, instead of the default blue.
  25293. 20:01:04All right, so I think I have now an about link
  25294. 20:01:08in a navigation part of my screen.
  25295. 20:01:10Let me go ahead and save this and reload.
  25296. 20:01:14All right, so not exactly what I wanted.
  25297. 20:01:16It's a bulleted list, still, so I need to override this somehow.
  25298. 20:01:19Let me read Bootstrap's documentation a little more clearly.
  25299. 20:01:22And let me pretend to do that, for time's sake.
  25300. 20:01:25If I go under content, oops, if I go under components,
  25301. 20:01:28and I go to Navs and Tabs, long story short,
  25302. 20:01:32if you want to create a pretty menu like this, where your links are
  25303. 20:01:35from the left to the right, just like Stanford,
  25304. 20:01:37I essentially need HTML like this.
  25305. 20:01:40And this is subtle, but I left off this class.
  25306. 20:01:42I should have added a class called NAV on my UL.
  25307. 20:01:45So that was my bad.
  25308. 20:01:46Let me go in here and say add class equals
  25309. 20:01:49NAV, and then again, this class NAV item, Bootstrap told me to,
  25310. 20:01:53NAV link text dark, Bootstrap told me to.
  25311. 20:01:56Let me go back to my page here, reload, and OK, still kind of ugly.
  25312. 20:02:02But at least the About link is in the top left hand corner,
  25313. 20:02:05just like it should be in the real google.com.
  25314. 20:02:07Now let me whip up a couple of more links real fast.
  25315. 20:02:10Let me go and do a little copy/paste, though I bet next week
  25316. 20:02:13we can avoid this kind of copy/paste.
  25317. 20:02:15Let me change this link to be Store.google.com.
  25318. 20:02:20The text will be store.
  25319. 20:02:22Let me go ahead and create another one here for Gmail.
  25320. 20:02:26So this one's going to go to, officially, how about,
  25321. 20:02:31technically it's www.google.com/gmail.
  25322. 20:02:35Normally it just redirects.
  25323. 20:02:37And let me grab one more of these.
  25324. 20:02:39And for Google Images, and I'm going to paste this, whoops,
  25325. 20:02:42I'm going to, come on.
  25326. 20:02:44I'm going to put this here, too.
  25327. 20:02:45This is going to be images, and that URL is IMG.hp, is the URL.
  25328. 20:02:53All right, let me go ahead and reload the browser page.
  25329. 20:02:56Now it's coming along, right?
  25330. 20:02:57About, store, Gmail, images.
  25331. 20:02:59It's not quite what I want.
  25332. 20:03:01So I'd have to read the documentation to figure out
  25333. 20:03:03how to maybe nudge one of these over, to start right aligning it.
  25334. 20:03:07And there's a couple of ways to do this.
  25335. 20:03:09But one way is if I want Gmail to move all the way over and push everything
  25336. 20:03:13else, I can say that add some margin to the Gmail list item, margin start auto.
  25337. 20:03:23This is in Bootstrap's documentation, a way of saying whatever space you have,
  25338. 20:03:27just automatically shove everything apart.
  25339. 20:03:29And now, if I reload the page again, now, voila, Gmail and images
  25340. 20:03:34is over to the right.
  25341. 20:03:35All right, so now we're kind of moving along.
  25342. 20:03:37Let me go ahead and add the big blue button to sign in.
  25343. 20:03:40So here with sign in, let me go ahead and, over in my same NAV, yeah,
  25344. 20:03:45so let's go ahead and do one more LI, class equals NAV item.
  25345. 20:03:49And then, inside of this LI tag, what am I going to do?
  25346. 20:03:52Turns out there is a class that can turn a link into a button, if you say BTN,
  25347. 20:03:58for button, and then button primary, makes it blue,
  25348. 20:04:01the HREF for this one is going to be https://accounts.goo
  25349. 20:04:04gle.com/service/login, which is literally where you go if you click
  25350. 20:04:08on that big blue button.
  25351. 20:04:09The role of this link is that of button.
  25352. 20:04:11And then sign in, is going to be the text on it.
  25353. 20:04:15If I now reload the page, now we're getting even closer,
  25354. 20:04:18although it looks a little stupid.
  25355. 20:04:20Notice that sign in is way in the top right hand corner,
  25356. 20:04:22whereas the real google.com has a little bit of margin around it?
  25357. 20:04:26OK, that's an easy fix, too.
  25358. 20:04:28Let me go back into my HTML here.
  25359. 20:04:30Let me add margin-3.
  25360. 20:04:31This, too, is a Bootstrap thing.
  25361. 20:04:33They have a class called m-something.
  25362. 20:04:35The something is a number from like 1 to 5,
  25363. 20:04:38I believe, that adds just some amount of white space.
  25364. 20:04:41So if I reload now, OK, it's just a little prettier.
  25365. 20:04:45And now let me accelerate.
  25366. 20:04:47Just to demonstrate how I can take this home, let me go ahead
  25367. 20:04:50and open up my premade version of this, whereby
  25368. 20:04:55I added to this some final flourishes.
  25369. 20:04:58If I go to Search2.html, I decided to replace their logo
  25370. 20:05:02with just this out of a cat, and notice that I
  25371. 20:05:05re-implemented essentially google.com.
  25372. 20:05:07Here's a text box, here's two buttons, even though they're
  25373. 20:05:10a little washed out on the screen.
  25374. 20:05:11I even figured out how to get dots that look pretty similar to Google's.
  25375. 20:05:14And if we view source, you can see how I kind of finished this code.
  25376. 20:05:18If I go to view developer tools, and I go to elements, and I go into this div,
  25377. 20:05:25and I go into this div, you'll see that here's an image tag for happy cat.
  25378. 20:05:31And I added some classes there to make it fluid, and width 25% of the screen.
  25379. 20:05:35If I go into the form tag, this is the same form tag as before.
  25380. 20:05:38But, notice, I used button tags this time,
  25381. 20:05:40with button and button light classes.
  25382. 20:05:43And then I stylized them in a certain way.
  25383. 20:05:45And so in the end result, if I want to go ahead and search now for birds,
  25384. 20:05:49and click Google search, voila, I've implemented
  25385. 20:05:51something that's pretty darn close to Google.com,
  25386. 20:05:54without even touching raw CSS myself.
  25387. 20:05:57And now here's the value, then, of a framework.
  25388. 20:06:00You can just start to use off the shelf functionality
  25389. 20:06:02that someone else created for you.
  25390. 20:06:04But if you want to make refinements, you don't really
  25391. 20:06:07like the shade of blue that Bootstrap chose, or the gray button,
  25392. 20:06:09or you want to curve things a bit more, that's
  25393. 20:06:11where you can create your own CSS file, and do
  25394. 20:06:14the last mile, sort of fine tuning things.
  25395. 20:06:16And that tends to be best practice.
  25396. 20:06:17Stand on the shoulders of others as much as you can, using libraries.
  25397. 20:06:21And then if you really don't like what the library is doing,
  25398. 20:06:23then use your own skills and understanding of HTML and CSS
  25399. 20:06:26to refine things a bit further.
  25400. 20:06:29But still, after all of that, all of these examples we've done thus far
  25401. 20:06:33are still static, other than the Google one,
  25402. 20:06:35which searches on the real Google.com.
  25403. 20:06:37Let's take a final 5 minute break and we'll
  25404. 20:06:39give you a sense of what we can next do, next week onward, with JavaScript.
  25405. 20:06:43See you in five.
  25406. 20:06:44All right, so I think it's fair to say, we're
  25407. 20:06:48about to see our very last language.
  25408. 20:06:50Next week and final projects are ultimately
  25409. 20:06:52going to be about synthesizing so many of these.
  25410. 20:06:55Thankfully, this language called JavaScript is quite similar
  25411. 20:06:58syntactically to both C and Python.
  25412. 20:07:00And, indeed, if you can imagine doing something in either of those,
  25413. 20:07:03you can probably do it in some form in JavaScript.
  25414. 20:07:05The most fundamental difference today, though,
  25415. 20:07:07is that when you have written C code and Python code thus far,
  25416. 20:07:11you've done it on the server.
  25417. 20:07:12You've done it in the terminal window environment.
  25418. 20:07:14And when you run the code, it's running in the cloud on the server.
  25419. 20:07:17The difference now today with JavaScript is,
  25420. 20:07:20even though you're going to write it in the cloud using VS Code,
  25421. 20:07:23recall that, when a browser gets the page containing this code,
  25422. 20:07:27it's going to get a copy of the HTML, the CSS, and the JavaScript code.
  25423. 20:07:32So JavaScript, that we see today, is all going to be executed in the browser,
  25424. 20:07:37on users' own Macs, PCs, and phones, not in the server.
  25425. 20:07:40JavaScript can be used on the server, using an environment called Node.js.
  25426. 20:07:44It's an alternative to Python or Ruby or Java or other languages.
  25427. 20:07:47We are using it today client side, which is a key difference.
  25428. 20:07:51So in Scratch, let's do this one last time.
  25429. 20:07:53If you wanted to create a variable in Scratch, set encounter equal to 0.
  25430. 20:07:56In JavaScript, it's going to look like this.
  25431. 20:07:59You don't specify the type, but you do use the keyword let,
  25432. 20:08:02and there's a few others as well, that say let counter equal 0 semicolon.
  25433. 20:08:07If you want to increment that variable by one, you in JavaScript
  25434. 20:08:11could say something like, counter equals counter plus 1,
  25435. 20:08:14or you can do it more succinctly, with plus equals,
  25436. 20:08:17or the plus plus is back in JavaScript.
  25437. 20:08:20You can now say counter plus plus semicolon again.
  25438. 20:08:23In Scratch, if you wanted to do a conditional like this,
  25439. 20:08:26asking if x less than y, it looks pretty much like C. The parentheses are,
  25440. 20:08:30unfortunately, back.
  25441. 20:08:32The curly braces here are back, if you have multiple statements in particular.
  25442. 20:08:35But, syntactically, it's pretty much the same as it was for if, for if else,
  25443. 20:08:39and even for it's else if else.
  25444. 20:08:42Unlike Python, it's two words again, else if.
  25445. 20:08:45So quite, quite like C, nothing new beyond that.
  25446. 20:08:49If you want to do something forever in Scratch, you'd use this block.
  25447. 20:08:52In JavaScript, you can do it a few ways, similar to Python, similar to C,
  25448. 20:08:55you just say while true.
  25449. 20:08:57In JavaScript, Booleans are lowercase again, just like in C.
  25450. 20:09:00So it's lowercase true.
  25451. 20:09:02If you want to do something a finite number of times,
  25452. 20:09:04like repeat three times, looks almost like C as well.
  25453. 20:09:08The only difference, really, is using the word let here, instead of INT.
  25454. 20:09:12And, again, you'll use let to create a string, or an INT,
  25455. 20:09:15or any other type of variable in JavaScript.
  25456. 20:09:17The browser will figure out what type you mean from context.
  25457. 20:09:21In C we would have said INT instead.
  25458. 20:09:24Ultimately, this language, and that's it for our tour of JavaScript syntax.
  25459. 20:09:27There's bunches of other features, but syntactically it's
  25460. 20:09:30going to be that accessible, relatively speaking.
  25461. 20:09:32The power of JavaScript running in the user's browser
  25462. 20:09:35is going to be that you can change this thing in memory.
  25463. 20:09:39Think about most any website, that's at all interesting today, that you use.
  25464. 20:09:43It's typically very interactive and dynamic.
  25465. 20:09:45If you're sitting in front of Gmail on a laptop or desktop with the browser tab
  25466. 20:09:49open, and someone sends you an email, all of a sudden,
  25467. 20:09:52another row appears in your inbox, another row, another row.
  25468. 20:09:55How is that implemented?
  25469. 20:09:56Honestly, it could be an HTML table.
  25470. 20:09:58Maybe it's a bunch of divs top to bottom.
  25471. 20:10:00The point, though, is, you don't have to hit Command R or Control
  25472. 20:10:04R to reload the page to see more email.
  25473. 20:10:06It automatically appears every few seconds or minutes.
  25474. 20:10:10How is that working?
  25475. 20:10:11When you visit Gmail.com, you are downloading not just
  25476. 20:10:14HTML and CSS with your initial inbox, presumably.
  25477. 20:10:18You're downloading some JavaScript code, that
  25478. 20:10:20is designed to keep talking every second, every 10 seconds or something,
  25479. 20:10:24to Gmail servers, and they, then, are using their code
  25480. 20:10:28to add another element, another element, another element,
  25481. 20:10:31to the existing DOM, document object model, which is the fancy term for tree
  25482. 20:10:36in memory that represents HTML, so that the web page can continue
  25483. 20:10:40to update in real time.
  25484. 20:10:42Google Maps, same thing.
  25485. 20:10:43If you click and drag and drag and drag, your browser did not
  25486. 20:10:46download the entire world to your Mac or PC by default.
  25487. 20:10:49It only downloaded what's in your viewport, the rectangular region.
  25488. 20:10:52But when you click and drag, it's going to get some more tiles up there,
  25489. 20:10:55some more images, some more images, as you keep dragging, using
  25490. 20:10:58JavaScript, again, behind the scenes.
  25491. 20:11:01So let's actually use JavaScript to start interacting with pages.
  25492. 20:11:04How can we do this?
  25493. 20:11:05We can put the JavaScript code in the head of the page,
  25494. 20:11:08in the body of the page, or even factor it out to a separate file.
  25495. 20:11:12So let's take a look.
  25496. 20:11:13Here is a new version of Hello.html, that, during the break,
  25497. 20:11:17I just added a form to, because it'd be nice if this page didn't just
  25498. 20:11:20say Hello, title, Hello, body, it said, Hello, David, Hello, Carter, Hello,
  25499. 20:11:24whoever uses it.
  25500. 20:11:25I've got a form that I borrowed from some of our earlier code,
  25501. 20:11:28and that form has an input whose ID is name, that also has a submit button.
  25502. 20:11:34But there's no code in this yet.
  25503. 20:11:36So let's add a little bit of JavaScript code as follows.
  25504. 20:11:39Suppose that, when this form is submitted, I want to greet the user.
  25505. 20:11:43How can I do that?
  25506. 20:11:44Well, let's do it the somewhat messy way first.
  25507. 20:11:47I can add an attribute called on submit to the form element,
  25508. 20:11:51and I can say on submit, call the function called greet, close quotes.
  25509. 20:11:56Unfortunately, this function doesn't yet exist.
  25510. 20:11:58But I can make it exist.
  25511. 20:11:59But there's another detail here.
  25512. 20:12:01When the user clicks submit, normally forms get submitted to the server.
  25513. 20:12:04I don't want to do that today.
  25514. 20:12:06I want to just submit the form to the browsers, keep on the same page,
  25515. 20:12:10and just print to the screen, Hello, David, or so forth.
  25516. 20:12:13So I'm also going to go ahead and say, return false.
  25517. 20:12:15And this is a JavaScript way of telling the browser, even when the user tries
  25518. 20:12:20to submit the form, return false.
  25519. 20:12:21Like, no, don't let them actually submit the form.
  25520. 20:12:24But do call this function called greet.
  25521. 20:12:26In the head of my page, I'm going to add a script tag, wherein the language is
  25522. 20:12:30implicitly JavaScript, and has no relationship,
  25523. 20:12:33for those of you who took APCS with Java, just a similarly named language,
  25524. 20:12:37but no relation, I'm going to name a function called Greet.
  25525. 20:12:41Apparently in JavaScript, the way you create a function is you
  25526. 20:12:44literally say the word function instead of Def.
  25527. 20:12:47You don't specify a return type.
  25528. 20:12:49And in this function, I could do something like this, alert quote
  25529. 20:12:54unquote, how about, Hello, there.
  25530. 20:12:57Initially I'm going to keep it simple, using a built-in function called alert,
  25531. 20:13:01which is not a good user interface.
  25532. 20:13:03There are better ways to do this.
  25533. 20:13:04But we're doing something simple first.
  25534. 20:13:06Let me now go ahead and load this page again.
  25535. 20:13:09It still looks as simple as before, with just a simple text box.
  25536. 20:13:12I'll zoom in to make it bigger.
  25537. 20:13:13I'm going to type my name, but I think it's going
  25538. 20:13:15to be ignored when I click Submit.
  25539. 20:13:17It just says, Hello, there.
  25540. 20:13:18And this is, again, this is an ugly user interface.
  25541. 20:13:21It literally says the whole code space URL of the web page
  25542. 20:13:24is saying this to you.
  25543. 20:13:25It's really just meant for simple interactions like this, for now.
  25544. 20:13:29All right, let's have it say Hello, David, somehow.
  25545. 20:13:31Well, how can I do this?
  25546. 20:13:33Well, if this element on the page was given by me a unique ID,
  25547. 20:13:37it'd be nice if, just like in CSS, I can go grab the value of that text box,
  25548. 20:13:41using code.
  25549. 20:13:42And I actually can.
  25550. 20:13:43Let me go ahead and do this.
  25551. 20:13:45Let me store, in a variable called name, the result
  25552. 20:13:49of calling a special function called document.queryselector.
  25553. 20:13:54This query selector function is JavaScript's version
  25554. 20:13:57of what we were doing in CSS, to select nodes,
  25555. 20:14:00using hashes or dots or other syntax.
  25556. 20:14:02It's the same syntax.
  25557. 20:14:04So if I want to select the element whose unique ID is name,
  25558. 20:14:09I can literally just pass, in single or double quotes, hash name,
  25559. 20:14:12just like in CSS.
  25560. 20:14:14That gives me the actual node from the tree.
  25561. 20:14:17It gives me one of these rectangles from the DOM, the document object model.
  25562. 20:14:21If I actually want to get at the specific value therein,
  25563. 20:14:24I need to go one step further and say .value.
  25564. 20:14:27So, similar in spirit to Python, where we
  25565. 20:14:29saw a lot of dot notation, where you can go inside an object,
  25566. 20:14:32inside of an object, that's what's going on.
  25567. 20:14:34Long story short, in JavaScript, there is a special global variable
  25568. 20:14:38called document, that lets you just do stuff with the document, the web page
  25569. 20:14:41itself.
  25570. 20:14:42One of those functions is called query selector.
  25571. 20:14:44That function returns to you whatever it is you're selecting.
  25572. 20:14:47And dot value means go inside of that rectangle,
  25573. 20:14:51and grab the actual text that the human typed in.
  25574. 20:14:54So if I want to now say, Hello, to that person,
  25575. 20:14:58the syntax is a little different from C and Python.
  25576. 20:15:01I can use concatenation, which actually does exist in Python,
  25577. 20:15:03but we didn't use it much.
  25578. 20:15:04I can go ahead and say hello, quote unquote "Hello," plus name.
  25579. 20:15:10All right, now, if I go back to the browser window,
  25580. 20:15:13reload the page, to get the latest version of the code, type in David,
  25581. 20:15:16and click Submit, now I see, Hello, David.
  25582. 20:15:20Not the best website, but it does demonstrate how
  25583. 20:15:23I can start to interact with the page.
  25584. 20:15:25But let me stipulate that this co-mingling of languages
  25585. 20:15:29is never a good thing.
  25586. 20:15:30It's fine to use classes, but using style
  25587. 20:15:33equals quote unquote and a whole bunch of CSS,
  25588. 20:15:35that was not going to scale well, once you have lots and lots of properties.
  25589. 20:15:38Same here, once you have more and more code,
  25590. 20:15:40you don't want to just put your code inside of this on submit handler.
  25591. 20:15:44So there's a better way.
  25592. 20:15:45Let's get rid of that on summit attribute,
  25593. 20:15:48and literally never use it again.
  25594. 20:15:50That was for demonstration's sake only.
  25595. 20:15:52And let's do this.
  25596. 20:15:53Let me move the script tag, actually, just below the form,
  25597. 20:15:57but still inside the body, so that the script tag exists only
  25598. 20:16:01after the form tag exists, logically.
  25599. 20:16:04Just like in Python, your code is read top to bottom, left to right.
  25600. 20:16:08And let me now do this.
  25601. 20:16:10Let me define this function called Greet, and then
  25602. 20:16:13let me do this, document.queryselector, let me select the form on the page.
  25603. 20:16:18It doesn't have a unique ID.
  25604. 20:16:20It doesn't need to.
  25605. 20:16:21I can just reference it by name, form, because there's only one of them.
  25606. 20:16:24And let me call this special function, add event listener.
  25607. 20:16:28This is a function that listens for events.
  25608. 20:16:31Now this is actually a term of art within programming.
  25609. 20:16:34Many different languages are governed by events.
  25610. 20:16:37And pretty much any user interface is governed by events, especially phones.
  25611. 20:16:40On phones, you have touches, and you have drags, and you have long press,
  25612. 20:16:45and you have pinch, and all of these other gestures.
  25613. 20:16:47On your Mac or PC you have click, you have drag,
  25614. 20:16:49you have key down, key up, as you're moving your hands up and down
  25615. 20:16:52on the keyboard.
  25616. 20:16:53This is a non-exhaustive list of all of the events
  25617. 20:16:57that you can listen for in the context of web programming.
  25618. 20:16:59And this might be a throwback to Scratch, where, recall,
  25619. 20:17:02Scratch let you broadcast events.
  25620. 20:17:04And we had the two puppets sort of talking to one another via Events.
  25621. 20:17:07In the world of web programming, game programming, any human physical device
  25622. 20:17:11these days, they're just governed by events.
  25623. 20:17:14And you write code that listens for these events happening.
  25624. 20:17:16So what do I want to listen for?
  25625. 20:17:18Well, I want to add an event listener for the Submit event.
  25626. 20:17:21And when that happens, I want to call the Greet function, like this.
  25627. 20:17:26So this is kind of interesting.
  25628. 20:17:28Thank you, I have my Greet function as before, no changes.
  25629. 20:17:32But I'm adding one line of code down here.
  25630. 20:17:34I'm telling the browser to use document.queryselector
  25631. 20:17:38to select the form.
  25632. 20:17:39Then I'm adding an event listener, specifically for the Submit event.
  25633. 20:17:42And when that happens, I call Greet.
  25634. 20:17:44Notice I am not using parentheses after Greet.
  25635. 20:17:47I don't want to call Greet right away.
  25636. 20:17:49I want to tell the browser to call Greet, when it hears this Submit event.
  25637. 20:17:55Now let me go ahead and deliberately, I think, trip over something
  25638. 20:18:03here, let me type in my name, David, submit, and there we go.
  25639. 20:18:08All right, Hello, David.
  25640. 20:18:09All right, but let's now make this slightly better designed.
  25641. 20:18:13Right now, I'm defining a function Greet, which is fine.
  25642. 20:18:16But I'm only using it in one place.
  25643. 20:18:18And you might recall, we stumbled on this in Python,
  25644. 20:18:21where I was like, why are we creating a special function called get value
  25645. 20:18:24when we're only using it like one line later?
  25646. 20:18:26And we introduced what type of function in Python the other day?
  25647. 20:18:29AUDIENCE: Lambda.
  25648. 20:18:30SPEAKER 1: Yeah, so lambda functions, anonymous functions.
  25649. 20:18:33You can actually do this in JavaScript as well.
  25650. 20:18:35If I want to define a function all at once, I can actually do this.
  25651. 20:18:40Let me cut this onto my clipboard, paste it over here.
  25652. 20:18:43Let me fix all of the alignment.
  25653. 20:18:45Let me get rid of the name.
  25654. 20:18:46And I can actually, now, do this.
  25655. 20:18:50The syntax is a little weird.
  25656. 20:18:52But using now just these four lines of code, I can do this.
  25657. 20:18:56I can tell the browser to add an event listener for the Submit event.
  25658. 20:18:59And then when it hears that, call this function that has no name.
  25659. 20:19:03And unlike Python, this function can have multiple lines,
  25660. 20:19:06which is actually a nice thing.
  25661. 20:19:07It looks a little weird.
  25662. 20:19:08There's a lot of indentation in curly braces going on now.
  25663. 20:19:11But you can think of this as just being, run these two lines of code,
  25664. 20:19:15when the form is submitted.
  25665. 20:19:18But if I want to block the form from actually being submitted,
  25666. 20:19:20I've got to do one other thing.
  25667. 20:19:21And you would only know this from being told it or reading the documentation.
  25668. 20:19:24I need to do this function, prevent default,
  25669. 20:19:28passing in this E argument, which is a variable that represents
  25670. 20:19:32the event, more on that another time, that
  25671. 20:19:33just allows us to prevent whatever the default
  25672. 20:19:36handling of that particular event is.
  25673. 20:19:39So long story short, this is representative of the type of code
  25674. 20:19:42you might write in JavaScript, whereby you can actually interact
  25675. 20:19:45with your code, the user's actual form.
  25676. 20:19:48And we can do interesting things, too.
  25677. 20:19:50Built into browsers nowadays is functionality like this.
  25678. 20:19:53So here's a very simple example, that has just three buttons in it, one red,
  25679. 20:19:57one green, one blue.
  25680. 20:19:58Well, it turns out using JavaScript, you can control
  25681. 20:20:00the CSS of a page programmatically.
  25682. 20:20:02I can change the background of the body of the page
  25683. 20:20:05to red, to green, to blue, just by listening for clicks on these buttons,
  25684. 20:20:10and then changing CSS properties.
  25685. 20:20:12Just to give you a taste of this, if I view the page's source,
  25686. 20:20:15similar code here, I can select the red button by an ID
  25687. 20:20:19that I apparently defined on it, right up here.
  25688. 20:20:22I can add an event listener, this time not for submit, but for click.
  25689. 20:20:25And when it's clicked, I execute this one line of code.
  25690. 20:20:28And this one line of code we haven't seen before,
  25691. 20:20:30but you can go into the body of the page, its style property,
  25692. 20:20:33and you can change its background color to red.
  25693. 20:20:36This is one example of two different groups
  25694. 20:20:38not talking to one another in advance.
  25695. 20:20:40In CSS, properties that have two words are usually hyphenated,
  25696. 20:20:43like background-color.
  25697. 20:20:45Unfortunately, in JavaScript, if you do something dash something,
  25698. 20:20:48that's subtraction, which is logically nonsensical here.
  25699. 20:20:52So in CSS, you can convert background-color to, in JavaScript,
  25700. 20:20:56background Color, where you capitalize the C,
  25701. 20:20:59and you get rid of the minus sign.
  25702. 20:21:01What else can we do here?
  25703. 20:21:03Well, back in the day, there used to be a blink tag.
  25704. 20:21:05And it's one of the few historical examples
  25705. 20:21:07of a tag that was removed from HTML, because in the late '90s, early 2000s,
  25706. 20:21:12this is what the web looked like.
  25707. 20:21:14There was a lot of this kind of stuff.
  25708. 20:21:16There was even a marquee that would move text
  25709. 20:21:18from left to right over the screen.
  25710. 20:21:19And the web was a very ugly place.
  25711. 20:21:21I will admit, my very first web page probably used both of these tags.
  25712. 20:21:25But how can we bring it back?
  25713. 20:21:26Well, this is a version of the blink tag implemented in JavaScript.
  25714. 20:21:29How?
  25715. 20:21:30I wrote some code in this example, that waits every 500 milliseconds to change
  25716. 20:21:35the CSS of the page to be visible, invisible, visible,
  25717. 20:21:39invisible, because built into JavaScript is support for a clock.
  25718. 20:21:42So you can just do something on some sort of schedule.
  25719. 20:21:45Let me go ahead and open up this example, autocomplete.
  25720. 20:21:47So let me zoom back out.
  25721. 20:21:49In Autocomplete.html, I whipped up as an example, that has just a text box,
  25722. 20:21:53but I also grabbed the dictionary from problem
  25723. 20:21:56set 5 speller, so that if I want to search for something like Apple,
  25724. 20:22:00this searches that 140,000 words, using JavaScript,
  25725. 20:22:04to create what we know in the world of the web as autocomplete.
  25726. 20:22:07When you start searching for something, you
  25727. 20:22:09should start to see words that start with that phrase.
  25728. 20:22:11And sure enough, if I search for something like banana,
  25729. 20:22:14here's the three variants of bananas that appear in that file, and so forth.
  25730. 20:22:17How is that working?
  25731. 20:22:18Just JavaScript, when it finds matching words,
  25732. 20:22:21it's just updating the DOM, the tree in the computer's memory,
  25733. 20:22:24to show more and more text, or less.
  25734. 20:22:27And for one final example, this is how programs like DoorDash and Google Maps
  25735. 20:22:34and Uber Eats and so work.
  25736. 20:22:35You have built into browsers today some fancy APIs, application programming
  25737. 20:22:40interfaces, whereby you can ask for information about the user's device.
  25738. 20:22:44For instance, here, I wrote a program, in Geolocation.html, that's
  25739. 20:22:47apparently asking to know my location.
  25740. 20:22:49All right, let me go ahead and allow it this time,
  25741. 20:22:51if that's something you're comfortable with on your own device.
  25742. 20:22:54It's taking a moment, because sometimes these things take a little while
  25743. 20:22:57to analyze.
  25744. 20:22:58But, hopefully, in just a moment, there are apparently my GPS coordinates,
  25745. 20:23:02and as a final flourish today, for what you can do with a little bit of HTML
  25746. 20:23:06for your structure, CSS for your style, and now
  25747. 20:23:08JavaScript for your logic, which we'll tie in again next week, let me go ahead
  25748. 20:23:13and search Google for those GPS coordinates.
  25749. 20:23:15Zoom in here on Google Maps, and if we zoom in, in, in,
  25750. 20:23:21OK, we're pretty close.
  25751. 20:23:22We're not on that street, but there, oh, there it is, actually.
  25752. 20:23:26There is the marker it had put for us.
  25753. 20:23:27We're indeed here in Memorial Hall.
  25754. 20:23:30So all that with JavaScript, but the basic understanding
  25755. 20:23:32of the DOM and the document object model,
  25756. 20:23:34we'll pick up where we left off next week.
  25757. 20:23:36And now add a back-end.
  25758. 20:23:37See you next time.
  25759. 20:23:37[MUSIC PLAYING]
  25760. 20:24:56DAVID: All right.
  25761. 20:24:57So this is CS50 and this is week nine, and this is it
  25762. 20:25:01in terms of programming fundamentals.
  25763. 20:25:03Today, we come rather full circle with so many of the languages
  25764. 20:25:06that we've been looking at over the past several weeks.
  25765. 20:25:08And with HTML and CSS and JavaScript last week,
  25766. 20:25:11we're going to add back into the mix, Python and SQL.
  25767. 20:25:14And with that, do we have the ability to program for the web.
  25768. 20:25:18And even though this isn't the only user interface out
  25769. 20:25:20there, increasingly-- or people certainly using laptops and desktops
  25770. 20:25:23and a browser to access applications that people have written,
  25771. 20:25:26but it's also, increasingly, the way that mobile apps are written as well.
  25772. 20:25:31There are languages called Swift for iOS,
  25773. 20:25:33there are languages called Java for Android,
  25774. 20:25:35but coding applications in both of those language
  25775. 20:25:38means knowing twice as many language, building twice as many applications,
  25776. 20:25:42potentially.
  25777. 20:25:42So we're increasingly seeing, for better or for worse,
  25778. 20:25:45that the world is starting to really standardize,
  25779. 20:25:47at least for the next some number of years, on HTML, CSS, and JavaScript
  25780. 20:25:51coupled with other languages like Python and SQL on the so-called backend.
  25781. 20:25:55And so today, we'll tie all of those together
  25782. 20:25:57and give you the last of the tools in your toolkit with which
  25783. 20:26:00to tackle final projects to go off into the real world,
  25784. 20:26:03ultimately, and somehow solve problems with programming.
  25785. 20:26:05But we need an additional tool today, and we've sort of outgrown HTTP server.
  25786. 20:26:11This is just a program that comes on certain computers
  25787. 20:26:14that you can install for free, happens to be
  25788. 20:26:16written in a language called JavaScript, but it's a program
  25789. 20:26:18that we've been using to run a web server in VSCO.
  25790. 20:26:22But you can run it on your own Mac or PC or anywhere else.
  25791. 20:26:24But all this particular HTTP server does is
  25792. 20:26:28serve up static content like HTML files, CSS files,
  25793. 20:26:32JavaScript files, maybe images, maybe video files, but just static content.
  25794. 20:26:36It has no ability to really interact with the user beyond simple clicks.
  25795. 20:26:41You can create a web form and serve it visually using HTTP server,
  25796. 20:26:46but if the human types in input into a form and click Submit, unless you
  25797. 20:26:50submit it elsewhere to something like google.com like we did last time,
  25798. 20:26:53it's not actually going to go anywhere because this server can't actually
  25799. 20:26:56process the requests that are coming in.
  25800. 20:26:59So today, we're going to introduce another type of server that
  25801. 20:27:02comes with Python that allows us to not only serve web pages
  25802. 20:27:06but also process user input.
  25803. 20:27:07And recall that all that input is going to come ultimately from the URL,
  25804. 20:27:11or more deeply inside of those virtual envelopes.
  25805. 20:27:14So here's the canonical URL we talked about last week for random website
  25806. 20:27:17like www.example.com.
  25807. 20:27:20And I've highlighted the slash to connote the root of the web server,
  25808. 20:27:23like the default folder where, presumably, there's
  25809. 20:27:26a file called index.html or something else in there.
  25810. 20:27:29Otherwise, you might have a more explicit mention
  25811. 20:27:32of the actual file named file.html.
  25812. 20:27:34You can have folders, as you probably gleaned from the most recent problem
  25813. 20:27:37set.
  25814. 20:27:38You can have files in folders like this, and these
  25815. 20:27:40are all examples of what a programmer would typically call a path.
  25816. 20:27:44So it might not just be a single word, it
  25817. 20:27:45might have multiple slashes and multiple folders and some folders and files.
  25818. 20:27:49But this is just more generally known as a path.
  25819. 20:27:51But there's another term of our, that's essentially equivalent,
  25820. 20:27:54that we'll introduce today.
  25821. 20:27:55This is also synonymously called a route, which is maybe
  25822. 20:27:59a better generic description of what these things are because it turns out
  25823. 20:28:03they don't have to map to, that is, refer
  25824. 20:28:05to a specific folder or a specific file, you
  25825. 20:28:08can come up with your own routes in a website.
  25826. 20:28:11And just make sure that when the user visits that, you give them
  25827. 20:28:13a certain website page.
  25828. 20:28:14If they visit something else, you give them a different web page.
  25829. 20:28:17It doesn't have to map to a very specific file, as we'll soon see.
  25830. 20:28:20And if you want to get input from the user, just like Google does,
  25831. 20:28:23like q=cats, you can add a question mark at the end of this route.
  25832. 20:28:28The key, or the HTTP parameter name that you want to define for yourself,
  25833. 20:28:32and then equal sum value that, presumably, the human typed in.
  25834. 20:28:35If you have more of these, you can put an ampersand,
  25835. 20:28:37and then more key equals value pairs ampersand, repeat, repeat, repeat.
  25836. 20:28:41The catch, though, is that using the tools that we had last week alone,
  25837. 20:28:46we don't really have the ability to parse, that is, to analyze and extract
  25838. 20:28:51things like q equals cats.
  25839. 20:28:53You could have appended question mark q equals cats or anything else
  25840. 20:28:56to any of URLs in your home page for problem set eight,
  25841. 20:29:00but it doesn't actually do anything useful, necessarily,
  25842. 20:29:04unless you use some fancy JavaScript.
  25843. 20:29:06The server is not going to bother even looking in that for you.
  25844. 20:29:09But today, we're going to introduce using a bit of Python.
  25845. 20:29:12And in fact, we're going to use a web server implemented in Python, instead
  25846. 20:29:15of using HTTP server alone, to automatically, for you,
  25847. 20:29:19look for any key value pairs after the question mark
  25848. 20:29:22and then hand them to you in the form of a Python dictionary.
  25849. 20:29:25Recall that a dictionary in Python, a dict object, is just key value pairs.
  25850. 20:29:29That seems like a perfect fit for these kinds of parameters.
  25851. 20:29:33And you're not going to have to write that code yourself.
  25852. 20:29:36It's going to be handed to you by way of what's called a framework.
  25853. 20:29:39So this will be the second of two frameworks,
  25854. 20:29:41really, that we look at in the class.
  25855. 20:29:43And a framework is essentially a bunch of libraries
  25856. 20:29:46that someone else wrote and a set of conventions,
  25857. 20:29:48therefore, for doing things.
  25858. 20:29:49So those of you who really started dabbling with Bootstrap
  25859. 20:29:52this past week to make your home pages prettier and nicely laid out,
  25860. 20:29:56you are using a framework.
  25861. 20:29:57Why?
  25862. 20:29:58Well, you're using libraries, code that someone else wrote, like all the CSS,
  25863. 20:30:01maybe some of the JavaScript that the Bootstrap people wrote for you.
  25864. 20:30:04But it's also a framework in the sense that you have to go all in.
  25865. 20:30:08You have to use Bootstraps classes, and you
  25866. 20:30:11have to lay out your divs or your spans or your table tags
  25867. 20:30:15in a sort of Bootstrap-friendly way.
  25868. 20:30:17And it's not too onerous, but you're following conventions
  25869. 20:30:19that a bunch of humans standardized on.
  25870. 20:30:21So similarly, in the world of Python, is there another framework
  25871. 20:30:25we're going to start using today.
  25872. 20:30:26And whereas Bootstrap is used for CSS and JavaScript,
  25873. 20:30:30Flask is going to be used for Python.
  25874. 20:30:32And it just solves a lot of common problems for us.
  25875. 20:30:34It's going to make it easier for us to analyze the URLs
  25876. 20:30:38and get key value pairs, it's going to make it easier
  25877. 20:30:40for us to find files or images that the human wants
  25878. 20:30:43to see when visiting our website.
  25879. 20:30:45It's even going to make it easier to send emails automatically,
  25880. 20:30:48like when someone fills out a form.
  25881. 20:30:49You can dynamically, using code, send them an email as well.
  25882. 20:30:52So Flask, and with it some related libraries,
  25883. 20:30:55it's just going to make stuff like that easier for us.
  25884. 20:30:58And to do this, all we have to do is adhere to some pretty minimalist
  25885. 20:31:03requirements of this framework.
  25886. 20:31:05We're going to have to create a file for ourselves called app.py,
  25887. 20:31:08this is where our web app or application is going to live.
  25888. 20:31:11If we have any libraries that we want to use, the convention in the Python world
  25889. 20:31:15is to have a very simple text file called requirements.txt
  25890. 20:31:19where you list the names of those libraries,
  25891. 20:31:21top to bottom, in that text file, similar in spirit to the include
  25892. 20:31:26or the import statements that we saw in C and Python, respectively.
  25893. 20:31:30We're going to have a static folder or static directory, which
  25894. 20:31:33means any files you create that are not ever going to change,
  25895. 20:31:36like images, CSS files, JavaScript files,
  25896. 20:31:39they're going to go in this folder.
  25897. 20:31:40And then lastly, any HTML that you write,
  25898. 20:31:43web pages you want the human to see, are going
  25899. 20:31:45to go in a folder called templates.
  25900. 20:31:47So this is, again, evidence of what we mean by a framework.
  25901. 20:31:50Do you have to make a web app like this?
  25902. 20:31:52No, but if you're using this particular framework,
  25903. 20:31:54this is what people decided would be the human conventions.
  25904. 20:31:58If you've heard of other frameworks like Django or asp.net or bunches of others,
  25905. 20:32:02there are just different conventions out there for creating applications.
  25906. 20:32:06Flask is a very nice microframework in that that's it.
  25907. 20:32:10All you have to do is adhere to these pretty minimalist requirements
  25908. 20:32:13to get some code up and running.
  25909. 20:32:16All right, so let's go ahead and make a web app.
  25910. 20:32:19Let me go ahead and switch over to VS Code
  25911. 20:32:21here, and let me practice what I'm preaching here
  25912. 20:32:23by first creating app.py.
  25913. 20:32:25And let's go ahead and create an application that very simply,
  25914. 20:32:29maybe, says hello to the user.
  25915. 20:32:31So something that, initially, is not all that dynamic, pretty static, in fact.
  25916. 20:32:35But we'll build on that as we've always done.
  25917. 20:32:37So in app.py, what I'm going to do first is exactly the line of code
  25918. 20:32:41I had on the screen earlier.
  25919. 20:32:43From Flask, import Flask, with a capital F second and a lowercase f first.
  25920. 20:32:49And I'm also going to preemptively import
  25921. 20:32:52a couple of functions, render template, and request.
  25922. 20:32:56More on those in just a bit.
  25923. 20:32:58And then below that, I'm going to say, go ahead and do this.
  25924. 20:33:00Give me a web-- a variable called app that's
  25925. 20:33:03going to be the result of calling the Flask function and passing in it
  25926. 20:33:07this weird incantation here, name.
  25927. 20:33:10So we've seen this a few weeks back when we played around with Python
  25928. 20:33:13and we had that if main thing at the bottom of the screen.
  25929. 20:33:16For now, just know that __name__ refers to the name of the current file.
  25930. 20:33:21And so this line here, simple as it is, tells Python, hey, Python,
  25931. 20:33:26turn this file into a Flask application.
  25932. 20:33:30Flask is a function that just figures out, then, how to do the rest.
  25933. 20:33:33The last thing I'm going to do for this very simple web application is this.
  25934. 20:33:37I'm going to say that I'm going to have a function called
  25935. 20:33:41index that takes no arguments.
  25936. 20:33:42And whenever this function is called, I want
  25937. 20:33:44to return the results of rendering a template called index.html.
  25938. 20:33:50And that's it.
  25939. 20:33:51So let's assume there's a file somewhere, haven't created
  25940. 20:33:53it yet, called index.html.
  25941. 20:33:55But render template means render this file
  25942. 20:33:57that is printed to the user's screen, so to speak.
  25943. 20:34:01The last thing I'm going to do is I have to tell Flask
  25944. 20:34:03when to call this index function.
  25945. 20:34:06And so I'm going to tell it to define a route for, quote unquote, "slash."
  25946. 20:34:11And that's it.
  25947. 20:34:13So let's take a look at what I just created here.
  25948. 20:34:15This is slightly new syntax, and it's really the only weirdness
  25949. 20:34:18that we'll have today in Python.
  25950. 20:34:19This is what's known in Python is what's called a decorator.
  25951. 20:34:22A decorator is a special type of function
  25952. 20:34:24that modifies, essentially, another function.
  25953. 20:34:27For our purposes, just know that on line six this says,
  25954. 20:34:30hey Python, define a route for slash, the default
  25955. 20:34:33page on my website application.
  25956. 20:34:35The next two lines, seven and eight, say, hey Python,
  25957. 20:34:37define a function called index, takes no arguments.
  25958. 20:34:40And the only thing you should ever do is return render template of quote unquote
  25959. 20:34:45"index.html."
  25960. 20:34:47All right, so that's it.
  25961. 20:34:48So really, the next question, naturally, should be all right, well,
  25962. 20:34:51what is in index.html?
  25963. 20:34:55Well, let me go ahead and do that next.
  25964. 20:34:56Let me create a directory called templates, practicing, again,
  25965. 20:35:00what I preached earlier.
  25966. 20:35:01So I'm going to create a new empty directory called templates,
  25967. 20:35:04I'm going to go and CD into that directory
  25968. 20:35:08and then do code of index.html.
  25969. 20:35:11So here is going to be my index page.
  25970. 20:35:13And I'm going to do a very simple web page, doc type HTML.
  25971. 20:35:16I'm just going to borrow some stuff from last week.
  25972. 20:35:18HTML language equals English.
  25973. 20:35:20I'll close that tag.
  25974. 20:35:21I'll then do a head tag, I'll do a meta tag, the name of which is viewport.
  25975. 20:35:25This makes my site recall responsive.
  25976. 20:35:28That is, it just grows and shrink to fit the size of the device.
  25977. 20:35:30The initial scale for which is going to be one, and the width of which
  25978. 20:35:34is going to be device width.
  25979. 20:35:36So I'm typing this out, I have it printed here.
  25980. 20:35:38This is stuff I typically copy paste.
  25981. 20:35:40But then lastly, I'm going to add in my title, which will just
  25982. 20:35:42be hello for the name of this app.
  25983. 20:35:44And then the body--
  25984. 20:35:45whoops, Bobby.
  25985. 20:35:46The body of this tag will be--
  25986. 20:35:50there we go.
  25987. 20:35:51The body of this page, rather, will just be hello comma world.
  25988. 20:35:54So very uninteresting and really a regression to where we began last week.
  25989. 20:35:58But let's go now and experiment with these two files.
  25990. 20:36:01I'm not going to bother with a static folder
  25991. 20:36:03right now, because I don't have any other files that I want to serve up.
  25992. 20:36:06No images, no CSS, nothing like that.
  25993. 20:36:08And honestly, requirements.txt is going to be pretty simple.
  25994. 20:36:11I'm going to go requirements.txt and just say make sure the system has
  25995. 20:36:15access to the Flask library itself.
  25996. 20:36:18All right, but that's the only thing we can add in there for now.
  25997. 20:36:21All right, so now I have two files, app.py, and I have index.html.
  25998. 20:36:27But index.html thank you is inside of my templates directory
  25999. 20:36:30so how do I actually start a web server last week,
  26000. 20:36:33I would have said HTTP server.
  26001. 20:36:34But HTTP server is not a Python thing.
  26002. 20:36:36It has no idea about Flask or Python or anything I just wrote.
  26003. 20:36:41HTTP server will just spit out static files.
  26004. 20:36:43So if I ran HTTP server, and then I clicked on app.py,
  26005. 20:36:47I would literally see my Python code.
  26006. 20:36:49It would not get executed because HTTP server is just for static content.
  26007. 20:36:53But today, I'm going to run a different command called Flask run.
  26008. 20:36:57So this framework Flask that I actually preinstalled in advance,
  26009. 20:37:01so it wasn't strictly necessary that I create that requirements.txt file just
  26010. 20:37:04yet, comes with a program called Flask, takes command line arguments like
  26011. 20:37:08the word run, and when I do that, you'll see somewhat similar output to last
  26012. 20:37:12week whereby you'll see the name--
  26013. 20:37:14your URL for your unique preview of that.
  26014. 20:37:17You might see a pop up saying that your application is running
  26015. 20:37:20on TCP port, something or other.
  26016. 20:37:22By default, last week, we used port 8080.
  26017. 20:37:24Flask, just because, prefers port 5,000.
  26018. 20:37:27So that's fine too.
  26019. 20:37:28I'm going to go ahead and open up this URL now.
  26020. 20:37:31And once it authenticates and redirects me,
  26021. 20:37:33just to make sure I'm allowed to access that particular port, let me zoom in.
  26022. 20:37:37Voila, there's the extent of this application.
  26023. 20:37:40If I view source by right-clicking or control clicking,
  26024. 20:37:43there's my HTML that's been spit out.
  26025. 20:37:45So really, I've just reinvented the wheel from last week
  26026. 20:37:48because there's no dynamism now, nothing at all.
  26027. 20:37:51But what if I do this?
  26028. 20:37:52Let me close the source and let me zoom out.
  26029. 20:37:54So you can see my URL bar.
  26030. 20:37:56Let me zoom in now, and I have a very unique cryptic URL.
  26031. 20:37:59But the point is that it ends with nothing.
  26032. 20:38:01Or implicitly, it ends with slash.
  26033. 20:38:03This is just Chrome being a little helpful.
  26034. 20:38:05It doesn't bother showing you a slash, even though it's implicitly there.
  26035. 20:38:08But let me do something explicit like my name equals, quote unquote, "David."
  26036. 20:38:14So there's a key value pair that I've manually
  26037. 20:38:17typed into my URL bar and hit Enter.
  26038. 20:38:20Nothing happens, nothing changes.
  26039. 20:38:22It still says hello, world.
  26040. 20:38:23But the opportunity today is to now, dynamically, get at the input
  26041. 20:38:27from that URL and start displaying it to the user.
  26042. 20:38:31So let me go back over here to my terminal window and code.
  26043. 20:38:35Let me move that down to the bottom there.
  26044. 20:38:37And what if I want to say, huh, hello, name.
  26045. 20:38:41I ideally want to say something like--
  26046. 20:38:42I don't want to hard code David because then it's never
  26047. 20:38:44going to say hello to anyone else.
  26048. 20:38:46I want to put like a variable name here, like name should go here.
  26049. 20:38:51But it's not an HTML tag, so I need some kind of placeholder.
  26050. 20:38:55Well, here's what I can do.
  26051. 20:38:57If I go back to my Python code, I can now define a variable called name.
  26052. 20:39:02And I can ask Flask to go into the current request,
  26053. 20:39:06into its arguments, that is in the URL, as they're called,
  26054. 20:39:10and get whatever the value of the parameter called name is.
  26055. 20:39:14That puts that into a variable for me.
  26056. 20:39:16And then, in render template-- this is one of those functions
  26057. 20:39:19that can take more than one argument.
  26058. 20:39:21If it takes another argument, you can pass
  26059. 20:39:23in the name of any variable you want.
  26060. 20:39:25So if I want to pass in my name, I can literally say name equals name.
  26061. 20:39:29So this is the name of a variable I want to give to the template.
  26062. 20:39:34This is the actual variable that I want to get the value from.
  26063. 20:39:39And now lastly, in my index.html, the syntax as of today in Flask,
  26064. 20:39:45is to do two curly braces and then put the name of the variable
  26065. 20:39:49that you want to plug in.
  26066. 20:39:51So here's what we mean by a template.
  26067. 20:39:53A template is like a blueprint in the real world, where
  26068. 20:39:56it's plans to make something.
  26069. 20:39:58This is the plan to make a web page that has all of this code literally,
  26070. 20:40:02but there's this placeholder with two curly braces here and here
  26071. 20:40:06that says go ahead and plug in the value of the name variable right there.
  26072. 20:40:10So in this sense, it's similar in spirit to our f strings
  26073. 20:40:13or format strings in Python.
  26074. 20:40:14The syntax is a little different just because reasonable people
  26075. 20:40:17disagree, different people, different frameworks come up
  26076. 20:40:19with different conventions.
  26077. 20:40:21The convention in Flask, in their templates,
  26078. 20:40:23is to use two curly braces here.
  26079. 20:40:26The hope is that you, the programmer, will never
  26080. 20:40:28want to display two curly braces in your actual web page.
  26081. 20:40:32But even if you do, there's a workaround.
  26082. 20:40:34We can escape that.
  26083. 20:40:35So now let me go ahead and go back to my browser tab here.
  26084. 20:40:39Previously, even though I added name equals David
  26085. 20:40:41to the end of the URL with a question mark, it still said hello, world.
  26086. 20:40:44But now, hopefully, if I made these changes,
  26087. 20:40:47let me go ahead and open up my terminal window.
  26088. 20:40:51Let me restart Flask so it loads my changes by default.
  26089. 20:40:55Let me go back to my hello tab and click reload so it grabs the page anew
  26090. 20:40:59from the server.
  26091. 20:41:01And there we go, hello, David.
  26092. 20:41:02I can play around now and I can change the URL appear to, for instance,
  26093. 20:41:05Carter.
  26094. 20:41:06Zoom out, hit Enter.
  26095. 20:41:07And now we have something more dynamic.
  26096. 20:41:10So the new pieces here are, in Python, we have some code here
  26097. 20:41:14that allows us to access, programmatically, everything
  26098. 20:41:18that's after the question mark in the URL.
  26099. 20:41:20And the only thing we have to do that is call this function request.args.get.
  26100. 20:41:26You and I don't have to bother figuring out
  26101. 20:41:28where is the question mark, where is the equal sign, where
  26102. 20:41:30are the ampersands, potentially.
  26103. 20:41:32The framework, Flask, does all of that for us.
  26104. 20:41:36OK, any questions then on these principles thus far?
  26105. 20:41:43Yeah, in back.
  26106. 20:41:44AUDIENCE: Why do you say the question mark in the URL?
  26107. 20:41:50DAVID: Why do you need a question mark in the URL?
  26108. 20:41:52The short answer is just because that is where key value pairs must go.
  26109. 20:41:59If you're making a GET request from a browser to a server,
  26110. 20:42:02the convention, standardized by the HTTP protocol, is to put them in the URL
  26111. 20:42:07after the so-called route or path, then a question mark.
  26112. 20:42:11And it delineates what's part of the root or the path,
  26113. 20:42:13and what's part of the human input to the right.
  26114. 20:42:17Other questions?
  26115. 20:42:18Yeah.
  26116. 20:42:19AUDIENCE: Can you go over again why the left and right in the [INAUDIBLE]??
  26117. 20:42:22DAVID: Sure.
  26118. 20:42:23This is this annoying thing about Python.
  26119. 20:42:25When you pass in parameters, two functions that have names,
  26120. 20:42:29you typically say something equals something else.
  26121. 20:42:32So let me make a slight tweak here.
  26122. 20:42:35How about I say name of person here.
  26123. 20:42:39This allows me to invent my own variable for my template
  26124. 20:42:44and assign it the value of name.
  26125. 20:42:46I now, though, have to go into my index file and say name of person--
  26126. 20:42:52did I get that right?
  26127. 20:42:53Name of person, yeah.
  26128. 20:42:55So these two have to match.
  26129. 20:42:57And so this is just stupid because it's unnecessarily verbose.
  26130. 20:43:00So what typically people do is they just use the same name as the variable
  26131. 20:43:04itself, even though it looks admittedly stupid, but it has two different roles.
  26132. 20:43:08The thing to the left of the equal sign is
  26133. 20:43:10the name of the variable you plan to use in the template, the thing on the right
  26134. 20:43:14is the actual value you're assigning it.
  26135. 20:43:16And this is because its general purpose.
  26136. 20:43:18I could override this and I could say something like name always
  26137. 20:43:21equals Emma, no matter what that variable is.
  26138. 20:43:23And now if I go back to my browser and reload,
  26139. 20:43:26no matter what's in the URL, David or Carter, It's always--
  26140. 20:43:30OK, Emma broke the server.
  26141. 20:43:32What did I do?
  26142. 20:43:34Oh, I didn't change my template back.
  26143. 20:43:36There we go.
  26144. 20:43:37Let me change that back to be name, so that it's name there
  26145. 20:43:40and it's name here.
  26146. 20:43:41But I've hardcoded Emma's name, so now we're
  26147. 20:43:43only ever going to see Emma no matter whose name is in the URL.
  26148. 20:43:47That's all.
  26149. 20:43:48All right, so this is bad user interface.
  26150. 20:43:51If, in order to get a greeting for the day, you, the user,
  26151. 20:43:54have to manually change the URL, which none of us ever do.
  26152. 20:43:57This is not how web pages work.
  26153. 20:43:58What is the more normal mechanism for getting input from the user
  26154. 20:44:02and putting it in that URL automatically?
  26155. 20:44:06How did we do that last week?
  26156. 20:44:09With Google, if you recall.
  26157. 20:44:11AUDIENCE: We have the search bar and we [INAUDIBLE] you have
  26158. 20:44:15to make something in there [INAUDIBLE].
  26159. 20:44:22DAVID: OK, so we did make something in order to get the input from the user.
  26160. 20:44:25And specifically, what was the tag or the terminology we used last week?
  26161. 20:44:29AUDIENCE: [INAUDIBLE].
  26162. 20:44:30DAVID: Sorry, a little louder?
  26163. 20:44:32Oh, no.
  26164. 20:44:34But yeah.
  26165. 20:44:35AUDIENCE: Is it input?
  26166. 20:44:36DAVID: So the input tag, inside of the form tag.
  26167. 20:44:38So in short, forms, or of course, how the web works
  26168. 20:44:41and how we typically get input from the user,
  26169. 20:44:43whether it's a button or a text box or a dropdown menu or something else.
  26170. 20:44:46So let's go ahead and add that into the mix here.
  26171. 20:44:48So let's enhance this hello app to do a little something more by,
  26172. 20:44:52this time, just doing this.
  26173. 20:44:54Let me get rid of this name stuff and let me just
  26174. 20:44:58have a very simple index.html file that, by default, is going to simply ask
  26175. 20:45:03the user for some input as follows.
  26176. 20:45:06I'm going to go back into my index.html, and instead of printing out
  26177. 20:45:10the user's name, this is the page I'm going to use to actually get input
  26178. 20:45:13from the user.
  26179. 20:45:14So I'm going to create a form tag.
  26180. 20:45:16The method I'm going to use for now is going to be, quote unquote, "get."
  26181. 20:45:20Then, inside of that form, I'm going to have an input tag.
  26182. 20:45:23And I'm going to turn off autocomplete like we did last week.
  26183. 20:45:25I'm going to turn on auto focus, so it puts the cursor in the text box for me.
  26184. 20:45:29I'm going to give the name of this input the name, name.
  26185. 20:45:33Not to be too confusing, but I'm asking the human for their name.
  26186. 20:45:35So it makes sense that the name of the input should be, quote unquote, "name."
  26187. 20:45:39The placeholder I want the human to see in light gray text
  26188. 20:45:42will be Name with a capital N, just so it's a little grammatical.
  26189. 20:45:45And then type of this text fiel--
  26190. 20:45:47type of this input is going to be text.
  26191. 20:45:49Then I'm just going to give myself, like last week, a submit button.
  26192. 20:45:52And I don't care what it says, it's just going
  26193. 20:45:54to say the default submit terminology.
  26194. 20:45:56Let me go ahead, now, and open up my terminal window again.
  26195. 20:46:01Let me go to that same URL so that I can see-- whoops.
  26196. 20:46:11There we go.
  26197. 20:46:11So that was just cached from earlier.
  26198. 20:46:13Let me go back to that same URL, my GitHub preview.dev URL,
  26199. 20:46:16and here I have the form.
  26200. 20:46:18And now, I can type in anything I want.
  26201. 20:46:19The catch, though, is when I click Submit, where is it going to go?
  26202. 20:46:23Well, let's be explicit.
  26203. 20:46:24It does have a default value, but let me go into my index.html
  26204. 20:46:28and let me add, just like we did last week for it, Google.
  26205. 20:46:30Whereas previously, I said something like www.google.com/search, but today,
  26206. 20:46:36we're not going to rely on some third party.
  26207. 20:46:38I'm going to implement the so-called backend,
  26208. 20:46:40and I'm going to have the user submit this form to a second route,
  26209. 20:46:44not just slash, how about /greet.
  26210. 20:46:47I can make it up, whatever I want.
  26211. 20:46:48Greet feels like a nice operative word, so /greet is where the user will be
  26212. 20:46:53sent when they click Submit on this form.
  26213. 20:46:56All right, so let's go ahead now and go back to my browser tab.
  26214. 20:46:59Let me go ahead, actually, and let me reload Flask
  26215. 20:47:02here so that it reloads all of my changes.
  26216. 20:47:05Let me reload this tab so that I get the very latest HTML and, indeed,
  26217. 20:47:09quick safety check.
  26218. 20:47:10If I view page source, we indeed see that my browser
  26219. 20:47:13has downloaded the latest HTML.
  26220. 20:47:15So it definitely has changed.
  26221. 20:47:16Let's go ahead and type in David.
  26222. 20:47:18And when I click Submit here, what's going to happen?
  26223. 20:47:22Hypotheses.
  26224. 20:47:25What's going to happen visually, functionally, however you
  26225. 20:47:28want to interpret when I click Submit.
  26226. 20:47:32Yeah?
  26227. 20:47:32AUDIENCE: [INAUDIBLE] an empty page.
  26228. 20:47:34DAVID: OK, the user's going to go to an empty page.
  26229. 20:47:36Pretty good instinct, because--
  26230. 20:47:37no where else, if I mentioned /greet, it doesn't seem to exist.
  26231. 20:47:40How's the URL going to change, just to be clear?
  26232. 20:47:44What's going to appear, suddenly, in the URL?
  26233. 20:47:49Yeah?
  26234. 20:47:50AUDIENCE: 404?
  26235. 20:47:51DAVID: 404?
  26236. 20:47:52No, not in the URL.
  26237. 20:47:53Specifically in the URL, something's going to get added automatically
  26238. 20:47:56when I click.
  26239. 20:47:56AUDIENCE: The key value pair?
  26240. 20:47:58DAVID: The key value pair, right.
  26241. 20:47:59That's how forms work.
  26242. 20:48:00That's why our Google trick last week worked.
  26243. 20:48:02I sort of recreated a form on my own website.
  26244. 20:48:05And even though I didn't get around to implementing google.com itself,
  26245. 20:48:08I can still send the information to Google just relying on browsers,
  26246. 20:48:12standardizing--
  26247. 20:48:13to your question earlier, that whenever you submit a form,
  26248. 20:48:16it automatically ends up after a question mark in the URL
  26249. 20:48:19if you're using GET.
  26250. 20:48:20So this both of you are right, this is going to break.
  26251. 20:48:23And all three of you are right, in effect, 404 not found.
  26252. 20:48:26You can see it in the tab here.
  26253. 20:48:28That's the error that has come back.
  26254. 20:48:29But what's interesting, and most important, the URL did change.
  26255. 20:48:33And it went to /greet?name=david.
  26256. 20:48:37So I just, now, need to add some logic that actually
  26257. 20:48:40looks for that so-called route.
  26258. 20:48:41So let me go back to my app.py.
  26259. 20:48:44Let me define another route for, quote unquote, "slash greet."
  26260. 20:48:49And then, inside of-- under this, let me define another function.
  26261. 20:48:52I'll call it greet, but I could call it anything I want.
  26262. 20:48:56No arguments, for now, for this, and then
  26263. 20:48:58let me go ahead and do this in my app.py.
  26264. 20:49:02This time around, I do want to get the human's name.
  26265. 20:49:05So let me say requeste.args get quote unquote "name",
  26266. 20:49:09and let me store that in a variable called name.
  26267. 20:49:11Then let me return a template, and you know
  26268. 20:49:14what, I'm going to give myself a new template, greet.html.
  26269. 20:49:17Because this has a different purpose, it's not a form.
  26270. 20:49:19I want to say hello to the user in this HTML file,
  26271. 20:49:22and I want to pass, into it, the name that the human just typed in.
  26272. 20:49:27All right, so now if I go up and reload the page, what might happen now?
  26273. 20:49:34Other logical check here.
  26274. 20:49:36If I go ahead and hit reload or resubmit the form, what might happen now?
  26275. 20:49:42Any instincts?
  26276. 20:49:46Let me try, so let's try this.
  26277. 20:49:48Let's go ahead and reload the page.
  26278. 20:49:50Previously, it was not found.
  26279. 20:49:51Now it's worse, and this is the 500 error, internal server
  26280. 20:49:55error that I promised next week we will all encounter accidentally, ultimately.
  26281. 20:49:59But here we have an internal server error.
  26282. 20:50:01Because it's an internal error, this means something's wrong with your code.
  26283. 20:50:05So the route was actually found because it's not a 404 this time.
  26284. 20:50:09But if we go into VS Code here and we look at the console, the terminal
  26285. 20:50:14window, you'll see that--
  26286. 20:50:17this is actually a bit misleading.
  26287. 20:50:21Do I want to do this?
  26288. 20:50:22Let me reload this.
  26289. 20:50:24Let me reload here.
  26290. 20:50:25Oh, standby.
  26291. 20:50:27Come on.
  26292. 20:50:28There we go.
  26293. 20:50:30Come on.
  26294. 20:50:32OK, here we have this error here, and this
  26295. 20:50:34is where your terminal window is going to be helpful.
  26296. 20:50:37In your terminal window, by default, is typically
  26297. 20:50:40going to go helpful stuff like a log, L-O-G,
  26298. 20:50:43of what it is the server is seeing from the browser.
  26299. 20:50:46For instance, here's what the server just saw in purple.
  26300. 20:50:48Get /greet?name=david using HTTP version 1.0.
  26301. 20:50:54Here, though, is the status code that the server returned, 500.
  26302. 20:50:57Why, what's the error?
  26303. 20:50:58Well, here's where we get these annoying pretty cryptic Python messages
  26304. 20:51:02that help50 might ultimately help you with,
  26305. 20:51:03or here, we might just have a clue at the bottom.
  26306. 20:51:07And this is actually pretty clear, even though we've never
  26307. 20:51:09seen this error before.
  26308. 20:51:10What did I screw up here?
  26309. 20:51:11I just didn't create greet.html, right?
  26310. 20:51:14Template not found.
  26311. 20:51:15All right, so that must be the last piece of the puzzle.
  26312. 20:51:17And again, representative of how you might diagnose problems like these,
  26313. 20:51:21let me go into my terminal window.
  26314. 20:51:24After hitting Control C, which cancels or interrupts a process,
  26315. 20:51:28let me go into my templates directory.
  26316. 20:51:30If I type ls, I only have index.html.
  26317. 20:51:33So let's code up greet.html.
  26318. 20:51:36And in this file let's quickly do doc type.
  26319. 20:51:40Doc type HTML, open bracket HTML, language equals English.
  26320. 20:51:44Inside of this, I'll have the head tag, inside of here, I'll have the meta.
  26321. 20:51:48The name is viewport, the content of which is--
  26322. 20:51:53I always forget this to.
  26323. 20:51:55The content of which is initial scale equals one, width equals device width.
  26324. 20:52:02Quote unquote, title is still going to be,
  26325. 20:52:05I'll call this greet because this is my template.
  26326. 20:52:08And then here, in the body, I'm going to have hello comma name.
  26327. 20:52:13So I could have kept around the old version of this, but I just recreated,
  26328. 20:52:17essentially, my second template.
  26329. 20:52:19So index.html now is almost the same, but the title is different
  26330. 20:52:22and it has a form.
  26331. 20:52:24greet.html is almost the same, but it does not have a form.
  26332. 20:52:27It just has the hello comma name.
  26333. 20:52:29So let me now go ahead and rerun in the correct directory.
  26334. 20:52:34You have to run Flask wherever app.py is, not in your templates directory.
  26335. 20:52:38So let me do Flask run to get back to where I was.
  26336. 20:52:41Let me go into my other tab.
  26337. 20:52:43Cross my fingers this time that, when I go back to slash
  26338. 20:52:46and I get index.html's form, now I type in David and click Submit,
  26339. 20:52:51now we get hello, David.
  26340. 20:52:54And now we have a full-fledged web app that has two different routes,
  26341. 20:52:58slash and /greet, the latter of which takes input like this and then,
  26342. 20:53:03using a template, spits it out.
  26343. 20:53:05But something could go wrong, and let's see what happens here.
  26344. 20:53:08Suppose I don't type anything in.
  26345. 20:53:11Let me go here and just click Submit.
  26346. 20:53:13Now, I mean, it looks stupid.
  26347. 20:53:16So there's bunches of ways we could solve this.
  26348. 20:53:18I could require that the user have input on the previous page,
  26349. 20:53:21I could have some kind of error check for this.
  26350. 20:53:23But there's another mechanism I can use that I'll just show you.
  26351. 20:53:26It turns out this GET function, in the context of HTTP
  26352. 20:53:30and also in general with Python dictionaries,
  26353. 20:53:33you can actually supply a default value.
  26354. 20:53:35So if there is no name parameter or no value for a name parameter,
  26355. 20:53:39you can actually give it a default value like this.
  26356. 20:53:42So I'll say world, for instance.
  26357. 20:53:44Now, let me go back here.
  26358. 20:53:46Let me type in nothing again and click Submit.
  26359. 20:53:48And hopefully this time, I'll do-- oops, sorry.
  26360. 20:53:52Let me restart Flask to reload the template.
  26361. 20:53:54Let me go ahead and type nothing this time, clicking Submit.
  26362. 20:53:57And hopefully, we now--
  26363. 20:54:01Oh, interesting.
  26364. 20:54:03I should have faked this.
  26365. 20:54:05Suppose that the reason this--
  26366. 20:54:09Oh.
  26367. 20:54:11Suppose I just get rid of name altogether like this and hit Enter.
  26368. 20:54:15Now I see hello, world, and this is a subtlety
  26369. 20:54:17that I didn't intend to get into here.
  26370. 20:54:19When you have question mark name equals nothing,
  26371. 20:54:23you're passing in what's called-- whoops.
  26372. 20:54:25When you have greet question mark name equals something,
  26373. 20:54:29you actually are giving a value to name.
  26374. 20:54:31It is quote unquote with nothing in between.
  26375. 20:54:34That is different from having no value at all.
  26376. 20:54:36So allow me to just propose that the error here, we
  26377. 20:54:40would want to require this in a different way.
  26378. 20:54:42And probably the most robust way to do this
  26379. 20:54:45would be to go in here, in my HTML, and say that the name field is required.
  26380. 20:54:51Now, if I go back to my form after restarting Flask here,
  26381. 20:54:55and I go ahead and click reload on my form and type in nothing
  26382. 20:54:59and click Submit, now the browser is going to yell at me.
  26383. 20:55:03But just as a teaser for something we'll be
  26384. 20:55:05doing in the next problem set in terms of error checking,
  26385. 20:55:08you should never, ever, ever rely on client side safety checks like this.
  26386. 20:55:14Because we know, from last week, that a curious programmer can go to inspect,
  26387. 20:55:19and let me poke around the HTML here.
  26388. 20:55:21Let me go into the body, the form.
  26389. 20:55:24OK, you say required, I say not required.
  26390. 20:55:26You can just delete what's in the dom, in the browser,
  26391. 20:55:29and now I can go ahead and submit this form.
  26392. 20:55:32And it appears to be broken.
  26393. 20:55:34Not a big deal with a silly little greeting application like this.
  26394. 20:55:37But if you're trying to require that humans actually
  26395. 20:55:40provide input that is necessary for the correct operation of the site,
  26396. 20:55:43you don't want to trust that the HTML is not altered by some adversary.
  26397. 20:55:49All right, any questions, then, on this particular app
  26398. 20:55:52before we add another feature here?
  26399. 20:55:56Any questions here?
  26400. 20:55:58Yeah.
  26401. 20:55:59AUDIENCE: Do you guys [INAUDIBLE].
  26402. 20:56:04DAVID: Sorry, little louder.
  26403. 20:56:05In the index function--
  26404. 20:56:06AUDIENCE: Oh, sorry.
  26405. 20:56:08[INAUDIBLE]
  26406. 20:56:10DAVID: Sorry?
  26407. 20:56:11AUDIENCE: [INAUDIBLE]
  26408. 20:56:14DAVID: Would it be a problem if what?
  26409. 20:56:15AUDIENCE: You have to [INAUDIBLE].
  26410. 20:56:20DAVID: No.
  26411. 20:56:20I mean no, this is OK.
  26412. 20:56:22What you should really do is something we're going to do with another example
  26413. 20:56:24where I'm going to start error checking things.
  26414. 20:56:26So let me wave my hands at that and propose that we'll
  26415. 20:56:27solve this better in just a bit.
  26416. 20:56:29But it's not bad to do what I just did here, it's
  26417. 20:56:31only going to handle one of the scenarios that I was worried about.
  26418. 20:56:34Not all of them.
  26419. 20:56:35All right, so even though this is new to most of us
  26420. 20:56:38here, consider index.html, my first template, and consider greet.html,
  26421. 20:56:43my second template.
  26422. 20:56:45What might be arguably badly designed?
  26423. 20:56:48Even though this might be the first time you've
  26424. 20:56:50ever touched web programming like this.
  26425. 20:56:54What's bad or dumb about this design of these two templates alone?
  26426. 20:57:01And there's a reason, too, that I bored us by typing it out that second time.
  26427. 20:57:05Yeah?
  26428. 20:57:06AUDIENCE: [INAUDIBLE] you said, stuff like Notepad and [INAUDIBLE]..
  26429. 20:57:11DAVID: Yeah, there's so much repetition.
  26430. 20:57:13I mean, it was deliberately tedious that I was retyping everything.
  26431. 20:57:16The doc type, the HTML tag, the head tag, the title tag.
  26432. 20:57:19And little things did change along the way, like the title
  26433. 20:57:21and certainly, the content of the body.
  26434. 20:57:24But so much of this, I mean, almost all of the page
  26435. 20:57:27is a copy of itself in multiple files.
  26436. 20:57:30And God forbid we have a third template, a fourth template, a hundredth template
  26437. 20:57:33for a really big website.
  26438. 20:57:35This is going to get very tedious very quickly.
  26439. 20:57:37And suppose you want to change something in one place,
  26440. 20:57:39you're going to have to change it now in two, three, a hundred different places
  26441. 20:57:43instead.
  26442. 20:57:43So just like in programming more generally,
  26443. 20:57:46we have this ability to factor out commonalities.
  26444. 20:57:49So do you in the context of web programming,
  26445. 20:57:51and specifically templating, have the ability
  26446. 20:57:54to factor out all of those commonalities.
  26447. 20:57:56The syntax is going to be a little curious,
  26448. 20:57:58but it functionally is pretty straightforward.
  26449. 20:58:01Let me go ahead and do this.
  26450. 20:58:02Let me go ahead and copy the contents of index.html.
  26451. 20:58:06Let me go into my templates directory and code a file that,
  26452. 20:58:09by default, is called layout.html.
  26453. 20:58:12And let me go ahead, and per your answer, copy all of those
  26454. 20:58:15commonalities into this file now instead.
  26455. 20:58:18So here I have a file called layout.html.
  26456. 20:58:21I don't want to give every page the same title, maybe, but for now that's OK.
  26457. 20:58:26I'm going to call everything hello.
  26458. 20:58:27But in the body of the page, what I'm going to do here is just
  26459. 20:58:30have a placeholder for actual contents that do change.
  26460. 20:58:35So in this layout, I'm going to go ahead in here
  26461. 20:58:38and just put in the body of my page, how about this syntax?
  26462. 20:58:42And this is admittedly new.
  26463. 20:58:44Block body, and then percent sign close curly brace.
  26464. 20:58:48And then I'm going to do end block.
  26465. 20:58:50So a curious syntax here, but this is more template syntax.
  26466. 20:58:55The other template syntax we saw before was the two curly braces.
  26467. 20:58:59That's for just plugging in values.
  26468. 20:59:01There's this other syntax with Flask that allows you to, say, a single curly
  26469. 20:59:05brace, a percent sign, and then some functionality like this defining
  26470. 20:59:10a block.
  26471. 20:59:10And this one's a little weird because there's literally
  26472. 20:59:13nothing between the close curly and the open curly brace here.
  26473. 20:59:16But let's see what this can do for us.
  26474. 20:59:19Let me now go into my index.html, which is where I borrowed most of that code
  26475. 20:59:25from, and let me focus on what is minimally different.
  26476. 20:59:28The only thing that's really different in this page, title aside, is the form.
  26477. 20:59:33So let me go ahead and just cut that form out to my clipboard.
  26478. 20:59:37Let me change the first line of index.html
  26479. 20:59:40to say this file is going to extend layout.html,
  26480. 20:59:46and notice I'm using the curly braces again.
  26481. 20:59:48And this file is going to have its own body block
  26482. 20:59:52inside of which is just the HTML that I actually
  26483. 20:59:57want to make specific to this page.
  26484. 20:59:59And I'll keep my indentation nice and neat here.
  26485. 21:00:02And let's consider what I've done.
  26486. 21:00:03This is starting to look weird fast, and this is now
  26487. 21:00:05a mix of HTML with templating code.
  26488. 21:00:09Index.html, first line now says, hey, Flask, this file extends layout.html,
  26489. 21:00:15whatever that is.
  26490. 21:00:17This next line, three through 10, says, hey, Flask, here
  26491. 21:00:20is what I consider my body block to be.
  26492. 21:00:23Plug this into the layout placeholder.
  26493. 21:00:27Therefore, so if I now go back to layout.html, and layout.html,
  26494. 21:00:33it's almost all HTML by contrast.
  26495. 21:00:35But there is this placeholder, and if I want to put a default value,
  26496. 21:00:38I could say-- whoops.
  26497. 21:00:39If I want to put a default value, I could
  26498. 21:00:41put a default value there just in case some page does not have a body block.
  26499. 21:00:45But in general, that's not going to be relevant.
  26500. 21:00:47So this is just a placeholder, albeit a little verbose, that says
  26501. 21:00:50plug in the page-specific content right here.
  26502. 21:00:54So if I go now into greet.html, this one's even easier.
  26503. 21:00:58I'm going to cut this content and get rid of everything else.
  26504. 21:01:01Greet.html 2 is going to extend layouts, dot HTML extends plural,
  26505. 21:01:06and then I'm going to have my body block here simply be this one line of code.
  26506. 21:01:13And then I'm going to go ahead and end that block here.
  26507. 21:01:15These are not HTML tags, this is not HTML syntax.
  26508. 21:01:18Technically, the syntax we keep seeing with the curly braces,
  26509. 21:01:22and these now curly braces with percent signs, is an example of Jinja syntax,
  26510. 21:01:28J-I-N-J-A, which is a language, that some humans invented,
  26511. 21:01:33for this purpose of templating.
  26512. 21:01:35And the people who invented Flask decided,
  26513. 21:01:37we're not going to come up with our own syntax,
  26514. 21:01:40we're going to use these other people's syntax called Jinja syntax.
  26515. 21:01:44So again, there starts to be at this point in the course,
  26516. 21:01:46and really in computing, a lot of sharing, now, of ideas and sharing
  26517. 21:01:50of code.
  26518. 21:01:50So Flask is using this syntax, but other libraries and other languages
  26519. 21:01:54might also too.
  26520. 21:01:57All right, so now index.html is half HTML,
  26521. 21:02:01half templating code, Jinja syntax.
  26522. 21:02:04Greet.html is almost all Jinja syntax, no tags even,
  26523. 21:02:08but because they both extend layout.html,
  26524. 21:02:11now I think I've improved the design of this thing.
  26525. 21:02:14If I go back to app.py, none of this really needs to change.
  26526. 21:02:18I don't change my templates to mention layout.html,
  26527. 21:02:22that's already implicit in the fact that we have the extends keyword.
  26528. 21:02:25So now if I go ahead and open my terminal window,
  26529. 21:02:28go back to the same folder as app.py and do Flask run,
  26530. 21:02:32all right, my application is running on port 5000.
  26531. 21:02:35Let me now go back to the /route in my browser and hit Enter,
  26532. 21:02:39I have this form again.
  26533. 21:02:40And just as a little check, let me view the source of the page
  26534. 21:02:44that my browser is seeing.
  26535. 21:02:45And there's all of the code.
  26536. 21:02:48No mention of Jinja, no curly braces, no percent signs.
  26537. 21:02:51It's just HTML.
  26538. 21:02:52It's not quite pretty printed in the same way, but that's fine.
  26539. 21:02:54Because now, we're starting to dynamically generate websites.
  26540. 21:02:57And by that, I mean this isn't quite indented nicely or perfectly.
  26541. 21:03:00That's fine.
  26542. 21:03:01If it's indented in the source code version,
  26543. 21:03:03doesn't matter what the browser really sees.
  26544. 21:03:05Let me now go ahead and type in my name, click Submit.
  26545. 21:03:08I should see, yep, hello, David.
  26546. 21:03:10Let me go ahead and view the source of this page.
  26547. 21:03:12And we'll see almost the same thing with what's plugged in there.
  26548. 21:03:16So this is, now, web programming in the literal sense.
  26549. 21:03:19I did not hard code a page that says hello comma David, hello comma Carter,
  26550. 21:03:23hello comma Emma.
  26551. 21:03:24I hardcoded a page that has a template with a placeholder,
  26552. 21:03:27and now I'm using actual logic, some code in app.py,
  26553. 21:03:31to actually tell the server what to send to the browser.
  26554. 21:03:37All right, any questions, then, on where we're at here?
  26555. 21:03:42This is now a web application.
  26556. 21:03:45Simple though it is, it's no longer just a web site.
  26557. 21:03:49Yeah?
  26558. 21:03:49AUDIENCE: Is what we did just better for design or for memory [INAUDIBLE]??
  26559. 21:03:54DAVID: It better for design or for memory?
  26560. 21:03:57Both.
  26561. 21:03:57It's definitely better for design because, truly,
  26562. 21:03:59if we had a third page, fourth page, I would really
  26563. 21:04:02start just resorting to copy paste.
  26564. 21:04:03And as you saw with home page, often, in the head of your page,
  26565. 21:04:07you might want to include some CSS files like Bootstrap or something else.
  26566. 21:04:10You might want to have other information up there.
  26567. 21:04:13If you had to upgrade the version of Bootstrap or you change libraries,
  26568. 21:04:16so you want to change one of those lines,
  26569. 21:04:18you would literally have to go into three, four, a hundred different files
  26570. 21:04:21to make one simple change.
  26571. 21:04:23So that's bad design.
  26572. 21:04:25And in terms of memory, yes.
  26573. 21:04:26Theoretically, the server, because it knows there's this common layout,
  26574. 21:04:30it can theoretically do some optimizations underneath the hood.
  26575. 21:04:33Flask is probably doing that, but not in the mode we're using it.
  26576. 21:04:36We're using it in development mode, which
  26577. 21:04:38means it's typically reloading things each time.
  26578. 21:04:41Other questions on this application?
  26579. 21:04:47Anything at all?
  26580. 21:04:48All right, so let me ask a question, not just in terms of the code design.
  26581. 21:04:54What about the implications for privacy?
  26582. 21:04:56Why is this maybe not the best design for users, how I've implemented this?
  26583. 21:05:02I've used a web form, but--
  26584. 21:05:04Yeah?
  26585. 21:05:05AUDIENCE: For some reason, you wanted your name.
  26586. 21:05:06So these private people could just look at the URL.
  26587. 21:05:08DAVID: Yeah.
  26588. 21:05:09I mean, if you have a nosy sibling or roommate
  26589. 21:05:11and they have access to your laptop and they just
  26590. 21:05:13go trolling through your autocomplete or your history,
  26591. 21:05:15like, literally what you typed into a website is going to be visible.
  26592. 21:05:18Not a big deal if it's your name, but if it's your password, your credit
  26593. 21:05:21card or anything else that's mildly sensitive,
  26594. 21:05:23you probably don't want it ending up in the URL at all
  26595. 21:05:26even if you're in incognito mode or whatnot.
  26596. 21:05:29You just don't want to expose yourself or your users to that kind of risk.
  26597. 21:05:34So perhaps, we can do better than that.
  26598. 21:05:35And fortunately, this one is actually an easy change.
  26599. 21:05:38Let me go into my index.html where my form is.
  26600. 21:05:43And in my form, I can just change the method from GET to POST.
  26601. 21:05:48It's still going to send key value pairs to the server,
  26602. 21:05:50but it's not going to put them in the URL.
  26603. 21:05:52The upside of which is that we can assuage this privacy concern,
  26604. 21:05:56but I'm going to have to make one other change too.
  26605. 21:05:58Because now, if I go ahead and run Flask again after making that change,
  26606. 21:06:02and I now reload the form to make sure I have the latest version.
  26607. 21:06:07You should be in the habit of going to View, Developer,
  26608. 21:06:10View Source, or Developer Tools just to make sure
  26609. 21:06:12that what you're seeing in your browser is what you intend.
  26610. 21:06:15And yes, I do see what I wanted.
  26611. 21:06:18Method equals POST now.
  26612. 21:06:19Let me go ahead and type in David and click Submit.
  26613. 21:06:22Now I get a different error.
  26614. 21:06:24This one is HTTP 405, method not allowed.
  26615. 21:06:28Why is that?
  26616. 21:06:30Well, in my Flask application, I've only defined a couple of routes so far.
  26617. 21:06:34One of which is for slash, then that worked fine.
  26618. 21:06:37One of which is for /greet, and that used to work fine.
  26619. 21:06:40But apparently, what Flask is doing is it only supports GET by default.
  26620. 21:06:46So if I want to change this route to support different methods, I can say,
  26621. 21:06:51quote unquote "POST" inside of this parameter here.
  26622. 21:06:56So that now, I can actually support POST, not just GET.
  26623. 21:07:01And if I now restart Flask, so Flask run, Enter, and I go back to this URL.
  26624. 21:07:08Let me go back one screen to the form, reload
  26625. 21:07:11the page just to make sure I have the latest
  26626. 21:07:13even though nothing there has changed.
  26627. 21:07:14Type David and click Submit now, now I should see hello, world.
  26628. 21:07:18Notice that I'm at the greet route, but there's no mention of name
  26629. 21:07:25equals anything in the URL.
  26630. 21:07:28All right, so that's an interesting takeaway.
  26631. 21:07:30It's a simple change, but whereas GET puts things in the URL, POST does not.
  26632. 21:07:35But it still works so long as you tweak the backend
  26633. 21:07:37to look as a POST request, which means look deeper in the envelope.
  26634. 21:07:41It's not going to be as simple as looking at the URL itself.
  26635. 21:07:44Why shouldn't we just always use POST?
  26636. 21:07:49Why not use POST everywhere?
  26637. 21:07:53Any thoughts?
  26638. 21:07:55Right, because it's obnoxious to be putting any information in URLs
  26639. 21:07:58if you're leaving these little breadcrumbs in your history and people
  26640. 21:08:02can poke around and see what you've been doing.
  26641. 21:08:07Yeah, what do you think?
  26642. 21:08:09AUDIENCE: You're supposed to duplicate [INAUDIBLE]..
  26643. 21:08:15DAVID: Yeah.
  26644. 21:08:15I mean, if you get rid of GET requests and put nothing in the URL,
  26645. 21:08:18your history, your autocomplete, gets pretty less useful.
  26646. 21:08:22Because none of the information is there for storage, so you can't just
  26647. 21:08:25go through the menu and hit Enter.
  26648. 21:08:26You'd have to re-fill out the form.
  26649. 21:08:28And there's this other symptom that you can see here.
  26650. 21:08:30Let me zoom out and let me just reload this page.
  26651. 21:08:33Notice that you'll get this warning, and it'll
  26652. 21:08:34look different in Safari and Firefox and Edge and Chrome here, confirm form.
  26653. 21:08:39args
  26654. 21:08:40So your browser might remember what your inputs were and that's great,
  26655. 21:08:43but just while you're on the page.
  26656. 21:08:45And this is in contrast to GET, where the state is information.
  26657. 21:08:50Like, key value pairs is embedded in the URL itself.
  26658. 21:08:53And if you looked at an email I sent earlier today,
  26659. 21:08:56I deliberately linked to https://www.google.c
  26660. 21:08:59om/search?q=what+time+is+it.
  26661. 21:09:06This is, by definition, a GET request when you click on it.
  26662. 21:09:11Because it's going to grab the information, the key value pair,
  26663. 21:09:14from the URL, send it to Google server, and it's just going to work.
  26664. 21:09:18And the reason I sent this via email earlier was I
  26665. 21:09:20wanted people to very quickly be able to check what is the current time.
  26666. 21:09:23And so I can sort automate the process of creating a Google search for you,
  26667. 21:09:27but that you induce when you click that link.
  26668. 21:09:29If Google did not support GET, they only supported this, the best I could do
  26669. 21:09:35is send you all to this URL which, unfortunately,
  26670. 21:09:38has no useful information.
  26671. 21:09:39I would have had to add to my email, by the way, type in the words
  26672. 21:09:42what time is it.
  26673. 21:09:44So it's just bad for usability.
  26674. 21:09:46So there, too, we might have design when it comes to the low level code,
  26675. 21:09:49but also the design when it comes to the user experience, or UX,
  26676. 21:09:53as a computer scientist would call it.
  26677. 21:09:54Just in terms of what you want to optimize for, ultimately.
  26678. 21:09:58So GET and POST both have their roles.
  26679. 21:10:00It depends on what kind of functionality you want to provide
  26680. 21:10:02and what kind of sensitivity there might be around it.
  26681. 21:10:06All right, any questions, then, on this, our first web application?
  26682. 21:10:10Super simple, just gets someone's name and prints it back out.
  26683. 21:10:13But we now have all the plumbing with which
  26684. 21:10:16to create really most anything we want.
  26685. 21:10:21All right, let's go ahead and take a five minute break.
  26686. 21:10:24And when we come back, we'll add to this some first year intramural sports.
  26687. 21:10:27All right, so we are back.
  26688. 21:10:30And recall that the last thing we just changed
  26689. 21:10:32was the route to use POST instead of GET.
  26690. 21:10:34So gone is my name and any value in the URL.
  26691. 21:10:37But there was a subtle bug or change here that we didn't call out earlier.
  26692. 21:10:44I did type David into the form and I did click Submit,
  26693. 21:10:47and yet here it is saying hello comma world.
  26694. 21:10:50So that seems to be broken all of a sudden,
  26695. 21:10:53even though we added support for POST.
  26696. 21:10:56But something must be wrong.
  26697. 21:10:58Logically, it must be the case here.
  26698. 21:11:01Intuitively, that if I'm seeing hello, world, that's the default value
  26699. 21:11:05I gave the name variable.
  26700. 21:11:07It must be that it's not seeing a key called
  26701. 21:11:10name in request.args, which is this.
  26702. 21:11:14Gives you access to everything after the URL.
  26703. 21:11:16That's because there's this other thing we should know about,
  26704. 21:11:19which is not just request.args but request.form.
  26705. 21:11:21These are horribly named, but request.args is for GET requests,
  26706. 21:11:26request.form is for POST requests.
  26707. 21:11:28Otherwise, they're pretty much functionally the same.
  26708. 21:11:31But the onus is on you, the user or the programmer,
  26709. 21:11:33to make sure you're using the right one.
  26710. 21:11:35So I think if we want to get rid of the world
  26711. 21:11:38and actually see what I, the human, typed in,
  26712. 21:11:41I think I can just change request.args to request.form.
  26713. 21:11:45Still dot get, still quote unquote "name,"
  26714. 21:11:47and now, if I go ahead and rerun Flask in my terminal window,
  26715. 21:11:52go back to my browser, go back to-- and actually,
  26716. 21:11:54I won't even go back to the form.
  26717. 21:11:56I will literally just reload, Command R or Control R,
  26718. 21:11:59and what this warning is saying is it's going to submit
  26719. 21:12:02the same information to the website.
  26720. 21:12:05When I click Continue, now I should see hello comma David.
  26721. 21:12:08So again, you, too, are going to encounter, probably,
  26722. 21:12:11all these little subtleties.
  26723. 21:12:12But if you focus on, really, the first principles of last week,
  26724. 21:12:15like what it HTTP, how does it get request work,
  26725. 21:12:18how does a POST request work now, you should
  26726. 21:12:20have a lot of the mental building blocks with which
  26727. 21:12:22to solve problems like these.
  26728. 21:12:25And let me give you one other mental model, now, for what it is we're doing.
  26729. 21:12:28This framework called Flask is just an example of many different frameworks
  26730. 21:12:32that all implement the same paradigm, the same way of thinking
  26731. 21:12:36and the same way of programming applications.
  26732. 21:12:38And that's known as MVC, model view controller.
  26733. 21:12:41And here's a very simple diagram that represents the process that you
  26734. 21:12:46and I have been implementing thus far.
  26735. 21:12:48And actually, this is more than we've been implementing thus far.
  26736. 21:12:51In app.py is what a programmer would typically call the controller.
  26737. 21:12:55That's the code you're writing, this are called
  26738. 21:12:57business logic that makes all of the decisions, decides what to render,
  26739. 21:13:01what values to show, and so forth.
  26740. 21:13:03In layout.html, index.html, greet.html is the so-called view templates
  26741. 21:13:09that is the visualizations that the human actually
  26742. 21:13:12sees, the user interface.
  26743. 21:13:14Those things are dumb, they pretty much just say plop some values here.
  26744. 21:13:18All of the hard work is done in app.py.
  26745. 21:13:20So controller, AKA app.py, is where your Python code generally is.
  26746. 21:13:26And in your view is where your HTML and your Jinja code, your Jinja templating,
  26747. 21:13:31the curly braces, the curly braces with percent signs, usually is.
  26748. 21:13:35We haven't added an M to MVC yet model, that's
  26749. 21:13:39going to refer to things like CSV files or databases.
  26750. 21:13:42The model, where do you keep actual data, typically long term.
  26751. 21:13:46So we'll come back to that, but this picture,
  26752. 21:13:47where you have one of these-- each of these components communicating with one
  26753. 21:13:52another is representative of how a lot of frameworks work.
  26754. 21:13:55What we're teaching today, this week, is not really specific to Python.
  26755. 21:13:58It's not really specific to Flask, even though we're using Flask.
  26756. 21:14:01It really is a very common paradigm that you
  26757. 21:14:03could implement in Java, C sharp, or bunches of other languages as well.
  26758. 21:14:08All right, so let's now pivot back to VS Code here.
  26759. 21:14:12Let me stop running Flask, and let me go ahead
  26760. 21:14:14and create a new folder altogether after closing these files here.
  26761. 21:14:19And let me go ahead and create a folder called FroshIMS,
  26762. 21:14:24representing freshman intramural sports or first year intramural sports
  26763. 21:14:27that I can now CD into.
  26764. 21:14:29And now I'm going to code an app.py.
  26765. 21:14:32And in anticipation, I'm going to create another templates directory.
  26766. 21:14:36This one in the FroshIMS folder.
  26767. 21:14:38And then in my templates directory, I'm going to create a layout.html.
  26768. 21:14:42and I'm just going to get myself started here.
  26769. 21:14:44FroshIMS will go here.
  26770. 21:14:46I'm just copying my layout from earlier because most
  26771. 21:14:48of my interesting work, this time, is now going to be, initially, in app.py.
  26772. 21:14:53So what is it we're creating?
  26773. 21:14:54So literally, the very first thing I wrote as a web application
  26774. 21:14:5820 years ago, was a site that literally looked like this.
  26775. 21:15:02So I was like a sophomore or junior at the time.
  26776. 21:15:04I'd taken CS50 and a follow-on class only.
  26777. 21:15:06I had no idea how to do web programming.
  26778. 21:15:08Neither of those two courses taught web programming back in the day.
  26779. 21:15:11So I taught myself, at the time, a language called Perl.
  26780. 21:15:14And I learned a little something about CSV files, and I sort of read enough--
  26781. 21:15:18can't even say googled enough, because Google didn't come out
  26782. 21:15:20for a couple of years later.
  26783. 21:15:22Read enough online to figure out how to make a web application so that students
  26784. 21:15:26on campus, first years, could actually register
  26785. 21:15:29via a website for intramural sports.
  26786. 21:15:32Back in my day, you would literally fill out a piece of paper
  26787. 21:15:35and then walk it across the yard to Wigglesworth Hall, one of the dorms,
  26788. 21:15:38slide it under the dorm of the Proctor or RA,
  26789. 21:15:40and thus you were registered for sports so.
  26790. 21:15:431996, 1997.
  26791. 21:15:45We could do better by then.
  26792. 21:15:46There was an internet, just wasn't really being
  26793. 21:15:48used much on campus or more generally.
  26794. 21:15:50So background images that repeat infinitely
  26795. 21:15:54was in vogue, apparently, at the time.
  26796. 21:15:56All of this was like images that I had to hand make
  26797. 21:15:58because we did not have the features that JavaScript and CSS nowadays have.
  26798. 21:16:03So it was really just HTML, and it was really just controller code written,
  26799. 21:16:07not in Python, but in Perl.
  26800. 21:16:09And it was really just the same building blocks
  26801. 21:16:12that we hear already today now have.
  26802. 21:16:15So we'll get rid of all of the imagery and focus more
  26803. 21:16:17on the functionality and the aesthetics, but let's see
  26804. 21:16:19if we can whip up a web application via which someone could
  26805. 21:16:23register for one such intramural sport.
  26806. 21:16:26So in app.py, me go ahead and import some familiar things now.
  26807. 21:16:29From Flask, let's import capital Flask, which
  26808. 21:16:33is that function we need to kick everything kick start everything.
  26809. 21:16:36Render templates, so we have the ability to render, that is print out,
  26810. 21:16:39those templates, and request so that we have the ability
  26811. 21:16:42to get at input from the human.
  26812. 21:16:44Let me go ahead and create the application itself
  26813. 21:16:46using this magical incantation here.
  26814. 21:16:49And then let's go ahead and define a route for slash for instance first.
  26815. 21:16:56I'm going to define a function called index.
  26816. 21:16:58But just to be clear, this function could be anything.
  26817. 21:17:00Foo, bar, baz, anything else.
  26818. 21:17:03But I tend to name them in a manner that's
  26819. 21:17:05consistent with what the route is called.
  26820. 21:17:07But you could call it anything you want, it's
  26821. 21:17:09just the function that will get called for this particular route.
  26822. 21:17:12Now, let me go ahead here and just get things started.
  26823. 21:17:14Return, render template of index.html.
  26824. 21:17:18Just keep it simple, nothing more.
  26825. 21:17:19So there's nothing really FroshIM specific about this here,
  26826. 21:17:22I just want to make sure I'm doing everything correctly.
  26827. 21:17:25Meanwhile, I've got my layout.
  26828. 21:17:27OK, let me go ahead, and in my templates directory, code a file
  26829. 21:17:31called index.html.
  26830. 21:17:33And let's just do extends layout.html at the top
  26831. 21:17:40just so that we get benefit from that template.
  26832. 21:17:42And down here, I'm just going to say to do.
  26833. 21:17:44Just so that I have something going on visually to make sure
  26834. 21:17:47I've not screwed up yet.
  26835. 21:17:48In my FroshIMS directory, let me do Flask run.
  26836. 21:17:51Let me now go back to my previous URL, which used to be my hello example.
  26837. 21:17:54But now, I'm serving up the FroshIM site.
  26838. 21:17:59Oh, and I'm seeing nothing.
  26839. 21:18:01That's because I screwed up accidentally.
  26840. 21:18:04What did I do wrong in index.html?
  26841. 21:18:12What am I doing wrong?
  26842. 21:18:13This file extends layout.html, but--
  26843. 21:18:16AUDIENCE: You left out the block tag?
  26844. 21:18:17DAVID: Yeah.
  26845. 21:18:18I forgot to tell Flask what to plug into that layout.
  26846. 21:18:22So I just need to say block body, and then in here, I can just say to do
  26847. 21:18:26or whatever I want to eventually get around to.
  26848. 21:18:28Then end the block.
  26849. 21:18:30Let me end this tag here.
  26850. 21:18:31OK, so now it looks ugly, more cryptic.
  26851. 21:18:34But this is, again, the essence of doing templating.
  26852. 21:18:36Let me now restart Flask up here, let me go back to the page.
  26853. 21:18:41Let me reload.
  26854. 21:18:41Crossing my fingers this time, and there we go.
  26855. 21:18:43To do.
  26856. 21:18:44So it's not the application I want, but at least I
  26857. 21:18:46know I have some of the plumbing there by default.
  26858. 21:18:48All right, so if I want the user to be able to register
  26859. 21:18:50for one of these sports, let's enhance, now,
  26860. 21:18:53index.html to actually have a form that's
  26861. 21:18:56maybe got a dropdown menu for all of the sports for which you can register.
  26862. 21:18:59So let me go into this template here.
  26863. 21:19:01And instead of to do, let's go ahead and give myself,
  26864. 21:19:05how about an H1 tag that just says register so the user knows what it is
  26865. 21:19:08they're looking at.
  26866. 21:19:09How about a form tag that's going to use POST,
  26867. 21:19:13just because it's not really necessary to put this kind of information
  26868. 21:19:16in the URL.
  26869. 21:19:17The action for that, how about we plan to create
  26870. 21:19:20a register route so that we're sending information from to a register route.
  26871. 21:19:24So we'll have to come back to that.
  26872. 21:19:26In here, let me go ahead and create, how about an input with autocomplete
  26873. 21:19:32equals off, auto focus on.
  26874. 21:19:35How about a name equals name, because I'm
  26875. 21:19:37going to ask the student for their name using placeholder text of quote
  26876. 21:19:40unquote "name."
  26877. 21:19:41And the type of this box will be text.
  26878. 21:19:43So this is pretty much identical to before.
  26879. 21:19:45But if you've not seen this yet, let's create a select menu,
  26880. 21:19:48a so-called dropdown menu in HTML.
  26881. 21:19:51And maybe the first option I want to be in there
  26882. 21:19:54is going to be, oh, how about the current three
  26883. 21:19:58sports for the fall, which are basketball, and another option
  26884. 21:20:05is going to be soccer, and a third option is
  26885. 21:20:07going to be ultimate frisbee for first year intramurals right now.
  26886. 21:20:13So I've got those three options.
  26887. 21:20:14I've got my form.
  26888. 21:20:16I haven't implemented my route yet, but this feels like a good time
  26889. 21:20:20to go back now and check if my form has reloaded.
  26890. 21:20:23So let me go ahead and stop and start Flask.
  26891. 21:20:26You'll see there's ways to automate the process of restarting
  26892. 21:20:28the server that we'll do for you for problem set nine,
  26893. 21:20:31so you don't have to keep stopping Flask.
  26894. 21:20:32Let me reload my index route and OK, it's not that pretty.
  26895. 21:20:36It's not though, maybe--
  26896. 21:20:38nor was this.
  26897. 21:20:39But it now has at least some functionality
  26898. 21:20:41where I can type in my name and then type in the sport.
  26899. 21:20:44Now, I might be biasing people toward basketball.
  26900. 21:20:47Like UX wise, user experience wise, it's obnoxious to precheck
  26901. 21:20:51basketball but not the others.
  26902. 21:20:53So there's some little tweaks we can make there.
  26903. 21:20:55Let me go back into index.html.
  26904. 21:20:57Let me create an empty option up here that, technically, this option is not
  26905. 21:21:04going to have the name of any sports.
  26906. 21:21:05But it's just going to have a word I want the human to see,
  26907. 21:21:08so I'm actually going to disable this option and make it selected by default.
  26908. 21:21:12But I'm going to say sport up here.
  26909. 21:21:15And there's different ways to do this, this is just one way of creating,
  26910. 21:21:18essentially, a--
  26911. 21:21:20whoops, option.
  26912. 21:21:21Yep, that looks right.
  26913. 21:21:22Creating a placeholder sports so that the user
  26914. 21:21:24sees something in the dropdown.
  26915. 21:21:26Let me go ahead and restart Flask, reload the page,
  26916. 21:21:29and now it's just going to be marginally better.
  26917. 21:21:31Now you see sport that's checked by default,
  26918. 21:21:34but you have to check one of these other ones ultimately.
  26919. 21:21:37All right, so that's pretty good.
  26920. 21:21:38So let me now type in David.
  26921. 21:21:40I'll register for ultimate frisbee.
  26922. 21:21:43OK, I definitely forgot something.
  26923. 21:21:46Submit button.
  26924. 21:21:47So let's add that.
  26925. 21:21:48All right, so input type equals submit.
  26926. 21:21:52All right, let's put that in.
  26927. 21:21:54Restart Flask, reload.
  26928. 21:21:56Getting better.
  26929. 21:21:57Submit could be a little prettier.
  26930. 21:21:58Recall that we can change some of these HTTP-- these HTML attributes.
  26931. 21:22:03The value of this button should be register, maybe,
  26932. 21:22:05just to make things a little prettier.
  26933. 21:22:07Let me now reload the page and register.
  26934. 21:22:10All right, so now we really have the beginnings of the user interface
  26935. 21:22:13that I created some years ago to let people actually register for the sport.
  26936. 21:22:17So let's go, now, and create maybe the other route that we might need.
  26937. 21:22:21Let me go into app.py.
  26938. 21:22:22And in here, if we want to allow the user to register,
  26939. 21:22:25let's do a little bit of error checking which I promised we'd come back to.
  26940. 21:22:28What could the user do wrong?
  26941. 21:22:30Because assume that they will.
  26942. 21:22:32One, they might not type their name.
  26943. 21:22:34Two, they might not choose a sport.
  26944. 21:22:36So they might just submit an empty form.
  26945. 21:22:38So that's two things we could check for, just
  26946. 21:22:40so that we're not scoring bogus entries in our database, ultimately.
  26947. 21:22:43So let's create another route called greet, /greet.
  26948. 21:22:47And then in this route, let's create a function called greet
  26949. 21:22:50but can be called anything we want.
  26950. 21:22:52And then let's go ahead, and in the greet function, let's go ahead
  26951. 21:22:56and validate the submission.
  26952. 21:22:57So a little comment to myself here.
  26953. 21:22:59How about if there is not a request.form GET name value,
  26954. 21:23:08so that is if that function returns nothing,
  26955. 21:23:10like quote unquote, or the special word none in Python.
  26956. 21:23:14Or request.form.get"sport" not in quote unquote, what were they?
  26957. 21:23:25Basketball, the other one was soccer, and the last was ultimate frisbee.
  26958. 21:23:32Getting a little long, but notice what I'm-- the question I'm asking.
  26959. 21:23:35If the user did not give us a name, that is,
  26960. 21:23:39if this function returns the equivalent of false,
  26961. 21:23:41which is, quote unquote, or literally none if there's no such parameter.
  26962. 21:23:45Or if the sport the user provided is not some value in basketball, soccer,
  26963. 21:23:52or ultimate frisbee, which I've defined as a Python list, then let's go ahead
  26964. 21:23:56and just yell at the user in some way.
  26965. 21:23:57Let's return render template of failure.html.
  26966. 21:24:02And that's just going to be some error message inside of that file.
  26967. 21:24:06Otherwise, if they get this far, let's go ahead
  26968. 21:24:08and confirm registration by just returning-- whoops,
  26969. 21:24:12returning render template quote unquote "success" dot HTML.
  26970. 21:24:18All right, so a couple quick things to do.
  26971. 21:24:20Let me first go in and in my templates directory,
  26972. 21:24:25let's create this failure.html file.
  26973. 21:24:28And this is just meant to be a message to the user
  26974. 21:24:31that they fail to provide the information correctly.
  26975. 21:24:34So let me go ahead and in failure.html.
  26976. 21:24:37not repeat my past mistake.
  26977. 21:24:40So let me extend layout.html and in the block body, you are not registered.
  26978. 21:24:44I'll just yell at them like that so that they know something went wrong.
  26979. 21:24:47And then let me create one other file called success.html, that
  26980. 21:24:52similarly is mostly just Jinja syntax.
  26981. 21:24:54And I'm just going to say for now, even though they're not
  26982. 21:24:57technically registered in any database, you are registered.
  26983. 21:24:59That's what we mean by success.
  26984. 21:25:02All right, so let me go ahead, and back in my FroshIMS,
  26985. 21:25:05directory run Flask run.
  26986. 21:25:07Let me go back to the form and reload.
  26987. 21:25:09Should look the same.
  26988. 21:25:10All right, so now let me not cooperate and just
  26989. 21:25:13immediately click Register impatiently.
  26990. 21:25:17OK, what did I do wrong.
  26991. 21:25:20Register-- oh, I'm confusing our two examples.
  26992. 21:25:24All right, I spotted the error.
  26993. 21:25:26What did I do wrong?
  26994. 21:25:29Unintentional.
  26995. 21:25:32There's where I am, what did I actually invent over here?
  26996. 21:25:39Where did I screw up?
  26997. 21:25:42Anyone?
  26998. 21:25:44AUDIENCE: Register, not greet.
  26999. 21:25:45DAVID: Thank you.
  27000. 21:25:46So register, not greet.
  27001. 21:25:47I had last example on my mind, so the route should be register.
  27002. 21:25:50Ironically, the function could be greet, because that actually doesn't matter.
  27003. 21:25:54But to keep ourselves sane, let's use the one and the same words there.
  27004. 21:25:57Let me go ahead now and start Flask as intended.
  27005. 21:26:00Let me reload the form just to make sure all is working.
  27006. 21:26:02Now, let me not cooperate and be a bad user, clicking register--
  27007. 21:26:06oh my God.
  27008. 21:26:07OK, other unintended mistake.
  27009. 21:26:10But this one we've seen before.
  27010. 21:26:12Notice that by default, route only support GET.
  27011. 21:26:15So if I want to specifically support POST,
  27012. 21:26:18I have to pass in, by a methods parameter, a list of allowed route
  27013. 21:26:25methods that could be GET comma POST, but if I
  27014. 21:26:28don't have no need for a GET in this context, I can just do POST.
  27015. 21:26:32All right, now let's do this one last time.
  27016. 21:26:34Reload the form to make sure everything's OK, click Register,
  27017. 21:26:37and you are not registered.
  27018. 21:26:39So it's catching that.
  27019. 21:26:40All right, let me go ahead and at least give them my name.
  27020. 21:26:42Register.
  27021. 21:26:43You are not registered.
  27022. 21:26:44Fine, I'm going to go ahead and be David with ultimate frisbee register.
  27023. 21:26:49Huh.
  27024. 21:26:52OK.
  27025. 21:26:53What should I-- what did I mean to do here?
  27026. 21:26:58All right, so let's figure this out.
  27027. 21:27:00How to debug something like this, which is my third and final unintended,
  27028. 21:27:04unforced error?
  27029. 21:27:07How can we go about troubleshooting this?
  27030. 21:27:10Turn this into the teachable moment.
  27031. 21:27:13All right, well first, some safety checks.
  27032. 21:27:15What did I actually submit?
  27033. 21:27:17Let me go ahead and view page source, a good rule of thumb.
  27034. 21:27:20Look at the HTML that you actually sent to the user.
  27035. 21:27:23So here, I have an input with a name name.
  27036. 21:27:27So that's what I intended, that looks OK.
  27037. 21:27:29Ah, I see it already, even though you, if you've never
  27038. 21:27:32used a select menu, you might not know what, apparently,
  27039. 21:27:35is missing from here that I did have for my text input.
  27040. 21:27:41Just intuitively, logically.
  27041. 21:27:45What's going through my head, embarrassingly,
  27042. 21:27:47is, all right, if my form thinks that it's missing a name or a sport,
  27043. 21:27:51how did I create a situation in which name is blank or sport is blank?
  27044. 21:27:55Well, name, I don't think it's going to be blank
  27045. 21:27:57because I explicitly gave this text field a name name
  27046. 21:28:01and that did work last time.
  27047. 21:28:02I've now given a second input in the form of the select menu.
  27048. 21:28:06But what seems to be missing here that I'm assuming exists here?
  27049. 21:28:13It's just a dumb mistake I made.
  27050. 21:28:16What might be missing here?
  27051. 21:28:19If request.form gives you all of the inputs that the user might
  27052. 21:28:23have typed in, let me go into my actual code
  27053. 21:28:26here in my form and name equals sport.
  27054. 21:28:30I just didn't give a name to that input.
  27055. 21:28:32So it exists, and the browser doesn't care.
  27056. 21:28:34It's still going to display the form to you,
  27057. 21:28:36it just hasn't given it a unique name to actually transmit to the server.
  27058. 21:28:40So now, if I'm not going to put my foot in my mouth,
  27059. 21:28:42I think that's what I did wrong.
  27060. 21:28:44And again, my process for figuring that out
  27061. 21:28:46was looking at my code, thinking through logically,
  27062. 21:28:49is this right, is this right?
  27063. 21:28:50No, I was missing the name there.
  27064. 21:28:52So let's run Flask, let's reload the form
  27065. 21:28:55just to make sure it's all defaults again, type in my name and type
  27066. 21:28:59in ultimate frisbee, crossing my fingers extra hard this time.
  27067. 21:29:04And there.
  27068. 21:29:05You are registered.
  27069. 21:29:06So I can emphasize--
  27070. 21:29:06I did not intend to screw up in that way,
  27071. 21:29:08but that's exactly the right kind of thought process
  27072. 21:29:10to diagnose issues like this.
  27073. 21:29:12Go back to the basics, go back to what HTTP and what HTML forms are all about,
  27074. 21:29:16and just rule things in and out.
  27075. 21:29:18There's only a finite number of ways I could have screwed that up.
  27076. 21:29:21Yeah?
  27077. 21:29:22AUDIENCE: Are you [INAUDIBLE].
  27078. 21:29:25DAVID: Excuse-- say a little louder?
  27079. 21:29:27AUDIENCE: I don't understand why name equals sport [INAUDIBLE]..
  27080. 21:29:30DAVID: Why did name equal sport address the problem?
  27081. 21:29:33Well, let's first go back to the HTML.
  27082. 21:29:35Previously, it was just the reality that I had this user input dropdown menu,
  27083. 21:29:43but I never gave it a name.
  27084. 21:29:44But names, or more generally, key value pairs,
  27085. 21:29:47is how information is sent from a form to the server.
  27086. 21:29:51So if there's no name, there's no key to send, even if the human types a value.
  27087. 21:29:56It would be like nothing equals ultimate frisbee, and that just doesn't work.
  27088. 21:30:00The browser is just not going to send it.
  27089. 21:30:02However, in app.py, I was naively assuming that in my requests form,
  27090. 21:30:08there would be a name called quote unquote "sport."
  27091. 21:30:11It could have been anything, but I was assuming it was sport.
  27092. 21:30:13But I never told the form that.
  27093. 21:30:15And if I really wanted to dig in, we could do a little something more.
  27094. 21:30:19Let me go back to the way it was a moment ago.
  27095. 21:30:22Let me get rid of the name of the sport dropdown menu.
  27096. 21:30:25Let me rerun Flask down here and reload the form itself
  27097. 21:30:30after it finishes being served.
  27098. 21:30:33And now, let me do this.
  27099. 21:30:34View Developer Tools, and then let me watch the Network tab, which recall,
  27100. 21:30:39we played around with a little bit last week.
  27101. 21:30:41And we also played around with Curl, which let us see the HTTP requests.
  27102. 21:30:44Here's another-- here's what I would have
  27103. 21:30:46done if I still wasn't seeing the error and was really embarrassed on stage.
  27104. 21:30:49I would have typed in my name as before, I would have chosen ultimate frisbee.
  27105. 21:30:53I would have clicked register.
  27106. 21:30:55And now, I would have looked at the HTTP request.
  27107. 21:30:59And I would click on Register here.
  27108. 21:31:01And just like we did last week, I would go down to the request down here.
  27109. 21:31:04And there's a whole lot of stuff that we can typically ignore.
  27110. 21:31:07But here, let me zoom in, way at the bottom,
  27111. 21:31:10what Chrome's developer tools are doing for me,
  27112. 21:31:13it's showing me all of the form data that was submitted.
  27113. 21:31:16So this really would have been my telltale clue.
  27114. 21:31:18I'm just not sending the sport, even if the human typed it in.
  27115. 21:31:21And logically, because I've done this before,
  27116. 21:31:23that must mean I didn't give the thing a name.
  27117. 21:31:26But another good tool.
  27118. 21:31:28Like good programmers, web developers are using these kinds of tools
  27119. 21:31:31all the time.
  27120. 21:31:32They're not writing bug-free code.
  27121. 21:31:34That's not the point to get to.
  27122. 21:31:35The point to get to is being a good diagnostician,
  27123. 21:31:38I would say, in these cases.
  27124. 21:31:40OK, other questions on this?
  27125. 21:31:45Yeah.
  27126. 21:31:46AUDIENCE: What if you want to edit one HTML in CSS, [INAUDIBLE]..
  27127. 21:31:52DAVID: I'm sorry, a little bit louder?
  27128. 21:31:54AUDIENCE: If you want to edit in CSS or anything,
  27129. 21:31:57in HTML, once you have to fix the template, how do you that?
  27130. 21:32:01DAVID: So how would you edit CSS if you have these templates?
  27131. 21:32:05That process we'll actually see before long.
  27132. 21:32:07It's almost going to be the exact same.
  27133. 21:32:09Just to give you a teaser for this, and you'll do this in the problem set,
  27134. 21:32:12but we'll give you some distribution code to automate this process.
  27135. 21:32:15You can absolutely still do something like this.
  27136. 21:32:17Link href equals quote unquote "styles" dot
  27137. 21:32:22CSS rel equals style sheet, that's one of the techniques we showed last week.
  27138. 21:32:27The only difference today, using Flask, is that all of your static files,
  27139. 21:32:31by convention, should go in your static folder.
  27140. 21:32:34So the change you would make in your layout
  27141. 21:32:36would be to say that styles dot CSS is in your static folder.
  27142. 21:32:40And then, if I go into my FroshIMS directory,
  27143. 21:32:43I can create a static folder.
  27144. 21:32:46I can CD into it, nothing's there by default.
  27145. 21:32:48But if I now code a file called styles.css,
  27146. 21:32:51I could now do something like this body.
  27147. 21:32:54And in here, I could say background color, say FF0000 to make it red.
  27148. 21:33:05Let me go ahead now and restart Flask in the FroshIMS directory.
  27149. 21:33:10Cross my fingers because I'm doing this on the fly.
  27150. 21:33:12Go back to my form and reload.
  27151. 21:33:16Voila, now we've tied together last week's stuff as well.
  27152. 21:33:19If I answered the right question?
  27153. 21:33:22AUDIENCE: [INAUDIBLE] change one page and not the other.
  27154. 21:33:27DAVID: If you want to change one page and not the other in terms of CSS?
  27155. 21:33:30AUDIENCE: Yes.
  27156. 21:33:31DAVID: That depends.
  27157. 21:33:32In that case, you might want to have different CSS files for each page
  27158. 21:33:36if they're different.
  27159. 21:33:38You could use different classes in one template than you did in the other.
  27160. 21:33:42There's different ways to do that.
  27161. 21:33:43You could even have a placeholder in your layout
  27162. 21:33:47that allows you to plug in the URL of a specific style
  27163. 21:33:52sheet in your individual files.
  27164. 21:33:53But that starts to get more complicated quickly.
  27165. 21:33:56So in short, you can absolutely do it.
  27166. 21:33:58But typically, I would say most websites try not
  27167. 21:34:01to use different style Sheets per page.
  27168. 21:34:03They reuse the styles as much as they can.
  27169. 21:34:06All right, let me go ahead and revert this real quick.
  27170. 21:34:08And let's start to add a little bit more functionality here.
  27171. 21:34:11I'm going to go ahead and just remove the static folder just so as
  27172. 21:34:14to not complicate things just yet.
  27173. 21:34:16And let's go ahead and just play around with a different user interface
  27174. 21:34:19mechanism.
  27175. 21:34:19In my form here, the dropdown menu is perfectly fine.
  27176. 21:34:23Nothing wrong with it.
  27177. 21:34:24But suppose that I wanted to change it to checkboxes instead.
  27178. 21:34:27Maybe I want students to be able to register for multiple sports instead.
  27179. 21:34:31Well, it might make sense to clean this up in a couple of ways.
  27180. 21:34:34And let's do this.
  27181. 21:34:35Before we even get into the checkboxes, there's one subtle bad design here.
  27182. 21:34:40Notice that I've hardcoded basketball, soccer, and ultimate frisbee here.
  27183. 21:34:45And if you recall, in app.py, I also enumerated all three of those here.
  27184. 21:34:49And any time you see copy paste or the equivalent thereof,
  27185. 21:34:52feels like we could do better.
  27186. 21:34:54So what if I instead do this.
  27187. 21:34:56What if I instead give myself a global variable of Sports,
  27188. 21:35:00I'll capitalize the word just to connote that it's
  27189. 21:35:03meant to be constant even though Python does not have constants, per se.
  27190. 21:35:07The first sport will be basketball.
  27191. 21:35:09The second will be soccer.
  27192. 21:35:11The third will be ultimate frisbee.
  27193. 21:35:15Now I have one convenient place to store all of my sports
  27194. 21:35:19if it changes next semester or next year or whatnot.
  27195. 21:35:22But notice what I could do to.
  27196. 21:35:24I could now do something like this.
  27197. 21:35:26Let me pass into my index template a variable
  27198. 21:35:30called sports that's equal to that global variable sports.
  27199. 21:35:34Let me go into my index now, and this is really, now,
  27200. 21:35:37going to hint at the power of templating and Jinja, in this case here.
  27201. 21:35:41Let me go ahead and get rid of all three of these hard coded options
  27202. 21:35:45and let me show you some slightly different syntax for sport, in sports.
  27203. 21:35:50Then end for.
  27204. 21:35:52We've not seen this end for syntax.
  27205. 21:35:54There's like end block syntax, but it's as simple as that.
  27206. 21:35:57So you have a start and an end to your block without indentation mattering.
  27207. 21:36:00Watch what I can do here.
  27208. 21:36:02Option curly brace sport close curly brace.
  27209. 21:36:08Let me save that.
  27210. 21:36:09Let me go back into my terminal window, do Flask run.
  27211. 21:36:12And if I didn't mess up here, let me go back to this.
  27212. 21:36:16The red's going to go away because I deleted my CSS.
  27213. 21:36:18And now I still have a sport dropdown and all of those sports
  27214. 21:36:21are still there.
  27215. 21:36:22I can make one more improvement now.
  27216. 21:36:24I don't need to mention these same sports manually in app.py.
  27217. 21:36:27I can now just say if the user's inputed sport is not
  27218. 21:36:31in my global variable, sports, and ask the same question.
  27219. 21:36:35And this is really handy because if there's
  27220. 21:36:36another sport, for instance, that gets added, like say football,
  27221. 21:36:41all I have to do is change my global variable.
  27222. 21:36:43And if I reload the form now and look in the dropdown, boom,
  27223. 21:36:47now I have support for a fourth sport.
  27224. 21:36:49And I can keep adding and adding there.
  27225. 21:36:51So here's where templating starts to get really powerful in that
  27226. 21:36:55now, in this template, I'm using Jinja's for loop syntax, which
  27227. 21:37:00is almost identical to Python here, except you
  27228. 21:37:02need the curly brace and the percent sign and you need the weird ending
  27229. 21:37:06and for.
  27230. 21:37:07But it's the same idea as in Python.
  27231. 21:37:08Iterating over something with a for loop lets you generate more and more HTML.
  27232. 21:37:13And this is like every website out there.
  27233. 21:37:14For instance, Gmail.
  27234. 21:37:15When you visit your inbox and you see all of this big table of emails,
  27235. 21:37:19Google has not hardcoded your emails manually.
  27236. 21:37:22They have grabbed them from a database.
  27237. 21:37:24They have some kind of for loop like this,
  27238. 21:37:26and are just outputting table row after table row or div after div dynamically.
  27239. 21:37:32All right, so now, let's go ahead and change this, maybe,
  27240. 21:37:34to, oh, how about little checkboxes or radio buttons.
  27241. 21:37:40So let me go ahead and do this.
  27242. 21:37:41Instead of a select menu, I'm going to go ahead and do something like this.
  27243. 21:37:46For each of these sports let me go ahead and output, not an option,
  27244. 21:37:52but let me go ahead and output an input tag,
  27245. 21:37:55the name for which is quote unquote "sport," the type of which
  27246. 21:37:59is checkbox, the value of which is going to be the current "sport,"
  27247. 21:38:05quote unquote, and then afterward I need to redundantly, seemingly,
  27248. 21:38:09output the sport.
  27249. 21:38:10So you see a word next to the checkbox.
  27250. 21:38:11And we'll look at the result of this in just a moment.
  27251. 21:38:14So it's actually a little simpler than a select menu, a dropdown menu,
  27252. 21:38:17because now watch what happens if I reload my form.
  27253. 21:38:20Different user interface, and it's not as pretty,
  27254. 21:38:24but it's going to allow users to sign up for multiple sports at once now,
  27255. 21:38:27it would seem.
  27256. 21:38:28Now I can click on basketball and football and soccer
  27257. 21:38:31or some other combination thereof.
  27258. 21:38:34If I view the page's source, this is, again, the power of templating.
  27259. 21:38:37I didn't have to type out four inputs, I got them now automatically.
  27260. 21:38:41And these things all have the same name, but that's OK.
  27261. 21:38:45It turns out with Flask, if it sees multiple values for the same name,
  27262. 21:38:48it's going to hand them back to you as a list if you use the right function.
  27263. 21:38:52All right, but suppose we don't want users registering for multiple sports.
  27264. 21:38:56Maybe capacity is an issue.
  27265. 21:38:57Let me go ahead and change this checkbox to radio button, which
  27266. 21:39:01a radio button is mutually exclusive.
  27267. 21:39:03So you can only sign up for one.
  27268. 21:39:04So now, once I reload the page, there we go.
  27269. 21:39:09It now looks like this.
  27270. 21:39:12And because I've given each of these inputs the same name, quote unquote,
  27271. 21:39:16"sport," that's what makes them mutually exclusive.
  27272. 21:39:20The browser knows all four of these things are types of sports,
  27273. 21:39:23therefore I'm only going to let you select one of these things.
  27274. 21:39:26And that's simply because they all have the same name.
  27275. 21:39:29Again, if I view page source, notice all of them, name equal sport,
  27276. 21:39:32name equals sport, name equals sport, but what differs is the value
  27277. 21:39:36that each one is going to have.
  27278. 21:39:39All right, any questions, then, on this approach?
  27279. 21:39:45All right.
  27280. 21:39:45Well, let me go ahead and open a version of this
  27281. 21:39:47that I made in advance that's going to now start saving the information.
  27282. 21:39:51So thus far, we're not quite at the point
  27283. 21:39:53of where this website was, which actually allowed the proctors to see,
  27284. 21:39:56like in a database, everyone who had registered for sports.
  27285. 21:39:59Now, we're literally telling students you are registered
  27286. 21:40:01or you are not registered, but we're literally
  27287. 21:40:03doing nothing with this information.
  27288. 21:40:05So how might we go about implementing this?
  27289. 21:40:08Well, let me go ahead and close these tabs,
  27290. 21:40:10and let me go into what I call version three of this in the code for today.
  27291. 21:40:15And let me go into my source nine directory, FroshIMS3,
  27292. 21:40:19and let me go ahead and open up app.py.
  27293. 21:40:22So this is a premade version.
  27294. 21:40:24I've gotten rid of football, in this case.
  27295. 21:40:26But I've added one thing at the very top.
  27296. 21:40:28What's, in English, does this represent on line seven?
  27297. 21:40:33What would you describe what that thing is?
  27298. 21:40:38What are we looking at?
  27299. 21:40:40What do you think?
  27300. 21:40:41AUDIENCE: It's an empty dictionary.
  27301. 21:40:42DAVID: Yeah, it's an empty dictionary, right?
  27302. 21:40:43Registrants is apparently a variable on the left.
  27303. 21:40:45It's being assigned an empty dictionary on the right.
  27304. 21:40:47And a dictionary, again, is just key value pairs.
  27305. 21:40:49Here, again, is where dictionaries are just such a useful data structure.
  27306. 21:40:53Why?
  27307. 21:40:53Because this is going to allow me to remember that David registered
  27308. 21:40:56for ultimate frisbee, Carter registered for soccer,
  27309. 21:40:59Emma registered for something else.
  27310. 21:41:00You can associate keys with values, names with sports,
  27311. 21:41:04assuming a model where you can only register for one sport for now.
  27312. 21:41:07And so let's see what the logic is that handles this.
  27313. 21:41:12Here in my register route in the code I've premade,
  27314. 21:41:16notice that I'm validating the user's name.
  27315. 21:41:18Slightly differently from before but same idea.
  27316. 21:41:20I'm using request.form.get to get the human's name.
  27317. 21:41:23If not name, so if the human did not type a name,
  27318. 21:41:26I'm going to output error.html.
  27319. 21:41:29But notice I've started to make the user interface more expressive.
  27320. 21:41:33I'm telling the user, apparently, with a message what they did wrong.
  27321. 21:41:37Well how?
  27322. 21:41:38I'm apparently passing to my error template,
  27323. 21:41:41instead of just failure.html, a specific message.
  27324. 21:41:44So let's go down this rabbit hole.
  27325. 21:41:45Let me actually go into templates/error.hml, and sure enough,
  27326. 21:41:52here's a new file I created here, that adorably is apparently going to have
  27327. 21:41:55a grumpy cat as part of the error message, but notice what I've done.
  27328. 21:41:59In my block body I've got an H1 tag that just says error, big and bold.
  27329. 21:42:04I then have a paragraph tag that plugs in whatever
  27330. 21:42:07the error message is that the controller, app.py, is passing in.
  27331. 21:42:10And then just for fun, I have a picture of a grumpy cat connoting
  27332. 21:42:14that there was, in fact, an error.
  27333. 21:42:15Let's keep looking.
  27334. 21:42:16How do I validate sport?
  27335. 21:42:18I do similarly request.form.get of sport,
  27336. 21:42:22and I store it in a variable called sport.
  27337. 21:42:24If there's no such sport, that is the human did not check any of the boxes,
  27338. 21:42:28then I'm going to render error.html two, but I'm
  27339. 21:42:30going to give a different message, missing sport.
  27340. 21:42:33Else, if the sport they did type in is not in my sports global variable,
  27341. 21:42:38I'm going to render error.html, but complain differently,
  27342. 21:42:41you gave me an invalid sport somehow.
  27343. 21:42:44As if a hacker went into the HTML of the page,
  27344. 21:42:47changed it to add their own sport like volleyball.
  27345. 21:42:49Even though it's not offered, they submitted volleyball.
  27346. 21:42:51But that's OK, I'm rejecting it, even though they might have maliciously
  27347. 21:42:55tried to send it to me by changing the dom locally.
  27348. 21:42:58And then really, the magic is just this.
  27349. 21:43:00I remember that this person has registered
  27350. 21:43:03by indexing into the registrant dictionary
  27351. 21:43:06using the name the human typed in as the key and assigning it a value of sport.
  27352. 21:43:11Why is this useful?
  27353. 21:43:12Well, I added one final route here.
  27354. 21:43:15I have a /registrants route with a registrants function that renders
  27355. 21:43:19a template called registrants.html.
  27356. 21:43:21But it takes as input that global variable just like before.
  27357. 21:43:26So let's go down this rabbit hole let me go into templates registrants dot HTML.
  27358. 21:43:32Here's this template.
  27359. 21:43:34It looks a little crazy big, but it extends the layout.
  27360. 21:43:38Here comes the body.
  27361. 21:43:39I've got an H1 tag that says registrants, big and bold.
  27362. 21:43:42Then I've got a table that we saw last week.
  27363. 21:43:44This has a table head that just says name sport for two columns.
  27364. 21:43:48Then it has a table body where in, using this for loop in Jinja syntax,
  27365. 21:43:53I'm saying, for each name in the registrants variable,
  27366. 21:43:57output a table row, start tag, and end tag, inside of which,
  27367. 21:44:01two table datas, two cells, table data for name,
  27368. 21:44:04table data for registrants bracket name.
  27369. 21:44:08So it's very similar to Python syntax.
  27370. 21:44:10It essentially is Python syntax, albeit with these curly braces and the percent
  27371. 21:44:14sign.
  27372. 21:44:15So the net effect here is what?
  27373. 21:44:17Let me open up my terminal window, run Flask run.
  27374. 21:44:20Let me now go into the form that I premade here.
  27375. 21:44:24So gone is football.
  27376. 21:44:26Let me go ahead and type in David.
  27377. 21:44:27Let me choose, oh, no sport.
  27378. 21:44:30Register.
  27379. 21:44:31Error, missing sport.
  27380. 21:44:33And there is the grumpy cat.
  27381. 21:44:34So missing sport, though, specifically was outputed.
  27382. 21:44:37All right, fine.
  27383. 21:44:38Let me go ahead and say no name.
  27384. 21:44:41But I'll choose basketball.
  27385. 21:44:42Register.
  27386. 21:44:43Missing name.
  27387. 21:44:44All right, and let me maliciously, now, do this.
  27388. 21:44:47Now I'm hacking.
  27389. 21:44:48Let me go into this.
  27390. 21:44:49I'll type my name, sure, but let me go into the body tag down here.
  27391. 21:44:53Let me maliciously go down in ultimate frisbee, heck with that, let's
  27392. 21:44:57volleyball.
  27393. 21:44:59Change that and change this to volleyball.
  27394. 21:45:04Enter.
  27395. 21:45:05So now, I can register for any sport I want to create.
  27396. 21:45:08Let me click register, but invalid sports.
  27397. 21:45:11So again, that speaks to the power and the need
  27398. 21:45:14for checking things on backend and not trusting users.
  27399. 21:45:17It is that easy to hack websites otherwise if you're not validating data
  27400. 21:45:21server side.
  27401. 21:45:22All right, finally, let's just do this for real.
  27402. 21:45:24David is going to register for ultimate frisbee.
  27403. 21:45:26Clicking register.
  27404. 21:45:27And now, the output is not very pretty, but notice
  27405. 21:45:30I'm at the registrants route.
  27406. 21:45:32And if I zoom out, I have an HTML table.
  27407. 21:45:34Two columns, name and sport, David and ultimate frisbee.
  27408. 21:45:38Let me go back to the form, letting me pretend Carter walked up to my laptop
  27409. 21:45:41and registered for basketball.
  27410. 21:45:43Register.
  27411. 21:45:44Now we see two rows in this table, David, ultimate frisbee, Carter,
  27412. 21:45:49basketball.
  27413. 21:45:49And if we do this one more time, maybe Emma
  27414. 21:45:51comes along and registers for soccer register.
  27415. 21:45:53All of this information is being stored in this dictionary, now.
  27416. 21:45:58All right, so that's great.
  27417. 21:45:59Now we have a database, albeit in the form of a Python dictionary.
  27418. 21:46:03But why is this, maybe, not the best implementation?
  27419. 21:46:09Why is it not great?
  27420. 21:46:09Yeah.
  27421. 21:46:10AUDIENCE: You are storing [INAUDIBLE].
  27422. 21:46:18DAVID: Yeah.
  27423. 21:46:18So we're only storing this dictionary in the computer's memory,
  27424. 21:46:21and that's great until I hit Control C and kill Flask,
  27425. 21:46:24stopping the web server.
  27426. 21:46:26Or the server reboots, or maybe I close my laptop or whatever.
  27427. 21:46:29If the server stops running, memory is going to be lost.
  27428. 21:46:32RAM is volatile.
  27429. 21:46:34It's thrown away when you lose power or stop the program.
  27430. 21:46:37So maybe this isn't the best approach.
  27431. 21:46:39Maybe it would be better to use a CSV file.
  27432. 21:46:41And in fact, some 20 years ago, that's literally what I did.
  27433. 21:46:43I stored everything in a CSV file.
  27434. 21:46:45But let's skip that step, because we already saw last week,
  27435. 21:46:48or a couple of weeks ago now, how we can use SQLite.
  27436. 21:46:51Let's see if we can't marry in some SQL here
  27437. 21:46:54to store an actual database for the program.
  27438. 21:46:58Let me go back here and let me open up, say,
  27439. 21:47:00version four of this, which is almost the same but it
  27440. 21:47:03adds a bit more functionality.
  27441. 21:47:05Let me close these tabs and let me open up app.py now in version four.
  27442. 21:47:10So notice it's almost the same, but at the top,
  27443. 21:47:13I'm creating a database connection to a database called FroshIMS.db.
  27444. 21:47:18So that's a database I created in advance.
  27445. 21:47:20So let's go down that rabbit hole.
  27446. 21:47:21What does it look like?
  27447. 21:47:22Let me make my terminal window bigger.
  27448. 21:47:24Let me run SQLite 3 of FroshIMS.db.
  27449. 21:47:28OK, I'm in.
  27450. 21:47:29Let's do .schema.
  27451. 21:47:30and let's just infer what I designed this to be.
  27452. 21:47:33I have a table called registrants, which has one, two, three columns.
  27453. 21:47:37An ID column that's an integer, a name column that's text but cannot be null,
  27454. 21:47:42and a sport column that's also text, cannot be null,
  27455. 21:47:44and the primary key is just ID.
  27456. 21:47:46So that I have a unique ID for every registration.
  27457. 21:47:49Let's see if there's anyone in there yet.
  27458. 21:47:51Select star from registrants.
  27459. 21:47:55OK, there's no one in there.
  27460. 21:47:56No one is yet registered for sports.
  27461. 21:47:58So let's go back to the code and continue on.
  27462. 21:48:00In my code now, I've got the same global variable
  27463. 21:48:03for validation and generation of my HTML.
  27464. 21:48:07Looks like my index route is the same.
  27465. 21:48:09It's dynamically generating the menu of sports.
  27466. 21:48:13Interestingly, we'll come back to this.
  27467. 21:48:14There's a deregister route that's going to allow someone
  27468. 21:48:17to deregister themselves if they want to exit the sport
  27469. 21:48:22or undo their registration.
  27470. 21:48:23But this is the juicy part.
  27471. 21:48:24Here's my new and improved register route.
  27472. 21:48:27Still works on POST, so some mild privacy there.
  27473. 21:48:30I'm validating the submission as follows.
  27474. 21:48:33I'm getting the user's inputted name, the user's inputted sport,
  27475. 21:48:36and if it is not a name or the sport is not in sports,
  27476. 21:48:41I'm going to render failure.html.
  27477. 21:48:42So I kept it simple.
  27478. 21:48:43There's no cat in this version.
  27479. 21:48:45It just says failure.
  27480. 21:48:46Otherwise, recall how we co-mingled SQL and Python before.
  27481. 21:48:50We're using CS50's SQL library, but that just
  27482. 21:48:53makes it a little easier to execute SQL queries and we're executing this.
  27483. 21:48:56Insert into registrants name comma sport.
  27484. 21:49:00What two values, the name and the sport, that came from that HTML form.
  27485. 21:49:05And then lastly, and this is a new function that we're calling out
  27486. 21:49:08explicitly now, Flask also gives you access
  27487. 21:49:10to a redirect function, which is how safetyschool.org, Harvardsucks.org,
  27488. 21:49:17and all these other sites we played around with last week
  27489. 21:49:19we're all implemented redirecting the user from one place to another.
  27490. 21:49:23This Flask function redirect comes from my just
  27491. 21:49:26having imported it at the very top of this file.
  27492. 21:49:30It handles the HTTP 301 or 302 or 307 code, whatever the appropriate one is.
  27493. 21:49:35It does that for me.
  27494. 21:49:37All right, so that's it for registering via this route.
  27495. 21:49:42Let's look at what the registrant's route is.
  27496. 21:49:45Here, we have a new route for /registrants.
  27497. 21:49:49And instead of just iterating over a dictionary like before,
  27498. 21:49:52we're getting back, let's see, db.execute of select star
  27499. 21:49:56from registrants.
  27500. 21:49:57So that's literally the programmatic version of what I just did manually.
  27501. 21:50:00That gives me back a list of dictionaries,
  27502. 21:50:02each of which represents one row in the table.
  27503. 21:50:05Then, I'm going to render register and start HTML,
  27504. 21:50:08passing in literally that list of dictionaries
  27505. 21:50:12just like using CS50's library in the past.
  27506. 21:50:15So let's go and look at these-- that form.
  27507. 21:50:18If I go into templates and open up registrants.html,
  27508. 21:50:24oh, OK, it's just a table like before.
  27509. 21:50:27And actually, let me change this syntactically for consistency.
  27510. 21:50:30We have a Jinja for loop that iterates over each registrant
  27511. 21:50:36and for each of them, outputs a table row.
  27512. 21:50:39Oh, but this is interesting.
  27513. 21:50:40Instead of just having two columns with the person's name and sport,
  27514. 21:50:44notice that I'm also outputting a full-fledged form.
  27515. 21:50:47All right, this is starting to get juicy.
  27516. 21:50:49So let's actually go back to my terminal window,
  27517. 21:50:52run Flask, and actually see what this example looks like now.
  27518. 21:50:56Let me reload the page.
  27519. 21:50:58All right.
  27520. 21:50:58In the home page, it looks exactly the same.
  27521. 21:51:00But let me now register for something.
  27522. 21:51:02David for ultimate frisbee, register.
  27523. 21:51:04Oh, damn it.
  27524. 21:51:07Let's try this again.
  27525. 21:51:08David registering for ultimate frisbee, register.
  27526. 21:51:12OK.
  27527. 21:51:13So good thing I have deregister.
  27528. 21:51:15So this is what it should now look like.
  27529. 21:51:16I have a page at the route called /registrants that has a table with two
  27530. 21:51:22columns, name and sport, David, ultimate frisbee.
  27531. 21:51:24But oh, wait, a third column.
  27532. 21:51:25Why?
  27533. 21:51:26Because if I view the page source, notice that it's not the prettiest UI.
  27534. 21:51:30For every row in this table, I'm also going to be outputting a form just
  27535. 21:51:34to deregister that user.
  27536. 21:51:36But before we see how that works, let me go ahead and register Carter,
  27537. 21:51:40for instance.
  27538. 21:51:40So Carter will give you basketball.
  27539. 21:51:42Again, register.
  27540. 21:51:43The table grows.
  27541. 21:51:44Now, let me go back and let's register Emma for soccer.
  27542. 21:51:48And the table should grow.
  27543. 21:51:50Before we look at that HTML, let's go back to my terminal window.
  27544. 21:51:55Let's go into SQLite FroshIMS.
  27545. 21:51:59Let me go into FroshIMS, and let me open up with SQLite 3 FroshIMS.db.
  27546. 21:52:10And now do select star from registrants.
  27547. 21:52:12And whereas, previously, when I executed this there were zero people, now
  27548. 21:52:16there's indeed three.
  27549. 21:52:17So now we see exactly what's going on underneath the hood.
  27550. 21:52:21So let's look at this form now-- this page now.
  27551. 21:52:24If I want to unregister, deregister one of these people specifically,
  27552. 21:52:29how do we do this?
  27553. 21:52:30Clicking one of those buttons will indeed
  27554. 21:52:33delete the row from the database.
  27555. 21:52:36But how do we go about linking a web page with Python code with a database?
  27556. 21:52:41This is the last piece of the puzzle.
  27557. 21:52:43Up until now, everything's been with forms and also with URLs.
  27558. 21:52:47But what if the user is not typing anything in,
  27559. 21:52:49they're just clicking a button?
  27560. 21:52:51Well, watch this.
  27561. 21:52:53Let me go ahead and sniff the traffic, which
  27562. 21:52:55you could be in the habit of doing now.
  27563. 21:52:57Any time you're curious how a website works, let me go to the Network tab.
  27564. 21:53:01And Carter, shall we deregister you from basketball?
  27565. 21:53:05Let's deregister Carter and let's see what just happened.
  27566. 21:53:09If I look at the deregister request, notice that it's a POST.
  27567. 21:53:13The status code that eventually came back as 302,
  27568. 21:53:16but let's look at the request itself.
  27569. 21:53:18All the headers there we'll ignore.
  27570. 21:53:21The only thing that button submits, cleverly,
  27571. 21:53:25is an ID parameter, a key equaling two.
  27572. 21:53:29What does two presumably represent or map to?
  27573. 21:53:34Where did this two come from?
  27574. 21:53:37It doesn't say Carter, it doesn't say basketball?
  27575. 21:53:40What is it?
  27576. 21:53:41AUDIENCE: The second person who registered.
  27577. 21:53:43DAVID: The second person that registered.
  27578. 21:53:44So those primary keys that we started talking about a couple of weeks
  27579. 21:53:47ago, why it's useful to be able to uniquely identify a row in a table,
  27580. 21:53:50here is just one of the reasons why.
  27581. 21:53:53If it suffices for me just to send the ID number of the person
  27582. 21:53:58I want to delete from the database, because I can then have code like this.
  27583. 21:54:03If I go into app.py and I look at my deregister route now, the last of them,
  27584. 21:54:09notice that I got this.
  27585. 21:54:11I first go into the form, and I get the ID that was submitted, hopefully.
  27586. 21:54:15If there was, in fact, an ID, and the form wasn't somehow empty,
  27587. 21:54:19I execute this line of code.
  27588. 21:54:21Delete from registrants where ID equals question mark,
  27589. 21:54:24and then I plug-in that number, deleting Carter and only Carter.
  27590. 21:54:29And I'm not using his name, because what if we have two people named Carter,
  27591. 21:54:32two people named Emma or David?
  27592. 21:54:34You don't want to delete both of them.
  27593. 21:54:35That's why these unique IDs are so, so important.
  27594. 21:54:39And here's another reason why.
  27595. 21:54:41You don't want to store some things in URLs.
  27596. 21:54:45Suppose we went to this URL, deregister?ID=3.
  27597. 21:54:53Suppose I, maliciously, emailed this URL to Emma.
  27598. 21:54:58It doesn't matter so much what the beginning is,
  27599. 21:55:00but supposed I emailed her this URL, /deregister?ID=3, and I said, hey,
  27600. 21:55:06Emma, click this.
  27601. 21:55:07And it uses GET instead of POST.
  27602. 21:55:10What did I just trick her into doing?
  27603. 21:55:15What's going to happen if Emma clicks this?
  27604. 21:55:17Yeah?
  27605. 21:55:17AUDIENCE: Deregistering?
  27606. 21:55:19DAVID: You would trick her into deregistering herself.
  27607. 21:55:21Why?
  27608. 21:55:22Because if she's logged into this FroshIMS website,
  27609. 21:55:24and the URL contains her ID just because I'm being malicious,
  27610. 21:55:28and she clicked on it and the website is using GET,
  27611. 21:55:31unfortunately, GET URLs are, again, stateful.
  27612. 21:55:34They have state information in the URLs.
  27613. 21:55:36And in this case, it's enough to delete the user and boom,
  27614. 21:55:39she would have accidentally deregistered herself.
  27615. 21:55:42And this is pretty innocuous.
  27616. 21:55:43Suppose that this was her bank account trying
  27617. 21:55:45to make a withdrawal or a deposit.
  27618. 21:55:47Suppose that this were some other website, a Facebook URL,
  27619. 21:55:50trying to trick her into posting something automatically.
  27620. 21:55:53Here, too, is another consideration when you
  27621. 21:55:55should use POST versus GET, because GET requests can
  27622. 21:55:59be plugged into emails sent via Slack messages, text messages, or the like.
  27623. 21:56:04And unless there's a prompt saying, are you sure
  27624. 21:56:06you want to deregister yourself, you might blindly
  27625. 21:56:09trick the user into being vulnerable to what's
  27626. 21:56:11called a cross-site request forgery.
  27627. 21:56:14A fancy way of saying you trick them into clicking a link
  27628. 21:56:17that they shouldn't have, because the website was using GET alone.
  27629. 21:56:21All right, any question, then, on these building blocks?
  27630. 21:56:25Yeah.
  27631. 21:56:26AUDIENCE: What do the first thing in the instance of the SQL
  27632. 21:56:32[INAUDIBLE] where they have three slashes?
  27633. 21:56:34What does that mean?
  27634. 21:56:35DAVID: When three columns, you mean?
  27635. 21:56:37AUDIENCE: No, three forward slashes.
  27636. 21:56:42DAVID: The three forward slashes.
  27637. 21:56:44I'm not sure I follow.
  27638. 21:56:46AUDIENCE: Yeah, so I think it's in [INAUDIBLE]..
  27639. 21:56:52DAVID: Sorry, it's in where?
  27640. 21:56:56Which file?
  27641. 21:56:57AUDIENCE: It's in [INAUDIBLE] scroll up.
  27642. 21:57:02[INAUDIBLE]
  27643. 21:57:06DAVID: Sorry, the other direction?
  27644. 21:57:07AUDIENCE: Yeah.
  27645. 21:57:08DAVID: OK.
  27646. 21:57:09AUDIENCE: [INAUDIBLE].
  27647. 21:57:12So please scroll a little bit more.
  27648. 21:57:16DAVID: Keep scrolling more?
  27649. 21:57:17Oh, this thing.
  27650. 21:57:18OK, sorry.
  27651. 21:57:20This is a URI, it's typical syntax that's referring to the SQLite
  27652. 21:57:27protocol, so to speak, which means use SQLite to talk to a file locally.
  27653. 21:57:32:// is just like you and I see in URLs.
  27654. 21:57:35The third slash, essentially, means current folder.
  27655. 21:57:37That's all.
  27656. 21:57:38So it's a weird curiosity, but it's typical
  27657. 21:57:41whenever you're referring to a local file and not one that's
  27658. 21:57:43elsewhere on the internet.
  27659. 21:57:45That's a bit of an oversimplification, but that's indeed a convention.
  27660. 21:57:48Sorry for not clicking earlier.
  27661. 21:57:50All right, let's do one other iteration of FroshIMS
  27662. 21:57:53here just to show what I was actually doing too, back in the day,
  27663. 21:57:56was not only storing these things in CSV files, as I recall.
  27664. 21:57:59I was also automatically generating an email
  27665. 21:58:02to the proctor in charge of the intramural sports program
  27666. 21:58:04so that they would have sort of a running history of people registering
  27667. 21:58:07and they could easily reply to them as well.
  27668. 21:58:09Let me go into FroshIMS version five, which I precreated here,
  27669. 21:58:13and let me go ahead and open up, say, app.py this time.
  27670. 21:58:18And this is some code that I wrote in advance.
  27671. 21:58:21And it looks a little scary at first glance, but I've done the following.
  27672. 21:58:24I have now added the Flask mail library to the picture
  27673. 21:58:30by adding Flask mail to requirements.txt and running a command
  27674. 21:58:33to automatically install email support for Flask as well.
  27675. 21:58:37And this is a little bit cryptic, but it's honestly mostly
  27676. 21:58:39copy paste from the documentation.
  27677. 21:58:41What I'm doing here is I'm configuring my Flask
  27678. 21:58:44application with a few configuration variables, if you will.
  27679. 21:58:47This is the syntax for that. app.config is a special dictionary that
  27680. 21:58:51comes with Flask that is automatically created when you create the app appear
  27681. 21:58:55on line nine, and I just had to fill in a whole bunch of configuration
  27682. 21:58:58values for the default sender address that I
  27683. 21:59:01want to send email as, the default password I want to use to send email,
  27684. 21:59:05the port number, the TCP port, that we talked about last week.
  27685. 21:59:08The mail server, I'm going to use Gmail's smtp.gmail.com server.
  27686. 21:59:12Use TLS, this means use encryption.
  27687. 21:59:14So I set that to true.
  27688. 21:59:15Mail username, this is going to grab it from my environment.
  27689. 21:59:18So for security purposes, I didn't want to hard code my own Gmail username
  27690. 21:59:21and password into the code.
  27691. 21:59:24So I'm actually storing those in what are called environment variables.
  27692. 21:59:26You'll see more of these in problem set nine,
  27693. 21:59:29and it's a very common convention on a server
  27694. 21:59:31in the real world to store sensitive information in the computer's memory
  27695. 21:59:36so that it can be accessed when your website is running,
  27696. 21:59:39but not in your source code.
  27697. 21:59:41It's way too easy if you put credentials,
  27698. 21:59:44sensitive stuff in your source code, to post it to GitHub
  27699. 21:59:47or to screenshot it accidentally, or for information to leak out.
  27700. 21:59:50So for today's purposes, know that the OS.environ dictionary refers to what
  27701. 21:59:55are called environment variables.
  27702. 21:59:57And this is like an out-of-band, a special way of defining key value
  27703. 22:00:01pairs in the computer's memory by running a certain command
  27704. 22:00:04but that never show up in your actual code.
  27705. 22:00:06Otherwise, there would be so many usernames and passwords
  27706. 22:00:09accidentally visible on the internet.
  27707. 22:00:11So I've installed this in advance.
  27708. 22:00:14Let me see if I can do this correctly.
  27709. 22:00:16Let me go over to another tab in just a moment.
  27710. 22:00:19And here, I have on my second screen here, John Harvards inbox.
  27711. 22:00:23It's currently empty, and I'm going to go ahead and register
  27712. 22:00:26for some sport as John Harvard here, hopefully.
  27713. 22:00:28So let me go ahead and run Flask run on this version five.
  27714. 22:00:32Let me go ahead and reload the main screen.
  27715. 22:00:36Not that one.
  27716. 22:00:37Let me reload the main screen here.
  27717. 22:00:38This time, clearly, I'm asking for name and email.
  27718. 22:00:41So name will be John Harvard.
  27719. 22:00:43[email protected].
  27720. 22:00:45He'll register for, how about soccer.
  27721. 22:00:51Register.
  27722. 22:00:52And if I did this correctly, not only is John Harvard, on his screen,
  27723. 22:00:57seeing you are registered, but when he checks his email on this other screen,
  27724. 22:01:06crossing his fingers that this actually works as a demonstration,
  27725. 22:01:13and I promise it did right before class.
  27726. 22:01:21Horrifying.
  27727. 22:01:22I don't think there's a mistake this time.
  27728. 22:01:28Let me try something over here real quick,
  27729. 22:01:31but I don't think this is broken.
  27730. 22:01:35It wouldn't have said success if it were.
  27731. 22:01:39I just tried submitting again, so I just did another you are registered.
  27732. 22:01:44Oh, I'm really sad right now.
  27733. 22:01:49AUDIENCE: [INAUDIBLE]
  27734. 22:01:51DAVID: What's that?
  27735. 22:01:52AUDIENCE: Check spam.
  27736. 22:01:53DAVID: I could check spam, but then it's--
  27737. 22:01:57not sure we want to show spam here on the internet that every one of us gets.
  27738. 22:02:01Oh, maybe.
  27739. 22:02:04Oh!
  27740. 22:02:05[LAUGHTER AND APPLAUDING]
  27741. 22:02:07Thank you.
  27742. 22:02:13OK.
  27743. 22:02:13Wow, that was a risky click I worried.
  27744. 22:02:15All right, so you are registered is the email that I sent out,
  27745. 22:02:19and it doesn't have any actual information in it.
  27746. 22:02:21But back in the day it would have, because I
  27747. 22:02:23included the student's name and their dorm
  27748. 22:02:25and all of the other fields of information that we asked for.
  27749. 22:02:27So let's just take a quick look at how that code might work.
  27750. 22:02:30I did have to configure Gmail in a certain way to allow,
  27751. 22:02:33what they call, less secure apps using SMTP,
  27752. 22:02:36which is the protocol used for outbound email.
  27753. 22:02:38But besides setting these things, let's look at the register route down here.
  27754. 22:02:42It's actually pretty straightforward.
  27755. 22:02:44In my register route, I validated the submission just like before.
  27756. 22:02:47Nothing new there.
  27757. 22:02:48I then confirmed the registration down here, nothing new there.
  27758. 22:02:52All I did was use two new lines of code.
  27759. 22:02:55And it's this easy to automate the sending of emails.
  27760. 22:02:57I apparently have done it too many times,
  27761. 22:02:59which is why it ended up in spam.
  27762. 22:03:01I created a variable called message.
  27763. 22:03:03I used a message function that I must have imported higher up,
  27764. 22:03:06so we'll go back to that.
  27765. 22:03:08Here's, apparently, the subject line as the first argument.
  27766. 22:03:10And the second argument is the named parameter recipients,
  27767. 22:03:15which takes a list of emails that should get the confirmation email.
  27768. 22:03:18So in brackets, I just put the one user's email
  27769. 22:03:21and then mail.send that message.
  27770. 22:03:24So let's scroll back up to see what message and what mail actually is.
  27771. 22:03:29Mail, I think, we saw.
  27772. 22:03:30Yep, mail is this, which I have as a variable
  27773. 22:03:33because I followed the documentation for this library.
  27774. 22:03:36You simply configure your current app with Mail support, capital M here.
  27775. 22:03:41And if you look up here now, on line seven,
  27776. 22:03:43here's the new library from Flask mail I imported.
  27777. 22:03:46Capital Mail, capital Message, so that I had the ability to create a message
  27778. 22:03:50and send a mail.
  27779. 22:03:52So such a simple thing whether you want to confirm things for users,
  27780. 22:03:55you want to do password resets.
  27781. 22:03:56It can be this easy to actually generate emails
  27782. 22:04:00provided you have the requisite access and software installed.
  27783. 22:04:03And just to make clear that I did add something here,
  27784. 22:04:05let me open up my requirements.txt file, and indeed, I
  27785. 22:04:09have both Flask and Flask-mail ready to go.
  27786. 22:04:13But I ran the command in advance to actually do that.
  27787. 22:04:16All right, any questions, then, on these examples here?
  27788. 22:04:22No?
  27789. 22:04:22All right.
  27790. 22:04:23So what other pieces might actually remain for us let me flip over here.
  27791. 22:04:29It turns out that a key component of most any web
  27792. 22:04:32application nowadays that we haven't touched on yet,
  27793. 22:04:34but it'll be one of our final flourishes today, is the notion of a session.
  27794. 22:04:38And a session is actually a feature that derives
  27795. 22:04:41from all of the basics we talked about today and last week,
  27796. 22:04:43and a session is the technical term for what you and I know as a shopping cart.
  27797. 22:04:47When you go to amazon.com and you start adding things to your shopping cart,
  27798. 22:04:50they follow you from page to page to page.
  27799. 22:04:53Heck if you close your browser, come back to the next day,
  27800. 22:04:56they're typically still your shopping cart, which is great for Amazon
  27801. 22:04:59because they want your business.
  27802. 22:05:01They don't want you to have to start from scratch the next day.
  27803. 22:05:03Similarly, when you log into any website these days,
  27804. 22:05:07even if it's not an e-commerce thing but it has usernames and passwords,
  27805. 22:05:11you and I are not in the habit of logging
  27806. 22:05:13into every darn page we visit on a website.
  27807. 22:05:15Typically, you log in once, and then for the next hour, day, week, year,
  27808. 22:05:19you stay logged into that website.
  27809. 22:05:21So somehow, the website is remembering that you have logged in.
  27810. 22:05:25And that is being implemented by way of this thing called
  27811. 22:05:27a session, and perhaps a more familiar term
  27812. 22:05:29that you might know as, and worry about, called cookies.
  27813. 22:05:32Let's go ahead and take one more five minute break here.
  27814. 22:05:35And when we come back, we'll look at cookies, sessions,
  27815. 22:05:37and these final features.
  27816. 22:05:39All right.
  27817. 22:05:40So the promise now is that we're going to implement
  27818. 22:05:43this notion of a session, which is going to allow us to log users in and keep
  27819. 22:05:47them logged in and even implement things like a shopping cart.
  27820. 22:05:50And the overarching goal here is to build an application that
  27821. 22:05:54is, quote unquote, "stateful."
  27822. 22:05:56Again, state refers to information, and something that's stateful
  27823. 22:05:59remembers information.
  27824. 22:06:01And in this context, the curiosity is that HTTP is technically
  27825. 22:06:05a stateless protocol.
  27826. 22:06:07Once you visit a URL, http://something, hit Enter,
  27827. 22:06:11web page is downloaded to your browser, like that's it.
  27828. 22:06:14You can unplug from the internet, you can turn off your Wi-Fi,
  27829. 22:06:17but you still have the web page locally.
  27830. 22:06:19And yet we somehow want to make sure that the next time you
  27831. 22:06:23click on a link on that website, it doesn't forget who you are.
  27832. 22:06:25Or the next thing you add to your shopping cart,
  27833. 22:06:27it doesn't forget what was already there.
  27834. 22:06:29So we somehow want to make HTTP stateful,
  27835. 22:06:32and we can actually do this using the building blocks we've seen thus far.
  27836. 22:06:36So concretely, here's a form you might see occasionally, but pretty rarely,
  27837. 22:06:40when you log into Gmail.
  27838. 22:06:42And I say rarely because most of you don't log into Gmail frequently,
  27839. 22:06:46you just stay logged in, pretty much endlessly, in your browser.
  27840. 22:06:49And that's because Google has made the conscious choice
  27841. 22:06:52to give you a very long session time, maybe a day, a week,
  27842. 22:06:55a month, a year, because they don't really
  27843. 22:06:57want to add friction to using their tool and making you log in every darn day.
  27844. 22:07:01By contrast, there's other applications on campus,
  27845. 22:07:04including some of the CS50 zone, that makes you log in every time.
  27846. 22:07:07Because we want to make sure that it's indeed you
  27847. 22:07:09accessing the site, and not a roommate or friend or someone maliciously.
  27848. 22:07:13So once you do fill out this form, how does Google subsequently
  27849. 22:07:16know that you are you, and when you reload the page even
  27850. 22:07:20or open a second tab for your same Gmail account,
  27851. 22:07:22how do they know that you're still David or Carter or Emma or someone else?
  27852. 22:07:26Well, let's look underneath the hood of what's going on.
  27853. 22:07:29When you log into Gmail, essentially, you initially
  27854. 22:07:32see a form like this using a GET request.
  27855. 22:07:35And the website responds like we saw last week
  27856. 22:07:37with some kind of HTTP response.
  27857. 22:07:39Hopefully 200 OK with the form.
  27858. 22:07:41Meanwhile, the website might also respond with an HTTP header
  27859. 22:07:46that, last week we didn't care about, this week, we now do.
  27860. 22:07:49Whenever you visit a website, it is very commonly the case
  27861. 22:07:53that the website is putting a cookie on your computer.
  27862. 22:07:56And you may generally know that cookies can be bad
  27863. 22:07:58and they track you in some way, and that's both a blessing and a curse.
  27864. 22:08:03Without cookies, you could not implement things like shopping carts and log-ins
  27865. 22:08:08as we know them today.
  27866. 22:08:10Unfortunately, they can also be used for ill purposes
  27867. 22:08:12like tracking you on every website and serving you ads more effectively and so
  27868. 22:08:16forth.
  27869. 22:08:16So with good comes some bad.
  27870. 22:08:18But the basic primitive for us, the computer scientist,
  27871. 22:08:21boils down to just HTTP headers.
  27872. 22:08:24A cookie is typically a big number, a big, seemingly random value,
  27873. 22:08:29that a server tells your browser to store in memory, or even
  27874. 22:08:33longer term, store on disk.
  27875. 22:08:35So you can think of it like a file that a server is planting on your computer.
  27876. 22:08:38And the promise that HTTP makes is that if a server sets
  27877. 22:08:43a cookie on your computer, you will represent
  27878. 22:08:45that same cookie or that same value on every subsequent request.
  27879. 22:08:49So when you visit the website like Gmail,
  27880. 22:08:51they plop a cookie on your computer like this with some session
  27881. 22:08:55equals value, some long random value.
  27882. 22:08:57One, two, three, A, B, C, something like that.
  27883. 22:09:00And when you then visit another page on gmail.com or any other website,
  27884. 22:09:04you send the opposite header, not set cookie, but just cookie colon,
  27885. 22:09:09and you send the exact same value.
  27886. 22:09:11It's similar to going to a club or an amusement park
  27887. 22:09:13where you pay once, you go through the gates once,
  27888. 22:09:15you get checked by security once, and then
  27889. 22:09:17they very often take like a little stamp and say, OK, now you can come and go.
  27890. 22:09:22And then for you, efficiency-wise, if you come back later in the day
  27891. 22:09:25or later in the evening, you can just present your hand.
  27892. 22:09:27You've been stamped, presumably.
  27893. 22:09:29They've already-- you've already paid, you've
  27894. 22:09:32already been searched or whatnot.
  27895. 22:09:33And so it's this sort of fast track ticket
  27896. 22:09:35back into the club, back into the park.
  27897. 22:09:37That's essentially what a cookie is doing for you, whereby
  27898. 22:09:41it's a way of reminding the website we've already done this,
  27899. 22:09:43you already asked me for my username and password.
  27900. 22:09:46This is my path to now come and go.
  27901. 22:09:48Now, unlike this hand stamp, which can be easily copied or transferred
  27902. 22:09:52or duplicated or kept on over multiple days,
  27903. 22:09:55these cookies are really big, seemingly random values, letters and numbers.
  27904. 22:09:59So statistically, there's no way someone else
  27905. 22:10:02is just going to guess your cookie value and pretend to be you It's just
  27906. 22:10:05very low probability, statistically.
  27907. 22:10:08But this is all it boils down to is this agreement between browser and server
  27908. 22:10:12to send these values back and forth in this way.
  27909. 22:10:16So when we actually translate this, now, to code,
  27910. 22:10:19let's do something like a simple login app.
  27911. 22:10:21Let me go into a folder I made in advance today called login.
  27912. 22:10:24And let me code up app.py and let's take a look in here.
  27913. 22:10:28So what's going on?
  27914. 22:10:30A couple of new things up top.
  27915. 22:10:31If I want to have the ability to stamp my users hands, virtually,
  27916. 22:10:36and implement sessions, I'm going to have to import from Flask support
  27917. 22:10:40for sessions.
  27918. 22:10:41So this is another feature you get for free by using a framework
  27919. 22:10:44and not having to implement all this yourself.
  27920. 22:10:46And from the Flask session library, I'm going
  27921. 22:10:48to import Session, capital S. Why?
  27922. 22:10:51I'm going to configure the session as follows.
  27923. 22:10:53Long story short, there's different ways to implement sessions.
  27924. 22:10:56The server can store these cookies in a database, in a file,
  27925. 22:11:00in memory, in RAM, in other places too.
  27926. 22:11:03We are telling it to store these cookies on the server's hard drive.
  27927. 22:11:07So in fact, whenever you use sessions as you will for problem set nine,
  27928. 22:11:11you'll actually see a folder suddenly appear called Flask_session,
  27929. 22:11:15inside of which are the cookies, essentially,
  27930. 22:11:17for any users or friends or yourself who've been
  27931. 22:11:20visiting your particular application.
  27932. 22:11:22So I'm setting it to use the file system,
  27933. 22:11:24and I don't want them to be permanent because I want,
  27934. 22:11:26when you close your browser, the session to go away.
  27935. 22:11:29They could be made to be permanent and last much longer.
  27936. 22:11:32Then I tell my app to support sessions.
  27937. 22:11:34And that's it for now.
  27938. 22:11:35Let's see what this application actually does before we dissect the code.
  27939. 22:11:39Let me go over to my terminal window, run Flask run, and then let me go ahead
  27940. 22:11:44and reload my preview URL.
  27941. 22:11:49Give it a second to kick back in.
  27942. 22:11:51Let me go ahead and open my URL.
  27943. 22:11:53Come on.
  27944. 22:11:55Oops, let me go ahead.
  27945. 22:11:58Too long of a break.
  27946. 22:11:59There we go.
  27947. 22:11:59So this website simply has a login form.
  27948. 22:12:02There's no password, though I could certainly
  27949. 22:12:04add that and check for that too.
  27950. 22:12:05It just asks for your name.
  27951. 22:12:07So I'm going to log in as myself, David, and click Login.
  27952. 22:12:10And now notice I'm currently at the /login route.
  27953. 22:12:12But notice this.
  27954. 22:12:13If I try to go to the default route, just,
  27955. 22:12:16slash, which is where most websites live by default,
  27956. 22:12:18notice that I magically get redirected to log in.
  27957. 22:12:21So somehow, my code knows, hey, if you're not logged in, you're going
  27958. 22:12:24to /login instead.
  27959. 22:12:26Let me type in my name, David, and click Login.
  27960. 22:12:29And now notice I am back at slash.
  27961. 22:12:32Chrome is sort of annoyingly hiding it, but this is the same thing as just
  27962. 22:12:35a single slash.
  27963. 22:12:36And now notice it says you are logged in as David.
  27964. 22:12:39Log out.
  27965. 22:12:39What's cool is notice if I reload the page, it still knows that.
  27966. 22:12:43If I create a second tab and go to the same URL, it still knows that.
  27967. 22:12:46I could even--
  27968. 22:12:48I could keep doing this in multiple tabs,
  27969. 22:12:50it's still going to remember me on both of them as being logged in as David.
  27970. 22:12:53So how does that work?
  27971. 22:12:55Especially when I click Log Out, then I get forgotten altogether.
  27972. 22:13:00All right, so let's see how this works.
  27973. 22:13:01And it's some basic building blocks.
  27974. 22:13:03Under my /route, notice I have this.
  27975. 22:13:07If there is no name in the session, redirect the user to /login.
  27976. 22:13:12So these two lines together are what implement
  27977. 22:13:14that automatic redirection using HTTP 301 or 302 automatically.
  27978. 22:13:19It's handled for me with these two lines.
  27979. 22:13:21Otherwise, show index.html.
  27980. 22:13:23All right, let's go down that rabbit hole.
  27981. 22:13:25What's in index.html?
  27982. 22:13:26Well, if I look in my--
  27983. 22:13:29let me look in my templates folder for my login demo and look
  27984. 22:13:36at templates/index.html.
  27985. 22:13:40All right, so what's going on here?
  27986. 22:13:41I extend layout.html, I have a block body,
  27987. 22:13:46and then I've got some other syntax.
  27988. 22:13:47So we haven't seen this yet, but it's more Jinja stuff, which
  27989. 22:13:50again, is almost identical to Python.
  27990. 22:13:52If there's a name in the session variable,
  27991. 22:13:55then literally say you are logged in as curly braces session bracket name.
  27992. 22:14:00And then notice this, I've got a simple HTML link to log out via /logout.
  27993. 22:14:04Else, if there is no name in the session,
  27994. 22:14:07then it apparently says you are not logged in and it leads me to an HTML
  27995. 22:14:11link to /login and then end diff.
  27996. 22:14:13So again, Jinja does not rely on indentation.
  27997. 22:14:16Recall the HTML and CSS don't really care about indentation,
  27998. 22:14:19only the human does.
  27999. 22:14:20But in code with Jinja, you need these end tags,
  28000. 22:14:24end block, end for, end if, to make super obvious
  28001. 22:14:26that you're done with that thought.
  28002. 22:14:29So session is just this magic variable that we now
  28003. 22:14:32have access to because we've included these two lines of code
  28004. 22:14:36and these that handle that whole process of stamping every user's hand
  28005. 22:14:41with a different, unique identifier.
  28006. 22:14:43If I made my code space public and I let all of you
  28007. 22:14:46visit the exact same URL, all of you would be logged out by default.
  28008. 22:14:50You could all type your own names individually,
  28009. 22:14:52all log in at the same URL using different sessions.
  28010. 22:14:56And in fact, I would then see, if I go into my terminal window
  28011. 22:14:59here and my login directory, notice the Flask session directory I mentioned.
  28012. 22:15:03And if I CD into that and type ls, notice that I had two tabs open,
  28013. 22:15:07or actually, I think I started the server twice.
  28014. 22:15:10I have two files in there.
  28015. 22:15:11I would ultimately have one file for every one of you.
  28016. 22:15:14And that's what's beautiful about sessions
  28017. 22:15:16is it creates the illusion of per user storage.
  28018. 22:15:21Inside of my session is my name, inside of your session, so to speak,
  28019. 22:15:25is your name.
  28020. 22:15:26And the same is going to apply to shopping carts, ultimately, as well.
  28021. 22:15:30Let's see how login works here.
  28022. 22:15:32My login route supports both GET and POST, so I could play around if I want.
  28023. 22:15:36And notice this, this login route is kind of interesting as follows.
  28024. 22:15:41If the user got to this route via POST, my inference
  28025. 22:15:45is that they must have submitted a form.
  28026. 22:15:47Why?
  28027. 22:15:47Because that's how I'm going to design the HTML form in a second.
  28028. 22:15:50And if they did submit the form via POST,
  28029. 22:15:53I'm going to store, in the session, at the name
  28030. 22:15:56key, whatever the human's name is.
  28031. 22:15:59And then, I'm going to redirect them back to slash.
  28032. 22:16:01Otherwise, I'm going to show them the login form.
  28033. 22:16:04So this is what's cool.
  28034. 22:16:05If I go to this login form, which lives at,
  28035. 22:16:08literally, slash login, by default, when you visit a URL like that,
  28036. 22:16:12you're visiting via GET.
  28037. 22:16:14And so that's why I see the form.
  28038. 22:16:16However, notice this.
  28039. 22:16:18The form, very cleverly, submits to itself,
  28040. 22:16:22like the one route/login submits to its same self, /login,
  28041. 22:16:26but it uses POST when you submit the form.
  28042. 22:16:29And this is a nice way of having one route but for two different types
  28043. 22:16:33of operations or views.
  28044. 22:16:36When I'm just there visiting /login via URL, it shows me the form.
  28045. 22:16:40But if I submit the form, then this logic, these three lines, kick in,
  28046. 22:16:45and this just avoids my having to have both an index route and a greet route,
  28047. 22:16:49for instance.
  28048. 22:16:50I can just have one route that handles both GET and POST.
  28049. 22:16:55How about logout?
  28050. 22:16:56What does this do?
  28051. 22:16:57Well, it's as simple as this.
  28052. 22:16:58Change whatever name is in the session to be
  28053. 22:17:01none, which is Python's version of null, essentially, and then redirect the user
  28054. 22:17:05back to slash.
  28055. 22:17:06Because now, in index.html, I will not notice a name there anymore.
  28056. 22:17:12This will be false.
  28057. 22:17:13And so I'll tell the user instead, you are not logged in.
  28058. 22:17:16So like it's--
  28059. 22:17:18I want to say as simple as this is, though I realize
  28060. 22:17:20this is a bunch of steps involved.
  28061. 22:17:22This is the essence of every website on the internet that
  28062. 22:17:25has usernames and passwords.
  28063. 22:17:26And we skip the password name step for that, more on that in problem set nine,
  28064. 22:17:30but this is how every website out there remembers that you're logged in.
  28065. 22:17:34And how this works, ultimately, is that as soon
  28066. 22:17:37as you use in Python lines like this and lines like this,
  28067. 22:17:41Flask takes care of stamping the virtual hand of all of your users
  28068. 22:17:45and whenever Flask sees the same cookie coming back from a user,
  28069. 22:17:50it grabs the appropriate file from that folder,
  28070. 22:17:53loads it into the session global variable
  28071. 22:17:56so that your code is now unique to that user and their name.
  28072. 22:18:01Let's do one other example with sessions here
  28073. 22:18:03that'll show how we might use these, now, for shopping carts.
  28074. 22:18:06Let me go into the store example here.
  28075. 22:18:09Let me go ahead and run this thing first.
  28076. 22:18:10If I run store in my same tab and go back over here,
  28077. 22:18:16we'll see a very ugly e-commerce site that
  28078. 22:18:19just sells seven different books here.
  28079. 22:18:21But each of these books has a button via which I can add it to my cart.
  28080. 22:18:26All right, well where are these books coming from?
  28081. 22:18:28Well, let's poke around.
  28082. 22:18:29Let me go into my terminal window again.
  28083. 22:18:32Let me go into this example, which is called store,
  28084. 22:18:35and let me open up about index dot ht-- whoops.
  28085. 22:18:40Let's open up index, how about, books.html
  28086. 22:18:48is the default one, not index this time.
  28087. 22:18:50So if I look here, notice that that route that we just saw
  28088. 22:18:55uses a for loop in Jinja to iterate over a whole bunch of books, apparently,
  28089. 22:19:00and it outputs, in an H2 tag, the title of the book,
  28090. 22:19:03and then another one of these forms.
  28091. 22:19:05So that's interesting.
  28092. 22:19:07Let's go back one step.
  28093. 22:19:08Let's go ahead and open up app.py, because that must be-- excuse me,
  28094. 22:19:11what's ticking all of this off.
  28095. 22:19:13Notice that this file is importing session support.
  28096. 22:19:16It's configuring sessions down here, but it's also
  28097. 22:19:19connecting to a store.db file.
  28098. 22:19:22So it's adding some SQLite.
  28099. 22:19:23And notice this, in my /route, I'm selecting star from books,
  28100. 22:19:29which is going to give me a list of dictionaries,
  28101. 22:19:31each of which represents a row of books.
  28102. 22:19:33And I'm going to pass that list of books into my books.html template, which
  28103. 22:19:37is why this for loop works the way it does.
  28104. 22:19:41Let's look at this actual database.
  28105. 22:19:43Let me increase my terminal window and do SQLite of store.db.schema
  28106. 22:19:48will show me everything.
  28107. 22:19:49There's not much there.
  28108. 22:19:50It's a book-- it's a table called books with two columns, ID and title.
  28109. 22:19:55Let's do select star from books semicolon.
  28110. 22:19:58There are the seven books, each of which has a unique ID.
  28111. 22:20:01And you might see where this is going.
  28112. 22:20:03If I go to the UI and I look at each of these buttons
  28113. 22:20:06for add to cart, just like Amazon might have, notice that each of these buttons
  28114. 22:20:11is just a form.
  28115. 22:20:13And what's magical here, just like deregister,
  28116. 22:20:15even though I didn't highlight it at the time,
  28117. 22:20:17there's another type of input that allows
  28118. 22:20:19you to specify a value without the human being able easily to change it.
  28119. 22:20:23Instead of type equals text or type equals submit,
  28120. 22:20:26type equals hidden will put the value in the form but not reveal it to the user.
  28121. 22:20:30So that's how I'm saying that the idea of this book is one,
  28122. 22:20:34the idea of this book is two, the idea of this book is three, and so forth.
  28123. 22:20:38And each of these forms, then, will submit, apparently,
  28124. 22:20:40to /cart using POST and that would seem to be what adds things to cart.
  28125. 22:20:45So let's try this.
  28126. 22:20:46Let me click on one or two of these.
  28127. 22:20:48Let's add the first book, add to cart.
  28128. 22:20:51Here's my cart.
  28129. 22:20:52Notice my route change to /cart.
  28130. 22:20:54All right, let's go back and let's add the book number two.
  28131. 22:20:58There we have that one.
  28132. 22:20:59And let's skip ahead to the seventh book, Deathly Hallows,
  28133. 22:21:02and now we have all three books here.
  28134. 22:21:05So what does the cart route do at /cart?
  28135. 22:21:09Well, let's look.
  28136. 22:21:10If I go back to my terminal window, look at app.py and look at /cart, OK,
  28137. 22:21:15there's a lot going on here, but let's see.
  28138. 22:21:17So the /cart route supports both GET or POST,
  28139. 22:21:21which is a nice way to consolidate things into one URL.
  28140. 22:21:24All right, this is interesting.
  28141. 22:21:26If there is not a, quote unquote, "cart" key in session,
  28142. 22:21:30we haven't technically seen this syntax.
  28143. 22:21:32But long story short, these lines here do ensure that the cart exists.
  28144. 22:21:36What do I mean by that?
  28145. 22:21:37It makes sure that there's a cart key in the session, global variable,
  28146. 22:21:43and it's by default going to be an empty list.
  28147. 22:21:45Why?
  28148. 22:21:46That just means you have an empty shopping cart.
  28149. 22:21:48But if the user visits this route via POST and the user did provide an ID,
  28150. 22:21:55they didn't muck with the form in any way and try to hack into the website,
  28151. 22:21:59they gave me a valid ID, then I'm going to use this syntax.
  28152. 22:22:02If session bracket cart is a list--
  28153. 22:22:05recall from a couple of weeks ago that dot append just
  28154. 22:22:07adds something to the list.
  28155. 22:22:08So I'm going to add the ID to the list and return the user to cart.
  28156. 22:22:13Otherwise, if the user is at /cart via GET, implicitly, we just do this.
  28157. 22:22:18Select star from books where ID is in.
  28158. 22:22:22And this might be syntax you recall from Pset six.
  28159. 22:22:24It lets you look for multiple IDs all at once,
  28160. 22:22:27because if I have a list of session--
  28161. 22:22:29list of IDs in my cart, I can get all of those books at once.
  28162. 22:22:34So long story short, what has happened here?
  28163. 22:22:36I am storing, in the cart, the books that I myself have added to my cart.
  28164. 22:22:42My browser is sending the same hand stamp again and again,
  28165. 22:22:45which is how this website knows that it's me adding these books to my cart
  28166. 22:22:48and not you or not Carter or not Emma.
  28167. 22:22:50Indeed, if all of us visited the same long URL and I made it public
  28168. 22:22:54and allowed that, then we would all have our own illusions
  28169. 22:22:56of our own separate carts.
  28170. 22:22:58And each of those carts, in practice, would just
  28171. 22:23:00be stored in this Flask session directory on the server
  28172. 22:23:04so that the server can keep track of each
  28173. 22:23:06of us using, again, these cookie values that are being
  28174. 22:23:09sent back and forth via these headers.
  28175. 22:23:13All right.
  28176. 22:23:13I know that's a lot, but again, it's just
  28177. 22:23:15the new Python way of just leveraging those HTTP
  28178. 22:23:19headers from last week in a clever way.
  28179. 22:23:22Any questions before we look at one final set of examples?
  28180. 22:23:26Yeah.
  28181. 22:23:27AUDIENCE: [INAUDIBLE] understand how a log in has to do with [INAUDIBLE]??
  28182. 22:23:31How does it use [INAUDIBLE],, how do you change [INAUDIBLE]??
  28183. 22:23:34Because in order to use a GET request dot [INAUDIBLE] equals,
  28184. 22:23:39there has to be an exchange in [INAUDIBLE]..
  28185. 22:23:43DAVID: So I think you're asking about using the GET
  28186. 22:23:46and POST in the same function.
  28187. 22:23:48So this is just a nice aesthetic, if you will.
  28188. 22:23:52If I had to have separate routes for GET and POST, I mean,
  28189. 22:23:56it literally might mean I need twice as many routes in my file.
  28190. 22:23:59And it just starts to get a little annoying.
  28191. 22:24:01And these days, too, in terms of user experience,
  28192. 22:24:04this is maybe only appeals to the geek in us, but having clean URLs
  28193. 22:24:08is actually a thing.
  28194. 22:24:09You don't want to have lots of words in the URL,
  28195. 22:24:11it's nice if the URLs are nice and succinct and canonical, if you will.
  28196. 22:24:14So it's nice if I can centralize all of my shopping cart functionality in /cart
  28197. 22:24:21only, and not in multiple routes, one for GET, one for POST.
  28198. 22:24:25It's a little nitpicky of me, but this is commonly done here.
  28199. 22:24:30So what this code here means is that this route, this function,
  28200. 22:24:34henceforth will support both GET requests and POST requests.
  28201. 22:24:38But then I need to distinguish between whether it's GET or POST coming in.
  28202. 22:24:42Because if it's a GET request, I want to show the cart.
  28203. 22:24:44If it's a POST request, I want to update the cart.
  28204. 22:24:47And the simplest way to do that is just to check this value here.
  28205. 22:24:51In the request variable that we imported from Flask up above,
  28206. 22:24:54you can check what is the current type of request.
  28207. 22:24:57Is it a GET, is it a POST, or is it something else altogether?
  28208. 22:25:00There are other verbs.
  28209. 22:25:02If it's a POST, that must mean, because I created the web form that uses POST,
  28210. 22:25:07that the user clicked the Add to Cart button.
  28211. 22:25:10Otherwise, if it's not POST, it's implicitly going to be logically GET.
  28212. 22:25:16Then, I just want to show the user the contents of the cart
  28213. 22:25:20and I use these lines instead.
  28214. 22:25:21So it's just one way of avoiding having two routes for two different HTTP
  28215. 22:25:25verbs.
  28216. 22:25:26You can combine them so long as you have a check like this.
  28217. 22:25:29If I really wanted to be pedantic, I could do this elif request.method=get.
  28218. 22:25:38This would be more symmetric, but it's not really necessary,
  28219. 22:25:40because I know there's only two possibilities.
  28220. 22:25:43Hope that helps.
  28221. 22:25:46All right, let's do one final set of examples here
  28222. 22:25:48that's going to tie the last of these features
  28223. 22:25:51together to something that you probably see
  28224. 22:25:53quite often in real-world applications.
  28225. 22:25:56And that, for better or for worse, is now
  28226. 22:25:58going to involve tying back in some JavaScript from last week.
  28227. 22:26:01The goal at hand of these examples is not
  28228. 22:26:03to necessarily master how you yourself would write the Python code, the SQL
  28229. 22:26:06code, the JavaScript code, but just to give you a mental model for how
  28230. 22:26:09these different languages work.
  28231. 22:26:11So that for final projects, especially if you
  28232. 22:26:13do want to add JavaScript functionality, much more interactive user interface,
  28233. 22:26:16you at least have the bare bones of a mental model for how
  28234. 22:26:20you can tie these languages together.
  28235. 22:26:22Even though our focus, generally, has been more on Python and SQL
  28236. 22:26:26than on JavaScript from last week.
  28237. 22:26:28Let me go ahead and open up an example called shows, version zero of this.
  28238. 22:26:33And let me do Flask run.
  28239. 22:26:35And let me go into my URL here and see what this application looks
  28240. 22:26:39like by default. This has just a simple query text box with a search box.
  28241. 22:26:44Let's take a look at the HTML that just got sent to my browser.
  28242. 22:26:47All right, there's not much going on here at all.
  28243. 22:26:49So there's a form whose action is /search.
  28244. 22:26:52It's going to submit via GET.
  28245. 22:26:54It's going to use a q parameter, just like Google it seems, and submit it.
  28246. 22:26:58So this actually looks like the Google form we did last week.
  28247. 22:27:01So let's see what goes on here.
  28248. 22:27:03Let me search for something like cat.
  28249. 22:27:06Enter.
  28250. 22:27:07OK, so it looks like--
  28251. 22:27:09all right, so this is actually a somewhat familiar file.
  28252. 22:27:12What I've gone ahead and done is I've grabbed all of the titles of TV shows
  28253. 22:27:16from a couple of weeks ago when we first introduced SQL,
  28254. 22:27:19and I loaded them into this demo so that you can search
  28255. 22:27:21by keyword for any word you want.
  28256. 22:27:23I just searched for cat.
  28257. 22:27:24If we were to do this again, we would see all the title of TV shows
  28258. 22:27:27that contain D-O-G, dog, as a substring somewhere and so forth.
  28259. 22:27:32So this is a traditional way of doing this.
  28260. 22:27:34Just like in Google, it uses /search?q=cat, q=dog, and so forth.
  28261. 22:27:40How does that work?
  28262. 22:27:41Well, let's just take a quick look at app.py here.
  28263. 22:27:45Let me go into my zero example here, show zero, and open up
  28264. 22:27:50app.py and see what's going on.
  28265. 22:27:53All right, very simple.
  28266. 22:27:54Here's the form, that's how we started today.
  28267. 22:27:57And here is the /search route.
  28268. 22:28:00Well, what's going on here?
  28269. 22:28:01This gets a little interesting.
  28270. 22:28:02So I first select a whole bunch of shows by doing this.
  28271. 22:28:06Select star from shows, where title like question mark.
  28272. 22:28:10And then I'm using some percent signs from SQL
  28273. 22:28:15on both the left and the right, and I'm plugging
  28274. 22:28:17in whatever the user's input was for q.
  28275. 22:28:20If I didn't use like and I used equal instead,
  28276. 22:28:22I could get rid of these curly brace, these percent signs,
  28277. 22:28:25but then it would have to be a show called cat or called dog as opposed
  28278. 22:28:29to it being like cat or like dog.
  28279. 22:28:32This whole line returns to me a list of dictionaries, each of which
  28280. 22:28:35represents a show in the database.
  28281. 22:28:38And then, I'm passing all of those shows to a template called search.html.
  28282. 22:28:41So let's just follow that breadcrumb, let's open up shows dot--
  28283. 22:28:45sorry, search.html.
  28284. 22:28:48All right, so this is where templating gets cool.
  28285. 22:28:50So I just passed back hundreds of results, potentially,
  28286. 22:28:53but the only thing I'm outputting is an unordered list
  28287. 22:28:56and using a Jinja for loop and li tag containing
  28288. 22:29:00the titles of each of those shows.
  28289. 22:29:02And just to prove that this is indeed a familiar data set
  28290. 22:29:04and I actually simplified it a bit, if I look at shows.db with SQLite,
  28291. 22:29:09I threw away all the other stuff like ratings and actors and everyone else
  28292. 22:29:14and I just have, for instance, select star from shows
  28293. 22:29:18limit 10, just so we can see 10 of them.
  28294. 22:29:21There's 10 of the shows from that database.
  28295. 22:29:23So that's all that's in the database itself.
  28296. 22:29:25So it would look like this is a pretty vanilla web application.
  28297. 22:29:29It uses GET, it submits it to the server,
  28298. 22:29:31the server spits out a response, and that response, then,
  28299. 22:29:33looks like this, which is a huge number of li tags, one for each cat
  28300. 22:29:38or one for each dog match.
  28301. 22:29:40But everything else comes from a layout.html.
  28302. 22:29:44All the stuff at the top and at the bottom.
  28303. 22:29:46All right, so these days, though, we're in the habit of seeing autocomplete.
  28304. 22:29:50And you start typing something and you don't have to hit Submit,
  28305. 22:29:53you don't have to click a button, you don't have to go to a new page.
  28306. 22:29:56Web applications, nowadays, are much more dynamic.
  28307. 22:29:58So let's take a look at this version one of this thing.
  28308. 22:30:01Let me go into shows one and close my previous tabs
  28309. 22:30:07and run Flask run in here.
  28310. 22:30:09And it's almost the same thing, but watch the behavior change a little bit.
  28311. 22:30:14I'm reloading the form, there's no button now.
  28312. 22:30:16So gone is the need for a submit button.
  28313. 22:30:18I want to implement autocomplete now.
  28314. 22:30:20So let's go ahead and type in C. OK, there's
  28315. 22:30:22every show that starts with C. A, there's
  28316. 22:30:25every show that has C-A in it, rather.
  28317. 22:30:27T, there's every show with C-A-T in it.
  28318. 22:30:31I can start it again and do dog, but notice how instantaneous it was.
  28319. 22:30:34And notice my URL never changed, there's no /search route,
  28320. 22:30:38and it's just immediate.
  28321. 22:30:40With every keystroke, it is searching again and again and again.
  28322. 22:30:43That's a nice UX, user experience, because it's immediate.
  28323. 22:30:46This is what users are used to these days.
  28324. 22:30:48But if I look at the source code here, notice that in the source code,
  28325. 22:30:53there's just an empty UL by default but there is some fancy JavaScript code.
  28326. 22:30:58So let's see what's going on here.
  28327. 22:31:00This JavaScript code is doing the following.
  28328. 22:31:03Let me zoom in a little bit more.
  28329. 22:31:06This JavaScript code is first selecting, with query selector,
  28330. 22:31:10which you used this past week, quote unquote "input, " all right,
  28331. 22:31:13so that's just getting the text box.
  28332. 22:31:15Then it's adding an event listener to that input for the input event.
  28333. 22:31:19We didn't talk about this last week, but literally,
  28334. 22:31:21when you provide any kind of input by typing,
  28335. 22:31:23by pasting, by any other user interface mechanism,
  28336. 22:31:27it triggers an event called input.
  28337. 22:31:29So similar to key press or key up.
  28338. 22:31:31I then have a function, no worries about this async function for now.
  28339. 22:31:35Then what do I do inside of this?
  28340. 22:31:37All right, so this is new, and this is the part
  28341. 22:31:39that let's just focus on the ideas and not the syntax.
  28342. 22:31:41JavaScript, nowadays, comes with a function
  28343. 22:31:43called fetch that allows you to GET or POST information to a server
  28344. 22:31:48without reloading the whole page.
  28345. 22:31:49You can sort of secretly do it inside of the page.
  28346. 22:31:52What do I want to fetch?
  28347. 22:31:53slash search question mark q equals whatever the value of that input is.
  28348. 22:31:59When I get back a response, I want to get the text of that response
  28349. 22:32:03and store it in a variable called shows.
  28350. 22:32:05And I'm deliberately bouncing around, ignoring special words
  28351. 22:32:08like await and await here, but for now, just focus on what came back.
  28352. 22:32:11A response came back from the server, I'm getting the text from it,
  28353. 22:32:14storing it in a variable called shows.
  28354. 22:32:16What am I then doing?
  28355. 22:32:17I'm using query selector to select my UL, which is empty by default,
  28356. 22:32:22and I'm changing its inner HTML to be equal to the shows that
  28357. 22:32:26came back from the server.
  28358. 22:32:28So let's poke around.
  28359. 22:32:29Here's where, again, developer tools are quite powerful.
  28360. 22:32:32Let me go ahead and reload this page to get rid of everything.
  28361. 22:32:36And let me now open up inspect.
  28362. 22:32:39Let me go to the Network tab and let's just sniff the traffic going
  28363. 22:32:43between my browser and server.
  28364. 22:32:44I'm going to search for C. Notice that immediately triggered an HTTP request
  28365. 22:32:49to /search?q=c.
  28366. 22:32:54So I didn't even finish my cat thought, but notice what came back.
  28367. 22:32:57A bunch of response headers, but let's actually click on the raw response.
  28368. 22:33:02This is literally the response from the server, just a whole bunch of li tags.
  28369. 22:33:07No UL, no HTML, no title, no body, nothing.
  28370. 22:33:10Just li tags.
  28371. 22:33:11And we can actually simulate this.
  28372. 22:33:12Let me manually go to that same URL, q=c, Enter.
  28373. 22:33:17We are just going to get back--
  28374. 22:33:19whoops, sorry.
  28375. 22:33:20slash search q equals c, we are just going to get back this stuff,
  28376. 22:33:25which if I view source, it's not even a complete web page.
  28377. 22:33:27The browser is trying to show it to me as a complete web page with bullets,
  28378. 22:33:31but it's really just partial HTML.
  28379. 22:33:33But that's perfect, because this is literally
  28380. 22:33:36what I essentially want my Python code to copy paste
  28381. 22:33:39into the otherwise empty UL tag.
  28382. 22:33:42And that's what this JavaScript code then, here, is doing.
  28383. 22:33:46Once it gets back that response from the server, it's using these lines of code
  28384. 22:33:51to plug all of those li's into the UL after the fact.
  28385. 22:33:56Again, changing the so-called dom.
  28386. 22:33:58But there's a slightly better way to do this because, honestly, this
  28387. 22:34:01is not the best design.
  28388. 22:34:02Because if you've got a hundred shows or more, you're sending all of these tags
  28389. 22:34:07unnecessarily.
  28390. 22:34:08Why do I need to send all of these stupid HTML tags?
  28391. 22:34:10Why don't I just create those when I'm ready to create them?
  28392. 22:34:13Well, here's the final flourish.
  28393. 22:34:15Whenever making a web application nowadays,
  28394. 22:34:18where client and server keep talking to one another, Google Maps does this,
  28395. 22:34:22Gmail does this, literally every cool application
  28396. 22:34:25nowadays you load the page once and then it
  28397. 22:34:27keeps on interacting with you without you
  28398. 22:34:29reloading or having to change the URL.
  28399. 22:34:31Let's actually use a format called JSON, JavaScript Object Notation, which
  28400. 22:34:36is to say there's just a better, more efficient, better
  28401. 22:34:39designed way to send that same data.
  28402. 22:34:42I'm going to go into shows two now and do Flask run.
  28403. 22:34:46And I'm going to go back to my page here.
  28404. 22:34:48The user interface is exactly the same, and it still works exactly the same.
  28405. 22:34:52Here's C, C-A, C-A-T, and so forth.
  28406. 22:34:56But let's see what's coming back now.
  28407. 22:34:59If I go to /search?q=cat, Enter, notice that I get this crazy-looking syntax.
  28408. 22:35:09But the fact that it's so compact is actually a good thing.
  28409. 22:35:12This is actually going to-- let me format it a little nicer, well,
  28410. 22:35:16or a little worse.
  28411. 22:35:17This is what's called JavaScript Object Notation.
  28412. 22:35:20In JavaScript, an angle-- a square bracket means here comes an array.
  28413. 22:35:26In JavaScript, a curly bracket says here comes an object, AKA, a dictionary.
  28414. 22:35:32And you might recall from--
  28415. 22:35:35did we do?
  28416. 22:35:36Yes, sort of recall that you can now have keys and values in JavaScript
  28417. 22:35:42notation using colons like this.
  28418. 22:35:45So long story short, cryptic as this is to you and me
  28419. 22:35:48and not very human friendly, it's very machine friendly.
  28420. 22:35:52Because for every title in that database,
  28421. 22:35:55I get back its ID and its title, its ID and its title, its ID and its title.
  28422. 22:36:01And this is a very generic format that an API, an application programming
  28423. 22:36:05interface, might return to you.
  28424. 22:36:07And this is how APIs, nowadays, work.
  28425. 22:36:09You get back very raw textual data in this format, JSON format,
  28426. 22:36:13and then you can write code that actually programmatically turns
  28427. 22:36:17that JSON data into any language you want, for instance, HTML.
  28428. 22:36:22So here's the third and final version of this program.
  28429. 22:36:25I, again, select my input.
  28430. 22:36:27I, again, listen for input.
  28431. 22:36:29I then, when I get input, call this function.
  28432. 22:36:32I fetch slash search q equals whatever that input was, C or C-A or C-A-T.
  28433. 22:36:38I then wait for the response, but instead of getting text,
  28434. 22:36:41I'm calling this other function that comes with JavaScript these days,
  28435. 22:36:44called JSON, that just parses that.
  28436. 22:36:47It turns it into a dictionary for me, or really a list of dictionaries for me,
  28437. 22:36:51and stores it in a variable called shows.
  28438. 22:36:53And this is where you start to see the convergence of HTML with JavaScript.
  28439. 22:36:57Let me initialize a variable called HTML to nothing, quote unquote,
  28440. 22:37:01using single quotes, but I could also use double quotes.
  28441. 22:37:03This is JavaScript syntax for a loop.
  28442. 22:37:06Let me iterate over every ID in the show's list
  28443. 22:37:10that I just got back in the server, that big chunk of JSON data.
  28444. 22:37:13Let me create a variable called Title that's equal to the shows--
  28445. 22:37:19the title of the show at that ID.
  28446. 22:37:21But for reasons we'll come back to, let me
  28447. 22:37:23replace a couple of scary characters.
  28448. 22:37:25Then let me dynamically add to this variable, an li tag, the actual title,
  28449. 22:37:31and a close li tag.
  28450. 22:37:33And then very lastly, after this for loop,
  28451. 22:37:35let me update the ULs in our HTML to be the HTML I just created on the fly.
  28452. 22:37:42So in short, don't worry too much about the syntax
  28453. 22:37:44because you won't need to use this unless you start playing
  28454. 22:37:47with more advanced features quite soon.
  28455. 22:37:49But what we're doing is, with JavaScript, we're
  28456. 22:37:51creating a bigger and bigger and bigger string of HTML
  28457. 22:37:54containing all of the open brackets, the li tags, the closed brackets,
  28458. 22:37:57but we're just grabbing the raw data from the server.
  28459. 22:38:00And so in fact in problem set nine, you're
  28460. 22:38:02going to use a real world third party API, application programming
  28461. 22:38:06interface, for which you sign up.
  28462. 22:38:08The data you're going to get back from that API is not
  28463. 22:38:10going to be show titles, but actually stock quotes and stocks
  28464. 22:38:14ticker symbols and the prices of last--
  28465. 22:38:17at which stocks were last bought or sold,
  28466. 22:38:19and you're going to get that data back in JSON format.
  28467. 22:38:21And you're going to write a bit of code that's then going to convert that
  28468. 22:38:24to the requisite HTML on the page.
  28469. 22:38:27So the final result here is literally the kind of autocomplete
  28470. 22:38:31that you and I see and take for granted every day,
  28471. 22:38:33and that's ultimately how it works.
  28472. 22:38:35HTML and CSS are used to present the data, your so-called view.
  28473. 22:38:39Python might be used to send or get the data on the backend server.
  28474. 22:38:43And then lastly, JavaScript is going to be used
  28475. 22:38:46to make things dynamic and interactive.
  28476. 22:38:48So I know that's a whole bunch of building blocks,
  28477. 22:38:50but the whole point of problem set nine to tie everything together,
  28478. 22:38:53set the stage for hopefully a very successful final project.
  28479. 22:38:55Why don't we go ahead and wrap up there, and we'll see
  28480. 22:38:58you one last time next week for emoji.

About this transcript

This page contains the full transcript of Harvard CS50 – Full Computer Science University Course by freeCodeCamp.org, generated from the public captions YouTube serves with the video. The transcript has 256,684 words across 28,480 segments, with the original timestamps preserved so you can click any line to jump to that moment in the embedded player.

What you can do with it

Use the transcript to take notes, quote the speaker, build a study guide, generate a summary with ChatGPT or Claude via the YouTube Summary tool, or export it as a timed subtitle file with YouTube to SRT. You can also re-open it in the transcriber to translate the transcript into 100+ languages.

Free YouTube transcript tool

YouTube2Text is a free YouTube transcript generator — no signup, no daily limit. Paste any YouTube link and get the full transcript instantly, with timestamps, click-to-jump, translation to 100+ languages, AI prompts for ChatGPT, Claude, and Gemini, and exports to TXT, SRT, VTT, or Markdown.