1 00:00:00,000 --> 00:00:11,330 2 00:00:11,330 --> 00:00:12,360 >> DAVID MALAN: All right. 3 00:00:12,360 --> 00:00:15,970 This is CS50, and this is the end of week nine. 4 00:00:15,970 --> 00:00:18,560 It's been a whirlwind over the past few days. 5 00:00:18,560 --> 00:00:21,580 And problem set seven, if you're knee deep into it, realize there's quite a 6 00:00:21,580 --> 00:00:23,340 bit new that's in there. 7 00:00:23,340 --> 00:00:26,660 But let's see if we can't piece everything together here briefly 8 00:00:26,660 --> 00:00:29,230 before then veering off in yet another direction and seeing 9 00:00:29,230 --> 00:00:30,510 where else we can go. 10 00:00:30,510 --> 00:00:32,630 >> So thus far, we've talked about HTML. 11 00:00:32,630 --> 00:00:33,740 We've talked about CSS. 12 00:00:33,740 --> 00:00:34,705 We've talked about PHP. 13 00:00:34,705 --> 00:00:36,520 You've started to experience SQL. 14 00:00:36,520 --> 00:00:38,360 Today, we'll talk a bit about JavaScript. 15 00:00:38,360 --> 00:00:41,230 But how do all of these disparate languages fit together? 16 00:00:41,230 --> 00:00:44,970 >> So we talked last week about the notion of having a server. 17 00:00:44,970 --> 00:00:48,470 So let's just draw this rectangle as a web server here. 18 00:00:48,470 --> 00:00:52,200 And a web server serves surely files. 19 00:00:52,200 --> 00:00:54,640 And some of those files can be HTML files. 20 00:00:54,640 --> 00:00:58,270 So one of the things that a web server can spit out might be a file that 21 00:00:58,270 --> 00:01:01,290 we'll just draw like this containing some HTML. 22 00:01:01,290 --> 00:01:04,786 So in layman's terms, what does HTML let you do? 23 00:01:04,786 --> 00:01:06,036 >> AUDIENCE: Page look nice. 24 00:01:06,036 --> 00:01:09,670 25 00:01:09,670 --> 00:01:12,310 >> DAVID MALAN: OK, make a page look nice, although I think I've proven 26 00:01:12,310 --> 00:01:13,370 that otherwise. 27 00:01:13,370 --> 00:01:18,250 So HTML does let you lay out pages structurally, and it allows you to 28 00:01:18,250 --> 00:01:22,410 sort of aesthetically mark up a page, mark up static content, so that you 29 00:01:22,410 --> 00:01:23,640 can then view it with a web browser. 30 00:01:23,640 --> 00:01:24,690 >> But that's the key. 31 00:01:24,690 --> 00:01:26,130 It's static content. 32 00:01:26,130 --> 00:01:28,590 You write it, you save it, and then you ship it. 33 00:01:28,590 --> 00:01:31,130 And the web server then serves it up to your visitors. 34 00:01:31,130 --> 00:01:35,700 >> But we stylize things using a different language altogether. 35 00:01:35,700 --> 00:01:40,150 We started to use a style attribute on certain tags. 36 00:01:40,150 --> 00:01:43,400 And the style attribute let us set things like font size and color. 37 00:01:43,400 --> 00:01:46,460 And you've probably started to discover, or you soon will for final 38 00:01:46,460 --> 00:01:50,160 projects potentially, yet other properties that you can use in CSS. 39 00:01:50,160 --> 00:01:54,710 And so in layman's terms, what really then does CSS do? 40 00:01:54,710 --> 00:01:57,810 Those are just examples thereof. 41 00:01:57,810 --> 00:02:00,730 What does it let you do that HTML doesn't seem to from what 42 00:02:00,730 --> 00:02:02,606 we've seen thus far? 43 00:02:02,606 --> 00:02:04,850 >> AUDIENCE: Define styles by yourself. 44 00:02:04,850 --> 00:02:06,700 >> DAVID MALAN: Define styles by yourself. 45 00:02:06,700 --> 00:02:10,280 So define things like classes as you may have encountered, or uniquely 46 00:02:10,280 --> 00:02:13,800 identify nodes in a document so that you can stylize them. 47 00:02:13,800 --> 00:02:16,890 But more specifically, I'd say that CSS really lets you take things the 48 00:02:16,890 --> 00:02:20,790 last mile and allows you to specify much more precisely the aesthetics, 49 00:02:20,790 --> 00:02:24,340 whereas HTML for the most part lets you structure your pages. 50 00:02:24,340 --> 00:02:27,310 >> And even though there are some defaults, like we saw the tag for 51 00:02:27,310 --> 00:02:30,690 a heading tag, which roughly speaking made things big and bold. 52 00:02:30,690 --> 00:02:34,250 That's a pretty generic definition of the tag-- big and bold. 53 00:02:34,250 --> 00:02:35,260 What font size is that? 54 00:02:35,260 --> 00:02:36,080 What color is that? 55 00:02:36,080 --> 00:02:36,890 How bold is that? 56 00:02:36,890 --> 00:02:39,830 And CSS lets you more finely tune things like that. 57 00:02:39,830 --> 00:02:42,150 As well as layout, as some of you have seen. 58 00:02:42,150 --> 00:02:45,180 >> And frankly, CSS is a bit of a messy language. 59 00:02:45,180 --> 00:02:48,370 It's very powerful in that you can make literally any website that you've 60 00:02:48,370 --> 00:02:51,880 seen on the web today with it, but it's kind of a pain in the neck. 61 00:02:51,880 --> 00:02:54,440 And some of you have banged your head against the walls already just to do 62 00:02:54,440 --> 00:02:58,560 something stupid like center a menu on problem set seven if you've gotten to 63 00:02:58,560 --> 00:02:59,470 that point already. 64 00:02:59,470 --> 00:03:01,530 >> But realize, those things get easier over time. 65 00:03:01,530 --> 00:03:02,820 You start to notice patterns. 66 00:03:02,820 --> 00:03:06,020 And again, Google will be your friend for the various ways in which you can 67 00:03:06,020 --> 00:03:07,220 solve these kinds of problems. 68 00:03:07,220 --> 00:03:11,520 >> And I dare say with CSS, and HTML more generally, you can solve problems in 69 00:03:11,520 --> 00:03:15,910 many more ways, all of which might very well be correct, than you could 70 00:03:15,910 --> 00:03:18,900 in something like C, even now PHP, or JavaScript. 71 00:03:18,900 --> 00:03:21,080 There are just many different ways to lay things out. 72 00:03:21,080 --> 00:03:22,570 >> But this started to get messy, we said. 73 00:03:22,570 --> 00:03:26,480 Just kind of commingling your HTML and your CSS with the style attribute was 74 00:03:26,480 --> 00:03:27,590 a little sloppy. 75 00:03:27,590 --> 00:03:31,460 And so we instead said, sort of abstractly speaking, that you should 76 00:03:31,460 --> 00:03:34,050 at least start to factor out your CSS probably. 77 00:03:34,050 --> 00:03:37,430 Not your style attributes, but at least use the style tag inside what 78 00:03:37,430 --> 00:03:38,840 part of the web page? 79 00:03:38,840 --> 00:03:39,560 >> AUDIENCE: Head. 80 00:03:39,560 --> 00:03:40,120 >> DAVID MALAN: In the head. 81 00:03:40,120 --> 00:03:43,270 Up until now, we only had the title up there, but you can also add a style 82 00:03:43,270 --> 00:03:47,230 tag, and you can put your CSS roughly speaking toward the top of the page. 83 00:03:47,230 --> 00:03:52,550 But then we took things one step further and we factored that out more 84 00:03:52,550 --> 00:03:54,130 into a separate file. 85 00:03:54,130 --> 00:03:57,240 >> And so these two files were somehow now linked. 86 00:03:57,240 --> 00:03:59,550 And indeed it was the tag that did that. 87 00:03:59,550 --> 00:04:02,920 And what was one of the overarching motivations for factoring out our CSS 88 00:04:02,920 --> 00:04:04,057 all the more? 89 00:04:04,057 --> 00:04:05,280 >> AUDIENCE: Reusability. 90 00:04:05,280 --> 00:04:05,785 >> DAVID MALAN: Reusability. 91 00:04:05,785 --> 00:04:06,150 Right? 92 00:04:06,150 --> 00:04:09,470 You may have seen in p-set seven already that a lot of the pages, the 93 00:04:09,470 --> 00:04:12,260 buying page, the selling page, the portfolio page, are probably 94 00:04:12,260 --> 00:04:13,550 structured somewhat similarly. 95 00:04:13,550 --> 00:04:17,579 There's a CS50 finance logo at the top unless you've decided to change it. 96 00:04:17,579 --> 00:04:19,839 There's a footer at the bottom of pages. 97 00:04:19,839 --> 00:04:24,315 And CSS allows you then to factor it out it into a separate file so that if 98 00:04:24,315 --> 00:04:27,780 you want to change something globally across your whole site, you can really 99 00:04:27,780 --> 00:04:29,390 just change it in one place. 100 00:04:29,390 --> 00:04:32,750 >> But there is a price you pay potentially by having factored out the 101 00:04:32,750 --> 00:04:38,380 CSS from my HTML file into a separate file referencing it with the 102 00:04:38,380 --> 00:04:40,650 tag, which we saw on Monday. 103 00:04:40,650 --> 00:04:43,850 What might the downside be of this? 104 00:04:43,850 --> 00:04:48,830 Thinking back a week ago to when we're talking about HTTP and TCP/IP and how 105 00:04:48,830 --> 00:04:52,070 the internet works. 106 00:04:52,070 --> 00:04:53,530 Something over here? 107 00:04:53,530 --> 00:04:54,730 >> AUDIENCE: It takes more time. 108 00:04:54,730 --> 00:04:55,470 >> DAVID MALAN: It takes more time. 109 00:04:55,470 --> 00:04:56,750 Why? 110 00:04:56,750 --> 00:04:59,450 >> AUDIENCE: [INAUDIBLE]. 111 00:04:59,450 --> 00:04:59,750 >> DAVID MALAN: Yeah. 112 00:04:59,750 --> 00:05:01,240 So it arguably takes a bit more time. 113 00:05:01,240 --> 00:05:04,290 Because one, the CSS is obviously not in the same file. 114 00:05:04,290 --> 00:05:06,920 So now you have to make not one, but two requests. 115 00:05:06,920 --> 00:05:11,230 And each of those requests as we saw in Chrome in the so-called Inspector, 116 00:05:11,230 --> 00:05:15,740 and we looked at the network tab, each of those files requires one HTTP 117 00:05:15,740 --> 00:05:18,360 request, which we saw takes some amount of time. 118 00:05:18,360 --> 00:05:19,290 Now, maybe it's not a lot. 119 00:05:19,290 --> 00:05:20,670 Maybe it's only 20 milliseconds. 120 00:05:20,670 --> 00:05:22,260 Maybe it's 200 milliseconds. 121 00:05:22,260 --> 00:05:25,530 >> But think about a page like Facebook, or CNN, or Google, which are much 122 00:05:25,530 --> 00:05:28,060 larger than the examples we've looked at thus far. 123 00:05:28,060 --> 00:05:32,070 Those pages might have dozens of files, each of which might require a 124 00:05:32,070 --> 00:05:33,550 download of a file. 125 00:05:33,550 --> 00:05:35,800 So things can potentially start to slow down. 126 00:05:35,800 --> 00:05:39,280 >> And especially these days when we all have mobile phones in our pockets and 127 00:05:39,280 --> 00:05:43,010 slower internet connections, having to wait a few more milliseconds, a few 128 00:05:43,010 --> 00:05:46,110 more milliseconds for additional files can actually be slow. 129 00:05:46,110 --> 00:05:50,430 Latency is the word that describes the kind of waiting that you have that you 130 00:05:50,430 --> 00:05:53,110 experience when waiting for some piece of information. 131 00:05:53,110 --> 00:05:54,430 >> But there is an upside. 132 00:05:54,430 --> 00:05:56,600 So it's not all sort of a-- 133 00:05:56,600 --> 00:05:58,170 it actually is a bit of a seesaw here. 134 00:05:58,170 --> 00:06:02,970 Downside now, but what browsers can do if they're smart in order to avoid 135 00:06:02,970 --> 00:06:08,870 having to request the same styles.css file again can be to do what? 136 00:06:08,870 --> 00:06:09,390 >> Cache it. 137 00:06:09,390 --> 00:06:10,370 So caching-- 138 00:06:10,370 --> 00:06:11,690 C-A-C-H-E-- 139 00:06:11,690 --> 00:06:15,810 generally means here just to save the file you requested the first time, and 140 00:06:15,810 --> 00:06:17,440 then check your cache for it. 141 00:06:17,440 --> 00:06:20,400 Check you're sort of storage container, and if you already have a 142 00:06:20,400 --> 00:06:24,520 copy of styles.css, even if some other page in the p-set, or any website, 143 00:06:24,520 --> 00:06:28,560 requests it again, just to give the user that same cached copy. 144 00:06:28,560 --> 00:06:30,140 Don't bother requesting it. 145 00:06:30,140 --> 00:06:32,560 >> Downside there, though, as some of you have tripped over in the p-set. 146 00:06:32,560 --> 00:06:35,870 If you make a change on the server and you go back to the browser and you 147 00:06:35,870 --> 00:06:39,250 reload, sometimes the browser does you a favor and doesn't bother 148 00:06:39,250 --> 00:06:43,660 re-downloading your styles.css file because, come on, what are the odds 149 00:06:43,660 --> 00:06:47,620 that these styles that Facebook uses are going to change hour to hour or 150 00:06:47,620 --> 00:06:48,140 day to day? 151 00:06:48,140 --> 00:06:48,800 It's pretty low. 152 00:06:48,800 --> 00:06:52,260 They might change over time, but not by the minute or by the hour. 153 00:06:52,260 --> 00:06:55,810 >> So a trick, just FYI when doing web development, is often hold down the 154 00:06:55,810 --> 00:06:59,500 shift key for instance and then click reload in your browser, and that will 155 00:06:59,500 --> 00:07:03,280 typically tell the browser reload everything, even if you already have 156 00:07:03,280 --> 00:07:04,180 it in the cache. 157 00:07:04,180 --> 00:07:06,630 So again, upsides and downsides, but all of them 158 00:07:06,630 --> 00:07:08,260 ultimately design decisions. 159 00:07:08,260 --> 00:07:11,520 >> So now, we didn't just end the story here. 160 00:07:11,520 --> 00:07:15,790 If I now go back and back and back and back, we started to introduce not just 161 00:07:15,790 --> 00:07:18,060 HTML, but PHP. 162 00:07:18,060 --> 00:07:20,786 So in layman's terms, what does PHP let us do? 163 00:07:20,786 --> 00:07:22,770 >> AUDIENCE: [INAUDIBLE]. 164 00:07:22,770 --> 00:07:24,258 >> DAVID MALAN: What's that? 165 00:07:24,258 --> 00:07:25,250 >> AUDIENCE: Introduce logic into the code. 166 00:07:25,250 --> 00:07:26,620 >> DAVID MALAN: Yeah, introduce logic into your code. 167 00:07:26,620 --> 00:07:29,570 So it's a true programming language with loops, and variables, and 168 00:07:29,570 --> 00:07:32,620 functions, and conditions, and all of the things we've been using way back 169 00:07:32,620 --> 00:07:33,780 when since scratch. 170 00:07:33,780 --> 00:07:36,780 And PHP, we've seen, can be used either at the command line-- it 171 00:07:36,780 --> 00:07:39,190 doesn't have to have anything to do with the web, even though that's 172 00:07:39,190 --> 00:07:43,150 really its origins and what it tends to be good at and conducive to-- 173 00:07:43,150 --> 00:07:47,130 but you can use PHP merely by nature of the fact that it has a print() 174 00:07:47,130 --> 00:07:49,660 function, and a printf() function, or an echo() function. 175 00:07:49,660 --> 00:07:52,440 There's bunches of ways you can print text with PHP. 176 00:07:52,440 --> 00:07:56,540 >> Therefore, you can use this programming language to output exactly 177 00:07:56,540 --> 00:07:58,460 what we were talking about before. 178 00:07:58,460 --> 00:08:01,360 You can dynamically generate your HTML. 179 00:08:01,360 --> 00:08:02,300 Maybe not all of it. 180 00:08:02,300 --> 00:08:06,460 Maybe you hard code things, like the header, and the footer, and the logo, 181 00:08:06,460 --> 00:08:07,950 and your style sheets, and all of that. 182 00:08:07,950 --> 00:08:11,190 But for something like p-set seven, where you're manipulating stocks and 183 00:08:11,190 --> 00:08:14,690 showing the user's portfolio, which is going to dynamically change, you could 184 00:08:14,690 --> 00:08:18,960 surely use PHP and the logic it gives you as a programming language to 185 00:08:18,960 --> 00:08:22,320 output dynamically subsets of the page. 186 00:08:22,320 --> 00:08:25,900 >> So when you talk about dynamic websites, or web programming, that's 187 00:08:25,900 --> 00:08:27,200 what you're really talking about. 188 00:08:27,200 --> 00:08:31,450 Using a language like PHP, or things called Python, or Ruby, or Java, or 189 00:08:31,450 --> 00:08:35,900 yet other languages, to query a database often, or another server, and 190 00:08:35,900 --> 00:08:38,580 then dynamically spit out HTML. 191 00:08:38,580 --> 00:08:42,470 >> Now the end result, as an aside, is that the HTML of most websites, 192 00:08:42,470 --> 00:08:45,970 including your p-set seven, is probably going to be a huge mess if 193 00:08:45,970 --> 00:08:48,060 you look at the source code in a browser. 194 00:08:48,060 --> 00:08:49,010 That's not a big deal. 195 00:08:49,010 --> 00:08:51,550 At this point, when we care about style, we care about the 196 00:08:51,550 --> 00:08:52,740 stuff that you write. 197 00:08:52,740 --> 00:08:56,240 We won't care about the stuff that what your code outputs. 198 00:08:56,240 --> 00:08:59,520 So don't worry about indentation here if it's PHP that's 199 00:08:59,520 --> 00:09:01,190 actually outputting stuff. 200 00:09:01,190 --> 00:09:04,430 After all, the browser won't care, and a human won't be looking 201 00:09:04,430 --> 00:09:05,400 at the source anyway. 202 00:09:05,400 --> 00:09:09,000 We the staff, for instance, would be looking at your PHP. 203 00:09:09,000 --> 00:09:13,440 >> So let me give a quick example now of why else this might be useful. 204 00:09:13,440 --> 00:09:18,620 So frankly, I can't remember the last time I used C to solve a problem in 205 00:09:18,620 --> 00:09:19,620 the real world. 206 00:09:19,620 --> 00:09:22,330 It was probably in graduate school when I needed to use a language that 207 00:09:22,330 --> 00:09:26,710 was fairly low level and gave me the opportunity to do something very high 208 00:09:26,710 --> 00:09:30,720 performing to really save as many CPU cycles as I could, in large part 209 00:09:30,720 --> 00:09:33,990 because I was using huge data sets, and every CPU cycle counted. 210 00:09:33,990 --> 00:09:37,750 And frankly, even in things like phones these days and other devices 211 00:09:37,750 --> 00:09:39,910 where you don't quite have as much memory and you don't quite have as 212 00:09:39,910 --> 00:09:44,160 much CPU, using faster languages is still appealing. 213 00:09:44,160 --> 00:09:47,290 >> But in the real world, when you just want to throw some program together to 214 00:09:47,290 --> 00:09:50,340 analyze some data, or you've collected a whole bunch of registrations for 215 00:09:50,340 --> 00:09:53,330 some student group and you want to very quickly automate sending emails 216 00:09:53,330 --> 00:09:56,240 one by one to every one of those registrants, you're going to reach for 217 00:09:56,240 --> 00:09:59,240 a higher level language than C so to speak. 218 00:09:59,240 --> 00:10:04,060 Something like PHP or Python, or Ruby, or a half a dozen others that exist 219 00:10:04,060 --> 00:10:04,550 these days. 220 00:10:04,550 --> 00:10:07,200 But those three are probably the most trendy right now. 221 00:10:07,200 --> 00:10:10,840 >> And what this means is that you can open up a text editor like gedit or 222 00:10:10,840 --> 00:10:14,030 most anything else and then just start writing code without having to worry 223 00:10:14,030 --> 00:10:17,800 about compiling, without having to really worry about memory management, 224 00:10:17,800 --> 00:10:20,820 keeping in mind though that a little sloppiness will eventually come back 225 00:10:20,820 --> 00:10:24,790 to bite you if the data set gets larger or the problem gets big. 226 00:10:24,790 --> 00:10:27,230 But what this means for us is the following. 227 00:10:27,230 --> 00:10:29,860 >> Let me go ahead and run speller from problem set six. 228 00:10:29,860 --> 00:10:33,480 So this is my trie-based implementation that I used on the big 229 00:10:33,480 --> 00:10:35,500 board where I performed not so well. 230 00:10:35,500 --> 00:10:38,720 We'll come back in a week's time and revisit those who did end up atop the 231 00:10:38,720 --> 00:10:40,430 big board at our last lecture. 232 00:10:40,430 --> 00:10:44,520 But for now, let me go ahead and just run my solution in text, and we'll do 233 00:10:44,520 --> 00:10:48,460 the King James Bible, and here we go. 234 00:10:48,460 --> 00:10:51,080 >> So those are all of the supposedly misspelled words out of 235 00:10:51,080 --> 00:10:52,240 the King James Bible. 236 00:10:52,240 --> 00:10:55,560 And my implementation took half a second in total. 237 00:10:55,560 --> 00:10:58,270 So not too bad on this particular computer. 238 00:10:58,270 --> 00:11:01,540 But think of how much code I had to write. 239 00:11:01,540 --> 00:11:02,880 Think how much code you had to write. 240 00:11:02,880 --> 00:11:06,170 Think how many hours you spent in the D-hall or your dorm or wherever 241 00:11:06,170 --> 00:11:07,890 actually coding up that solution. 242 00:11:07,890 --> 00:11:11,850 >> Well, if I actually have a higher level language like PHP, take note of 243 00:11:11,850 --> 00:11:13,350 what I can do here. 244 00:11:13,350 --> 00:11:16,410 First, suppose that this is instead your distribution code. 245 00:11:16,410 --> 00:11:17,790 This is a file called speller. 246 00:11:17,790 --> 00:11:20,220 It's available as part of today's distribution code. 247 00:11:20,220 --> 00:11:22,670 And I'm going to wave my hand at most of the details, but this is actually 248 00:11:22,670 --> 00:11:25,500 an interesting example of how you might port a language 249 00:11:25,500 --> 00:11:28,870 like C over to PHP. 250 00:11:28,870 --> 00:11:33,420 I literally opened two text windows, one with my C version of speller.c, 251 00:11:33,420 --> 00:11:36,960 and I just started translating it in my head to PHP and typing it out using 252 00:11:36,960 --> 00:11:38,840 the closest equivalent functions. 253 00:11:38,840 --> 00:11:40,100 >> So some of these things are different. 254 00:11:40,100 --> 00:11:43,730 We saw last time that PHP doesn't use include in quite the same way. 255 00:11:43,730 --> 00:11:47,050 It uses require typically, though include does exist. 256 00:11:47,050 --> 00:11:50,330 Define is a little different from #define in C, but that's 257 00:11:50,330 --> 00:11:51,890 how we make a constant. 258 00:11:51,890 --> 00:11:55,860 $argc it turns out exists in PHP, so we've seen that before. 259 00:11:55,860 --> 00:11:58,650 These are just variables, all of which start with dollar signs. 260 00:11:58,650 --> 00:12:00,590 Recall these are just a bunch of floating points. 261 00:12:00,590 --> 00:12:03,970 >> So long story short, you're welcome to flip through this if curious, this is 262 00:12:03,970 --> 00:12:10,010 almost a line-for-line conversion of the C version of speller.c into PHP. 263 00:12:10,010 --> 00:12:12,630 And you could do this again for half a dozen other languages. 264 00:12:12,630 --> 00:12:14,910 >> But what's interesting is this. 265 00:12:14,910 --> 00:12:16,910 Or what's frankly disheartening is this. 266 00:12:16,910 --> 00:12:20,790 Let me go ahead and type about dictionary.php, and claim that I'm 267 00:12:20,790 --> 00:12:23,670 going to go ahead and re-implement problem set six here. 268 00:12:23,670 --> 00:12:27,530 >> So let's propose first that in this file, which will be implemented in 269 00:12:27,530 --> 00:12:30,550 PHP, so let me open my tags like that. 270 00:12:30,550 --> 00:12:34,780 Let me give myself a global variable, $size gets zero. 271 00:12:34,780 --> 00:12:36,710 And I'm going to give myself a hash table. 272 00:12:36,710 --> 00:12:38,110 I'll use a hash table for this thing. 273 00:12:38,110 --> 00:12:42,070 How do I declare a hash table in PHP? 274 00:12:42,070 --> 00:12:42,990 Done. 275 00:12:42,990 --> 00:12:43,980 OK. 276 00:12:43,980 --> 00:12:48,870 >> So open bracket close bracket represents what in PHP, as we've seen? 277 00:12:48,870 --> 00:12:51,850 An array, but an array that could be an associative array. 278 00:12:51,850 --> 00:12:54,320 An associative array is a data structure that 279 00:12:54,320 --> 00:12:55,860 associates keys with values. 280 00:12:55,860 --> 00:12:59,430 >> Now in the simplest numerically indexed array, those keys are what? 281 00:12:59,430 --> 00:13:02,250 282 00:13:02,250 --> 00:13:03,960 Zero, one, two, three, right? 283 00:13:03,960 --> 00:13:08,780 Old school stuff back from C. But it can also be strings like foo, and bar, 284 00:13:08,780 --> 00:13:12,210 or maxwell, or any such string. 285 00:13:12,210 --> 00:13:14,240 So I can leverage that in just a moment. 286 00:13:14,240 --> 00:13:17,550 >> Let me go ahead and declare a function like-- 287 00:13:17,550 --> 00:13:19,020 let's do load() first. 288 00:13:19,020 --> 00:13:20,690 So function load(). 289 00:13:20,690 --> 00:13:23,440 And PHP is a little different in that you literally type function, but you 290 00:13:23,440 --> 00:13:24,930 don't type a return type. 291 00:13:24,930 --> 00:13:28,760 I'm going to go ahead and say that the load() function should take in 292 00:13:28,760 --> 00:13:31,000 argument $dictionary, just like C version did. 293 00:13:31,000 --> 00:13:32,510 I'm doing that from memory. 294 00:13:32,510 --> 00:13:34,910 >> And I propose that I'm going to do this. 295 00:13:34,910 --> 00:13:37,080 I'm simply going to do foreach. 296 00:13:37,080 --> 00:13:40,710 I'm going to call a function called file(), passing in the name of that 297 00:13:40,710 --> 00:13:44,990 file, which is the variable $dictionary as $word. 298 00:13:44,990 --> 00:13:49,410 And then inside of my for loop here, I'm going to go ahead and store in my 299 00:13:49,410 --> 00:13:57,440 $table that $word gets true. 300 00:13:57,440 --> 00:13:57,918 Done. 301 00:13:57,918 --> 00:14:01,264 Oh, wait. 302 00:14:01,264 --> 00:14:02,422 Done. 303 00:14:02,422 --> 00:14:02,760 OK. 304 00:14:02,760 --> 00:14:04,970 >> That is the load() function say in PHP. 305 00:14:04,970 --> 00:14:05,865 Now, why does that work? 306 00:14:05,865 --> 00:14:07,010 And I'm kind of cheating here. 307 00:14:07,010 --> 00:14:09,980 >> So, one, foreach we saw briefly last time. 308 00:14:09,980 --> 00:14:13,680 It just means that you can iterate over an array without bothering with i 309 00:14:13,680 --> 00:14:16,150 and n and plus plus, and all of that. 310 00:14:16,150 --> 00:14:21,350 Dictionary is of course the file name, something like large or small, the two 311 00:14:21,350 --> 00:14:22,830 dictionaries we used last time. 312 00:14:22,830 --> 00:14:26,715 File is a function that opens up text file, reads it in line by line, and 313 00:14:26,715 --> 00:14:29,840 hands you back a huge array, each of whose elements is a 314 00:14:29,840 --> 00:14:31,340 line from that file. 315 00:14:31,340 --> 00:14:36,040 So that's the combination of fopen, and fread, and while loop, and fclose, 316 00:14:36,040 --> 00:14:37,080 and all of that. 317 00:14:37,080 --> 00:14:40,150 Finally, as word just means that's the variable I'm going to have access to 318 00:14:40,150 --> 00:14:41,890 on every iteration in this loop. 319 00:14:41,890 --> 00:14:46,910 >> So in short, this one liner here means open up the file whose name is in 320 00:14:46,910 --> 00:14:50,750 dictionary, the variable, iterate over it line by line, and each time you get 321 00:14:50,750 --> 00:14:54,290 a line, store in a variable called word, and then do something with word. 322 00:14:54,290 --> 00:14:55,280 What do I want to do? 323 00:14:55,280 --> 00:14:58,110 I want to put word into my hash table. 324 00:14:58,110 --> 00:15:00,860 >> Well, I can put something in my hash table just like in C 325 00:15:00,860 --> 00:15:02,140 using square brackets. 326 00:15:02,140 --> 00:15:03,660 This is the name for my hash table. 327 00:15:03,660 --> 00:15:07,180 I'm going to index into that hash table at this location. 328 00:15:07,180 --> 00:15:08,920 So not bracket zero, not bracket one. 329 00:15:08,920 --> 00:15:11,990 Bracket quote unquote something, whatever that word is. 330 00:15:11,990 --> 00:15:15,200 And just like you might have in your hash table work trie, you just store 331 00:15:15,200 --> 00:15:17,650 effectively a Boolean, implicitly or explicitly. 332 00:15:17,650 --> 00:15:18,260 Done. 333 00:15:18,260 --> 00:15:20,000 I'm storing the value true. 334 00:15:20,000 --> 00:15:23,150 >> Now there's a couple of things I'm cutting corners on here. 335 00:15:23,150 --> 00:15:27,720 Technically, there's going to be an annoying new line, /n, at the end of 336 00:15:27,720 --> 00:15:28,820 each of these words. 337 00:15:28,820 --> 00:15:31,770 So I should probably call a PHP function called chop(), which will 338 00:15:31,770 --> 00:15:33,460 quite literally chop that off. 339 00:15:33,460 --> 00:15:35,020 And I actually need to do one other thing. 340 00:15:35,020 --> 00:15:38,380 I should probably increment size on each iteration, so I'm keeping track 341 00:15:38,380 --> 00:15:39,560 globally of what it is. 342 00:15:39,560 --> 00:15:43,180 And frankly, and this is one of the stupider aspects of PHP, if you're 343 00:15:43,180 --> 00:15:46,950 using a global variable, you need to explicitly say that you are. 344 00:15:46,950 --> 00:15:51,670 So I'm going to actually type in global $size, global $table, and now 345 00:15:51,670 --> 00:15:52,690 my function is complete. 346 00:15:52,690 --> 00:15:57,475 >> So not quite as simple as before, but probably took less time than the C 347 00:15:57,475 --> 00:15:58,220 version, maybe? 348 00:15:58,220 --> 00:15:58,730 OK. 349 00:15:58,730 --> 00:16:00,390 >> So now let's do the check() function. 350 00:16:00,390 --> 00:16:04,300 Let's see if this at least took the hours on end that it took us in C. So 351 00:16:04,300 --> 00:16:06,500 let me go ahead and declare check as a function. 352 00:16:06,500 --> 00:16:09,070 Takes in argument word, which is going to come from speller. 353 00:16:09,070 --> 00:16:13,410 And I'm just going to check if the following variable isset, table 354 00:16:13,410 --> 00:16:18,400 bracket strtolower of word-- 355 00:16:18,400 --> 00:16:20,590 let's balance all of my parentheses-- 356 00:16:20,590 --> 00:16:24,275 then return true. 357 00:16:24,275 --> 00:16:27,020 358 00:16:27,020 --> 00:16:28,460 Else-- 359 00:16:28,460 --> 00:16:30,330 that was really the hard part of this program. 360 00:16:30,330 --> 00:16:31,940 Else, return false. 361 00:16:31,940 --> 00:16:32,630 Done. 362 00:16:32,630 --> 00:16:33,460 That's check(). 363 00:16:33,460 --> 00:16:34,520 >> Now, why does this work? 364 00:16:34,520 --> 00:16:37,040 Well, one I passed in a word, which is a string. 365 00:16:37,040 --> 00:16:41,400 Two, I'm checking inside of the hash table, who's called $table. 366 00:16:41,400 --> 00:16:45,470 I'm forcing it to lowercase by calling a function quite similar tolower() in 367 00:16:45,470 --> 00:16:48,580 C, but this does the whole word, not a single character. 368 00:16:48,580 --> 00:16:52,680 And if that is set, in other words there is a value set, in other words, 369 00:16:52,680 --> 00:16:54,880 if it's true, then yes, this is a word. 370 00:16:54,880 --> 00:16:56,530 Because I put it there with load(). 371 00:16:56,530 --> 00:16:59,100 And if not, I'm going to return false. 372 00:16:59,100 --> 00:17:00,090 >> Now the others are easy. 373 00:17:00,090 --> 00:17:03,570 Function size(), how do I do this? 374 00:17:03,570 --> 00:17:05,230 I essentially do return $size. 375 00:17:05,230 --> 00:17:07,770 But I technically need to do this annoying thing. 376 00:17:07,770 --> 00:17:10,640 And actually up hear, I was cutting one corner too many. 377 00:17:10,640 --> 00:17:12,920 I really need to do global $table. 378 00:17:12,920 --> 00:17:16,260 >> But that being said, unload). 379 00:17:16,260 --> 00:17:17,380 Unload() is amazing. 380 00:17:17,380 --> 00:17:20,500 Function unload(). 381 00:17:20,500 --> 00:17:23,990 How do I want to implement unload()? 382 00:17:23,990 --> 00:17:25,079 Done. 383 00:17:25,079 --> 00:17:25,450 OK. 384 00:17:25,450 --> 00:17:28,900 >> So unload(), memory management is completely taken care of for you in 385 00:17:28,900 --> 00:17:31,800 something like PHP and a lot of higher-level languages. 386 00:17:31,800 --> 00:17:32,600 So this is amazing. 387 00:17:32,600 --> 00:17:36,080 Like why the hell did we spent the past eight plus weeks on C writing 388 00:17:36,080 --> 00:17:41,030 apparently really slow, really time consuming problems with tens of hours 389 00:17:41,030 --> 00:17:42,530 of work under our belts? 390 00:17:42,530 --> 00:17:46,110 >> Well, for one thing, this may work fine for small programs. 391 00:17:46,110 --> 00:17:47,840 It certainly sped up my development time. 392 00:17:47,840 --> 00:17:49,790 But let's see what happens in the real world. 393 00:17:49,790 --> 00:17:52,370 >> Let me go into this directory in a terminal window. 394 00:17:52,370 --> 00:17:53,370 There's speller. 395 00:17:53,370 --> 00:17:56,570 And notice as an aside, and you might have encountered this in problem set 396 00:17:56,570 --> 00:17:58,190 six or problem set seven. 397 00:17:58,190 --> 00:18:01,610 You don't strictly have to end PHP files with .php. 398 00:18:01,610 --> 00:18:05,250 If you put a line like that first one at the very top, that's a special line 399 00:18:05,250 --> 00:18:10,980 of syntax that essentially means find the program called PHP and use it to 400 00:18:10,980 --> 00:18:12,270 interpret this file. 401 00:18:12,270 --> 00:18:15,410 So now no one really knows that I'm running a PHP program. 402 00:18:15,410 --> 00:18:19,860 I can run it just as though it were something compiled in C. 403 00:18:19,860 --> 00:18:20,650 >> But here's the thing. 404 00:18:20,650 --> 00:18:21,600 Actually, let's do this again. 405 00:18:21,600 --> 00:18:23,530 Dropbox/pset6/. 406 00:18:23,530 --> 00:18:25,390 There's speller. 407 00:18:25,390 --> 00:18:26,720 OK, 0.44 seconds. 408 00:18:26,720 --> 00:18:28,080 It got faster this time. 409 00:18:28,080 --> 00:18:29,745 >> Now let's go into the PHP version. 410 00:18:29,745 --> 00:18:43,070 411 00:18:43,070 --> 00:18:44,320 Nice touch. 412 00:18:44,320 --> 00:18:50,830 413 00:18:50,830 --> 00:18:53,285 But just think how much time I saved at office hours. 414 00:18:53,285 --> 00:18:56,990 415 00:18:56,990 --> 00:18:57,790 OK. 416 00:18:57,790 --> 00:19:01,020 >> So 3.59 seconds, which actually doesn't sound accurate either. 417 00:19:01,020 --> 00:19:03,710 But that's because long story short, when you're printing out a huge amount 418 00:19:03,710 --> 00:19:06,840 of stuff to the screen, that itself slows things down. 419 00:19:06,840 --> 00:19:11,260 What it really took the CPU in the appliance was 3.59 seconds, in 420 00:19:11,260 --> 00:19:15,260 contrast to C, which took 0.44 seconds most recently. 421 00:19:15,260 --> 00:19:17,620 That's truly an order of magnitude different. 422 00:19:17,620 --> 00:19:20,280 >> So where is that price coming from? 423 00:19:20,280 --> 00:19:21,790 Why is it so much slower? 424 00:19:21,790 --> 00:19:24,220 Why does PHP perform so poorly? 425 00:19:24,220 --> 00:19:25,242 Danielle? 426 00:19:25,242 --> 00:19:26,550 >> AUDIENCE: You didn't really use a hash table. 427 00:19:26,550 --> 00:19:27,710 >> DAVID MALAN: I didn't really use a hash table. 428 00:19:27,710 --> 00:19:28,760 So I kind of did. 429 00:19:28,760 --> 00:19:29,870 So it's an associative array. 430 00:19:29,870 --> 00:19:33,650 Most likely if the people at PHP are really smart, they used underneath the 431 00:19:33,650 --> 00:19:39,520 hood an actual hash table implemented in something like C or C++. 432 00:19:39,520 --> 00:19:41,290 But. 433 00:19:41,290 --> 00:19:42,760 Yeah. 434 00:19:42,760 --> 00:19:44,010 >> AUDIENCE: [INAUDIBLE]. 435 00:19:44,010 --> 00:19:46,690 436 00:19:46,690 --> 00:19:47,080 >> DAVID MALAN: Yeah. 437 00:19:47,080 --> 00:19:50,780 So each of the functions I wrote now-- actually, can you say that once more a 438 00:19:50,780 --> 00:19:51,480 little louder? 439 00:19:51,480 --> 00:19:54,509 >> AUDIENCE: Each of the functions that you included has a lot more full 440 00:19:54,509 --> 00:19:56,610 capacity than-- 441 00:19:56,610 --> 00:19:57,550 >> DAVID MALAN: So that's very true. 442 00:19:57,550 --> 00:20:01,490 There's a lot more overhead that we're not really seeing by focusing only on 443 00:20:01,490 --> 00:20:03,730 dictionary.php, which I just wrote. 444 00:20:03,730 --> 00:20:08,020 By contrast, there's a whole interpreter going in the background. 445 00:20:08,020 --> 00:20:12,040 Indeed, when I ran this program, it wasn't running compiled zeros and ones 446 00:20:12,040 --> 00:20:14,290 designed for my Intel CPU. 447 00:20:14,290 --> 00:20:19,270 Rather, it was running line by line PHP code that looks exactly 448 00:20:19,270 --> 00:20:20,350 like we typed it. 449 00:20:20,350 --> 00:20:22,475 And so whenever you use an interpreted language, you 450 00:20:22,475 --> 00:20:23,850 actually do pay this price. 451 00:20:23,850 --> 00:20:27,010 It's going to take some time to read your file top to bottom, left to 452 00:20:27,010 --> 00:20:30,740 right, and then execute each line again and again. 453 00:20:30,740 --> 00:20:34,250 >> Now in reality, especially on the web, you can actually expedite this process 454 00:20:34,250 --> 00:20:38,660 by caching the results of the PHP code being interpreted. 455 00:20:38,660 --> 00:20:41,640 And that makes sense on the web, because if you have not one user like 456 00:20:41,640 --> 00:20:46,300 me here, but 1,000 or 10,000 users, then maybe the first time the file is 457 00:20:46,300 --> 00:20:49,050 accessed it's slow, but thereafter it's much faster. 458 00:20:49,050 --> 00:20:51,000 >> But this too, again, is a trade off. 459 00:20:51,000 --> 00:20:53,870 And for something like a research data set, or even something large like 460 00:20:53,870 --> 00:20:58,330 this, your users will eventually start to feel that slowdown. 461 00:20:58,330 --> 00:21:02,670 >> So in short, interpreted languages are very much in vogue, very popular, and 462 00:21:02,670 --> 00:21:06,710 frankly are probably the languages you should reach for when solving problems 463 00:21:06,710 --> 00:21:08,200 subsequent to CS50. 464 00:21:08,200 --> 00:21:12,720 But realize how much you're really taking for granted underneath the hood 465 00:21:12,720 --> 00:21:15,910 really those past several weeks in hash tables, and trees, and tries, 466 00:21:15,910 --> 00:21:20,770 which are used ultimately to actually implement things like open bracket, 467 00:21:20,770 --> 00:21:24,200 square bracket, which we can now gratefully take for granted. 468 00:21:24,200 --> 00:21:26,360 >> So let's take a look now in this web context. 469 00:21:26,360 --> 00:21:29,890 And I mentioned last time that there's a bunch of superglobals in PHP that 470 00:21:29,890 --> 00:21:32,490 aren't really relevant at the command line. 471 00:21:32,490 --> 00:21:36,210 They're more relevant in the context of using PHP in a web context. 472 00:21:36,210 --> 00:21:41,220 So running PHP on a web server in order to generate stuff like HTML. 473 00:21:41,220 --> 00:21:44,540 >> And we glanced at $_GET and $_POST, and that's where automatically users' 474 00:21:44,540 --> 00:21:49,100 input ends up simply if you submit a form to a file ending in .php on a web 475 00:21:49,100 --> 00:21:50,460 server like the appliance. 476 00:21:50,460 --> 00:21:53,310 But let's look briefly at $_COOKIE and $_SESSION. 477 00:21:53,310 --> 00:21:56,670 >> In layman's terms, what is a cookie as you understand it in the context of 478 00:21:56,670 --> 00:21:58,220 using the web? 479 00:21:58,220 --> 00:21:59,450 >> AUDIENCE: File on the computer. 480 00:21:59,450 --> 00:21:59,920 >> DAVID MALAN: Yeah. 481 00:21:59,920 --> 00:22:03,500 It's a file on the user's computer planted by whatever website 482 00:22:03,500 --> 00:22:04,410 you happen to visit. 483 00:22:04,410 --> 00:22:07,334 So when you go to Facebook, when you go to bankofamerica.com, when you go 484 00:22:07,334 --> 00:22:10,330 to google.com, when you go to almost any website in the world these days, 485 00:22:10,330 --> 00:22:14,850 including cs50.net, a cookie is planted on your computer, which is 486 00:22:14,850 --> 00:22:19,800 either a value stored in RAM in your computer in your browser's memory, or 487 00:22:19,800 --> 00:22:22,800 sometimes indeed a file stored on your hard drive. 488 00:22:22,800 --> 00:22:26,960 >> And what's typically stored in that file is not your user name, not your 489 00:22:26,960 --> 00:22:31,060 password, typically not something sensitive unless the website is not so 490 00:22:31,060 --> 00:22:35,040 good with their security, but rather it is a big unique identifier among 491 00:22:35,040 --> 00:22:35,680 other things. 492 00:22:35,680 --> 00:22:38,920 It's a big random number planted on your computer but you can think of as 493 00:22:38,920 --> 00:22:42,740 sort of a virtual hand stamp like from a club or some amusement park that 494 00:22:42,740 --> 00:22:47,160 allows the staff, the owners of that service, to remember who you are. 495 00:22:47,160 --> 00:22:51,030 So if the big random number is like 12345678, although that's obviously 496 00:22:51,030 --> 00:22:54,180 not too random, think of that as the hand stamp that when you visit 497 00:22:54,180 --> 00:22:57,930 facebook.com for the first time, they stamp that number on your hand. 498 00:22:57,930 --> 00:23:01,510 And then because you speak HTTP, you being a browser, and because Facebook 499 00:23:01,510 --> 00:23:06,440 obviously speaks the same as a web server, the protocol HTTP says that 500 00:23:06,440 --> 00:23:09,930 anytime you subsequently visit facebook.com, whether it's a second 501 00:23:09,930 --> 00:23:13,560 later, an hour later, even the next day, so long as you haven't explicitly 502 00:23:13,560 --> 00:23:17,050 logged out, which effectively is like washing your hands. 503 00:23:17,050 --> 00:23:20,280 HTTP says you should present your hand stamp every time you 504 00:23:20,280 --> 00:23:22,020 return to that website. 505 00:23:22,020 --> 00:23:24,390 >> What Facebook then does is they look at that hand stamp and 506 00:23:24,390 --> 00:23:26,850 they say, oh, 123456789. 507 00:23:26,850 --> 00:23:30,260 I don't know at first glance that this is David Malan in Cambridge, 508 00:23:30,260 --> 00:23:34,690 Massachusetts, but they can check their database and say, oh, the person 509 00:23:34,690 --> 00:23:39,930 on whose computer we planted 123456789 is David Malan from Cambridge, 510 00:23:39,930 --> 00:23:40,440 Massachusetts. 511 00:23:40,440 --> 00:23:46,000 Let's show that user then his profile page or his News Feed. 512 00:23:46,000 --> 00:23:49,660 >> But there's a problem here if this is how the web indeed works. 513 00:23:49,660 --> 00:23:51,390 Let's take a look at a quick example. 514 00:23:51,390 --> 00:23:55,190 Let's actually go to say facebook.com. 515 00:23:55,190 --> 00:23:58,130 But before we could go there, let me go ahead and open up Chrome's 516 00:23:58,130 --> 00:23:59,790 Inspector down here. 517 00:23:59,790 --> 00:24:01,140 Let me look at the network tab. 518 00:24:01,140 --> 00:24:06,020 And now let's go ahead and type in https://facebook.com. 519 00:24:06,020 --> 00:24:09,410 And I'm doing that so that we don't see all of those redirects and waste 520 00:24:09,410 --> 00:24:10,660 time looking through those. 521 00:24:10,660 --> 00:24:12,690 Let me hit enter. 522 00:24:12,690 --> 00:24:13,130 >> All right. 523 00:24:13,130 --> 00:24:14,580 We see a whole bunch of requests. 524 00:24:14,580 --> 00:24:15,640 There comes Facebook. 525 00:24:15,640 --> 00:24:16,930 There's a whole bunch of files. 526 00:24:16,930 --> 00:24:19,290 And here, per my mention of latency last time, that's 527 00:24:19,290 --> 00:24:21,240 a lot of HTTP requests. 528 00:24:21,240 --> 00:24:23,700 But the first one is probably the most interesting. 529 00:24:23,700 --> 00:24:26,420 >> So let's scroll down here, and I'll zoom in in a second. 530 00:24:26,420 --> 00:24:29,090 This is going to be kind of a mess, but let's see. 531 00:24:29,090 --> 00:24:31,660 Facebook is sending us a whole bunch of stuff. 532 00:24:31,660 --> 00:24:33,490 >> But whoa, interesting. 533 00:24:33,490 --> 00:24:37,880 They're planting not one, but four hand stamps onto my hand here. 534 00:24:37,880 --> 00:24:40,400 Set-cookie, Set-cookie, set-cookie, set-cookie. 535 00:24:40,400 --> 00:24:44,030 And there are a few features here. 536 00:24:44,030 --> 00:24:46,170 All of them mention some kind of expiration. 537 00:24:46,170 --> 00:24:50,090 And it looks like Facebook is hoping to remember me until 2015. 538 00:24:50,090 --> 00:24:53,670 So that's presumably the time by which I must log out or they'll just 539 00:24:53,670 --> 00:24:55,710 automatically assume I'm not coming back. 540 00:24:55,710 --> 00:24:57,840 So that's actually a decent amount of time. 541 00:24:57,840 --> 00:24:59,170 >> And there are some other things going on here. 542 00:24:59,170 --> 00:25:03,036 This cookie appears to be forcibly deleted by saying it expired in 1970 543 00:25:03,036 --> 00:25:04,460 before cookies existed. 544 00:25:04,460 --> 00:25:06,510 So the browser is just going to assume OK, that's like 545 00:25:06,510 --> 00:25:07,910 washing the hands stamp. 546 00:25:07,910 --> 00:25:11,240 >> But now when my browser makes a subsequent request-- 547 00:25:11,240 --> 00:25:14,340 let me go ahead and do this again and reload. 548 00:25:14,340 --> 00:25:18,170 Now let me scroll back to the top request and go down 549 00:25:18,170 --> 00:25:20,760 here, request headers. 550 00:25:20,760 --> 00:25:21,390 Notice this. 551 00:25:21,390 --> 00:25:25,280 So now I'm under not response headers, but notice it says request headers. 552 00:25:25,280 --> 00:25:29,220 And notice that my browser as part of its request after hitting reload has 553 00:25:29,220 --> 00:25:32,780 sent at least the following information. 554 00:25:32,780 --> 00:25:34,670 Not set-cookie, but cookie. 555 00:25:34,670 --> 00:25:38,750 So this is the line, the HTTP header so to speak, where my browser is sort 556 00:25:38,750 --> 00:25:43,340 of without my knowing it presenting my hand for Facebook's inspection. 557 00:25:43,340 --> 00:25:46,020 >> So these cookies can be used then for what? 558 00:25:46,020 --> 00:25:49,420 To remember who you are, or remember how many times you've been there, or 559 00:25:49,420 --> 00:25:50,280 really anything. 560 00:25:50,280 --> 00:25:52,742 >> So here is counter.php. 561 00:25:52,742 --> 00:25:53,780 And let me zoom in on the font. 562 00:25:53,780 --> 00:25:58,380 And each time I reload this page, notice it's remembering how many times 563 00:25:58,380 --> 00:25:59,250 I've been there. 564 00:25:59,250 --> 00:26:00,570 Well, that's not all that impressive. 565 00:26:00,570 --> 00:26:03,140 Let's just close that tab, and now let's go back to 566 00:26:03,140 --> 00:26:07,860 http://localhost/counter.php. 567 00:26:07,860 --> 00:26:08,970 >> Oh, that's interesting. 568 00:26:08,970 --> 00:26:10,960 It still remembered, even though I closed the tab. 569 00:26:10,960 --> 00:26:14,010 And frankly, if I close the browser, if implemented in the right way, I 570 00:26:14,010 --> 00:26:18,950 could still remember that this user is who he or she was the first time, and 571 00:26:18,950 --> 00:26:22,840 only once I go into Chrome's menu, which over here is here, and go to 572 00:26:22,840 --> 00:26:25,990 History, and click Clear Browsing Data, as some of you may have in the 573 00:26:25,990 --> 00:26:33,050 past, only then will your cookies actually be deleted during web 574 00:26:33,050 --> 00:26:33,970 development. 575 00:26:33,970 --> 00:26:35,340 >> So, if we go-- 576 00:26:35,340 --> 00:26:37,080 let's close up gedit here. 577 00:26:37,080 --> 00:26:38,910 And if we go now to this file. 578 00:26:38,910 --> 00:26:44,210 Let me go into our vhosts/localhost/public, and let me do 579 00:26:44,210 --> 00:26:46,340 counter.php. 580 00:26:46,340 --> 00:26:48,350 Notice that this is a pretty simple program. 581 00:26:48,350 --> 00:26:50,250 It's a pretty simple website. 582 00:26:50,250 --> 00:26:51,770 >> So the top of the file is just comments. 583 00:26:51,770 --> 00:26:54,930 But here's a new line that you may have seen already in p-set seven, 584 00:26:54,930 --> 00:26:56,000 session_start(). 585 00:26:56,000 --> 00:27:00,380 This is a line of PHP code that essentially tells the web server, make 586 00:27:00,380 --> 00:27:03,400 sure to stamp hands and make sure to check hand stamps. 587 00:27:03,400 --> 00:27:06,810 That's all that line does, and it does all of that process for us. 588 00:27:06,810 --> 00:27:09,510 Then notice I've just got two branches here. 589 00:27:09,510 --> 00:27:14,150 If the counter key inside of this special global variable called 590 00:27:14,150 --> 00:27:18,010 $_SESSION is set-- in other words, if there's some value there-- 591 00:27:18,010 --> 00:27:22,440 let's get it and store it in a local variable called $counter. 592 00:27:22,440 --> 00:27:27,000 Else, let's assign $counter the default value of 0. 593 00:27:27,000 --> 00:27:30,320 >> Now here's one aspect of PHP that's both a blessing and a curse. 594 00:27:30,320 --> 00:27:32,080 PHP is a little sloppy. 595 00:27:32,080 --> 00:27:35,160 So whereas in C, what would the scope of counter have been 596 00:27:35,160 --> 00:27:36,725 either here or here? 597 00:27:36,725 --> 00:27:39,270 598 00:27:39,270 --> 00:27:41,690 >> It would have been confined to those curly braces. 599 00:27:41,690 --> 00:27:42,090 Guess what? 600 00:27:42,090 --> 00:27:46,920 In PHP, it exists even outside of those curly braces, here, and here, 601 00:27:46,920 --> 00:27:49,120 and here, and here, and even down below. 602 00:27:49,120 --> 00:27:52,400 So I say this is a blessing in the sense that you don't have to think as 603 00:27:52,400 --> 00:27:54,070 hard as we did weeks ago. 604 00:27:54,070 --> 00:27:56,880 But it's also a bit of a curse in that no matter where you use a variable in 605 00:27:56,880 --> 00:28:00,020 PHP, at least in a program like this, it's globally accessible for 606 00:28:00,020 --> 00:28:01,170 better or for worse. 607 00:28:01,170 --> 00:28:06,130 So you have to keep in mind now that your variables may not be undefined. 608 00:28:06,130 --> 00:28:07,640 You might have defined them elsewhere. 609 00:28:07,640 --> 00:28:09,460 >> But what am I going to do ultimately? 610 00:28:09,460 --> 00:28:13,160 I'm going to store inside of that global variable as a value of the 611 00:28:13,160 --> 00:28:17,060 counter key the result of doing counter plus 1. 612 00:28:17,060 --> 00:28:18,910 So this is just the arithmetic that does the 613 00:28:18,910 --> 00:28:20,590 incrementation of that counter. 614 00:28:20,590 --> 00:28:24,850 And the fact that I'm storing that value back in here is means to 615 00:28:24,850 --> 00:28:29,970 essentially update the database to remember that user 123456789 has been 616 00:28:29,970 --> 00:28:31,010 here two times. 617 00:28:31,010 --> 00:28:33,780 And when I do it again the next time I reload the page, it's going to check 618 00:28:33,780 --> 00:28:36,710 my hand stamp and say, oh, user 123456789 has now 619 00:28:36,710 --> 00:28:38,410 been here three times. 620 00:28:38,410 --> 00:28:43,390 >> And so what PHP and similar languages are doing for us is they are figuring 621 00:28:43,390 --> 00:28:47,720 out how and where and for how long to store values in this special 622 00:28:47,720 --> 00:28:48,830 superglobal. 623 00:28:48,830 --> 00:28:52,750 And this superglobal the next time I visit the page is sort of magically 624 00:28:52,750 --> 00:28:57,440 pre-populated, filled with values that were there the last time you visited, 625 00:28:57,440 --> 00:29:02,310 whether that was a second ago, a week ago, or in 2013 and we're now talking 626 00:29:02,310 --> 00:29:03,790 about 2015. 627 00:29:03,790 --> 00:29:07,600 PHP and the web server take care of all of that for you. 628 00:29:07,600 --> 00:29:08,850 >> AUDIENCE: [INAUDIBLE]. 629 00:29:08,850 --> 00:29:11,900 630 00:29:11,900 --> 00:29:15,760 >> DAVID MALAN: Variables in PHP are essentially always global unless you 631 00:29:15,760 --> 00:29:18,400 declare them inside of a function, and then they are local to 632 00:29:18,400 --> 00:29:19,420 the function only. 633 00:29:19,420 --> 00:29:22,300 But because I've not written any functions, they are now effectively 634 00:29:22,300 --> 00:29:25,090 global throughout my whole file here. 635 00:29:25,090 --> 00:29:26,040 >> AUDIENCE: Is there a way to make them local? 636 00:29:26,040 --> 00:29:28,470 >> DAVID MALAN: Is there any way to make them local? 637 00:29:28,470 --> 00:29:30,680 Only by wrapping them into functions. 638 00:29:30,680 --> 00:29:32,790 Which in the latest version of PHP, you can do this with 639 00:29:32,790 --> 00:29:34,130 an anonymous function. 640 00:29:34,130 --> 00:29:35,930 But more on that in the context of JavaScript. 641 00:29:35,930 --> 00:29:37,260 But the short answer is no. 642 00:29:37,260 --> 00:29:40,888 A longer answer is yes. 643 00:29:40,888 --> 00:29:42,380 Nice. 644 00:29:42,380 --> 00:29:43,380 Good quiz question. 645 00:29:43,380 --> 00:29:43,930 All right. 646 00:29:43,930 --> 00:29:47,760 >> So lastly, the page itself is actually pretty simple. 647 00:29:47,760 --> 00:29:51,470 Notice that once I exit PHP mode, recall that all of this stuff down 648 00:29:51,470 --> 00:29:53,700 below is just going to get spit out raw to the browser. 649 00:29:53,700 --> 00:29:57,050 Which is fine, because I do want to send the user some HTML, but I do want 650 00:29:57,050 --> 00:29:59,140 to dynamically update that HTML. 651 00:29:59,140 --> 00:30:03,930 And one way I can do this is to sort of very quickly drop back into PHP 652 00:30:03,930 --> 00:30:07,730 mode, use open bracket question mark equal sign, and then output the value 653 00:30:07,730 --> 00:30:08,650 of counter. 654 00:30:08,650 --> 00:30:12,360 >> Or if this looks a little cryptic, this equal sign is actually just some 655 00:30:12,360 --> 00:30:16,190 syntactic sugar for this printf($counter). 656 00:30:16,190 --> 00:30:19,160 But frankly, that's just a little ugly and a little annoying to type. 657 00:30:19,160 --> 00:30:23,660 So PHP very nicely offers this feature where you can just say it more 658 00:30:23,660 --> 00:30:25,450 succinctly in the same way. 659 00:30:25,450 --> 00:30:26,940 >> So what's going on underneath the hood? 660 00:30:26,940 --> 00:30:31,210 Let's quickly look at the network tab here for counter.php. 661 00:30:31,210 --> 00:30:35,090 And let me go ahead and first let's clear your cookies. 662 00:30:35,090 --> 00:30:38,670 Let's clear browsing data since the beginning of time. 663 00:30:38,670 --> 00:30:39,680 Now let's go back over here. 664 00:30:39,680 --> 00:30:41,340 Now let's reload the page. 665 00:30:41,340 --> 00:30:42,170 And I'm back at zero. 666 00:30:42,170 --> 00:30:44,810 Because my hand stamp has been washed, I now get a new cookie. 667 00:30:44,810 --> 00:30:48,780 >> Indeed if I look at the network tab and look at response headers, notice 668 00:30:48,780 --> 00:30:51,960 that the appliance is sending me a cookie whose name is somewhat 669 00:30:51,960 --> 00:30:55,820 arbitrarily, but kind of reasonably, PHPSESSID. 670 00:30:55,820 --> 00:30:58,440 And it's sending me this really big random number. 671 00:30:58,440 --> 00:30:59,440 It's not quite a number. 672 00:30:59,440 --> 00:31:00,390 It's not quite hexadecimal. 673 00:31:00,390 --> 00:31:03,600 It's some kind of alphanumeric string, but presumably it's random. 674 00:31:03,600 --> 00:31:06,830 And that is the hand stamp so to speak that I'm referring to. 675 00:31:06,830 --> 00:31:11,960 >> Meanwhile if I click reload and then look at this second line for my second 676 00:31:11,960 --> 00:31:17,600 request, notice now that my request headers include PHPSESSID equals this, 677 00:31:17,600 --> 00:31:19,390 not set-cookie, but just cookie. 678 00:31:19,390 --> 00:31:22,950 And that's my browser's presentation of my hand stamp. 679 00:31:22,950 --> 00:31:28,820 >> So now as a teaser, and we'll talk more about this in a week or so, but 680 00:31:28,820 --> 00:31:31,590 in what way does this make you vulnerable, your Facebook account 681 00:31:31,590 --> 00:31:34,137 vulnerable, and other such accounts vulnerable? 682 00:31:34,137 --> 00:31:35,510 >> AUDIENCE: If somebody has your cookie. 683 00:31:35,510 --> 00:31:36,750 >> DAVID MALAN: Yeah, if someone has your cookie. 684 00:31:36,750 --> 00:31:39,920 I mean truly, much like some of you might have tried at like a club or an 685 00:31:39,920 --> 00:31:44,030 amusement park, if you try something like this to copy the stamp, albeit 686 00:31:44,030 --> 00:31:47,560 backwards onto another person's hand, and then he or she presents it as 687 00:31:47,560 --> 00:31:53,250 their own, if it actually does look identical, 123456789, then the web 688 00:31:53,250 --> 00:31:57,980 server is apparently just going to trust that that user is you. 689 00:31:57,980 --> 00:32:01,450 >> And this is indeed a fundamental threat any time you use cookies 690 00:32:01,450 --> 00:32:05,420 because if someone just spoofs so to speak your cookie, figures out what it 691 00:32:05,420 --> 00:32:08,660 is, either by truly copying it by looking at your computer 692 00:32:08,660 --> 00:32:09,890 and being like, OK. 693 00:32:09,890 --> 00:32:14,520 David's cookie is JJ3JIK and so forth, and then they're smart enough to know 694 00:32:14,520 --> 00:32:18,080 how to sort of manually send that cookie from a browser or from a 695 00:32:18,080 --> 00:32:22,350 program they write, they could totally log into a website as you. 696 00:32:22,350 --> 00:32:28,560 It is not that hard to pretend to be someone else unless we revisit p-set 697 00:32:28,560 --> 00:32:30,790 two, which introduced what? 698 00:32:30,790 --> 00:32:32,065 >> AUDIENCE: Cryptography. 699 00:32:32,065 --> 00:32:33,860 >> DAVID MALAN: A little bit of cryptography. 700 00:32:33,860 --> 00:32:36,550 Simple cryptography, at least in the standard edition, but crypto 701 00:32:36,550 --> 00:32:36,870 nonetheless. 702 00:32:36,870 --> 00:32:37,410 less. 703 00:32:37,410 --> 00:32:41,440 So it turns out if you encrypt all of these headers using something that you 704 00:32:41,440 --> 00:32:48,770 might now know more familiarly as SSL, secure socket layer, or https:// URLs, 705 00:32:48,770 --> 00:32:51,890 then all of these things we've been glancing at are actually encrypted, 706 00:32:51,890 --> 00:32:54,800 which means that it's like you can't read the hand stamp. 707 00:32:54,800 --> 00:32:59,350 Only facebook.com can, or google.com, or in this case, the appliance can 708 00:32:59,350 --> 00:33:00,550 read that hand stamp. 709 00:33:00,550 --> 00:33:04,020 >> Tragically though, and again, this is all too appropriate with the NSA stuff 710 00:33:04,020 --> 00:33:06,410 of late, even SSL is breakable. 711 00:33:06,410 --> 00:33:09,850 And it's actually not that hard to even crack that encryption. 712 00:33:09,850 --> 00:33:12,040 Not so much by cracking the encryption, but by tricking the 713 00:33:12,040 --> 00:33:15,720 browser into decrypting the data prematurely. 714 00:33:15,720 --> 00:33:17,880 But again, we'll tease you with that before long. 715 00:33:17,880 --> 00:33:21,242 For now, just be afraid. 716 00:33:21,242 --> 00:33:23,070 It's tragically kind of true. 717 00:33:23,070 --> 00:33:23,760 >> All right. 718 00:33:23,760 --> 00:33:27,910 So, where does this now leave us? 719 00:33:27,910 --> 00:33:29,010 Well, let's do this. 720 00:33:29,010 --> 00:33:31,790 Let's go ahead and take a quick teaser before we take a break. 721 00:33:31,790 --> 00:33:33,790 And I think we'll linger a bit longer today, but we're going to dive into 722 00:33:33,790 --> 00:33:37,850 something brand new and sexy, which will whet your appetite for even more. 723 00:33:37,850 --> 00:33:38,950 So that's the teaser. 724 00:33:38,950 --> 00:33:41,520 >> So SQL, we started talking about ever so briefly last time. 725 00:33:41,520 --> 00:33:44,670 You'll really get your hands dirty with some of it in p-set seven. 726 00:33:44,670 --> 00:33:46,480 And in layman's terms, what does SQL-- 727 00:33:46,480 --> 00:33:47,110 S-Q-L-- 728 00:33:47,110 --> 00:33:49,850 do for you? 729 00:33:49,850 --> 00:33:50,310 What is it? 730 00:33:50,310 --> 00:33:51,546 Yeah. 731 00:33:51,546 --> 00:33:53,240 >> AUDIENCE: Let's you access data. 732 00:33:53,240 --> 00:33:53,360 >> DAVID MALAN: Yeah. 733 00:33:53,360 --> 00:33:55,120 It let's you access data in a database. 734 00:33:55,120 --> 00:33:56,710 Structured Query Language. 735 00:33:56,710 --> 00:33:59,890 And this is essentially a programming language. 736 00:33:59,890 --> 00:34:03,400 There are features of it that we won't even use in class. 737 00:34:03,400 --> 00:34:04,710 But you can effectively define functions. 738 00:34:04,710 --> 00:34:06,870 They're called stored procedures in SQL. 739 00:34:06,870 --> 00:34:09,860 But we'll keep it fairly simple and just use it for some basic operations 740 00:34:09,860 --> 00:34:14,320 like selecting data, inserting data, updating data, and deleting data. 741 00:34:14,320 --> 00:34:17,400 >> And you can really think of a database, like a SQL database, as just 742 00:34:17,400 --> 00:34:18,800 being Microsoft Excel. 743 00:34:18,800 --> 00:34:21,989 Because SQL refers to a relational database, where 744 00:34:21,989 --> 00:34:23,480 relation just means tables. 745 00:34:23,480 --> 00:34:24,739 Rows and columns. 746 00:34:24,739 --> 00:34:27,929 So anything you can put in a spreadsheet like this or Google Docs, 747 00:34:27,929 --> 00:34:32,460 you could put into a SQL database by declaring a table. 748 00:34:32,460 --> 00:34:34,800 >> Now, how do you actually access that information? 749 00:34:34,800 --> 00:34:38,239 Well, with commands or queries like this. 750 00:34:38,239 --> 00:34:40,199 SELECT, INSERT, UPDATE, and DELETE. 751 00:34:40,199 --> 00:34:44,489 And for the most part, those are the four only ingredients you'll need to 752 00:34:44,489 --> 00:34:47,370 do something quite powerfully in problem set seven. 753 00:34:47,370 --> 00:34:49,940 >> Now back in the day, you would actually interact with a database in a 754 00:34:49,940 --> 00:34:52,730 black and white terminal window at a blinking prompt like this. 755 00:34:52,730 --> 00:34:56,370 And the database we're running on the appliance is called MySQL, which is 756 00:34:56,370 --> 00:34:58,560 free and open source database engine. 757 00:34:58,560 --> 00:35:02,240 If you Google and read the Wikipedia article, you'll know that the name is 758 00:35:02,240 --> 00:35:05,060 a bit of transition for some versions of Linux. 759 00:35:05,060 --> 00:35:10,460 Maria database is actually a fork so to speak of MySQL. 760 00:35:10,460 --> 00:35:12,740 >> Long story short, Oracle bought MySQL. 761 00:35:12,740 --> 00:35:13,870 Oracle's a big company. 762 00:35:13,870 --> 00:35:17,010 People have been worried that it would no longer remain quite as open source, 763 00:35:17,010 --> 00:35:20,930 so this is just a copy of MySQL that's still free, still open source, and 764 00:35:20,930 --> 00:35:23,550 installed in Fedora Linux by default. 765 00:35:23,550 --> 00:35:26,130 >> But this is kind of a pain in the neck to get acquainted with a 766 00:35:26,130 --> 00:35:27,310 database this way. 767 00:35:27,310 --> 00:35:30,560 So we include in the CS50 appliance a free open source tool called 768 00:35:30,560 --> 00:35:31,700 phpMyAdmin. 769 00:35:31,700 --> 00:35:33,940 Just a coincidence that it's written in PHP. 770 00:35:33,940 --> 00:35:36,450 There's no fundamental need for PHP here. 771 00:35:36,450 --> 00:35:40,090 But this is just a web-based tool that we downloaded for free, installed in 772 00:35:40,090 --> 00:35:43,850 the appliance, that allows us to have a graphical user interface with which 773 00:35:43,850 --> 00:35:48,610 to explore the p-set seven database with which to create new databases, 774 00:35:48,610 --> 00:35:51,980 say for your own final project if you'd like, and ultimately create 775 00:35:51,980 --> 00:35:55,900 dynamic websites like CS50 Finance that allow you to query data and 776 00:35:55,900 --> 00:35:58,140 update data dynamically. 777 00:35:58,140 --> 00:36:01,420 >> You're not going to have to use just a simple text file or CSV. 778 00:36:01,420 --> 00:36:05,950 You can actually use a smart database program so that you can execute more 779 00:36:05,950 --> 00:36:10,240 sophisticated queries than just reading through everything linearly. 780 00:36:10,240 --> 00:36:14,150 >> So for instance, this is what we give you out of the box for p-set seven. 781 00:36:14,150 --> 00:36:18,280 This is a table with apparently at least three columns, one of which is 782 00:36:18,280 --> 00:36:21,450 username, one of which is hash, and the other of which is ID. 783 00:36:21,450 --> 00:36:26,200 >> But the interesting thing, and just to tease out one thought here, username 784 00:36:26,200 --> 00:36:29,270 is presumably already unique, right? 785 00:36:29,270 --> 00:36:31,190 I mean, most any website, if you have a username, there 786 00:36:31,190 --> 00:36:32,370 can't be two caesars. 787 00:36:32,370 --> 00:36:33,440 There can't be two malans. 788 00:36:33,440 --> 00:36:34,950 There can't be two jharvards. 789 00:36:34,950 --> 00:36:35,600 Its unique. 790 00:36:35,600 --> 00:36:38,610 Otherwise, they don't know which jharvard it actually is. 791 00:36:38,610 --> 00:36:42,710 So what might be the motivation for also having a third column on the left 792 00:36:42,710 --> 00:36:46,970 there called ID, which looks like a number that's similarly unique? 793 00:36:46,970 --> 00:36:51,300 It feels a little redundant to me at first glance. 794 00:36:51,300 --> 00:36:54,910 Why might it be compelling to have not only unique usernames, 795 00:36:54,910 --> 00:36:56,837 but also unique numbers? 796 00:36:56,837 --> 00:36:59,460 >> AUDIENCE: They could have the same password. 797 00:36:59,460 --> 00:37:01,720 >> DAVID MALAN: People might have the same password, sure. 798 00:37:01,720 --> 00:37:03,900 That could absolutely happen. 799 00:37:03,900 --> 00:37:08,270 But if they have this unique username, I would argue that that doesn't really 800 00:37:08,270 --> 00:37:11,630 matter, because if they type in their username, I only need to check their 801 00:37:11,630 --> 00:37:15,060 password, their hash thereof. 802 00:37:15,060 --> 00:37:15,970 Why else? 803 00:37:15,970 --> 00:37:17,950 >> AUDIENCE: Faster searching. 804 00:37:17,950 --> 00:37:18,680 >> DAVID MALAN: Faster searching. 805 00:37:18,680 --> 00:37:19,548 Why? 806 00:37:19,548 --> 00:37:21,460 >> AUDIENCE: ID is just one. 807 00:37:21,460 --> 00:37:24,040 >> DAVID MALAN: ID is just one character, or to be more precise, it's a number, 808 00:37:24,040 --> 00:37:26,910 so it's probably 32 bits or something like that. 809 00:37:26,910 --> 00:37:30,270 Whereas the username, apparently Jason Hirschhorn's up there is sort of 810 00:37:30,270 --> 00:37:33,900 ridiculously long, and it's going to take me a lot more time to string 811 00:37:33,900 --> 00:37:40,910 compare H-I-R-S-C-H-H-O-R-N, and maybe a /0 or something like that, in order 812 00:37:40,910 --> 00:37:45,100 to look up Jason, as opposed to just saying give me user number two. 813 00:37:45,100 --> 00:37:46,510 That's 32 bits. 814 00:37:46,510 --> 00:37:48,550 It's a single INT that you have to compare. 815 00:37:48,550 --> 00:37:52,150 And indeed, that's exactly why databases tend to assign unique IDs to 816 00:37:52,150 --> 00:37:53,710 rows in them. 817 00:37:53,710 --> 00:37:56,280 >> Now what other data types are there besides INT and apparently 818 00:37:56,280 --> 00:37:57,160 strings like this? 819 00:37:57,160 --> 00:37:59,700 Well, to be more proper, SQL databases, like 820 00:37:59,700 --> 00:38:02,060 MySQL, have CHAR fields. 821 00:38:02,060 --> 00:38:05,320 And CHAR a little misleadingly is not a single CHAR. 822 00:38:05,320 --> 00:38:10,290 A CHAR field in a MySQL database is one or more characters, but it's a 823 00:38:10,290 --> 00:38:11,780 fixed number of characters. 824 00:38:11,780 --> 00:38:15,710 >> So for instance, if I go over to phpMyAdmin as you may have already, or 825 00:38:15,710 --> 00:38:21,340 soon will a problem set seven, and I go to my database, and just for fun, 826 00:38:21,340 --> 00:38:25,700 let's create a new table called test with just two columns. 827 00:38:25,700 --> 00:38:27,160 I'll then click Go. 828 00:38:27,160 --> 00:38:30,070 And this will become fairly familiar, especially as you tinker 829 00:38:30,070 --> 00:38:31,130 around on your own. 830 00:38:31,130 --> 00:38:34,140 Here I might type ID to create a new table of type INT. 831 00:38:34,140 --> 00:38:37,770 But here I might type username to recreate that earlier table. 832 00:38:37,770 --> 00:38:40,700 And notice I have a whole bunch of types to choose from. 833 00:38:40,700 --> 00:38:43,610 >> And this too is why phpMyAdmin is kind of nice. 834 00:38:43,610 --> 00:38:46,770 It's kind of self-teaching in that you can just kind of point, and click, and 835 00:38:46,770 --> 00:38:50,730 look at dropdown menus, and infer from that what powers SQL gives you. 836 00:38:50,730 --> 00:38:54,090 >> And indeed, if I choose CHAR, I then have to specify the length, or how 837 00:38:54,090 --> 00:38:55,940 many values, how many CHARs. 838 00:38:55,940 --> 00:39:00,090 So very common values are things like 255, but that's a little long. 839 00:39:00,090 --> 00:39:02,250 Commonly is eight for a username. 840 00:39:02,250 --> 00:39:03,590 But that's a little small these days. 841 00:39:03,590 --> 00:39:05,430 So this is a design decision. 842 00:39:05,430 --> 00:39:08,630 Is it 8 characters max, 32, 255, 1,000? 843 00:39:08,630 --> 00:39:09,830 It's really up to you. 844 00:39:09,830 --> 00:39:12,350 But a CHAR field is a fixed number. 845 00:39:12,350 --> 00:39:16,420 So choose too few and you're kind of screwed if you want a longer username. 846 00:39:16,420 --> 00:39:19,132 Choose too many and what's the downside? 847 00:39:19,132 --> 00:39:20,820 >> AUDIENCE: [INAUDIBLE]. 848 00:39:20,820 --> 00:39:21,620 >> DAVID MALAN: It's wasteful. 849 00:39:21,620 --> 00:39:24,835 Just like in C, if you have a bigger chunk of memory than you need, you're 850 00:39:24,835 --> 00:39:27,190 just wasting time and wasting space. 851 00:39:27,190 --> 00:39:31,430 So as an alternative, there exists VARCHAR, which solves this problem by 852 00:39:31,430 --> 00:39:36,390 treating length not as a fixed length, but as a maximum length, and using a 853 00:39:36,390 --> 00:39:40,990 variable number of CHARs, which then tends to use only as many CHARs as you 854 00:39:40,990 --> 00:39:42,710 actually need. 855 00:39:42,710 --> 00:39:43,670 That sounds perfect. 856 00:39:43,670 --> 00:39:45,640 >> Why don't we get rid of the CHAR data type then? 857 00:39:45,640 --> 00:39:48,500 What might be the downside of using VARCHARs, which sounds 858 00:39:48,500 --> 00:39:51,644 like it's a nice win? 859 00:39:51,644 --> 00:39:52,596 Yeah? 860 00:39:52,596 --> 00:39:53,846 >> AUDIENCE: [INAUDIBLE]. 861 00:39:53,846 --> 00:39:57,360 862 00:39:57,360 --> 00:39:57,790 >> DAVID MALAN: OK, good. 863 00:39:57,790 --> 00:40:01,101 So if all of your data is the same length, what's the concern? 864 00:40:01,101 --> 00:40:05,250 >> AUDIENCE: Because you're wasting data by telling them all. 865 00:40:05,250 --> 00:40:09,060 >> DAVID MALAN: So if all of your data is the same length, though, I would argue 866 00:40:09,060 --> 00:40:12,300 that specifying a maximum length on VARCHAR is no different from 867 00:40:12,300 --> 00:40:16,070 specifying a fixed length on CHAR if you know that number in advance. 868 00:40:16,070 --> 00:40:19,500 But there is indeed, and I'll sort of extract from that answer the reality 869 00:40:19,500 --> 00:40:22,610 that there's still a max, which could be annoying, especially if you 870 00:40:22,610 --> 00:40:25,920 encounter a person's name that's unusually long that you didn't 871 00:40:25,920 --> 00:40:26,860 anticipate. 872 00:40:26,860 --> 00:40:31,420 And it's also a little less efficient to actually search on VARCHARs as 873 00:40:31,420 --> 00:40:35,620 opposed to searching CHARs, especially for long tables that have lots and 874 00:40:35,620 --> 00:40:36,510 lots of data. 875 00:40:36,510 --> 00:40:40,060 So here too, thematic is again no obvious choice. 876 00:40:40,060 --> 00:40:42,870 >> So just to give you a sense of other data types that might be of interest 877 00:40:42,870 --> 00:40:45,400 either for p-set seven or in the future, there's INT. 878 00:40:45,400 --> 00:40:47,270 There's BIGINT, which is like long long. 879 00:40:47,270 --> 00:40:48,880 It tends to be 64 bits. 880 00:40:48,880 --> 00:40:51,640 There's DECIMAL, which you'll see in the problem set, which is a much 881 00:40:51,640 --> 00:40:55,300 cleaner answer to the problems we encountered with float and floating 882 00:40:55,300 --> 00:40:55,980 point imprecision. 883 00:40:55,980 --> 00:40:57,390 And then there's DATETIME. 884 00:40:57,390 --> 00:41:01,530 There's literally a data type that has to look like a year, a month, a day, 885 00:41:01,530 --> 00:41:03,730 and an hour, minute, and second. 886 00:41:03,730 --> 00:41:07,470 >> But SQL databases also have things we'll call indexes. 887 00:41:07,470 --> 00:41:11,630 And an index is something that you specify when creating the table to 888 00:41:11,630 --> 00:41:15,720 make searches and other operations more efficient. 889 00:41:15,720 --> 00:41:18,550 Specifically, there's something called the PRIMARY index that you could 890 00:41:18,550 --> 00:41:19,440 declare as follows. 891 00:41:19,440 --> 00:41:22,330 >> We did this for you with the users table we give you. 892 00:41:22,330 --> 00:41:26,160 But notice if I were manually recreating the users table here giving 893 00:41:26,160 --> 00:41:27,110 it a name of users. 894 00:41:27,110 --> 00:41:28,125 I already specified ID. 895 00:41:28,125 --> 00:41:29,330 I specified INT. 896 00:41:29,330 --> 00:41:32,000 I specified username with maximum 32 characters. 897 00:41:32,000 --> 00:41:36,140 But if we keep scrolling in this fairly wide window, notice there's a 898 00:41:36,140 --> 00:41:38,260 bunch of other things I can specify. 899 00:41:38,260 --> 00:41:40,950 >> One, I can specify attributes like, you know what, this 900 00:41:40,950 --> 00:41:42,190 INT should be UNSIGNED. 901 00:41:42,190 --> 00:41:45,510 I don't want negative numbers, so let's make it UNSIGNED. 902 00:41:45,510 --> 00:41:48,660 Null is not relevant here because I do want every user to 903 00:41:48,660 --> 00:41:49,640 have a unique number. 904 00:41:49,640 --> 00:41:50,830 I don't want it to be null. 905 00:41:50,830 --> 00:41:52,330 >> But this is interesting. 906 00:41:52,330 --> 00:41:57,780 I can specify that ID is either the primary key of this database, or it's 907 00:41:57,780 --> 00:42:00,620 unique, or it's indexed, or full text. 908 00:42:00,620 --> 00:42:05,630 So for today's purposes, long story short, PRIMARY means that this shall 909 00:42:05,630 --> 00:42:10,570 be both conceptually and technically the field that we use to uniquely 910 00:42:10,570 --> 00:42:12,140 identify users. 911 00:42:12,140 --> 00:42:16,140 >> So when we look up users, this is sort of a promise to look them up mostly by 912 00:42:16,140 --> 00:42:17,370 that unique identifier. 913 00:42:17,370 --> 00:42:21,930 And the database will ensure that if you have a user number 3, you cannot 914 00:42:21,930 --> 00:42:25,400 physically insert another user with that same number 3. 915 00:42:25,400 --> 00:42:28,380 The database will just refuse to save your changes. 916 00:42:28,380 --> 00:42:32,310 Which is a good thing, because you can protect yourself from yourself. self 917 00:42:32,310 --> 00:42:34,270 >> Alternatively, for username. 918 00:42:34,270 --> 00:42:37,670 So the second row, recall, is the username field. 919 00:42:37,670 --> 00:42:41,860 So the second row here is username, as we did on the far left there. 920 00:42:41,860 --> 00:42:43,940 >> So what else might I want to specify? 921 00:42:43,940 --> 00:42:47,840 I'm not allowed, according to SQL, to specify two primary keys. 922 00:42:47,840 --> 00:42:50,750 you can specify a joint key where you look at both fields, but they can't 923 00:42:50,750 --> 00:42:52,260 individually be primary keys. 924 00:42:52,260 --> 00:42:54,750 So that's out of the question. 925 00:42:54,750 --> 00:42:56,040 So which might I want to choose? 926 00:42:56,040 --> 00:42:59,710 >> Well, UNIQUE is similar in spirit to a primary key where you specify this 927 00:42:59,710 --> 00:43:03,570 field shall be unique, but it's not going to be the one 928 00:43:03,570 --> 00:43:04,410 I use all the time. 929 00:43:04,410 --> 00:43:08,450 And we're not going to use this one all the time for what reason again? 930 00:43:08,450 --> 00:43:10,490 It's slower potentially if it's a long username. 931 00:43:10,490 --> 00:43:11,740 It's just a waste of time. 932 00:43:11,740 --> 00:43:16,140 >> INDEX, meanwhile, specifies that it's not going to be unique, but I'd like 933 00:43:16,140 --> 00:43:19,470 you to work your magic underneath the hood to make it faster for me to 934 00:43:19,470 --> 00:43:21,420 search on this field. 935 00:43:21,420 --> 00:43:23,320 So this probably isn't relevant here. 936 00:43:23,320 --> 00:43:26,500 For username, I'd argue that UNIQUE is a good answer. 937 00:43:26,500 --> 00:43:31,200 But suppose that we made users more interesting than just usernames, 938 00:43:31,200 --> 00:43:32,430 hashes, and ID numbers. 939 00:43:32,430 --> 00:43:33,860 What if we gave people full names? 940 00:43:33,860 --> 00:43:37,700 What if we gave them addresses and other data about them? 941 00:43:37,700 --> 00:43:43,360 >> Well, if you specify that a column in a database is indexed, that means that 942 00:43:43,360 --> 00:43:47,730 MySQL, or Oracle, or whatever database you're using, should work its magic 943 00:43:47,730 --> 00:43:51,300 and use some kind of fancy data structure like a tree, or a trie, or a 944 00:43:51,300 --> 00:43:55,940 hash table, or something to guarantee that when you search for data using 945 00:43:55,940 --> 00:43:58,150 select on that particular field-- 946 00:43:58,150 --> 00:44:01,310 like show me everyone that lives on Oxford Street. 947 00:44:01,310 --> 00:44:02,540 A query like that. 948 00:44:02,540 --> 00:44:06,250 If you have specified in advance that you want an index on that field, the 949 00:44:06,250 --> 00:44:09,050 searches will be much, much faster. 950 00:44:09,050 --> 00:44:12,090 >> If you don't specify an index, the best you can do is a linear search if 951 00:44:12,090 --> 00:44:13,030 it's not sorted. 952 00:44:13,030 --> 00:44:16,220 But if you specify INDEX, the smart people who made the database-- 953 00:44:16,220 --> 00:44:19,340 people like you who now know trees and tries and hash tables-- 954 00:44:19,340 --> 00:44:23,220 will automatically build such a data structure in RAM to make sure that 955 00:44:23,220 --> 00:44:26,050 those searches are much faster. 956 00:44:26,050 --> 00:44:29,660 >> FULLTEXT meanwhile is similar in spirit, but allows you to do wildcard 957 00:44:29,660 --> 00:44:35,480 searches, like show me everyone that lives at streets that begin with the 958 00:44:35,480 --> 00:44:36,960 letter O for whatever reason. 959 00:44:36,960 --> 00:44:38,850 You can do wildcard searches like that. 960 00:44:38,850 --> 00:44:45,880 Or, more compelling things like show me everyone who has the word-- 961 00:44:45,880 --> 00:44:49,400 show me everyone whose name starts with a particular letter. 962 00:44:49,400 --> 00:44:51,880 You can search for keywords in this way. 963 00:44:51,880 --> 00:44:52,630 All right. 964 00:44:52,630 --> 00:44:55,760 >> So, design opportunities there potentially. 965 00:44:55,760 --> 00:44:57,740 There are others that I'll wave my hands at. 966 00:44:57,740 --> 00:45:00,530 It turns out that you can have different storage engines. 967 00:45:00,530 --> 00:45:04,390 And this is more arcane than we need certainly for problem set seven. 968 00:45:04,390 --> 00:45:06,920 By default, you guys are using something called InnoDB. 969 00:45:06,920 --> 00:45:10,910 You'll see mention of this somewhere in phpMyAdmin's interface most likely. 970 00:45:10,910 --> 00:45:14,130 But know that there are other design decisions that are of potential 971 00:45:14,130 --> 00:45:18,030 interest come final projects if you do something web-based. 972 00:45:18,030 --> 00:45:19,330 >> But let's do this. 973 00:45:19,330 --> 00:45:23,130 Let's go ahead and put this on the screen as a teaser for a story 974 00:45:23,130 --> 00:45:26,330 involving you, a roommate, and a glass of milk. 975 00:45:26,330 --> 00:45:28,240 Let's take a two minute or so break here. 976 00:45:28,240 --> 00:45:31,060 And if you can stick around, let's come back, look a bit more at SQL, and 977 00:45:31,060 --> 00:45:35,160 then a bit of JavaScript with p-set eight in mind. 978 00:45:35,160 --> 00:45:36,120 >> All right. 979 00:45:36,120 --> 00:45:40,420 So, let's get you thinking about a corner case that can very easily arise 980 00:45:40,420 --> 00:45:44,240 in the context of using a database, or frankly, even using real world things 981 00:45:44,240 --> 00:45:46,280 like ATMs to get money. 982 00:45:46,280 --> 00:45:47,640 So here's a refrigerator. 983 00:45:47,640 --> 00:45:50,040 Suppose you've got one too in your dorm or your house. 984 00:45:50,040 --> 00:45:54,990 And you've got one roommate, and both of you really like milk for instance. 985 00:45:54,990 --> 00:45:57,210 >> So you come home from class one day. 986 00:45:57,210 --> 00:45:58,490 He or she's not yet back. 987 00:45:58,490 --> 00:45:59,180 You open the fridge. 988 00:45:59,180 --> 00:46:00,870 You really want a big glass of milk. 989 00:46:00,870 --> 00:46:01,820 There's no milk. 990 00:46:01,820 --> 00:46:02,920 So what do you do? 991 00:46:02,920 --> 00:46:03,840 You close the fridge. 992 00:46:03,840 --> 00:46:04,670 You grab your keys. 993 00:46:04,670 --> 00:46:05,930 You go out to the square. 994 00:46:05,930 --> 00:46:09,240 And you get in line at CVS at those self checkout things, which always 995 00:46:09,240 --> 00:46:11,180 take longer than actually having cashiers. 996 00:46:11,180 --> 00:46:11,820 Anyhow. 997 00:46:11,820 --> 00:46:15,490 >> So then, meanwhile, dot dot dot, your roommate comes home and he or she 998 00:46:15,490 --> 00:46:17,440 similarly has a hankering for some milk. 999 00:46:17,440 --> 00:46:20,380 So he or she opens the fridge, looks inside, and oh, damn. 1000 00:46:20,380 --> 00:46:21,160 No milk. 1001 00:46:21,160 --> 00:46:24,750 So he or she heads out, happens to go to the other CVS, which was only a 1002 00:46:24,750 --> 00:46:27,900 block away for some reason, and he or she gets in line to buy some milk. 1003 00:46:27,900 --> 00:46:30,480 >> Meanwhile, you come home, he or she comes home, and what do 1004 00:46:30,480 --> 00:46:31,980 you ultimately have? 1005 00:46:31,980 --> 00:46:33,080 Twice as much milk. 1006 00:46:33,080 --> 00:46:34,620 But you don't really like milk that much. 1007 00:46:34,620 --> 00:46:37,300 So now you have so much milk that now one of them is just going to go sour 1008 00:46:37,300 --> 00:46:37,820 eventually. 1009 00:46:37,820 --> 00:46:39,370 So this is a really bad problem. 1010 00:46:39,370 --> 00:46:39,900 Right? 1011 00:46:39,900 --> 00:46:41,990 >> So what has happened? 1012 00:46:41,990 --> 00:46:44,810 So fundamentally, this is kind of a ridiculous example. 1013 00:46:44,810 --> 00:46:48,580 But underneath the hood, what we've had happen here is both of you checked 1014 00:46:48,580 --> 00:46:52,390 the state of some piece of memory, the refrigerator. 1015 00:46:52,390 --> 00:46:54,420 Both of you checked the state of some variable. 1016 00:46:54,420 --> 00:46:57,360 You both drew a conclusion that you then acted on. 1017 00:46:57,360 --> 00:47:01,420 But unfortunately, while your roommate was at the store, the state of that 1018 00:47:01,420 --> 00:47:05,670 variable changed, he or she came back and now wants to change the state, but 1019 00:47:05,670 --> 00:47:07,480 it's already been changed on him or her. 1020 00:47:07,480 --> 00:47:11,120 And of course, he or she would not have gone to the store if they knew 1021 00:47:11,120 --> 00:47:13,010 that you were already en route. 1022 00:47:13,010 --> 00:47:16,430 >> So in the real world, how could you avoid this problem, assuming you have 1023 00:47:16,430 --> 00:47:18,940 a fridge, you have a roommate, and you actually like milk? 1024 00:47:18,940 --> 00:47:19,760 >> AUDIENCE: Communicating. 1025 00:47:19,760 --> 00:47:20,580 >> DAVID MALAN: Communicating. 1026 00:47:20,580 --> 00:47:21,160 OK. 1027 00:47:21,160 --> 00:47:22,500 But how might you communicate? 1028 00:47:22,500 --> 00:47:23,990 >> AUDIENCE: Leave a note. 1029 00:47:23,990 --> 00:47:25,480 >> DAVID MALAN: Leave a note, right? 1030 00:47:25,480 --> 00:47:28,025 Always leave a note, for fans of the show. 1031 00:47:28,025 --> 00:47:31,580 All right, so always leave a note, or put truly like a padlock or something 1032 00:47:31,580 --> 00:47:35,440 on the refrigerator that keeps your roommate from inspecting the state of 1033 00:47:35,440 --> 00:47:36,540 that variable. 1034 00:47:36,540 --> 00:47:40,800 >> Now, why might this be germane to problem set seven, or to ATMs. 1035 00:47:40,800 --> 00:47:46,780 Well, imagine a world in an ATM where you might be able to go up to an ATM 1036 00:47:46,780 --> 00:47:48,920 machine here, and another ATM here. 1037 00:47:48,920 --> 00:47:50,680 And this happens quite often. 1038 00:47:50,680 --> 00:47:54,150 And suppose you had two ATM cards, which is possible to obtain. 1039 00:47:54,150 --> 00:47:57,420 And you log into both machines effectively simultaneously, hopefully 1040 00:47:57,420 --> 00:47:58,660 while no one's looking. 1041 00:47:58,660 --> 00:48:01,260 And then you type in your PIN roughly simultaneously. 1042 00:48:01,260 --> 00:48:06,280 And then you do a balance query to see how much cash you have. 1043 00:48:06,280 --> 00:48:08,920 And let's say you have $100 left in your account. 1044 00:48:08,920 --> 00:48:13,310 So essentially simultaneously, you say one, zero, zero, enter. 1045 00:48:13,310 --> 00:48:16,000 And you hopefully get back some money. 1046 00:48:16,000 --> 00:48:18,440 >> But how much money might you get back? 1047 00:48:18,440 --> 00:48:21,710 Now computers at the end of the day, especially if they're talking to 1048 00:48:21,710 --> 00:48:27,360 servers, don't necessarily do things in the order that's expected. 1049 00:48:27,360 --> 00:48:30,860 >> So suppose what happens, because of whatever network speed issues there 1050 00:48:30,860 --> 00:48:34,530 are, or CPU issues there are, or anything like that, suppose that the 1051 00:48:34,530 --> 00:48:38,530 first ATM checks your balance and sees, oh, this person has $100. 1052 00:48:38,530 --> 00:48:41,840 But then gets distracted because maybe a backup is happening and so it's 1053 00:48:41,840 --> 00:48:42,500 slowing down. 1054 00:48:42,500 --> 00:48:45,080 Or maybe while checking, the network connection got a little slower because 1055 00:48:45,080 --> 00:48:45,910 this just happens. 1056 00:48:45,910 --> 00:48:47,100 They're physical devices. 1057 00:48:47,100 --> 00:48:49,330 So meanwhile, the second ATM is asking the same question. 1058 00:48:49,330 --> 00:48:53,030 How much money does David have? $100 is the answer. 1059 00:48:53,030 --> 00:48:58,930 But because the first ATM hasn't yet sent the message subtract $100, both 1060 00:48:58,930 --> 00:49:03,000 ATMs have inspected the bank's vault, seeing there's $100 there, and now 1061 00:49:03,000 --> 00:49:07,160 both machines potentially are going to spit out an answer. 1062 00:49:07,160 --> 00:49:12,240 >> Now, this is great for you in some sense if what the bank does ultimately 1063 00:49:12,240 --> 00:49:17,200 is change the amount to minus 100 by setting the variable equal to your 1064 00:49:17,200 --> 00:49:21,570 bank account equal to 0, as opposed to doing minus 100. 1065 00:49:21,570 --> 00:49:24,410 Now in the worst case for the bank-- 1066 00:49:24,410 --> 00:49:27,470 or in the best for the bank, meanwhile, they give you $200, and 1067 00:49:27,470 --> 00:49:31,690 your bank account now shows negative $100, which really doesn't 1068 00:49:31,690 --> 00:49:32,950 benefit you at all. 1069 00:49:32,950 --> 00:49:36,500 But the point is that this race condition for two roommates getting 1070 00:49:36,500 --> 00:49:40,660 milk, or for two ATMs trying to get cash and change the state of a vault 1071 00:49:40,660 --> 00:49:44,510 at the same time exists any time you have a database. 1072 00:49:44,510 --> 00:49:48,290 >> Now in problem set seven, this issue arises in the sense that if you buy a 1073 00:49:48,290 --> 00:49:52,110 share of Facebook stock, and then for instance you buy a second share of 1074 00:49:52,110 --> 00:49:55,160 Facebook stock, you need to make a decision as the programmer. 1075 00:49:55,160 --> 00:49:58,710 In order to decide how to update the database, odds are you're going to 1076 00:49:58,710 --> 00:50:02,250 have one row for that stock, and this is one way to implement it. 1077 00:50:02,250 --> 00:50:06,640 And you're going to have one share of FB, which is their stock ticker symbol 1078 00:50:06,640 --> 00:50:10,120 for this username, or this user ID, the unique identifier. 1079 00:50:10,120 --> 00:50:12,340 >> But the same story can happen here. 1080 00:50:12,340 --> 00:50:15,800 If you do a SELECT in SQL, as you'll see in problem set seven when you see, 1081 00:50:15,800 --> 00:50:18,460 oh, David has one share of Facebook stock. 1082 00:50:18,460 --> 00:50:23,240 Let me now change this to be two shares, because he wants to buy a 1083 00:50:23,240 --> 00:50:24,120 second share. 1084 00:50:24,120 --> 00:50:27,860 But suppose David actually had two browser windows open, or suppose that 1085 00:50:27,860 --> 00:50:32,150 it's a joint account with two spouses, and both of them are trying to perform 1086 00:50:32,150 --> 00:50:36,770 the same operation, there, too, the potential exists for a decision to be 1087 00:50:36,770 --> 00:50:39,670 made based on the previous state of the world-- 1088 00:50:39,670 --> 00:50:41,290 the account has one share-- 1089 00:50:41,290 --> 00:50:45,630 and both people, or both servers, now try to say increment it to two shares. 1090 00:50:45,630 --> 00:50:49,020 But in this case, you might have charged me money for both shares, but 1091 00:50:49,020 --> 00:50:50,830 incremented just that one time. 1092 00:50:50,830 --> 00:50:54,730 >> So in short, the fundamental problem here, as with the joke about leaving a 1093 00:50:54,730 --> 00:50:58,750 note, or putting a padlock on it, is if two people, or two threads-- 1094 00:50:58,750 --> 00:50:59,930 think back to scratch-- 1095 00:50:59,930 --> 00:51:03,220 can inspect the state of some variable and then try to change that variable, 1096 00:51:03,220 --> 00:51:07,950 but those two things don't happen at the same time but can get interrupted 1097 00:51:07,950 --> 00:51:11,500 by other things happening, data can get into a very weird state. 1098 00:51:11,500 --> 00:51:15,450 And you can benefit or you can suffer in the sense of the money example. 1099 00:51:15,450 --> 00:51:18,110 >> So in problem set seven, we give you this one line of code, which long 1100 00:51:18,110 --> 00:51:21,000 story short, solves this problem in MySQL. 1101 00:51:21,000 --> 00:51:24,950 This very long instruction that doesn't even fit onto one line on the 1102 00:51:24,950 --> 00:51:30,370 screen here ensures that your operation is what's called atomic. 1103 00:51:30,370 --> 00:51:33,720 It all happens at once, or it doesn't happen at all. 1104 00:51:33,720 --> 00:51:37,530 This very long phrase cannot get interrupted partially. 1105 00:51:37,530 --> 00:51:39,840 >> And what it does is literally what it says. 1106 00:51:39,840 --> 00:51:44,200 Insert into some table the following three fields those specific values, 1107 00:51:44,200 --> 00:51:47,280 but on duplicate key, don't do an insert. 1108 00:51:47,280 --> 00:51:48,280 Do an update. 1109 00:51:48,280 --> 00:51:52,450 So this is like doing a SELECT and an INSERT so to speak at the same time. 1110 00:51:52,450 --> 00:51:55,150 And what is the key that's probably being referred to here? 1111 00:51:55,150 --> 00:51:58,300 1112 00:51:58,300 --> 00:52:01,380 >> It turns out, and you'll see this in problem set seven's spec, because 1113 00:52:01,380 --> 00:52:06,040 we've declared there to be a unique key on this particular table such that 1114 00:52:06,040 --> 00:52:08,480 you can't have multiple rows for the same user with the 1115 00:52:08,480 --> 00:52:10,150 same penny stock symbol-- 1116 00:52:10,150 --> 00:52:13,780 in this example here, DVN.V is a silly penny stock that we 1117 00:52:13,780 --> 00:52:14,980 refer to in the spec. 1118 00:52:14,980 --> 00:52:17,860 Because we've declared it to be unique, what this means is that if you 1119 00:52:17,860 --> 00:52:23,580 try to insert a duplicate row, you're instead going to update it without 1120 00:52:23,580 --> 00:52:27,020 anyone else having a chance to change the state of the world either. 1121 00:52:27,020 --> 00:52:29,400 So in short, this ensures things are atomic. 1122 00:52:29,400 --> 00:52:32,530 >> More generally though, databases like MySQL-- 1123 00:52:32,530 --> 00:52:35,460 and you don't need this feature for p-set seven, but keep it in mind for 1124 00:52:35,460 --> 00:52:36,200 the future-- 1125 00:52:36,200 --> 00:52:38,870 support what are called transactions, where you can say 1126 00:52:38,870 --> 00:52:40,990 START TRANSACTION literally. 1127 00:52:40,990 --> 00:52:43,270 You can then execute two SQL statements. 1128 00:52:43,270 --> 00:52:45,710 And a SQL statement, as you'll see in p-set seven, looks a little 1129 00:52:45,710 --> 00:52:46,750 something like this. 1130 00:52:46,750 --> 00:52:48,820 Update a table called account. 1131 00:52:48,820 --> 00:52:52,550 Set the balance column equal to whatever the balance column currently 1132 00:52:52,550 --> 00:52:57,280 is minus 1,000 where the number, the account number, like the user ID, 1133 00:52:57,280 --> 00:53:00,830 equals 2, and then update account dot dot dot. 1134 00:53:00,830 --> 00:53:04,350 >> So in layman's terms, what do these two queries seem to be doing in the 1135 00:53:04,350 --> 00:53:05,840 real world sense of banking? 1136 00:53:05,840 --> 00:53:07,440 >> AUDIENCE: Transferring to savings. 1137 00:53:07,440 --> 00:53:08,020 >> DAVID MALAN: Exactly. 1138 00:53:08,020 --> 00:53:10,470 Transferring funds from one account to the other. 1139 00:53:10,470 --> 00:53:14,400 And this is another example where you really want these two things to happen 1140 00:53:14,400 --> 00:53:15,570 or not happen. 1141 00:53:15,570 --> 00:53:18,880 You don't want something to get in the middle of them and potentially mess up 1142 00:53:18,880 --> 00:53:22,220 the math, or mess up how much money you have, or how much 1143 00:53:22,220 --> 00:53:23,170 money the bank has. 1144 00:53:23,170 --> 00:53:26,890 So what's really nice about transactions in MySQL is that, and 1145 00:53:26,890 --> 00:53:30,160 databases more generally, is that they and smart people who've implemented 1146 00:53:30,160 --> 00:53:33,670 these features figure out how to make sure that both of those things happen 1147 00:53:33,670 --> 00:53:35,120 or not at all. 1148 00:53:35,120 --> 00:53:38,580 >> And if you are truly aspiring to make a website that's used by people on 1149 00:53:38,580 --> 00:53:41,490 campus, people in the real world, doing something in the startup sense, 1150 00:53:41,490 --> 00:53:43,300 these are the kinds of design decisions that 1151 00:53:43,300 --> 00:53:45,020 become ever so important. 1152 00:53:45,020 --> 00:53:48,240 Otherwise, you start to lose data, lose users, or in the worst case as 1153 00:53:48,240 --> 00:53:51,800 we've seen here, potentially lose money. 1154 00:53:51,800 --> 00:53:56,180 So again, more on that in problem set seven, as well as perhaps for some of 1155 00:53:56,180 --> 00:53:57,530 you in final projects. 1156 00:53:57,530 --> 00:54:01,870 >> So let's change that picture we had a moment ago just in one more way. 1157 00:54:01,870 --> 00:54:04,070 So let me actually see if I can-- 1158 00:54:04,070 --> 00:54:06,030 nope, that's gone. 1159 00:54:06,030 --> 00:54:06,690 There it is. 1160 00:54:06,690 --> 00:54:09,020 >> So this is where we left last time. 1161 00:54:09,020 --> 00:54:12,390 And it turns out we're going to toss one more thing into the mix here-- 1162 00:54:12,390 --> 00:54:14,510 a language called JavaScript. 1163 00:54:14,510 --> 00:54:18,060 So JavaScript actually fits into this piece-- 1164 00:54:18,060 --> 00:54:22,086 and I didn't quite leave enough room, so this is not now to scale. 1165 00:54:22,086 --> 00:54:23,900 OK, this is really pathetic. 1166 00:54:23,900 --> 00:54:27,075 OK, so that's JavaScript. 1167 00:54:27,075 --> 00:54:27,340 All right. 1168 00:54:27,340 --> 00:54:28,760 I'm really doing it a disservice. 1169 00:54:28,760 --> 00:54:29,390 All right. 1170 00:54:29,390 --> 00:54:34,790 >> So JavaScript is another programming language, and our last, If that helps 1171 00:54:34,790 --> 00:54:37,770 reassure that there's not much more of the fire hydrants here. 1172 00:54:37,770 --> 00:54:41,100 So JavaScript is also an interpreted language, which means you don't 1173 00:54:41,100 --> 00:54:42,670 compile it into zeros and ones. 1174 00:54:42,670 --> 00:54:43,690 You just run it. 1175 00:54:43,690 --> 00:54:47,680 But what's fundamentally different with JavaScript usually is that you 1176 00:54:47,680 --> 00:54:49,815 don't run it on your web server. 1177 00:54:49,815 --> 00:54:52,570 It doesn't get run in the appliance per se. 1178 00:54:52,570 --> 00:54:57,490 Rather, it gets downloaded by a user via HTTP into their browser-- 1179 00:54:57,490 --> 00:55:00,260 Chrome, Safari, Internet Explorer, Firefox, whatever-- 1180 00:55:00,260 --> 00:55:03,860 and it's the browser that executes this particular programming language. 1181 00:55:03,860 --> 00:55:08,000 >> So to be clear, PHP thus far has been executed either at the command line in 1182 00:55:08,000 --> 00:55:11,290 our black and white window, on a server like the appliance, a computer 1183 00:55:11,290 --> 00:55:14,490 like the appliance, or it's been executed by a web server 1184 00:55:14,490 --> 00:55:15,860 running on a computer. 1185 00:55:15,860 --> 00:55:20,490 But the theme here is that PHP thus far has been executed server-side, so 1186 00:55:20,490 --> 00:55:24,820 the user and the user's browser never sees a line of PHP code. 1187 00:55:24,820 --> 00:55:28,530 >> In fact, if you ever open a browser for your website or another and you 1188 00:55:28,530 --> 00:55:32,400 actually see PHP code in your window, someone has screwed up. 1189 00:55:32,400 --> 00:55:34,950 Because it's not meant to be sent to a browser directly. 1190 00:55:34,950 --> 00:55:38,150 It's supposed to be executed and turned into something like HTML. 1191 00:55:38,150 --> 00:55:40,120 >> But JavaScript is essentially the opposite. 1192 00:55:40,120 --> 00:55:44,350 It's meant to be run typically inside of a user's browser window. 1193 00:55:44,350 --> 00:55:46,840 And what kinds of websites use JavaScript then these days? 1194 00:55:46,840 --> 00:55:49,640 1195 00:55:49,640 --> 00:55:52,180 >> Like literally every popular website. 1196 00:55:52,180 --> 00:55:55,430 Every website that you guys probably use daily use JavaScript for the 1197 00:55:55,430 --> 00:55:57,330 simplest and even the sexiest features. 1198 00:55:57,330 --> 00:55:59,800 >> So something like Facebook Chat if you use that. 1199 00:55:59,800 --> 00:56:01,040 How does that actually work? 1200 00:56:01,040 --> 00:56:05,090 Well thus far, all of the stuff we've done with HTML and PHP assumes that 1201 00:56:05,090 --> 00:56:08,750 you pull up a URL, and you hit Enter, and you see some HTML content. 1202 00:56:08,750 --> 00:56:11,970 And you click the link, that changes the URL, changes the page, and reloads 1203 00:56:11,970 --> 00:56:12,740 some new content. 1204 00:56:12,740 --> 00:56:16,340 Click another URL or submit a form, you get whisked to another page and 1205 00:56:16,340 --> 00:56:17,420 you see some new content. 1206 00:56:17,420 --> 00:56:22,710 >> But using something like Facebook Chat, or Gchat, or Google Maps, rarely 1207 00:56:22,710 --> 00:56:27,350 does the whole page refresh such that you see a white screen momentarily and 1208 00:56:27,350 --> 00:56:28,470 then new content. 1209 00:56:28,470 --> 00:56:32,610 Rather, web pages today are dynamically getting updated again and 1210 00:56:32,610 --> 00:56:35,570 again and again all sort of behind the scenes. 1211 00:56:35,570 --> 00:56:38,560 And it turns out that when you do go to something like Facebook, or Gchat, 1212 00:56:38,560 --> 00:56:43,050 or Gmail, and the page updates automatically without reloading the 1213 00:56:43,050 --> 00:56:47,630 whole screen, what's happened is that your browser has made sort of secretly 1214 00:56:47,630 --> 00:56:49,410 additional HTTP requests-- 1215 00:56:49,410 --> 00:56:52,740 not for whole web pages, but just for little chunks of data, like the 1216 00:56:52,740 --> 00:56:55,740 instant message that your friend just sent you, or the status update that 1217 00:56:55,740 --> 00:56:58,210 someone just sent you, or the tweet that someone just sent. 1218 00:56:58,210 --> 00:57:02,120 It's just making little requests for data, and then using JavaScript, this 1219 00:57:02,120 --> 00:57:06,370 programming language, to change what the web page looks like without the 1220 00:57:06,370 --> 00:57:09,860 server helping, without the server generating that HTML. 1221 00:57:09,860 --> 00:57:13,820 >> So in short, JavaScript can be used then to not only fetch new data from 1222 00:57:13,820 --> 00:57:16,750 the server without reloading a whole page or submitting a form. 1223 00:57:16,750 --> 00:57:20,060 It can also be used to change the so-called DOM-- 1224 00:57:20,060 --> 00:57:21,520 document object model-- 1225 00:57:21,520 --> 00:57:24,620 which is just the fancy way for saying the tree of HTML 1226 00:57:24,620 --> 00:57:26,220 that we saw last time. 1227 00:57:26,220 --> 00:57:31,640 >> So to reassure, JavaScript is syntactically so similar to C as well. 1228 00:57:31,640 --> 00:57:32,820 There's no main function. 1229 00:57:32,820 --> 00:57:35,430 You just start writing the code and it will get executed, or 1230 00:57:35,430 --> 00:57:36,900 interpreted more properly. 1231 00:57:36,900 --> 00:57:38,660 Conditions will look like this. 1232 00:57:38,660 --> 00:57:41,230 No different from C or PHP for that matter. 1233 00:57:41,230 --> 00:57:43,890 Boolean expressions or-ed together will look like this. 1234 00:57:43,890 --> 00:57:45,590 Anded together look like this. 1235 00:57:45,590 --> 00:57:47,750 >> Switches will look like this. 1236 00:57:47,750 --> 00:57:49,440 For loops will look like this. 1237 00:57:49,440 --> 00:57:51,060 While loops will look like this. 1238 00:57:51,060 --> 00:57:53,316 Do while loops will look like this. 1239 00:57:53,316 --> 00:57:54,780 >> This is new. 1240 00:57:54,780 --> 00:57:58,753 So JavaScript has not a foreach construct per se, but this construct 1241 00:57:58,753 --> 00:58:03,870 for variable i in array, and i in this case becomes an index value. 1242 00:58:03,870 --> 00:58:06,880 So it's a little different from that foreach, though new versions of 1243 00:58:06,880 --> 00:58:10,280 JavaScript are coming out all the time, so even these language features 1244 00:58:10,280 --> 00:58:10,880 are evolving. 1245 00:58:10,880 --> 00:58:16,920 >> And as an aside, JavaScript these days can also be used on a server just like 1246 00:58:16,920 --> 00:58:19,920 PHP using a framework called Node.js. 1247 00:58:19,920 --> 00:58:24,670 One of CS50's TFs, Kevin, has led a seminar on Node.js that's available at 1248 00:58:24,670 --> 00:58:26,440 cs50.net/seminars. 1249 00:58:26,440 --> 00:58:28,830 So if you're curious, know that you can use this on the server side as 1250 00:58:28,830 --> 00:58:33,870 well, but that's a fairly recent trend, but a powerful one at that. 1251 00:58:33,870 --> 00:58:35,270 >> This is a little different. 1252 00:58:35,270 --> 00:58:37,910 This is an array in JavaScript. 1253 00:58:37,910 --> 00:58:40,115 And what strikes you as different versus C or PHP? 1254 00:58:40,115 --> 00:58:43,890 1255 00:58:43,890 --> 00:58:47,420 There are a few quick stories we can tell here. 1256 00:58:47,420 --> 00:58:49,367 What's missing versus PHP? 1257 00:58:49,367 --> 00:58:51,652 >> AUDIENCE: [INAUDIBLE]. 1258 00:58:51,652 --> 00:58:52,110 >> DAVID MALAN: Yes? 1259 00:58:52,110 --> 00:58:53,322 Sorry, say again? 1260 00:58:53,322 --> 00:58:54,740 >> AUDIENCE: Not declaring the type of variable. 1261 00:58:54,740 --> 00:58:56,390 >> DAVID MALAN: We're not declaring the type of variable. 1262 00:58:56,390 --> 00:58:59,630 So actually quite like PHP, we're not specifying the types of this variable. 1263 00:58:59,630 --> 00:59:02,670 Rather, we're more generically saying var for variable. 1264 00:59:02,670 --> 00:59:06,690 We don't have PHP's nuisance of the dollar sign, which while tedious to 1265 00:59:06,690 --> 00:59:09,160 type, does make more clear that something's a variable. 1266 00:59:09,160 --> 00:59:11,830 Whereas here, we're sort of back to C's approach by just calling a 1267 00:59:11,830 --> 00:59:14,500 variable by the name we want to give it, like numbers. 1268 00:59:14,500 --> 00:59:17,170 And also like PHP, we have square brackets for the 1269 00:59:17,170 --> 00:59:19,170 values inside that array. 1270 00:59:19,170 --> 00:59:22,490 >> So variables in JavaScript also might look like this. 1271 00:59:22,490 --> 00:59:26,900 Notice here this is a string called s, but similarly have we not specified 1272 00:59:26,900 --> 00:59:28,750 that it's a string. 1273 00:59:28,750 --> 00:59:33,160 Here though is a feature that doesn't exist in exactly the same way in PHP, 1274 00:59:33,160 --> 00:59:34,460 but a bit similarly. 1275 00:59:34,460 --> 00:59:36,530 This is an object in JavaScript. 1276 00:59:36,530 --> 00:59:42,110 And objects are sort of the Swiss Army Knife of a data structure in that you 1277 00:59:42,110 --> 00:59:43,900 can use them for any number of things. 1278 00:59:43,900 --> 00:59:46,860 >> Here, for instance, we're declaring a variable called quote. 1279 00:59:46,860 --> 00:59:49,110 The type of that variable is an object. 1280 00:59:49,110 --> 00:59:53,550 You can think of this as a C struct that has keys and values. 1281 00:59:53,550 --> 00:59:55,250 Symbol is a key. 1282 00:59:55,250 --> 00:59:57,350 FB is a value, apparently a stock symbol. 1283 00:59:57,350 --> 00:59:57,930 Comma. 1284 00:59:57,930 --> 01:00:02,180 Price is another key, and its value is apparently a floating point, or a 1285 01:00:02,180 --> 01:00:06,510 number more generally in JavaScript, of $49.26. 1286 01:00:06,510 --> 01:00:09,030 >> So PHP doesn't have-- 1287 01:00:09,030 --> 01:00:12,980 we haven't seen in PHP objects quite like this, but we did see an analog, 1288 01:00:12,980 --> 01:00:14,093 which was what? 1289 01:00:14,093 --> 01:00:14,980 >> AUDIENCE: [INAUDIBLE]. 1290 01:00:14,980 --> 01:00:16,110 >> DAVID MALAN: Associative arrays. 1291 01:00:16,110 --> 01:00:19,990 So whereas PHP has associative arrays whose syntax is ever slightly so 1292 01:00:19,990 --> 01:00:20,370 different-- 1293 01:00:20,370 --> 01:00:21,780 we saw the square brackets. 1294 01:00:21,780 --> 01:00:23,860 We saw the weird arrows symbols. 1295 01:00:23,860 --> 01:00:27,330 JavaScript has objects, but this is mostly a semantic difference and a 1296 01:00:27,330 --> 01:00:29,260 different synonym for now. 1297 01:00:29,260 --> 01:00:35,060 However, as an aside, PHP also has objects in a way that Java and other 1298 01:00:35,060 --> 01:00:37,810 languages have objects in object-oriented programming. 1299 01:00:37,810 --> 01:00:40,440 But we'll use these just for data types for now. 1300 01:00:40,440 --> 01:00:42,170 Objects and associative arrays. 1301 01:00:42,170 --> 01:00:44,140 >> This one might make it a little more clear. 1302 01:00:44,140 --> 01:00:45,890 Here's why an object is useful. 1303 01:00:45,890 --> 01:00:48,760 When you want to declare a student, like Zamyla, we can actually 1304 01:00:48,760 --> 01:00:52,630 encapsulate so to speak inside of that object using curly brackets just like 1305 01:00:52,630 --> 01:00:55,060 before a whole bunch of keys and values in here. 1306 01:00:55,060 --> 01:00:59,150 We have an ID, a house, and a name for Zamyla, followed by a semicolon as 1307 01:00:59,150 --> 01:01:00,690 usual at the end. 1308 01:01:00,690 --> 01:01:04,840 >> Down here too, this is slightly different, but also very powerful 1309 01:01:04,840 --> 01:01:05,690 these days. 1310 01:01:05,690 --> 01:01:08,780 Here's an array, and I know that because there's a square bracket up 1311 01:01:08,780 --> 01:01:11,090 top and a square bracket at the bottom. 1312 01:01:11,090 --> 01:01:16,050 And this is an array of what data type apparently in JavaScript? 1313 01:01:16,050 --> 01:01:21,260 This is an array of it looks like three objects. 1314 01:01:21,260 --> 01:01:24,580 And I know it's an object only because of the curly braces. 1315 01:01:24,580 --> 01:01:28,760 And notice there's open curly brace, some stuff, close curly brace, comma, 1316 01:01:28,760 --> 01:01:31,180 then some more, comma, and then some more. 1317 01:01:31,180 --> 01:01:33,800 So that's three arguments separated by two commas. 1318 01:01:33,800 --> 01:01:36,810 >> So this is an array of three objects. 1319 01:01:36,810 --> 01:01:39,940 And each of those objects appears to be a student or staff member of some 1320 01:01:39,940 --> 01:01:42,370 sort, each with an ID, house, and name. 1321 01:01:42,370 --> 01:01:45,060 But I've called this something called JSON-- 1322 01:01:45,060 --> 01:01:47,450 JavaScript Object Notation. 1323 01:01:47,450 --> 01:01:52,060 And this is a data format that actually is so very popular and in 1324 01:01:52,060 --> 01:01:55,100 vogue these days that if you write an application that uses the Facebook 1325 01:01:55,100 --> 01:01:59,150 API, the Twitter API, really almost any API out there these days, 1326 01:01:59,150 --> 01:02:02,820 including some of CS50's own, the data you get back is not in 1327 01:02:02,820 --> 01:02:04,720 old school CSV format. 1328 01:02:04,720 --> 01:02:06,780 >> Because recall that CSV is super simple. 1329 01:02:06,780 --> 01:02:10,230 It is just columns separated by commas. 1330 01:02:10,230 --> 01:02:13,190 JSON data gives you more metadata. 1331 01:02:13,190 --> 01:02:17,800 It associates a key with every value so they don't have to just assume that 1332 01:02:17,800 --> 01:02:22,460 the zeroth column is one value, column one is another, column two is another. 1333 01:02:22,460 --> 01:02:26,790 Everything in a JSON object here is sort of self-describing, because every 1334 01:02:26,790 --> 01:02:30,940 one of names in this file has literally name in front of it as a 1335 01:02:30,940 --> 01:02:32,510 quoted string. 1336 01:02:32,510 --> 01:02:34,950 >> So let's take a look at a couple of examples here. 1337 01:02:34,950 --> 01:02:36,800 Let me go into the appliance. 1338 01:02:36,800 --> 01:02:41,000 And let me go into our vhost directory into public. 1339 01:02:41,000 --> 01:02:45,590 And let me go into the JavaScript directory. 1340 01:02:45,590 --> 01:02:49,610 And let's go ahead and open up dom-0.html, where DOM just means 1341 01:02:49,610 --> 01:02:51,010 document object model. 1342 01:02:51,010 --> 01:02:53,490 It's the tree stuff to which I referred to earlier. 1343 01:02:53,490 --> 01:02:54,950 >> And let me propose the following. 1344 01:02:54,950 --> 01:02:57,720 Here's a web page whose body is pretty simple. 1345 01:02:57,720 --> 01:03:00,170 So down here at the bottom, notice I have a form. 1346 01:03:00,170 --> 01:03:01,500 We've seen those before. 1347 01:03:01,500 --> 01:03:07,600 It has two inputs, one of which has an ID of name, one of which has a type of 1348 01:03:07,600 --> 01:03:09,830 submit, and the first one's type is text. 1349 01:03:09,830 --> 01:03:11,900 So this actually sounds pretty simple. 1350 01:03:11,900 --> 01:03:13,090 >> Let's go here. 1351 01:03:13,090 --> 01:03:15,390 Let's go back to this page here. 1352 01:03:15,390 --> 01:03:21,030 Let's go into localhost, and go into our JavaScript directory, and go to 1353 01:03:21,030 --> 01:03:24,640 dom-0, and here we have this form. 1354 01:03:24,640 --> 01:03:26,550 So that's apparently all this page does. 1355 01:03:26,550 --> 01:03:28,740 It has a name field with a Submit button. 1356 01:03:28,740 --> 01:03:30,340 But I'm not going to use PHP here. 1357 01:03:30,340 --> 01:03:34,310 I'm going to do everything client side so to speak in JavaScript as follows. 1358 01:03:34,310 --> 01:03:39,100 >> Notice that I've indeed given the name field of this input a unique 1359 01:03:39,100 --> 01:03:42,350 identifier, which will actually save me some time in a moment. 1360 01:03:42,350 --> 01:03:45,480 And notice I've introduced another tag in the head of my web page, the 1361 01:03:45,480 --> 01:03:46,565 tag. 1362 01:03:46,565 --> 01:03:50,120 >> So it's in this sense that JavaScript is a client-side programming language. 1363 01:03:50,120 --> 01:03:55,020 In this case, just like CSS, I've put it straight inside of my HTML. 1364 01:03:55,020 --> 01:03:58,810 But notice I've declared a function that looks a little like PHP 1365 01:03:58,810 --> 01:04:01,530 syntactically, but this is actually JavaScript, because again, it's 1366 01:04:01,530 --> 01:04:03,920 client-side in the browser. 1367 01:04:03,920 --> 01:04:07,590 And take a guess what this is going to do, even though some of the syntax 1368 01:04:07,590 --> 01:04:09,338 here is new. 1369 01:04:09,338 --> 01:04:11,760 >> AUDIENCE: Say hello to whoever. 1370 01:04:11,760 --> 01:04:14,020 >> DAVID MALAN: It's going to say hello to whoever visits this page. 1371 01:04:14,020 --> 01:04:15,120 So how? 1372 01:04:15,120 --> 01:04:18,070 >> So notice, it turns out in JavaScript there's an alert() function. 1373 01:04:18,070 --> 01:04:22,840 This is a very sort of sad function that really just tends to annoy users. 1374 01:04:22,840 --> 01:04:25,440 It's not one you should really use typically, but it's a quick and dirty 1375 01:04:25,440 --> 01:04:27,710 way of sort of printing something to a graphical user 1376 01:04:27,710 --> 01:04:29,180 interface, like a browser. 1377 01:04:29,180 --> 01:04:31,400 Notice here that I've got a string in single quotes. 1378 01:04:31,400 --> 01:04:36,010 It turns out that unlike C, JavaScript can actually have you use single 1379 01:04:36,010 --> 01:04:38,730 quotes, and frankly it's just kind of the stylistic convention among 1380 01:04:38,730 --> 01:04:41,180 JavaScript programmers to use single quotes. 1381 01:04:41,180 --> 01:04:43,750 PHP, they actually have slightly different meaning. 1382 01:04:43,750 --> 01:04:45,810 But for now, just know that that's the only reason. 1383 01:04:45,810 --> 01:04:49,270 The convention in JavaScript is often to use single quotes, but we could use 1384 01:04:49,270 --> 01:04:50,950 double quotes in both places as well. 1385 01:04:50,950 --> 01:04:52,610 >> So this is interesting. 1386 01:04:52,610 --> 01:04:56,430 Recall last time that we had that picture on the screen that drew a tree 1387 01:04:56,430 --> 01:04:59,720 where you had the HTML node, and the head node, and the body node, 1388 01:04:59,720 --> 01:05:00,800 and then some text. 1389 01:05:00,800 --> 01:05:04,700 But there was one special node at the very top that I called the document. 1390 01:05:04,700 --> 01:05:08,260 Well, it turns out in JavaScript, any time you write a program in JavaScript 1391 01:05:08,260 --> 01:05:11,040 in a browser, you have access to a special global variable. 1392 01:05:11,040 --> 01:05:14,130 Similar in spirit to PHP's superglobals, this one is called in 1393 01:05:14,130 --> 01:05:16,050 all lowercase document. 1394 01:05:16,050 --> 01:05:21,480 >> It's like a struct, but this struct also has functions inside of it. 1395 01:05:21,480 --> 01:05:23,790 So a C struct just has data typically. 1396 01:05:23,790 --> 01:05:29,060 But a JavaScript object as this technically is also has functions, 1397 01:05:29,060 --> 01:05:31,830 otherwise known as methods, inside of it. 1398 01:05:31,830 --> 01:05:35,750 And you can call a function inside of this object quite literally doing its 1399 01:05:35,750 --> 01:05:39,610 name, dot, and then the name of the function, or again method. 1400 01:05:39,610 --> 01:05:41,160 It's just a synonym, really. 1401 01:05:41,160 --> 01:05:42,450 >> And what does this function do? 1402 01:05:42,450 --> 01:05:43,840 You can kind of guess from its name. 1403 01:05:43,840 --> 01:05:45,590 Get element by ID. 1404 01:05:45,590 --> 01:05:50,040 So this is going to search the web page, search that tree, looking for 1405 01:05:50,040 --> 01:05:55,210 whatever node, AKA element, has a unique ID of quote unquote name. 1406 01:05:55,210 --> 01:05:56,560 And then what am I going to do? 1407 01:05:56,560 --> 01:06:00,350 I'm going to get the value inside of that node in the tree, and I'm going 1408 01:06:00,350 --> 01:06:02,580 to somehow say hello to that name. 1409 01:06:02,580 --> 01:06:05,360 >> So take a guess, even though we've not seen this yet, what do the plus 1410 01:06:05,360 --> 01:06:07,396 symbols mean here and here probably? 1411 01:06:07,396 --> 01:06:08,230 >> AUDIENCE: Concatenate. 1412 01:06:08,230 --> 01:06:09,220 >> DAVID MALAN: Concatenate. 1413 01:06:09,220 --> 01:06:11,290 Right, and these are just sort of design decisions 1414 01:06:11,290 --> 01:06:12,280 people made years ago. 1415 01:06:12,280 --> 01:06:15,190 In PHP, you concatenate things with dots. 1416 01:06:15,190 --> 01:06:18,800 In C, you jump through several hoops and call functions like strcopy() or 1417 01:06:18,800 --> 01:06:20,600 strcat() or other such functions. 1418 01:06:20,600 --> 01:06:22,060 But in JavaScript, you use pluses. 1419 01:06:22,060 --> 01:06:24,770 So this is just concatenating three strings-- 1420 01:06:24,770 --> 01:06:27,850 hello, a name, and then an exclamation point. 1421 01:06:27,850 --> 01:06:30,390 >> So when and why is this function called though? 1422 01:06:30,390 --> 01:06:33,150 Well, take a guess from the HTML at the bottom. 1423 01:06:33,150 --> 01:06:35,810 Why is greet() called, or when? 1424 01:06:35,810 --> 01:06:39,730 1425 01:06:39,730 --> 01:06:44,030 >> Apparently, as best I can tell, on submit, when this form is submitted, 1426 01:06:44,030 --> 01:06:47,200 I'm going to do whatever is inside of these quotes. 1427 01:06:47,200 --> 01:06:50,900 And specifically, I'm going to call greet() and then return false. 1428 01:06:50,900 --> 01:06:53,090 >> Well, let's see what the net effect here is first. 1429 01:06:53,090 --> 01:06:58,290 So let me go ahead and type in, say, Loren, Submit. 1430 01:06:58,290 --> 01:06:59,440 Hello Loren. 1431 01:06:59,440 --> 01:07:02,990 Let's see if maybe this was just a lucky implementation. 1432 01:07:02,990 --> 01:07:03,200 Nope. 1433 01:07:03,200 --> 01:07:05,990 So it's typing out whatever name I actually put there. 1434 01:07:05,990 --> 01:07:07,970 >> But notice what's not changing. 1435 01:07:07,970 --> 01:07:10,360 The URL is still dom-0.html. 1436 01:07:10,360 --> 01:07:11,820 There's no register.php. 1437 01:07:11,820 --> 01:07:13,110 There's no second file. 1438 01:07:13,110 --> 01:07:14,930 There's no action attribute. 1439 01:07:14,930 --> 01:07:19,720 So what is this return false presumably doing? 1440 01:07:19,720 --> 01:07:23,660 Why am I calling greet() and then returning false probably? 1441 01:07:23,660 --> 01:07:26,420 What normally happens when you click Submit on a form that even we have 1442 01:07:26,420 --> 01:07:27,854 seen in the past week? 1443 01:07:27,854 --> 01:07:29,900 >> AUDIENCE: [INAUDIBLE]. 1444 01:07:29,900 --> 01:07:30,860 >> DAVID MALAN: It goes somewhere, right? 1445 01:07:30,860 --> 01:07:32,720 It goes to some destination URL. 1446 01:07:32,720 --> 01:07:34,120 But I don't want that to happen here. 1447 01:07:34,120 --> 01:07:37,620 I want my web page to be completely dynamic like Gmail, where once you're 1448 01:07:37,620 --> 01:07:38,650 there, you stay there. 1449 01:07:38,650 --> 01:07:42,900 The URL doesn't change in a way that indicates the whole page is reloading. 1450 01:07:42,900 --> 01:07:46,680 Rather, I just want to change something like printing out something 1451 01:07:46,680 --> 01:07:48,320 here on the screen. 1452 01:07:48,320 --> 01:07:49,630 >> Well let me clean this up a little bit. 1453 01:07:49,630 --> 01:07:55,370 Let me open up not dom-0, but let me open up dom-2. 1454 01:07:55,370 --> 01:07:57,350 Just so you've seen some syntax here. 1455 01:07:57,350 --> 01:08:02,080 >> It turns out that what we just did is using raw JavaScript. 1456 01:08:02,080 --> 01:08:04,420 So this is truly the language JavaScript. 1457 01:08:04,420 --> 01:08:07,340 Some of you might know of a library called jQuery. 1458 01:08:07,340 --> 01:08:09,980 >> So jQuery is not the same thing as JavaScript. 1459 01:08:09,980 --> 01:08:14,110 It's just a library that a really smart guy wrote and popularized such 1460 01:08:14,110 --> 01:08:18,100 that almost everyone in the world now uses jQuery when using JavaScript. 1461 01:08:18,100 --> 01:08:20,890 And at first glance, honestly, it looks a little more cryptic. 1462 01:08:20,890 --> 01:08:24,990 But you'll find, especially if you go there for your final project with web 1463 01:08:24,990 --> 01:08:29,029 development, you'll find that this cleans things up and saves you quite a 1464 01:08:29,029 --> 01:08:30,229 few lines of code. 1465 01:08:30,229 --> 01:08:33,189 >> So let's just glance at how this form is working. 1466 01:08:33,189 --> 01:08:35,664 Notice what did I remove apparently from my HTML? 1467 01:08:35,664 --> 01:08:38,240 1468 01:08:38,240 --> 01:08:40,630 There's no on submit handler so to speak. 1469 01:08:40,630 --> 01:08:41,470 There's no attribute. 1470 01:08:41,470 --> 01:08:43,359 Because you know, what I didn't really like? 1471 01:08:43,359 --> 01:08:45,640 I felt like we were falling into old habits there. 1472 01:08:45,640 --> 01:08:49,340 Just like it was starting to feel sloppy to intermingle both CSS with 1473 01:08:49,340 --> 01:08:52,149 HTML, because you're kind of throwing different languages all over the 1474 01:08:52,149 --> 01:08:56,180 place, similarly did this start to feel like a bad road to go down where 1475 01:08:56,180 --> 01:09:01,069 I'm putting JavaScript code inside of my HTML rather than factoring it out. 1476 01:09:01,069 --> 01:09:02,279 >> So that's the lesson here. 1477 01:09:02,279 --> 01:09:05,080 In dom-2.html, I'm factoring it out. 1478 01:09:05,080 --> 01:09:07,399 And I'm doing things slightly differently. 1479 01:09:07,399 --> 01:09:09,630 For now, I'm going to wave my hands at what this really does 1480 01:09:09,630 --> 01:09:10,590 underneath the hood. 1481 01:09:10,590 --> 01:09:14,210 But just for now assume that that first line of code in this library 1482 01:09:14,210 --> 01:09:18,170 called jQuery just means when the document is ready, do the following. 1483 01:09:18,170 --> 01:09:20,080 >> Because web pages can take some time to load. 1484 01:09:20,080 --> 01:09:23,029 You might be on a slow internet connection, and it might be spinning 1485 01:09:23,029 --> 01:09:25,290 and spinning, and finally it's loaded. 1486 01:09:25,290 --> 01:09:29,060 That line of code just says wait until the whole page is ready, the document 1487 01:09:29,060 --> 01:09:31,189 is ready, before executing this code. 1488 01:09:31,189 --> 01:09:34,390 >> And now notice, this is probably the most useful first 1489 01:09:34,390 --> 01:09:36,189 take away from jQuery. 1490 01:09:36,189 --> 01:09:42,140 This line here is very similar in spirit to this much longer line here. 1491 01:09:42,140 --> 01:09:46,920 Whereas in raw JavaScript code, there exists a document global object that 1492 01:09:46,920 --> 01:09:50,460 has a function called getElementById(), the people who wrote 1493 01:09:50,460 --> 01:09:55,720 jQuery simplified that to just say dollar sign, and then inside of 1494 01:09:55,720 --> 01:10:00,250 parentheses put two quotes, and then put a hash symbol followed by the 1495 01:10:00,250 --> 01:10:02,250 unique ID you want to grab. 1496 01:10:02,250 --> 01:10:06,170 So this is equivalent to document.getElementById. 1497 01:10:06,170 --> 01:10:11,090 >> Meanwhile, .submit just means on submission of whatever form you're 1498 01:10:11,090 --> 01:10:14,240 referring to on the left, go ahead and execute this. 1499 01:10:14,240 --> 01:10:16,600 But this is now the curiosity too. 1500 01:10:16,600 --> 01:10:19,560 What's weird about what I've highlighted here? 1501 01:10:19,560 --> 01:10:23,840 1502 01:10:23,840 --> 01:10:28,594 Not only is it kind of syntactically new, there's also something missing. 1503 01:10:28,594 --> 01:10:29,558 >> AUDIENCE: It's just called function? 1504 01:10:29,558 --> 01:10:31,970 It's not called alert? 1505 01:10:31,970 --> 01:10:32,440 >> DAVID MALAN: Yeah. 1506 01:10:32,440 --> 01:10:35,450 Well, so alert() is down here, to be fair. 1507 01:10:35,450 --> 01:10:39,520 But there is no mention of a name, like you know, foo or 1508 01:10:39,520 --> 01:10:40,980 something up here. 1509 01:10:40,980 --> 01:10:43,830 And indeed, this is one of the features of JavaScript that's quite 1510 01:10:43,830 --> 01:10:45,370 powerful, but also quite new. 1511 01:10:45,370 --> 01:10:47,460 And PHP actually has this as well. 1512 01:10:47,460 --> 01:10:49,500 >> Let me go ahead and do something real quick. 1513 01:10:49,500 --> 01:10:52,030 Let me go ahead and put this out here. 1514 01:10:52,030 --> 01:10:52,600 Let me do this. 1515 01:10:52,600 --> 01:10:53,690 Function. 1516 01:10:53,690 --> 01:10:56,455 Let's call this handler(). 1517 01:10:56,455 --> 01:10:58,290 A handler function so to speak. 1518 01:10:58,290 --> 01:11:00,110 Something that handles some operation. 1519 01:11:00,110 --> 01:11:02,700 Let me clean up my indentation. 1520 01:11:02,700 --> 01:11:04,380 And put this here. 1521 01:11:04,380 --> 01:11:06,090 And put that here. 1522 01:11:06,090 --> 01:11:06,470 Yep. 1523 01:11:06,470 --> 01:11:07,060 OK. 1524 01:11:07,060 --> 01:11:10,300 >> So now I have a function called handler() that I don't really know 1525 01:11:10,300 --> 01:11:10,890 what it does yet. 1526 01:11:10,890 --> 01:11:12,710 It just still has that stuff. 1527 01:11:12,710 --> 01:11:13,900 Whoops. 1528 01:11:13,900 --> 01:11:15,820 Took too much. 1529 01:11:15,820 --> 01:11:18,490 Let's do this. 1530 01:11:18,490 --> 01:11:18,990 All right. 1531 01:11:18,990 --> 01:11:20,240 Sorry. 1532 01:11:20,240 --> 01:11:23,140 1533 01:11:23,140 --> 01:11:23,690 All right. 1534 01:11:23,690 --> 01:11:24,720 Let me do this. 1535 01:11:24,720 --> 01:11:25,020 OK. 1536 01:11:25,020 --> 01:11:27,040 That looks nice and straight forward now. 1537 01:11:27,040 --> 01:11:29,090 Let me do this. 1538 01:11:29,090 --> 01:11:29,860 Do this. 1539 01:11:29,860 --> 01:11:30,950 And OK. 1540 01:11:30,950 --> 01:11:33,080 So now, let's put this over here. 1541 01:11:33,080 --> 01:11:35,840 1542 01:11:35,840 --> 01:11:37,270 No more programming on the fly. 1543 01:11:37,270 --> 01:11:37,900 OK. 1544 01:11:37,900 --> 01:11:40,000 >> So now, let's go back to where the story began. 1545 01:11:40,000 --> 01:11:43,530 Previously, I said that this line here means when the document is ready, go 1546 01:11:43,530 --> 01:11:44,380 ahead and do this. 1547 01:11:44,380 --> 01:11:45,660 What do I want to do? 1548 01:11:45,660 --> 01:11:49,070 Well specifically, I want to go ahead and do the following. 1549 01:11:49,070 --> 01:11:53,700 Execute this line of code, and then what I want you to do is call this 1550 01:11:53,700 --> 01:11:56,370 function when the form is submitted. 1551 01:11:56,370 --> 01:11:57,730 >> Now this is what's interesting. 1552 01:11:57,730 --> 01:11:59,170 This is not itself a function. 1553 01:11:59,170 --> 01:12:02,540 Notice I am not putting parentheses here in the normal way. 1554 01:12:02,540 --> 01:12:06,800 I'm literally passing a function called handler() to another function 1555 01:12:06,800 --> 01:12:10,800 called submit() as an argument as though it's like a variable. 1556 01:12:10,800 --> 01:12:14,290 And this is one of the features of JavaScript, is functions themselves 1557 01:12:14,290 --> 01:12:15,710 are really just objects. 1558 01:12:15,710 --> 01:12:18,350 In fact, they're really just variables of some sort. 1559 01:12:18,350 --> 01:12:21,340 And if the name of the function is handler(), there is no reason I can't 1560 01:12:21,340 --> 01:12:23,390 pass it in as an argument here. 1561 01:12:23,390 --> 01:12:27,530 And this means when the form with the ID of demo is 1562 01:12:27,530 --> 01:12:29,320 submitted, call this function. 1563 01:12:29,320 --> 01:12:32,770 >> But now if I undo all of this, why then did I perhaps do 1564 01:12:32,770 --> 01:12:34,850 this a moment ago? 1565 01:12:34,850 --> 01:12:36,840 Well, this is an anonymous function. 1566 01:12:36,840 --> 01:12:41,080 Because frankly, I realized why am I bothering to waste time declaring a 1567 01:12:41,080 --> 01:12:45,540 function called handler() only to call it in one and only one place? 1568 01:12:45,540 --> 01:12:48,640 If I don't need the name, and I don't need to call it more than one place, 1569 01:12:48,640 --> 01:12:51,200 let's just implement the function right where I need it. 1570 01:12:51,200 --> 01:12:55,190 And so JavaScript and PHP support what are called anonymous functions that 1571 01:12:55,190 --> 01:12:57,900 allow me to do exactly that here. 1572 01:12:57,900 --> 01:12:59,570 >> But we're just scratching the surface. 1573 01:12:59,570 --> 01:13:02,430 Let's tease with just a couple final examples here. 1574 01:13:02,430 --> 01:13:04,600 >> If I go into quote.php. 1575 01:13:04,600 --> 01:13:07,160 1576 01:13:07,160 --> 01:13:11,870 Notice that this is actually a PHP function, a PHP program, that I wrote 1577 01:13:11,870 --> 01:13:15,270 that expects an HTTP parameter called symbol, and I can pass in 1578 01:13:15,270 --> 01:13:16,730 a value like FB. 1579 01:13:16,730 --> 01:13:20,010 And if we actually look at the source code, this is querying a free website 1580 01:13:20,010 --> 01:13:23,680 called Yahoo Finance, just like p-set seven, and it's returning to me 1581 01:13:23,680 --> 01:13:26,580 something in apparently the format known is JSON-- 1582 01:13:26,580 --> 01:13:28,010 JavaScript Object Notation. 1583 01:13:28,010 --> 01:13:28,810 It's just an object. 1584 01:13:28,810 --> 01:13:32,500 Notice the curly braces, the quotes, the colon, and the commas. 1585 01:13:32,500 --> 01:13:34,720 >> Now meanwhile, this is pretty cool. 1586 01:13:34,720 --> 01:13:38,520 Because I can probably use a programming language to generate URLs 1587 01:13:38,520 --> 01:13:40,370 that look like this dynamically, right? 1588 01:13:40,370 --> 01:13:43,340 I can change this to Google and get back Google's 1589 01:13:43,340 --> 01:13:47,930 stock price of $1,017.55. 1590 01:13:47,930 --> 01:13:49,640 So let's see if we can't use this now. 1591 01:13:49,640 --> 01:13:56,590 >> Let me go to ajax-0 here, which looks like the following. 1592 01:13:56,590 --> 01:13:59,750 It's just a website that has a form with a button. 1593 01:13:59,750 --> 01:14:05,860 Let me here go ahead and type in YHOO for Yahoo's stock symbol, click Get 1594 01:14:05,860 --> 01:14:10,530 Quote, and now notice I've gotten an alert with 32.86. 1595 01:14:10,530 --> 01:14:14,050 >> Let me actually go to a fancier version of this page, version two, and 1596 01:14:14,050 --> 01:14:17,530 type in let's say Microsoft, MSFT. 1597 01:14:17,530 --> 01:14:18,410 Get Quote. 1598 01:14:18,410 --> 01:14:19,850 And now notice, no alert. 1599 01:14:19,850 --> 01:14:22,770 Notice where it says price to be determined? 1600 01:14:22,770 --> 01:14:27,060 There is the simplest of examples that hints at what Gchat, and Facebook 1601 01:14:27,060 --> 01:14:30,070 Chat, and Gmail, and other such websites are doing by actually 1602 01:14:30,070 --> 01:14:31,290 changing the web page. 1603 01:14:31,290 --> 01:14:31,800 >> Notice this. 1604 01:14:31,800 --> 01:14:33,120 Let me reload the page. 1605 01:14:33,120 --> 01:14:35,080 Let me open up Chrome's Inspector. 1606 01:14:35,080 --> 01:14:36,890 Let me go to the elements tab down here. 1607 01:14:36,890 --> 01:14:42,310 Now notice if I zoom in down here and open this up, notice that this is my 1608 01:14:42,310 --> 01:14:44,500 HTML DOM-- my document object model. 1609 01:14:44,500 --> 01:14:45,920 This is my HTML. 1610 01:14:45,920 --> 01:14:48,750 But now notice, even though it's going to be a little hard to see it in both 1611 01:14:48,750 --> 01:14:52,080 places at once, if I type in FB up here, watch the bottom 1612 01:14:52,080 --> 01:14:54,110 of the screen only. 1613 01:14:54,110 --> 01:14:57,720 >> It's actually changing my HTML on the fly. 1614 01:14:57,720 --> 01:15:01,670 And it's doing this quite simply by doing something like this. 1615 01:15:01,670 --> 01:15:06,800 If I open up ajax-2, notice implementing something as sexy as 1616 01:15:06,800 --> 01:15:09,560 that, even though it's pretty ugly, but as sophisticated as that 1617 01:15:09,560 --> 01:15:11,910 functionally, it has some HTML at the bottom. 1618 01:15:11,910 --> 01:15:13,810 But notice I used to tag. 1619 01:15:13,810 --> 01:15:16,640 We've not used this before, but this is like a , but it doesn't force 1620 01:15:16,640 --> 01:15:17,840 everything onto a new line. 1621 01:15:17,840 --> 01:15:20,830 It just makes a rectangular region on the same line essentially. 1622 01:15:20,830 --> 01:15:22,870 >> Notice that I gave it an ID of price. 1623 01:15:22,870 --> 01:15:26,800 And it turns out by using the same JavaScript library, I have a function 1624 01:15:26,800 --> 01:15:30,440 called quote() that's called whenever the form is submitted. 1625 01:15:30,440 --> 01:15:31,800 And what I'm doing is this. 1626 01:15:31,800 --> 01:15:35,730 I'm declaring a variable in JavaScript called url, saving the value 1627 01:15:35,730 --> 01:15:38,650 quote.php?symbol=. 1628 01:15:38,650 --> 01:15:44,220 In other words, I myself am beginning to prepare an HTTP request, and then 1629 01:15:44,220 --> 01:15:49,250 I'm concatenating onto that with a plus whatever the element with the ID 1630 01:15:49,250 --> 01:15:54,190 of symbol is, which notice is that text field right down here. 1631 01:15:54,190 --> 01:15:56,630 So just like we had forms in the past. 1632 01:15:56,630 --> 01:16:01,450 >> And then it turns out in jQuery, if you call .val(), that calls of a val 1633 01:16:01,450 --> 01:16:05,900 function, a value function, that gets whatever the user has typed in. 1634 01:16:05,900 --> 01:16:08,920 And then all of the network traffic that happens is this. 1635 01:16:08,920 --> 01:16:11,230 $.getJSON. 1636 01:16:11,230 --> 01:16:13,720 >> And as an aside, dollar sign is just a shorthand notation. 1637 01:16:13,720 --> 01:16:16,860 It's really jQuery.getJSON. 1638 01:16:16,860 --> 01:16:21,520 Get me to JSON from this URL, and when the request comes back, call this 1639 01:16:21,520 --> 01:16:26,550 function and pass in as the argument whatever came back from the server. 1640 01:16:26,550 --> 01:16:31,205 >> So in other words, if I go back to the browser, and I go back to quote.php, 1641 01:16:31,205 --> 01:16:35,590 what my browser is doing is getting this chunk of data. 1642 01:16:35,590 --> 01:16:38,930 And when I go to this web page here, notice if we instead go to the network 1643 01:16:38,930 --> 01:16:43,820 tab and clear it, and then type in something like GOOG for Google and Get 1644 01:16:43,820 --> 01:16:46,340 Quote, notice the page didn't change. 1645 01:16:46,340 --> 01:16:50,990 But an HTTP request was made, and what came back here if we look at the 1646 01:16:50,990 --> 01:16:56,130 response is a whole bunch of JSON that we accessed finally with 1647 01:16:56,130 --> 01:16:58,070 this simple line here. 1648 01:16:58,070 --> 01:17:00,150 >> Data is what was gotten from the server. 1649 01:17:00,150 --> 01:17:02,120 Price is the name of the key I care about. 1650 01:17:02,120 --> 01:17:05,230 So data.price gives me that. 1651 01:17:05,230 --> 01:17:07,540 >> Now meanwhile, and this is the last example. 1652 01:17:07,540 --> 01:17:09,280 You can do yet more with the page. 1653 01:17:09,280 --> 01:17:12,440 One actually, well two. 1654 01:17:12,440 --> 01:17:14,780 We can bring back the tag, if you remember this. 1655 01:17:14,780 --> 01:17:15,850 That's JavaScript. 1656 01:17:15,850 --> 01:17:17,110 We can do that. 1657 01:17:17,110 --> 01:17:17,690 Very exciting. 1658 01:17:17,690 --> 01:17:18,800 We'll leave that as a cliffhanger. 1659 01:17:18,800 --> 01:17:21,590 >> But more excitingly, you can do things like this. 1660 01:17:21,590 --> 01:17:25,940 If I go to geolocation-1, it turns out that Chrome knows that we are at 1661 01:17:25,940 --> 01:17:30,672 latitude longitude 42.37 .-71.10. 1662 01:17:30,672 --> 01:17:32,940 So there's even more there at your disposal. 1663 01:17:32,940 --> 01:17:34,290 But more on that next week. 1664 01:17:34,290 --> 01:17:35,540 See you Monday. 1665 01:17:35,540 --> 01:17:37,558