1 00:00:00,000 --> 00:00:03,486 [MUSIC PLAYING] 2 00:00:03,486 --> 00:00:48,807 3 00:00:48,807 --> 00:00:49,890 DAVID J. MALAN: All right. 4 00:00:49,890 --> 00:00:54,365 So this CS50, and this is week eight, the week of all Hallows' Eve. 5 00:00:54,365 --> 00:00:57,240 Indeed, thanks to our friends here in the American Repertory Theater, 6 00:00:57,240 --> 00:01:00,720 the stage looks amazing today with some special lighting 7 00:01:00,720 --> 00:01:02,280 and some special characters. 8 00:01:02,280 --> 00:01:04,410 Of course, speaking of characters, this past week 9 00:01:04,410 --> 00:01:08,400 you all explored 50-ville for the very first time, looking for the rubber 10 00:01:08,400 --> 00:01:09,720 duck that had gone missing. 11 00:01:09,720 --> 00:01:12,600 And thankfully, the culprits have been found, 12 00:01:12,600 --> 00:01:18,690 and allow me to say that a little someone would like to say hello. 13 00:01:18,690 --> 00:01:21,750 Yes, even he has rather dressed up for the occasion, 14 00:01:21,750 --> 00:01:24,400 but thank you for all the hard work there. 15 00:01:24,400 --> 00:01:28,080 So this week, of course, we transition to the world of web programming, 16 00:01:28,080 --> 00:01:30,368 the motivation being that for the past many weeks, 17 00:01:30,368 --> 00:01:32,160 pretty much all of the code we have written 18 00:01:32,160 --> 00:01:35,897 has been focused on command line programs, compiling your code, 19 00:01:35,897 --> 00:01:38,730 interpreting your code, but generally just interacting with a fairly 20 00:01:38,730 --> 00:01:41,970 mundane blinking prompt, textually. 21 00:01:41,970 --> 00:01:44,550 But of course, the software that you and I use every day 22 00:01:44,550 --> 00:01:48,630 these days is in the form of laptops and desktops in browsers 23 00:01:48,630 --> 00:01:53,370 or on mobile devices or apps, and today, we begin to transition 24 00:01:53,370 --> 00:01:55,860 to a set of languages and a set of technologies 25 00:01:55,860 --> 00:01:59,340 via which you can start to apply all of the past week's knowledge 26 00:01:59,340 --> 00:02:02,670 and mental models for procedural programming 27 00:02:02,670 --> 00:02:05,872 to a much more familiar, a much more graphical domain. 28 00:02:05,872 --> 00:02:08,039 Indeed, over the course of the next couple of weeks, 29 00:02:08,039 --> 00:02:11,400 we'll be focused on web programming and the use of languages 30 00:02:11,400 --> 00:02:15,780 called HTML and CSS and JavaScript, with which today's websites are made, 31 00:02:15,780 --> 00:02:19,740 and increasingly with which today's mobile applications or apps 32 00:02:19,740 --> 00:02:22,090 on your phone are made as well. 33 00:02:22,090 --> 00:02:24,270 But in order to get to that point in the story, 34 00:02:24,270 --> 00:02:27,840 we need to consider what the framework is 35 00:02:27,840 --> 00:02:31,920 on top of which we're going to run these websites or these web applications. 36 00:02:31,920 --> 00:02:34,200 And so that invites the question of the internet. 37 00:02:34,200 --> 00:02:36,180 Exactly what is the internet? 38 00:02:36,180 --> 00:02:39,600 All of us use it every day, but let's take a couple of volunteers 39 00:02:39,600 --> 00:02:44,940 from the audience, just to define for us what we mean by the internet. 40 00:02:44,940 --> 00:02:47,760 All of us are literally on the internet right now, 41 00:02:47,760 --> 00:02:52,600 but if you take a step back and think about it, what is the internet? 42 00:02:52,600 --> 00:02:56,470 How might you define it for someone less technical than you 43 00:02:56,470 --> 00:02:58,360 or someone less familiar? 44 00:02:58,360 --> 00:03:00,060 Sophia, how would you define it? 45 00:03:00,060 --> 00:03:01,810 AUDIENCE: The network of all the computers 46 00:03:01,810 --> 00:03:05,320 around the world that are taking in information from the network 47 00:03:05,320 --> 00:03:06,880 and also giving it information. 48 00:03:06,880 --> 00:03:07,880 DAVID J. MALAN: Perfect. 49 00:03:07,880 --> 00:03:09,710 The internet is this network of networks, 50 00:03:09,710 --> 00:03:12,610 so if you have a small network in your home, a small network 51 00:03:12,610 --> 00:03:15,010 or a large network at your company or you university 52 00:03:15,010 --> 00:03:18,040 and you start to interconnect all of those networks using cables 53 00:03:18,040 --> 00:03:22,090 or some kind of wireless technology, you get the internet, so to speak, 54 00:03:22,090 --> 00:03:23,690 a network of networks. 55 00:03:23,690 --> 00:03:26,620 And this is really the infrastructure, if you will, 56 00:03:26,620 --> 00:03:29,690 on top of which all of today's applications are run. 57 00:03:29,690 --> 00:03:33,100 So when you use the web, when you use chat, when you use Slack, 58 00:03:33,100 --> 00:03:36,400 when you use video conferencing, Zoom or the like, you're using the internet, 59 00:03:36,400 --> 00:03:39,430 but think of the internet really as the lower-level plumbing that 60 00:03:39,430 --> 00:03:42,910 gets the zeros and ones from you to someone else and back, 61 00:03:42,910 --> 00:03:45,340 and the applications on top of that are all 62 00:03:45,340 --> 00:03:47,410 implemented, ultimately, in software. 63 00:03:47,410 --> 00:03:50,500 And so if we consider, then, that we've got all of these computers 64 00:03:50,500 --> 00:03:52,810 interconnected somehow, it stands to reason 65 00:03:52,810 --> 00:03:55,570 that we need to somehow decide as a global community 66 00:03:55,570 --> 00:03:59,390 how to get data from point A to point B and beyond. 67 00:03:59,390 --> 00:04:03,258 And so throughout the internet are these computers called routers. 68 00:04:03,258 --> 00:04:05,050 And at the end of the day, they're probably 69 00:04:05,050 --> 00:04:07,750 a little bigger than the desktops and laptops with which you and I are 70 00:04:07,750 --> 00:04:09,583 familiar, but at the end of the day, they're 71 00:04:09,583 --> 00:04:13,390 the same kinds of devices with CPUs, Central Processing Units, the brains 72 00:04:13,390 --> 00:04:15,850 inside of the computer that do all the thinking, 73 00:04:15,850 --> 00:04:18,610 RAM or memory, where all of the values are stored, 74 00:04:18,610 --> 00:04:20,829 and hard disks, where data is persisted. 75 00:04:20,829 --> 00:04:23,320 And pictured here, for instance, is an image from MIT 76 00:04:23,320 --> 00:04:27,943 that depicted a few years back of what-- some of the most significant peering 77 00:04:27,943 --> 00:04:30,110 points on the internet throughout the United States. 78 00:04:30,110 --> 00:04:33,670 So each of the red dots here represents essentially one router 79 00:04:33,670 --> 00:04:36,880 or one very important place into which a lot of cables 80 00:04:36,880 --> 00:04:40,752 come in and then go out and interconnect all points of the country. 81 00:04:40,752 --> 00:04:43,210 And then this story continues well beyond the United States 82 00:04:43,210 --> 00:04:46,570 these days using oceanic cables and other wireless 83 00:04:46,570 --> 00:04:48,320 or satellite technologies or the like. 84 00:04:48,320 --> 00:04:52,510 So suffice it to say, there's this mesh, this interconnection 85 00:04:52,510 --> 00:04:56,680 of all of these different computers and in turn networks throughout the world, 86 00:04:56,680 --> 00:04:59,830 which is to say that there's many different paths that data can take 87 00:04:59,830 --> 00:05:03,670 to go from point A to point B. There isn't necessarily a line between you 88 00:05:03,670 --> 00:05:06,250 and Facebook.com or Stanford.edu. 89 00:05:06,250 --> 00:05:08,950 Rather, there's a whole bunch of routers-- 90 00:05:08,950 --> 00:05:11,740 sometimes a handful, sometimes as many as 30-- 91 00:05:11,740 --> 00:05:14,230 that will relay your data from left to right, 92 00:05:14,230 --> 00:05:18,340 to up to down, or in some other direction in order to get data from you 93 00:05:18,340 --> 00:05:20,410 to the web server that you're trying to contact 94 00:05:20,410 --> 00:05:23,240 and then back to you with the server's response. 95 00:05:23,240 --> 00:05:24,490 So how does all of this work? 96 00:05:24,490 --> 00:05:26,380 Well, decades ago, humans essentially had 97 00:05:26,380 --> 00:05:31,330 to get together and decide as a group what standards they were going to use, 98 00:05:31,330 --> 00:05:35,440 or more specifically, what protocols all of these computers are going to speak. 99 00:05:35,440 --> 00:05:39,370 A protocol isn't so much a language as it is a set of conventions, right? 100 00:05:39,370 --> 00:05:42,550 Back in healthier times, you and I, if we were meeting each other in person, 101 00:05:42,550 --> 00:05:45,040 might extend a hand, and if I did this, you would immediately 102 00:05:45,040 --> 00:05:47,165 know that you should probably extend your hand too, 103 00:05:47,165 --> 00:05:49,130 and we would have a physical handshake. 104 00:05:49,130 --> 00:05:50,650 And that's a human protocol. 105 00:05:50,650 --> 00:05:53,513 I initiate a communication with you by extending my hand. 106 00:05:53,513 --> 00:05:55,930 You acknowledge that communication by extending your hand. 107 00:05:55,930 --> 00:05:58,040 And then that interaction is complete. 108 00:05:58,040 --> 00:05:59,560 So we have these human protocols. 109 00:05:59,560 --> 00:06:02,260 In the world of computers, there's similarly protocols, 110 00:06:02,260 --> 00:06:04,590 but obviously it's all zeros and ones. 111 00:06:04,590 --> 00:06:07,510 So if the first computer sends this pattern of zeros and ones, 112 00:06:07,510 --> 00:06:11,540 the other computer should reply with a different set of zeros and ones. 113 00:06:11,540 --> 00:06:13,840 And so these protocols we're about to discuss just 114 00:06:13,840 --> 00:06:16,390 standardize what those patterns of zeros and ones are, 115 00:06:16,390 --> 00:06:19,660 or really, what all of the messages are going back and forth. 116 00:06:19,660 --> 00:06:23,860 And two of the protocols most commonly used to get data on the internet 117 00:06:23,860 --> 00:06:27,760 from point A to point B are called TCP/IP. 118 00:06:27,760 --> 00:06:31,600 TCP and IP are two separate protocols, but they're so often 119 00:06:31,600 --> 00:06:35,530 used together that you typically mention them in one breath, TCP/IP. 120 00:06:35,530 --> 00:06:39,400 And these are acronyms you've probably seen maybe on your Mac or PC 121 00:06:39,400 --> 00:06:41,500 or somewhere on your phone settings. 122 00:06:41,500 --> 00:06:44,470 And it refers to essentially two sets of conventions 123 00:06:44,470 --> 00:06:48,432 that computers use to get data from one point to another. 124 00:06:48,432 --> 00:06:50,140 So what do we mean by data and what do we 125 00:06:50,140 --> 00:06:52,630 mean by moving things between point A and point B? 126 00:06:52,630 --> 00:06:55,990 We'll just consider it as an old-school envelope, whereby 127 00:06:55,990 --> 00:06:58,917 if you wanted to send a letter to someone else in the world, 128 00:06:58,917 --> 00:07:01,750 you and I would probably reach for a piece of paper back in the day. 129 00:07:01,750 --> 00:07:04,300 We would pick up an envelope and we would write our note 130 00:07:04,300 --> 00:07:07,010 on that piece of paper, put the paper in the envelope, 131 00:07:07,010 --> 00:07:10,450 and then the most important step after writing the actual message 132 00:07:10,450 --> 00:07:12,220 would be to address the envelope. 133 00:07:12,220 --> 00:07:15,370 And of course, in the real world, you would put the recipient's address 134 00:07:15,370 --> 00:07:17,290 typically in the middle of the envelope. 135 00:07:17,290 --> 00:07:20,860 You might put your return address in the top corner of the envelope, 136 00:07:20,860 --> 00:07:22,910 and then maybe postage or something like that. 137 00:07:22,910 --> 00:07:25,390 But we humans have pretty much standardized 138 00:07:25,390 --> 00:07:28,060 through all of the postal systems that kind of convention 139 00:07:28,060 --> 00:07:29,080 when using envelopes. 140 00:07:29,080 --> 00:07:32,500 So the metaphor here is that the envelope and the message 141 00:07:32,500 --> 00:07:36,850 therein are generally thought of or referred to as packets, 142 00:07:36,850 --> 00:07:38,040 packets of information. 143 00:07:38,040 --> 00:07:39,790 And this would be the physical incarnation 144 00:07:39,790 --> 00:07:43,010 of what computers ultimately are just going to do using zeros and ones. 145 00:07:43,010 --> 00:07:45,010 So let's tease apart the two sets of conventions 146 00:07:45,010 --> 00:07:48,130 they use for actually putting data in these envelopes, 147 00:07:48,130 --> 00:07:52,420 addressing these envelopes, and sending them out from point A to point B. 148 00:07:52,420 --> 00:07:53,980 Let's consider first IP. 149 00:07:53,980 --> 00:07:56,650 IP stands for Internet Protocol, and pretty much 150 00:07:56,650 --> 00:08:00,580 any Mac and PC and iPhone and iPad and Android device 151 00:08:00,580 --> 00:08:05,080 these days has been designed by Apple or Google or someone else 152 00:08:05,080 --> 00:08:07,030 to understand IP. 153 00:08:07,030 --> 00:08:09,850 It's as though those companies have written software 154 00:08:09,850 --> 00:08:14,320 running on those devices that make sure that those devices all support IP, 155 00:08:14,320 --> 00:08:17,950 just like I was taught, presumably by some human, this human convention 156 00:08:17,950 --> 00:08:19,960 of shaking hands back in the day. 157 00:08:19,960 --> 00:08:23,500 IP, Internet Protocol, simply standardizes 158 00:08:23,500 --> 00:08:26,390 how computers address each other. 159 00:08:26,390 --> 00:08:29,642 So in our physical human world, if you wanted to send me an envelope 160 00:08:29,642 --> 00:08:32,559 for instance, you might write to Harvard's Computer Science Department 161 00:08:32,559 --> 00:08:38,110 at 33 Oxford Street, Cambridge, Massachusetts, 02138, USA. 162 00:08:38,110 --> 00:08:41,559 That is presumably a unique postal address 163 00:08:41,559 --> 00:08:43,900 that addresses the Computer Science building on campus 164 00:08:43,900 --> 00:08:47,530 so that if you drop an envelope in the mail in California or anywhere abroad 165 00:08:47,530 --> 00:08:51,460 it should eventually via some number of hops and mail carriers and the like 166 00:08:51,460 --> 00:08:54,250 make its way to that particular address. 167 00:08:54,250 --> 00:09:00,010 Computers, then, have similarly unique addresses known as IP addresses. 168 00:09:00,010 --> 00:09:05,260 And so when your computer, Mac, PC, phone, whatever, sends data from itself 169 00:09:05,260 --> 00:09:07,810 to another server, the address that it writes 170 00:09:07,810 --> 00:09:13,790 on the outside of that virtual envelope is the IP address of the remote server. 171 00:09:13,790 --> 00:09:16,210 So for instance, if I were to send a message to you, 172 00:09:16,210 --> 00:09:18,070 I would figure out what your IP address is. 173 00:09:18,070 --> 00:09:21,070 I would write that IP address virtually on the outside of this envelope. 174 00:09:21,070 --> 00:09:24,730 I would probably write my own IP address on the top left-hand corner 175 00:09:24,730 --> 00:09:26,500 of this metaphorical envelope. 176 00:09:26,500 --> 00:09:28,540 And then I would send it out on the internet. 177 00:09:28,540 --> 00:09:29,660 And what does that mean? 178 00:09:29,660 --> 00:09:33,310 It would mean I take that envelope and I hand it to the nearest router. 179 00:09:33,310 --> 00:09:36,760 So it turns out when you're at home, you actually have a router of your own. 180 00:09:36,760 --> 00:09:40,090 It's that device that connects to your cable modem or DSL modem or something 181 00:09:40,090 --> 00:09:40,660 like that. 182 00:09:40,660 --> 00:09:43,490 If you're on campus, like at a place like Harvard or Yale, 183 00:09:43,490 --> 00:09:46,930 Harvard and Yale have their own routers, so your computer, when on campus, 184 00:09:46,930 --> 00:09:48,640 just knows to hand data off to that. 185 00:09:48,640 --> 00:09:50,235 And if you're at home using-- 186 00:09:50,235 --> 00:09:53,110 or if you're elsewhere in the world, like in Starbucks or an airport, 187 00:09:53,110 --> 00:09:54,710 similarly are there routers there. 188 00:09:54,710 --> 00:09:57,910 So your computers generally know where the closest router is, 189 00:09:57,910 --> 00:10:00,680 and then router's purpose in life is, again, to figure out, 190 00:10:00,680 --> 00:10:03,740 does this packet go left, right, up, down, so to speak, 191 00:10:03,740 --> 00:10:07,120 in order to get it closer to its destination. 192 00:10:07,120 --> 00:10:09,740 But this sort of is a chicken and an egg. 193 00:10:09,740 --> 00:10:12,490 If I want to send you a piece of information, 194 00:10:12,490 --> 00:10:16,270 I need to know your IP address, but I don't really know your IP address 195 00:10:16,270 --> 00:10:18,320 until I know where you are. 196 00:10:18,320 --> 00:10:23,350 So there is this other system that you've probably seen an acronym for, 197 00:10:23,350 --> 00:10:26,540 too, called DNS, Domain Name System. 198 00:10:26,540 --> 00:10:30,130 And this is a technology that's deployed throughout the internet that's 199 00:10:30,130 --> 00:10:34,150 supported by Macs, PCs, and phones these days, that just translates what 200 00:10:34,150 --> 00:10:38,410 you and I would typically call domain names, or fully qualified domain names, 201 00:10:38,410 --> 00:10:42,160 from those English-like or human-readable characters 202 00:10:42,160 --> 00:10:44,690 to the corresponding IP addresses, right? 203 00:10:44,690 --> 00:10:48,280 There's a reason that companies do not advertise their websites 204 00:10:48,280 --> 00:10:51,310 as being a numeric IP address. 205 00:10:51,310 --> 00:10:52,940 None of us would ever remember them. 206 00:10:52,940 --> 00:10:55,090 They instead advertise them as Microsoft.com 207 00:10:55,090 --> 00:10:57,790 and Google.com and NewYorkTimes.com. 208 00:10:57,790 --> 00:11:01,120 DNS is a technology that your Mac and PC and phone 209 00:11:01,120 --> 00:11:03,760 support that know when a human types in one 210 00:11:03,760 --> 00:11:07,210 of those human-readable addresses, a domain name, DNS 211 00:11:07,210 --> 00:11:10,580 converts those names to the IP addresses. 212 00:11:10,580 --> 00:11:13,720 So literally, if you type in Harvard.edu or Yale.edu, 213 00:11:13,720 --> 00:11:16,330 enter into your web browser, your Mac or PC 214 00:11:16,330 --> 00:11:22,600 quickly looks up the IP address of that web server using the software that 215 00:11:22,600 --> 00:11:26,082 came with the Mac or PC and converts it to the corresponding IP address 216 00:11:26,082 --> 00:11:28,540 and then writes, virtually, on the outside of the envelope, 217 00:11:28,540 --> 00:11:31,120 the IP address of Harvard or Yale's web server 218 00:11:31,120 --> 00:11:33,170 before sending it out on the internet. 219 00:11:33,170 --> 00:11:34,900 So these are just services. 220 00:11:34,900 --> 00:11:39,700 DNS is a service that your own ISP, Internet Service Provider, provides. 221 00:11:39,700 --> 00:11:41,650 When you're on campus, it's Harvard or Yale. 222 00:11:41,650 --> 00:11:44,017 When you're at Starbucks, it's probably Starbucks. 223 00:11:44,017 --> 00:11:45,850 When you're in an airport, it's the airport. 224 00:11:45,850 --> 00:11:48,520 When you're at home, it's your own internet service provider 225 00:11:48,520 --> 00:11:50,930 like Verizon or Comcast or the like. 226 00:11:50,930 --> 00:11:54,680 So the world just decided to use that technology as well. 227 00:11:54,680 --> 00:11:57,820 And lastly, one other acronym for now, TCP. 228 00:11:57,820 --> 00:12:02,380 TCP, or Transmission Control Protocol, is a solution 229 00:12:02,380 --> 00:12:05,140 to a couple of problems, one of which is that it 230 00:12:05,140 --> 00:12:10,270 tends to be pretty convenient for individual servers on the internet 231 00:12:10,270 --> 00:12:12,875 to be able to do multiple things, right? 232 00:12:12,875 --> 00:12:15,250 And you can-- there's lots of things the internet can do. 233 00:12:15,250 --> 00:12:17,140 The servers can host email. 234 00:12:17,140 --> 00:12:18,220 They can host websites. 235 00:12:18,220 --> 00:12:20,650 They can host chat servers, video conferencing. 236 00:12:20,650 --> 00:12:24,820 I mean, that's already a growing list of features of software 237 00:12:24,820 --> 00:12:28,510 that you can use on the internet, and it would be nice, financially, 238 00:12:28,510 --> 00:12:32,110 administratively, if one server could do multiple things at once. 239 00:12:32,110 --> 00:12:33,460 And indeed, they can. 240 00:12:33,460 --> 00:12:37,120 So when a computer receives one of these virtual envelopes and that computer, 241 00:12:37,120 --> 00:12:41,710 that server, happens to support multiple services, email, web, chat, 242 00:12:41,710 --> 00:12:43,150 video, whatever-- 243 00:12:43,150 --> 00:12:46,610 it looks at the envelope for one additional piece of information. 244 00:12:46,610 --> 00:12:51,250 And that piece of information is known as a port number, P-O-R-T number, 245 00:12:51,250 --> 00:12:56,040 which is just a small integer that the world has decided represents specific 246 00:12:56,040 --> 00:12:56,860 services. 247 00:12:56,860 --> 00:13:00,690 So for instance, in the world of TCP, the world 248 00:13:00,690 --> 00:13:04,020 decided years ago that our computers should virtually 249 00:13:04,020 --> 00:13:07,680 write the number 80 on these envelopes after the IP address 250 00:13:07,680 --> 00:13:11,460 to signify that this is a request for a web page, or 443 251 00:13:11,460 --> 00:13:15,510 on the outside of the envelope if it's a secure request for a page using 252 00:13:15,510 --> 00:13:16,800 something called HTTPS. 253 00:13:16,800 --> 00:13:18,143 More on that in a bit. 254 00:13:18,143 --> 00:13:19,560 And there's other numbers as well. 255 00:13:19,560 --> 00:13:21,130 Email has its own unique numbers. 256 00:13:21,130 --> 00:13:22,518 Zoom has its own unique numbers. 257 00:13:22,518 --> 00:13:24,810 And all of these other internet services that you and I 258 00:13:24,810 --> 00:13:27,630 might use every day have their own unique TCP 259 00:13:27,630 --> 00:13:32,220 ports so that companies and people can have one server doing multiple things, 260 00:13:32,220 --> 00:13:35,220 but upon receipt of one of these envelopes, the server can look at it 261 00:13:35,220 --> 00:13:38,190 and be-- and realize, oh, this is a request for email. 262 00:13:38,190 --> 00:13:39,690 This is a request for a web page. 263 00:13:39,690 --> 00:13:44,130 This is a request for chat, or something else altogether. 264 00:13:44,130 --> 00:13:48,780 Now, notably, too, TCP also handles delivery, 265 00:13:48,780 --> 00:13:53,670 and it's the part of the protocol that also ensures that when you send data 266 00:13:53,670 --> 00:13:57,480 from point A to point B, if any data gets lost because literally 267 00:13:57,480 --> 00:14:02,370 something's wrong with one of those routers or because maybe the-- one 268 00:14:02,370 --> 00:14:05,850 of those writers got overwhelmed and just received more packets at once than 269 00:14:05,850 --> 00:14:06,550 it can handle-- 270 00:14:06,550 --> 00:14:08,550 that could happen, because these computers have, 271 00:14:08,550 --> 00:14:09,720 of course, finite memory. 272 00:14:09,720 --> 00:14:12,480 If you send too much data through one, the internet might get congested, 273 00:14:12,480 --> 00:14:15,522 your video might buffer, and a whole bunch of other symptoms might arise. 274 00:14:15,522 --> 00:14:20,320 So TCP also handles the process of retransmitting data as needed. 275 00:14:20,320 --> 00:14:22,380 If any of these packets is lost on the internet, 276 00:14:22,380 --> 00:14:25,920 literally TCP will also compel your Mac or PC, your phone, 277 00:14:25,920 --> 00:14:29,130 to resend that data as well. 278 00:14:29,130 --> 00:14:32,760 But what's notable about the internet is that data doesn't necessarily 279 00:14:32,760 --> 00:14:35,230 follow one specific path. 280 00:14:35,230 --> 00:14:38,940 In fact, if you send multiple packets from one person to another, 281 00:14:38,940 --> 00:14:43,330 those packets might actually take different routes each time. 282 00:14:43,330 --> 00:14:45,900 And this is actually a feature, not a bug, so to speak, 283 00:14:45,900 --> 00:14:48,450 because you can imagine servers getting congested 284 00:14:48,450 --> 00:14:50,280 or problems needed to getting-- 285 00:14:50,280 --> 00:14:52,090 needing to be routed around. 286 00:14:52,090 --> 00:14:55,800 And so TCP/IP also supports, with other protocols, 287 00:14:55,800 --> 00:14:59,640 an adaptive solution to this problem, whereby maybe your data will 288 00:14:59,640 --> 00:15:00,630 go this way sometimes. 289 00:15:00,630 --> 00:15:02,338 Maybe it'll go this way some other times. 290 00:15:02,338 --> 00:15:06,150 But this is why, in part, that sometimes your internet speeds are variable, 291 00:15:06,150 --> 00:15:08,790 because, again, these routers in between might be different 292 00:15:08,790 --> 00:15:10,830 or might be a little bit overloaded. 293 00:15:10,830 --> 00:15:13,200 So we thought we'd try to tell this story by enlisting 294 00:15:13,200 --> 00:15:14,920 the help of some of the CS50 staff. 295 00:15:14,920 --> 00:15:16,800 In fact, Brian, let me start with you. 296 00:15:16,800 --> 00:15:21,000 Would you mind taking on the role in just a moment of playing a web browser, 297 00:15:21,000 --> 00:15:24,480 someone's own Mac or PC or phone, and request of me-- 298 00:15:24,480 --> 00:15:28,165 maybe something silly, like asking me for a picture of a cat? 299 00:15:28,165 --> 00:15:29,040 BRIAN YU: Yeah, sure. 300 00:15:29,040 --> 00:15:32,250 So if I want to ask you, some web server, for a picture of a cat, 301 00:15:32,250 --> 00:15:35,580 I need to send a message to you in order to send that request to you. 302 00:15:35,580 --> 00:15:39,120 So I might write down my request on a sheet of paper. 303 00:15:39,120 --> 00:15:42,650 And I'll just put that request inside of an envelope. 304 00:15:42,650 --> 00:15:45,650 And then I would have to label that envelope with all the information we 305 00:15:45,650 --> 00:15:50,790 talked about, in particular with your IP address, that I might look up with DNS. 306 00:15:50,790 --> 00:15:52,400 And then I can send that envelope off. 307 00:15:52,400 --> 00:15:52,820 DAVID J. MALAN: All right. 308 00:15:52,820 --> 00:15:54,350 And I think we need a little bit of help here, 309 00:15:54,350 --> 00:15:56,340 because Brian and I are in different places. 310 00:15:56,340 --> 00:16:00,420 And so he and I can't just hand the envelope from one to the other. 311 00:16:00,420 --> 00:16:03,350 So let's go ahead and enlist the help of CS50 staff here, 312 00:16:03,350 --> 00:16:05,540 also, who have chimed in here on Zoom and see 313 00:16:05,540 --> 00:16:09,420 if we can't route this request from Brian, 314 00:16:09,420 --> 00:16:11,770 who's playing the role of a web browser, to me, 315 00:16:11,770 --> 00:16:14,000 who will play the role of a web server, in order 316 00:16:14,000 --> 00:16:16,530 to receive this request for a cat. 317 00:16:16,530 --> 00:16:17,152 So here we go. 318 00:16:17,152 --> 00:16:18,860 Let's see if we can enlist the team here. 319 00:16:18,860 --> 00:16:22,318 [MUSIC PLAYING] 320 00:16:22,318 --> 00:16:39,150 321 00:16:39,150 --> 00:16:39,800 All right. 322 00:16:39,800 --> 00:16:42,383 Well, thank you to Phyllis for having handed me this envelope. 323 00:16:42,383 --> 00:16:44,990 And what we have now is the request that Brian sent me. 324 00:16:44,990 --> 00:16:46,740 I'm going to go open it up, and I, indeed, 325 00:16:46,740 --> 00:16:49,470 see a message inside requesting a picture of a cat, which 326 00:16:49,470 --> 00:16:50,920 is not uncommon on the internet. 327 00:16:50,920 --> 00:16:53,070 So now if I'm the web server and I actually 328 00:16:53,070 --> 00:16:55,620 have an archive of pictures of cats, I'm going 329 00:16:55,620 --> 00:16:58,680 to go ahead and respond to Brian with one of those cats. 330 00:16:58,680 --> 00:17:01,954 But to do so, I'm going to go ahead and have to look up on my hard drive 331 00:17:01,954 --> 00:17:04,079 or somewhere in the computer that picture of a cat. 332 00:17:04,079 --> 00:17:07,800 And here's one here, so I'm going to go and send Brian this very happy cat. 333 00:17:07,800 --> 00:17:09,810 I've got some envelopes of my own, and I'm 334 00:17:09,810 --> 00:17:14,819 to go ahead and write Brian's IP address on the middle of this envelope, 335 00:17:14,819 --> 00:17:17,650 I'm going to put my IP address on the top-left of this envelope, 336 00:17:17,650 --> 00:17:19,650 and then maybe any other identifying information 337 00:17:19,650 --> 00:17:22,650 I need, and then I'll go ahead and put the cat into the envelope. 338 00:17:22,650 --> 00:17:25,480 But, of course, this isn't really going to fit. 339 00:17:25,480 --> 00:17:27,420 And this is actually quite commonly the case. 340 00:17:27,420 --> 00:17:30,940 Any time a computer is trying to transmit a decent amount of data, 341 00:17:30,940 --> 00:17:34,320 whether it's a big image or maybe it's an even bigger video file, 342 00:17:34,320 --> 00:17:36,840 for equity's sake, it tends to be good for computers 343 00:17:36,840 --> 00:17:40,010 to chop up large packets into multiple smaller packets. 344 00:17:40,010 --> 00:17:41,760 In fact, you might have heard of something 345 00:17:41,760 --> 00:17:44,400 called Net Neutrality or a more technical topic known 346 00:17:44,400 --> 00:17:45,540 as Quality of Service. 347 00:17:45,540 --> 00:17:49,350 In a nutshell, Net Neutrality speaks to just what kinds of decisions 348 00:17:49,350 --> 00:17:52,080 computers should make when it comes to prioritizing data. 349 00:17:52,080 --> 00:17:55,140 And a common convention is, historically, that all of us 350 00:17:55,140 --> 00:17:58,680 should chop up our large packets into smaller packets, send them out, 351 00:17:58,680 --> 00:18:01,410 so they can get then commingled with other people's packets 352 00:18:01,410 --> 00:18:04,020 and we all reach our destinations at the same rate. 353 00:18:04,020 --> 00:18:07,380 Net Neutrality, as an aside, is all about an interest 354 00:18:07,380 --> 00:18:12,090 by some parties in prioritizing maybe the data from certain companies that 355 00:18:12,090 --> 00:18:13,150 pay a bit more. 356 00:18:13,150 --> 00:18:16,960 And so this really speaks to just use or maybe abuse of these basic primitives 357 00:18:16,960 --> 00:18:17,460 here. 358 00:18:17,460 --> 00:18:19,597 But this is not fair for me to try to cram this one 359 00:18:19,597 --> 00:18:21,930 big image into an envelope, so I'm going to literally go 360 00:18:21,930 --> 00:18:27,350 ahead and tear the picture in half, essentially chop the packet into two. 361 00:18:27,350 --> 00:18:29,880 Let me go ahead now and put this into the envelope, 362 00:18:29,880 --> 00:18:31,780 because it'll fit a little more easily. 363 00:18:31,780 --> 00:18:34,140 So I've got one packet of information for Brian. 364 00:18:34,140 --> 00:18:37,290 I've got now-- let's see-- one more packet of information for Brian 365 00:18:37,290 --> 00:18:40,260 that I'll fit the other half of this image into. 366 00:18:40,260 --> 00:18:42,630 But I think I'm going to have to do something else. 367 00:18:42,630 --> 00:18:46,500 Before I drop this out on the internet and hand it back to Phyllis 368 00:18:46,500 --> 00:18:51,090 to send out back to Brian, I might need some additional information 369 00:18:51,090 --> 00:18:52,770 on these envelopes. 370 00:18:52,770 --> 00:18:55,740 I've already got Brian's IP in the To field. 371 00:18:55,740 --> 00:18:59,400 I've got my IP address in the From field. 372 00:18:59,400 --> 00:19:01,950 I've also jotted down the port number that I 373 00:19:01,950 --> 00:19:04,800 should use for Brian and my own return port number. 374 00:19:04,800 --> 00:19:07,830 And those are decided typically by my Mac or PC. 375 00:19:07,830 --> 00:19:10,560 But I feel like I probably need a little more information. 376 00:19:10,560 --> 00:19:14,460 What more should I virtually write on the outside of this envelope 377 00:19:14,460 --> 00:19:20,430 to make sure that the data is received as intended? 378 00:19:20,430 --> 00:19:21,750 Any intuition? 379 00:19:21,750 --> 00:19:27,340 No familiarity with TCP/IP assumed here. 380 00:19:27,340 --> 00:19:30,497 But if Brian's about to now get two envelopes, what additional data 381 00:19:30,497 --> 00:19:32,080 should I perhaps give him? [? Greg? ?] 382 00:19:32,080 --> 00:19:35,840 AUDIENCE: Brian may confuse the top of the photo with the bottom, 383 00:19:35,840 --> 00:19:39,125 so you need somehow to tell Brian that this is a top and this is a bottom, 384 00:19:39,125 --> 00:19:41,730 a link maybe to converge them. 385 00:19:41,730 --> 00:19:42,730 DAVID J. MALAN: Perfect. 386 00:19:42,730 --> 00:19:44,860 And so we need to make sure Brian knows the order 387 00:19:44,860 --> 00:19:47,527 in which these packets should be reassembled so that he, indeed, 388 00:19:47,527 --> 00:19:50,430 gets the cat the right way and not the wrong way, for instance. 389 00:19:50,430 --> 00:19:52,180 So what probably suffices is for me to add 390 00:19:52,180 --> 00:19:55,030 what we'll call a sequence number to each of these packets, which 391 00:19:55,030 --> 00:19:58,330 is essentially a number which you can think of as one of two, 392 00:19:58,330 --> 00:20:01,780 and on the other one, two of two, so that Brian knows when-- 393 00:20:01,780 --> 00:20:04,777 what order to reassemble the packets, but also more importantly, 394 00:20:04,777 --> 00:20:06,610 in case one of the packets, or both of them, 395 00:20:06,610 --> 00:20:10,690 gets lost or somehow dropped by one of the routers along the way, 396 00:20:10,690 --> 00:20:12,490 there's enough information on those packets 397 00:20:12,490 --> 00:20:18,620 to enable me and him to recover that and resend packet one and/or two as needed. 398 00:20:18,620 --> 00:20:19,870 So let's go ahead and do this. 399 00:20:19,870 --> 00:20:23,037 Let me go ahead and enlist the help of the team, starting with Phyllis here. 400 00:20:23,037 --> 00:20:25,330 And Phyllis, if you'd like to go ahead here and-- 401 00:20:25,330 --> 00:20:39,660 [MUSIC PLAYING] 402 00:20:39,660 --> 00:20:40,170 All right. 403 00:20:40,170 --> 00:20:41,962 Of course, that's only half of the problem. 404 00:20:41,962 --> 00:20:44,475 So I'm to go ahead now and send the second packet, finally. 405 00:20:44,475 --> 00:20:47,100 In an ideal world, I would actually send these out in parallel, 406 00:20:47,100 --> 00:20:50,017 but there's no reason that they couldn't still follow different paths. 407 00:20:50,017 --> 00:20:52,590 In fact, this one I worry might take a little bit more time. 408 00:20:52,590 --> 00:20:53,130 Let's see. 409 00:20:53,130 --> 00:20:53,755 [MUSIC PLAYING] 410 00:20:53,755 --> 00:20:57,558 [SINGING IN ITALIAN] 411 00:20:57,558 --> 00:21:22,190 412 00:21:22,190 --> 00:21:22,850 Amazing. 413 00:21:22,850 --> 00:21:25,920 Brian, do you want to go ahead and open up your envelopes and reassemble them? 414 00:21:25,920 --> 00:21:26,503 BRIAN YU: Yes. 415 00:21:26,503 --> 00:21:27,560 I have two envelopes. 416 00:21:27,560 --> 00:21:30,650 I guess I'll open up the one that says one of two first, 417 00:21:30,650 --> 00:21:33,530 and it is the top half of the cat. 418 00:21:33,530 --> 00:21:37,190 And then I'll open up the other envelope, which is two of two. 419 00:21:37,190 --> 00:21:40,250 And that is the bottom half of the cat. 420 00:21:40,250 --> 00:21:43,427 And so together, I think I now have the full cat. 421 00:21:43,427 --> 00:21:44,510 DAVID J. MALAN: Wonderful. 422 00:21:44,510 --> 00:21:46,468 Well, thank you to Brian and to the whole team. 423 00:21:46,468 --> 00:21:48,830 And so to recap, IP is this protocol, the set 424 00:21:48,830 --> 00:21:52,100 of conventions that standardizes what gets written on these envelopes. 425 00:21:52,100 --> 00:21:56,270 It's how computers uniquely address each other with numbers of some sort. 426 00:21:56,270 --> 00:21:59,300 TCP governs a few different things, but among them 427 00:21:59,300 --> 00:22:04,160 is this numbering of services, like 80 for insecure web traffic 428 00:22:04,160 --> 00:22:07,100 or 443 for secure web traffic that ensures 429 00:22:07,100 --> 00:22:09,320 that the data gets from one point to another 430 00:22:09,320 --> 00:22:13,370 and is handled by the right application running on that particular server. 431 00:22:13,370 --> 00:22:15,680 DNS, then, is what we use to begin with. 432 00:22:15,680 --> 00:22:18,052 If Brian had his own domain name, my computer 433 00:22:18,052 --> 00:22:19,760 would have had to look up his IP address, 434 00:22:19,760 --> 00:22:21,920 or conversely, he would have had to look up mine, 435 00:22:21,920 --> 00:22:24,110 so that we humans, who are actually using 436 00:22:24,110 --> 00:22:26,360 the internet in a human-friendly way, don't 437 00:22:26,360 --> 00:22:30,440 have to remember IP addresses, which, again, are just numbers, but instead 438 00:22:30,440 --> 00:22:34,890 can remember things like Harvard.edu, Yale.edu, and the like. 439 00:22:34,890 --> 00:22:38,330 So that, then, is the internet, the fundamental infrastructure, 440 00:22:38,330 --> 00:22:42,440 the plumbing on top of which we now have the ability to get data from point A 441 00:22:42,440 --> 00:22:45,500 to point B. And so in some sense, if you're comfortable with that, 442 00:22:45,500 --> 00:22:48,260 we can now abstract the internet away and just 443 00:22:48,260 --> 00:22:52,740 think of it as being a mechanism that gets data from one point to another. 444 00:22:52,740 --> 00:22:56,330 And so long as we can now assume that we have this fundamental public service 445 00:22:56,330 --> 00:22:58,290 that gets data from one point to another, 446 00:22:58,290 --> 00:23:00,950 now we can start to build on top of it in terms 447 00:23:00,950 --> 00:23:05,780 of software and other languages and actually use it for interesting things. 448 00:23:05,780 --> 00:23:10,220 But before we forge ahead to do those things, any questions or confusion 449 00:23:10,220 --> 00:23:16,100 we can clear up on TCP or IP or DNS or the internet or routers or any 450 00:23:16,100 --> 00:23:19,600 of these other new terms? 451 00:23:19,600 --> 00:23:21,100 [? Greg, ?] back to you. 452 00:23:21,100 --> 00:23:22,610 AUDIENCE: I have a question. 453 00:23:22,610 --> 00:23:26,920 So does chopping the information create any problem? 454 00:23:26,920 --> 00:23:29,950 Because, I don't know, a piece of information 455 00:23:29,950 --> 00:23:33,280 can go there for two seconds and another one for three seconds. 456 00:23:33,280 --> 00:23:35,128 Does it create any problem for the user? 457 00:23:35,128 --> 00:23:36,670 DAVID J. MALAN: Really good question. 458 00:23:36,670 --> 00:23:39,050 These packets can take different durations of time, 459 00:23:39,050 --> 00:23:41,860 and even though I did stipulate that they should go out to Phyllis's hands 460 00:23:41,860 --> 00:23:43,480 roughly at the same time, even if she needs 461 00:23:43,480 --> 00:23:45,250 to pass them in two different directions, 462 00:23:45,250 --> 00:23:47,080 there can absolutely be delays. 463 00:23:47,080 --> 00:23:49,750 And in fact, typically, you and I as humans 464 00:23:49,750 --> 00:23:54,190 will start to notice delays if packets take more than 200 milliseconds 465 00:23:54,190 --> 00:23:56,830 to get from point A to point B. After that, 466 00:23:56,830 --> 00:23:59,073 it looks like there's a bit of delay, and certainly 467 00:23:59,073 --> 00:24:01,990 if it's two or three seconds, you'll really notice that at that point, 468 00:24:01,990 --> 00:24:03,700 it's not necessarily a problem-- 469 00:24:03,700 --> 00:24:06,760 Brian hopefully would patiently wait for the second half 470 00:24:06,760 --> 00:24:10,510 of the cat for some amount of time if he only received one packet. 471 00:24:10,510 --> 00:24:13,465 Eventually, he as a human, and in turn, he as a computer, 472 00:24:13,465 --> 00:24:15,340 would probably get a little anxious and would 473 00:24:15,340 --> 00:24:20,050 ask me to retransmit a packet if it doesn't arrive after 5 seconds, 10 474 00:24:20,050 --> 00:24:21,280 seconds, 30 seconds. 475 00:24:21,280 --> 00:24:23,260 These time outs can typically be specified 476 00:24:23,260 --> 00:24:26,650 by the software running on the person's computer, but at that point, 477 00:24:26,650 --> 00:24:29,740 you and I would certainly notice the difference. 478 00:24:29,740 --> 00:24:30,250 All right. 479 00:24:30,250 --> 00:24:33,970 So if we now have this ability fundamentally to get data from point A 480 00:24:33,970 --> 00:24:38,230 to point B, what is actually inside of the envelope that Brian sent me, 481 00:24:38,230 --> 00:24:43,450 and what was inside the envelope I sent him besides just the picture of a cat? 482 00:24:43,450 --> 00:24:47,230 Well, for that, we transition to another language or another protocol, rather, 483 00:24:47,230 --> 00:24:51,280 called HTTP, HyperText Transfer Protocol. 484 00:24:51,280 --> 00:24:55,240 And this is an acronym you've probably seen or typed bunches of times. 485 00:24:55,240 --> 00:24:58,330 It's, of course, what appears in the beginning of URLs, Uniform Resource 486 00:24:58,330 --> 00:25:04,150 Locators, which are the tools that you and I use to actually figure out 487 00:25:04,150 --> 00:25:08,960 what websites or what image we actually want to request of the internet. 488 00:25:08,960 --> 00:25:14,080 So the web, the world-wide web, is really just one of many services 489 00:25:14,080 --> 00:25:16,090 that run on top of the internet. 490 00:25:16,090 --> 00:25:17,530 The web gives us web pages. 491 00:25:17,530 --> 00:25:19,780 Zoom gives us video conferencing. 492 00:25:19,780 --> 00:25:22,760 Other tools give us text chatting, voice chatting, and the like. 493 00:25:22,760 --> 00:25:25,840 So the web is really just an application on top of the internet. 494 00:25:25,840 --> 00:25:28,900 It's hands-down the most popular application, 495 00:25:28,900 --> 00:25:30,760 but it really is just an application. 496 00:25:30,760 --> 00:25:34,150 It's a service that's using that underlying plumbing. 497 00:25:34,150 --> 00:25:38,800 So HTTP is a different protocol that really governs 498 00:25:38,800 --> 00:25:40,930 what goes inside of these envelopes. 499 00:25:40,930 --> 00:25:43,990 TCP/IP governs what goes outside the envelopes. 500 00:25:43,990 --> 00:25:47,320 HTTP governs what goes inside of the envelopes, assuming we 501 00:25:47,320 --> 00:25:50,440 are talking about web browsers and web servers and not video conferencing 502 00:25:50,440 --> 00:25:51,710 or something else. 503 00:25:51,710 --> 00:25:56,620 So with HTTP, it comes with a few different commands, or a pretty limited 504 00:25:56,620 --> 00:26:00,100 vocabulary, two of which are the most important terms to know, 505 00:26:00,100 --> 00:26:01,390 which is GET and POST. 506 00:26:01,390 --> 00:26:03,620 These are literally English verbs, and they 507 00:26:03,620 --> 00:26:07,030 are two of the commands, if you will, that HTTP supports. 508 00:26:07,030 --> 00:26:10,450 And what Brian probably did inside of that envelope is 509 00:26:10,450 --> 00:26:14,890 he probably literally wrote down GET cat or something like that. 510 00:26:14,890 --> 00:26:17,680 POST is used for other applications that we'll get to before long, 511 00:26:17,680 --> 00:26:19,430 but "GET" is the operative word. 512 00:26:19,430 --> 00:26:22,780 And it literally is how a browser will request or get information 513 00:26:22,780 --> 00:26:23,530 from a server. 514 00:26:23,530 --> 00:26:25,660 So somewhere in the envelope Brian sent me 515 00:26:25,660 --> 00:26:30,670 was the English word "GET," probably followed by cat.jpg or something 516 00:26:30,670 --> 00:26:31,300 like that. 517 00:26:31,300 --> 00:26:34,300 There's probably a bit more information, but the essence of HTTP 518 00:26:34,300 --> 00:26:37,420 means that if Brian wants something from me and he's the browser 519 00:26:37,420 --> 00:26:42,070 and I'm the server, he should start his request with the standardized verb 520 00:26:42,070 --> 00:26:45,320 "GET" followed by the name of the file that he wants to get. 521 00:26:45,320 --> 00:26:48,430 So let's put this now into the context of one of the more familiar URLs. 522 00:26:48,430 --> 00:26:51,712 So here's, for instance, a canonical format of a URL. 523 00:26:51,712 --> 00:26:53,420 And let's highlight a few features of it. 524 00:26:53,420 --> 00:26:55,450 So first, HTTPS. 525 00:26:55,450 --> 00:26:57,460 Increasingly, you're seeing this on the web. 526 00:26:57,460 --> 00:27:00,040 Even if you don't type it, it's often automatically appearing 527 00:27:00,040 --> 00:27:02,530 in the address bar of your browser, because browsers or web 528 00:27:02,530 --> 00:27:04,510 servers are adding it for you. 529 00:27:04,510 --> 00:27:08,260 The S just refers to a secure version of HTTP. 530 00:27:08,260 --> 00:27:11,830 And we'll come back to this topic of security next week and beyond, too. 531 00:27:11,830 --> 00:27:17,620 But in the context of HTTP, this just means that the data between me 532 00:27:17,620 --> 00:27:20,800 and Brian and vice versa is encrypted somehow. 533 00:27:20,800 --> 00:27:23,350 It's way better than Caesar or other ciphers. 534 00:27:23,350 --> 00:27:25,238 It's way more mathematically sophisticated. 535 00:27:25,238 --> 00:27:27,280 But it essentially just scrambles the information 536 00:27:27,280 --> 00:27:30,670 so that Brian knows he's asking for a cat, I, the web server, 537 00:27:30,670 --> 00:27:34,450 knows he's asking for a cat, but if any of you or any of the TFs 538 00:27:34,450 --> 00:27:37,960 who were playing the role of routers maliciously or nosily 539 00:27:37,960 --> 00:27:41,613 opened the envelope instead of handing it off to the next staff member, 540 00:27:41,613 --> 00:27:43,780 they wouldn't understand what's inside the envelope, 541 00:27:43,780 --> 00:27:47,200 because it would look like, similar to Caesar and other ciphers, 542 00:27:47,200 --> 00:27:48,990 sort of like random zeros and ones. 543 00:27:48,990 --> 00:27:53,530 So HTTPS just means that the contents of these packets are encrypted. 544 00:27:53,530 --> 00:27:55,450 What else is salient about these URLs? 545 00:27:55,450 --> 00:27:57,250 Well, here's what we call a domain name. 546 00:27:57,250 --> 00:27:59,560 Odds are most everyone knows what a domain name is, 547 00:27:59,560 --> 00:28:02,620 and it's typically two phrases, something dot something else. 548 00:28:02,620 --> 00:28:04,840 And example.com is, of course, an example 549 00:28:04,840 --> 00:28:09,010 here, but Harvard.edu, Yale.edu, and millions of others these days. 550 00:28:09,010 --> 00:28:11,260 To the end of that, though, is what we would typically 551 00:28:11,260 --> 00:28:15,160 call the top-level domain or TLD. 552 00:28:15,160 --> 00:28:18,880 This is just the type of website, historically, 553 00:28:18,880 --> 00:28:20,050 that you're trying to visit. 554 00:28:20,050 --> 00:28:21,145 Dot com meant commercial. 555 00:28:21,145 --> 00:28:22,800 Dot edu meant education. 556 00:28:22,800 --> 00:28:24,970 Dot net meant some kind of network. 557 00:28:24,970 --> 00:28:26,710 Dot org is an organization. 558 00:28:26,710 --> 00:28:28,400 That's no longer really the case. 559 00:28:28,400 --> 00:28:32,050 In fact, there's hundreds, perhaps even thousands, of top-level domains 560 00:28:32,050 --> 00:28:36,190 nowadays that you can buy domains in that 561 00:28:36,190 --> 00:28:39,760 try to categorize things sometimes, but there's no hard rules 562 00:28:39,760 --> 00:28:42,670 around most of those top-level domains. 563 00:28:42,670 --> 00:28:45,905 You have to be an accredited educational institution to use dot edu. 564 00:28:45,905 --> 00:28:49,480 You have to be in the US military to use dot mil. 565 00:28:49,480 --> 00:28:52,240 There are similar constraints in other countries 566 00:28:52,240 --> 00:28:55,420 who have their own two-character country code TLDs, 567 00:28:55,420 --> 00:29:00,250 like dot UK for the United Kingdom, dot JP for Japan, and many others. 568 00:29:00,250 --> 00:29:02,980 Each country is free to standardize as it sees fit. 569 00:29:02,980 --> 00:29:06,550 But you and I can buy a dot com, a dot org, a dot net, a dot 570 00:29:06,550 --> 00:29:09,110 us, a dot-- there's many, many, many others. 571 00:29:09,110 --> 00:29:12,220 And if you go on Wikipedia you can see a nearly exhaustive list. 572 00:29:12,220 --> 00:29:16,030 But this just tends to categorize the type of website that it is. 573 00:29:16,030 --> 00:29:21,190 Besides that, there's this prefix, this, generally known as a hostname. 574 00:29:21,190 --> 00:29:23,530 And www is just a human convention. 575 00:29:23,530 --> 00:29:26,110 Years ago, pretty much any server on the internet 576 00:29:26,110 --> 00:29:31,960 that had a human-friendly name like this, www.example.com, 577 00:29:31,960 --> 00:29:33,820 this was just meant to connote to the user 578 00:29:33,820 --> 00:29:37,780 that, oh, www, this must be the address of a web server 579 00:29:37,780 --> 00:29:40,960 and not a mail server not a chat server or something else. 580 00:29:40,960 --> 00:29:42,265 It's not strictly required. 581 00:29:42,265 --> 00:29:43,390 It's just human convention. 582 00:29:43,390 --> 00:29:45,432 And odds are, you and I, when you visit websites, 583 00:29:45,432 --> 00:29:48,200 you probably don't even bother typing this in anymore. 584 00:29:48,200 --> 00:29:53,980 But it is a historical feature that allows a visual cue-- clue, typically, 585 00:29:53,980 --> 00:29:57,010 to the humans as to what type of server it is. 586 00:29:57,010 --> 00:30:01,420 So besides that, there's this one hidden piece of information as well. 587 00:30:01,420 --> 00:30:05,710 If you just want to visit example.com's homepage, you might just type this URL, 588 00:30:05,710 --> 00:30:08,170 or even just type example.com and hit Enter and let 589 00:30:08,170 --> 00:30:11,080 the browser redirect you, so to speak-- take you 590 00:30:11,080 --> 00:30:13,690 to this canonical form of the URL. 591 00:30:13,690 --> 00:30:17,710 But very often, you're technically requesting a specific file. 592 00:30:17,710 --> 00:30:22,413 And if not mentioned, that file name is typically index.html. 593 00:30:22,413 --> 00:30:25,330 It can be other things as well depending on the language or the server 594 00:30:25,330 --> 00:30:26,920 technology that someone's using. 595 00:30:26,920 --> 00:30:30,880 But implicit at the end of URLs is often the name of a file. 596 00:30:30,880 --> 00:30:34,000 Brian might have specifically requested cat.jpg, 597 00:30:34,000 --> 00:30:36,070 but if he were requesting not a picture of a cat 598 00:30:36,070 --> 00:30:40,000 but a full-fledged web page with text and other information, odds are, 599 00:30:40,000 --> 00:30:43,480 there's an implicit file name there, like index.html. 600 00:30:43,480 --> 00:30:47,080 And this is now important, because when we look inside this envelope, 601 00:30:47,080 --> 00:30:50,120 this is a piece of information that needs to then be in there. 602 00:30:50,120 --> 00:30:54,070 So let's take a look at some sample HTTP requests and responses, 603 00:30:54,070 --> 00:30:56,710 the more technical dive into what Brian and I and the staff 604 00:30:56,710 --> 00:30:58,540 acted out a moment ago. 605 00:30:58,540 --> 00:31:01,840 Technically speaking, when Brian sent me a request for that cat, 606 00:31:01,840 --> 00:31:05,980 he wrote inside this envelope, not only the key word GET and something like 607 00:31:05,980 --> 00:31:07,278 a cat.jpg-- 608 00:31:07,278 --> 00:31:09,070 he also specified a couple of other things. 609 00:31:09,070 --> 00:31:12,370 And let's genericize it now away from cats and just propose this. 610 00:31:12,370 --> 00:31:17,800 Inside of an HTTP request that is any of these virtual envelopes is literally 611 00:31:17,800 --> 00:31:21,910 a request for, like, GET followed by slash, if you don't want to cat, 612 00:31:21,910 --> 00:31:23,920 you just want the default homepage, followed 613 00:31:23,920 --> 00:31:28,150 by a mention of what version of HTTP the browser and server should speak. 614 00:31:28,150 --> 00:31:29,710 1.1 is pretty common. 615 00:31:29,710 --> 00:31:31,750 2 is pretty-- is increasingly common. 616 00:31:31,750 --> 00:31:33,123 3 is even now out there. 617 00:31:33,123 --> 00:31:35,290 But there's just different versions of the protocol. 618 00:31:35,290 --> 00:31:37,960 It's like humans have refined what it means to shake hands. 619 00:31:37,960 --> 00:31:40,490 These versions of protocols evolve over time. 620 00:31:40,490 --> 00:31:44,770 But there's also a line like this, Host colon www.example.com, 621 00:31:44,770 --> 00:31:49,000 because-- just in case I am a particularly fancy server that 622 00:31:49,000 --> 00:31:54,010 supports not only example.com but maybe Harvard.edu and Yale.edu. 623 00:31:54,010 --> 00:31:56,560 It's possible, long story short, for companies nowadays 624 00:31:56,560 --> 00:32:00,670 to host multiple websites and multiple domains on the same server. 625 00:32:00,670 --> 00:32:03,070 This little clue inside the envelope makes sure 626 00:32:03,070 --> 00:32:07,330 that it goes to example.com or Harvard.edu or Yale.edu 627 00:32:07,330 --> 00:32:11,080 if all of these entities are sharing the same physical server. 628 00:32:11,080 --> 00:32:13,945 So more specifically, a request might look-- instead look like this. 629 00:32:13,945 --> 00:32:16,570 If you're not just requesting the default homepage but you want 630 00:32:16,570 --> 00:32:20,620 a specific file, it might say /index.html instead. 631 00:32:20,620 --> 00:32:22,430 What does my response look like? 632 00:32:22,430 --> 00:32:23,960 So I've gotten Brian's envelope. 633 00:32:23,960 --> 00:32:26,470 Now I'm going to go ahead and respond with my own one or two 634 00:32:26,470 --> 00:32:27,490 or more envelopes. 635 00:32:27,490 --> 00:32:31,300 Inside of mine, yes, is going to go pieces of that cat, 636 00:32:31,300 --> 00:32:34,090 but some additional information as well, per the protocol. 637 00:32:34,090 --> 00:32:37,580 So my response-- just like in the human world, I might extend my hand, 638 00:32:37,580 --> 00:32:39,760 if I see Brian initiating a handshake. 639 00:32:39,760 --> 00:32:43,730 I'm going to respond with something like this, HTTP/1.1, 640 00:32:43,730 --> 00:32:47,920 which just reminds the browser what version I'm speaking, then a number, 641 00:32:47,920 --> 00:32:52,630 which is the status code, followed by a shorthand summary, like OK. 642 00:32:52,630 --> 00:32:54,490 200 OK means I got you. 643 00:32:54,490 --> 00:32:55,390 I found the cat. 644 00:32:55,390 --> 00:32:57,670 Here it comes, piece by piece, in these envelopes. 645 00:32:57,670 --> 00:33:01,220 And I also put it in the envelope a mention of the content type. 646 00:33:01,220 --> 00:33:04,450 If it's a web page, I'm going to put text/html. 647 00:33:04,450 --> 00:33:09,040 If it's a jpg, I might instead say image/jpg. 648 00:33:09,040 --> 00:33:12,250 And there's the different content types, otherwise known as line types, 649 00:33:12,250 --> 00:33:15,040 for all different file formats in the world. 650 00:33:15,040 --> 00:33:19,130 Well, that's not always going to be the case, that the response is 651 00:33:19,130 --> 00:33:23,930 as simple as that, whereby your browser requests information and the server 652 00:33:23,930 --> 00:33:26,060 responds with the requested information. 653 00:33:26,060 --> 00:33:28,570 Sometimes the users make their way to the wrong place. 654 00:33:28,570 --> 00:33:35,120 So for instance, suppose that a browser visits www.Harvard.edu, 655 00:33:35,120 --> 00:33:38,600 the response might not necessarily be OK initially. 656 00:33:38,600 --> 00:33:41,100 It might not be status code 200. 657 00:33:41,100 --> 00:33:42,710 And in fact, we can see this. 658 00:33:42,710 --> 00:33:46,250 Let me go ahead and open up on my screen here a browser 659 00:33:46,250 --> 00:33:51,350 window that's going to take me to, let's say, Harvard.edu. 660 00:33:51,350 --> 00:33:59,090 And I'm going to go ahead and type in to the URL bar http://www.Harvard.edu, 661 00:33:59,090 --> 00:34:00,350 Enter. 662 00:34:00,350 --> 00:34:02,840 Now, all this happened pretty quickly, but if I 663 00:34:02,840 --> 00:34:06,200 click on the URL bar, which has been simplified or shortened 664 00:34:06,200 --> 00:34:09,800 by Chrome at the moment, notice where I actually ended up. 665 00:34:09,800 --> 00:34:13,370 Somehow or other, my browser did not keep me at HTTP. 666 00:34:13,370 --> 00:34:16,062 It redirected me, so to speak, to HTTPS. 667 00:34:16,062 --> 00:34:18,020 This is probably intentional on Harvard's part. 668 00:34:18,020 --> 00:34:19,850 They would rather that I'd be visiting them 669 00:34:19,850 --> 00:34:22,857 securely so that if I'm reading articles or other content, 670 00:34:22,857 --> 00:34:25,190 that's really nobody's business except mine and Harvard. 671 00:34:25,190 --> 00:34:28,380 Certainly no one-- no routers in between should be able to see this. 672 00:34:28,380 --> 00:34:32,719 So somehow, Harvard redirected me from HTTP to HTTPS. 673 00:34:32,719 --> 00:34:34,050 Well, how can I see this? 674 00:34:34,050 --> 00:34:39,020 Well, it turns out, embedded in Chrome and Edge and Firefox and Safari-- 675 00:34:39,020 --> 00:34:40,489 all of today's browsers-- 676 00:34:40,489 --> 00:34:42,739 there are often developer tools that sometimes you 677 00:34:42,739 --> 00:34:44,630 have to enable via a certain menu-- 678 00:34:44,630 --> 00:34:46,730 but these developer tools are so powerful 679 00:34:46,730 --> 00:34:49,820 and they allow you, the user, or now you, the programmer, 680 00:34:49,820 --> 00:34:52,820 to actually see and understand what's going 681 00:34:52,820 --> 00:34:56,010 on underneath the hood of these browsers and servers. 682 00:34:56,010 --> 00:34:58,010 So I'm going to do this in Chrome, specifically. 683 00:34:58,010 --> 00:35:00,590 I'm going to go to View, Developer, and then I'm 684 00:35:00,590 --> 00:35:02,150 going to go to Developer Tools. 685 00:35:02,150 --> 00:35:05,540 And odds are if you're a Chrome User, this menu option has always been there, 686 00:35:05,540 --> 00:35:06,930 even if you never noticed it. 687 00:35:06,930 --> 00:35:08,480 So feel free to play along at home. 688 00:35:08,480 --> 00:35:10,783 And then notice this pops up on the top right here. 689 00:35:10,783 --> 00:35:12,950 I'm going to go ahead and move it down to the bottom 690 00:35:12,950 --> 00:35:15,890 just by clicking the dot, dot, dot menu and move the developer 691 00:35:15,890 --> 00:35:19,220 tools to the bottom of my screen, just so we can see things a little wider. 692 00:35:19,220 --> 00:35:22,470 And I'm going to go ahead and click on the Network tab up here. 693 00:35:22,470 --> 00:35:24,450 And when I click on the Network tab here, 694 00:35:24,450 --> 00:35:28,895 I'm going to see a whole bunch of information related to my last request, 695 00:35:28,895 --> 00:35:31,020 so I'm going to go ahead and do this request again. 696 00:35:31,020 --> 00:35:33,650 Let me go ahead and go back to the URL bar 697 00:35:33,650 --> 00:35:36,750 and let me go ahead and-- actually, just for good measure, 698 00:35:36,750 --> 00:35:38,297 let me do this in Incognito mode. 699 00:35:38,297 --> 00:35:40,130 And even though you perhaps are in the habit 700 00:35:40,130 --> 00:35:42,170 of using Incognito mode if you don't want the browser 701 00:35:42,170 --> 00:35:45,212 to remember where you've been or what you've logged in as-- and Incognito 702 00:35:45,212 --> 00:35:48,090 mode is incredibly powerful for developers tool 703 00:35:48,090 --> 00:35:52,640 so that you can reset the browser state to a first condition 704 00:35:52,640 --> 00:35:57,203 without any previous network browsing showing up in your history. 705 00:35:57,203 --> 00:35:59,120 So I'm going to do this again now in Incognito 706 00:35:59,120 --> 00:36:01,580 mode after having opened developer tools. 707 00:36:01,580 --> 00:36:07,250 http://www.Harvard.edu, Enter. 708 00:36:07,250 --> 00:36:10,670 And a whole bunch of stuff just flew by the window, some of which 709 00:36:10,670 --> 00:36:14,107 is this chart information, which shows me the performance. 710 00:36:14,107 --> 00:36:17,190 So to [? Greg, ?] your question earlier about noticing the amount of time, 711 00:36:17,190 --> 00:36:19,690 you can see that some of the requests that were just induced 712 00:36:19,690 --> 00:36:23,120 vary between a few milliseconds and over 1,000 milliseconds. 713 00:36:23,120 --> 00:36:27,020 But what I care about for now is this fairly arcane listing down here. 714 00:36:27,020 --> 00:36:29,630 A whole lot of stuff just flew across the screen, 715 00:36:29,630 --> 00:36:32,900 and indeed, if I zoom in on the bottom, simply visiting Harvard.edu 716 00:36:32,900 --> 00:36:39,890 induces 70 HTTP requests per this mention in the bottom left-hand corner. 717 00:36:39,890 --> 00:36:43,730 It resulted in 6.8 megabytes of information being transferred. 718 00:36:43,730 --> 00:36:47,810 And in total, it took a-- rather atrociously, 11.95 seconds. 719 00:36:47,810 --> 00:36:51,030 So [? Greg, ?] like, that is slow, relatively speaking. 720 00:36:51,030 --> 00:36:52,850 Well, absolutely speaking. 721 00:36:52,850 --> 00:36:55,130 So what's the takeaway here? 722 00:36:55,130 --> 00:36:57,050 Well, any time you visit a web page, there's 723 00:36:57,050 --> 00:37:00,410 not just the one web page itself with all of the text in it. 724 00:37:00,410 --> 00:37:04,100 There's probably images, maybe videos, maybe music and other things. 725 00:37:04,100 --> 00:37:06,070 All of those get downloaded separately. 726 00:37:06,070 --> 00:37:10,370 So if Brian had asked me for a full web page, like the course's home website, 727 00:37:10,370 --> 00:37:13,250 I might respond not with a single envelope or two envelopes. 728 00:37:13,250 --> 00:37:18,200 I might respond with 70 envelopes containing the responses to every piece 729 00:37:18,200 --> 00:37:23,420 of media that composes CS50's own website, or in this case, Harvard's. 730 00:37:23,420 --> 00:37:26,390 But for now, let's focus only on the first of these requests. 731 00:37:26,390 --> 00:37:28,970 If I look at the first row here in Chrome, 732 00:37:28,970 --> 00:37:32,030 I will see a reminder of where I visited first. 733 00:37:32,030 --> 00:37:35,810 But notice the Status column over here is 301. 734 00:37:35,810 --> 00:37:37,670 301 Moved Permanently. 735 00:37:37,670 --> 00:37:40,190 It turns out that there's numbers besides 200 736 00:37:40,190 --> 00:37:42,080 that tell browsers what to do. 737 00:37:42,080 --> 00:37:45,350 200 just means OK, here's the data we requested. 738 00:37:45,350 --> 00:37:49,790 301 means, nn-nn, whatever you requested has moved permanently 739 00:37:49,790 --> 00:37:51,230 to a different URL. 740 00:37:51,230 --> 00:37:53,540 So let me go ahead and click this first row 741 00:37:53,540 --> 00:37:56,850 and you'll see that a whole different set of tabs pops up. 742 00:37:56,850 --> 00:37:58,310 I'm going to click Headers here. 743 00:37:58,310 --> 00:37:59,900 And now let me define a term. 744 00:37:59,900 --> 00:38:04,010 When Brian and I are using HTTP inside of these envelopes and I write 745 00:38:04,010 --> 00:38:10,070 something like GET slash HTTP/1.1 or host colon www.example.com, 746 00:38:10,070 --> 00:38:13,970 each of those lines of text is what we'll call an HTTP header. 747 00:38:13,970 --> 00:38:16,470 It's a line of text inside of the envelope. 748 00:38:16,470 --> 00:38:19,110 So what we're seeing here is Chrome's summary 749 00:38:19,110 --> 00:38:21,810 of all of the headers that were inside of these envelopes. 750 00:38:21,810 --> 00:38:25,840 Let me go ahead and look at my request headers first. 751 00:38:25,840 --> 00:38:27,720 I'm going to click View Source. 752 00:38:27,720 --> 00:38:32,280 And I can literally see the raw request that my browser sent 753 00:38:32,280 --> 00:38:39,470 to www.Harvard.edu, GET slash HTTP/1.1, Host colon www.Harvard.edu, 754 00:38:39,470 --> 00:38:42,480 and then a bunch of other stuff which we'll ignore for now. 755 00:38:42,480 --> 00:38:45,030 But those are all HTTP headers. 756 00:38:45,030 --> 00:38:47,910 But if I scroll back up here, let's look at the response 757 00:38:47,910 --> 00:38:50,580 headers now, what came back in a different envelope 758 00:38:50,580 --> 00:38:52,920 from Harvard to my laptop. 759 00:38:52,920 --> 00:39:00,000 Notice here that it's HTTP 1.1, but it's not 200 OK, it's 301 Moved Permanently. 760 00:39:00,000 --> 00:39:02,430 This is a hint to my browser that, uh-uh, 761 00:39:02,430 --> 00:39:04,530 there's nothing at the URL you visited. 762 00:39:04,530 --> 00:39:07,080 You need to visit a different location instead. 763 00:39:07,080 --> 00:39:11,880 To know where I need to go, I need to scroll down and find this header here. 764 00:39:11,880 --> 00:39:15,365 Notice that the third line in the response is Location colon 765 00:39:15,365 --> 00:39:20,700 https://www.Harvard.edu. 766 00:39:20,700 --> 00:39:24,450 So this is how the envelope that comes back contains a clue to me to say, 767 00:39:24,450 --> 00:39:28,390 nn-nn, we have moved permanently to the secure version of the website. 768 00:39:28,390 --> 00:39:32,340 And if I zoom out now and click this little X to close those tabs, 769 00:39:32,340 --> 00:39:37,380 you'll see that the next request that my browser automatically sent on its own 770 00:39:37,380 --> 00:39:43,840 was to instead, if I scroll down here, to this request URL, 771 00:39:43,840 --> 00:39:48,300 https://www.Harvard.edu, and the response I 772 00:39:48,300 --> 00:39:53,250 got this time under this general summary here was now indeed 200. 773 00:39:53,250 --> 00:39:57,090 So this is just a simple mechanism that allows a browser and a server 774 00:39:57,090 --> 00:40:02,520 to intercommunicate in a way that can send them from one location to another. 775 00:40:02,520 --> 00:40:04,590 And let me make this a little more familiar. 776 00:40:04,590 --> 00:40:09,240 Odds are you have seen not this before, explicitly, because you, as a human, 777 00:40:09,240 --> 00:40:12,480 would rarely, if ever, see the number 301 or Moved Permanently 778 00:40:12,480 --> 00:40:14,670 until today, now that you're a programmer who's 779 00:40:14,670 --> 00:40:18,300 using these developer tools, but odds are you've seen another number. 780 00:40:18,300 --> 00:40:20,100 Maybe in the chat if you want to just chime 781 00:40:20,100 --> 00:40:24,240 in, if you're thinking about web pages and numbers, has anyone seen-- 782 00:40:24,240 --> 00:40:29,310 quite often, probably, a number that maybe now makes a little more sense? 783 00:40:29,310 --> 00:40:30,510 Brian, what are you seeing? 784 00:40:30,510 --> 00:40:32,190 BRIAN YU: A lot of people saying 404. 785 00:40:32,190 --> 00:40:34,230 I also saw 500 and a 502. 786 00:40:34,230 --> 00:40:37,800 DAVID J. MALAN: Yeah, so 404 is the code that humans adopted years 787 00:40:37,800 --> 00:40:39,880 ago that just signifies Not Found. 788 00:40:39,880 --> 00:40:44,970 So if you visit an incorrect URL or an old URL that no longer exists 789 00:40:44,970 --> 00:40:47,640 on a server, for maybe an old cat that's been deleted, 790 00:40:47,640 --> 00:40:52,350 the server will respond not with 200 OK but with 404 Not Found, 791 00:40:52,350 --> 00:40:56,490 thereby telling your browser to display some kind of error message. 792 00:40:56,490 --> 00:40:59,640 Weirdly, browsers years ago weren't especially user friendly, 793 00:40:59,640 --> 00:41:03,750 and then browsers just told us humans 404, 404, 794 00:41:03,750 --> 00:41:05,850 which frankly, is not very user friendly. 795 00:41:05,850 --> 00:41:09,720 But all it boils down to is this little hint inside of the response 796 00:41:09,720 --> 00:41:14,182 envelope coming back that indicates that something went wrong, 797 00:41:14,182 --> 00:41:15,390 that something was not found. 798 00:41:15,390 --> 00:41:17,520 And there's a whole list of these status codes, 799 00:41:17,520 --> 00:41:19,260 and this is certainly not something you need to memorize, 800 00:41:19,260 --> 00:41:21,420 but as we focus more and more on web programming, 801 00:41:21,420 --> 00:41:24,090 you'll just get naturally familiar with some of these. 802 00:41:24,090 --> 00:41:27,090 There's other ways of redirecting the user from one place to another. 803 00:41:27,090 --> 00:41:29,820 302 and 307 can be used. 804 00:41:29,820 --> 00:41:32,100 For efficiency, servers can sometimes respond 805 00:41:32,100 --> 00:41:36,570 with 304, which essentially means, you already asked me that question. 806 00:41:36,570 --> 00:41:38,730 The cat has not changed on the server. 807 00:41:38,730 --> 00:41:40,590 Use your own copy of the cat. 808 00:41:40,590 --> 00:41:44,835 So long story short, if Brian's own browser were smart, it would cache-- 809 00:41:44,835 --> 00:41:50,290 C-A-C-H-E-- that is, remember the cat that he just downloaded from me so that 810 00:41:50,290 --> 00:41:54,180 if Brian hits reload or he comes back to that same website again and wants 811 00:41:54,180 --> 00:41:57,960 to see the cat again, it just-- his browser loads the local copy instead 812 00:41:57,960 --> 00:42:01,230 of bothering me, the web server, and wasting time, milliseconds, 813 00:42:01,230 --> 00:42:02,250 sending another cat. 814 00:42:02,250 --> 00:42:04,570 304 would just say, the cat is the same. 815 00:42:04,570 --> 00:42:05,917 Use your own local copy. 816 00:42:05,917 --> 00:42:06,750 Then there's others. 817 00:42:06,750 --> 00:42:09,630 You might have seen 401 or 403 before, which 818 00:42:09,630 --> 00:42:13,020 refer to not being logged in correctly or something like that. 819 00:42:13,020 --> 00:42:15,160 500 is actually bad. 820 00:42:15,160 --> 00:42:18,570 And in fact, I can pretty much guarantee that over the next couple of weeks, 821 00:42:18,570 --> 00:42:24,265 all of you will experience your very first of several HTTP 500 errors. 822 00:42:24,265 --> 00:42:26,890 That's going to be next week that you screwed up with your code 823 00:42:26,890 --> 00:42:30,810 and you actually wrote buggy Python code that just meant the whole server didn't 824 00:42:30,810 --> 00:42:31,600 know what to do. 825 00:42:31,600 --> 00:42:33,360 And that's an internal server error. 826 00:42:33,360 --> 00:42:37,500 Fixable, and will help you debug it, but indeed, that's quite common as well. 827 00:42:37,500 --> 00:42:40,180 503 just means the server might be overloaded in some way 828 00:42:40,180 --> 00:42:43,568 and so service is unavailable, and there's others, dot, dot, dot, as well. 829 00:42:43,568 --> 00:42:45,360 So we can actually have a little bit of fun 830 00:42:45,360 --> 00:42:47,670 with this in a couple of different directions. 831 00:42:47,670 --> 00:42:52,470 It turns out that if we send this HTTP request, 832 00:42:52,470 --> 00:42:54,137 we can take a look at what comes back. 833 00:42:54,137 --> 00:42:55,470 And let me go ahead and do this. 834 00:42:55,470 --> 00:42:57,970 Instead of using my browser, I'm going to use a command line 835 00:42:57,970 --> 00:43:01,410 tool which tends to just be a little cleaner, because I don't have to futz 836 00:43:01,410 --> 00:43:02,790 around with all of these buttons. 837 00:43:02,790 --> 00:43:05,220 Let me go ahead and use a program called Curl. 838 00:43:05,220 --> 00:43:08,670 And Curl's purpose in life is just to connect to a URL. 839 00:43:08,670 --> 00:43:12,070 And it's not going to bother showing me the web page or any of the content. 840 00:43:12,070 --> 00:43:15,210 It's just going to show me the HTTP headers if I use a command line 841 00:43:15,210 --> 00:43:17,350 argument of dash capital I. 842 00:43:17,350 --> 00:43:23,650 And now I'm going to go ahead and http://safetyschool.org. 843 00:43:23,650 --> 00:43:25,150 And I'm going to go ahead and Enter. 844 00:43:25,150 --> 00:43:28,600 And this is my Mac now sending one envelope 845 00:43:28,600 --> 00:43:33,490 to safetyschool.org containing GET, that verb, requesting the home page. 846 00:43:33,490 --> 00:43:37,180 They are presumably going to respond to me with another envelope inside 847 00:43:37,180 --> 00:43:38,680 of which is some kind of response. 848 00:43:38,680 --> 00:43:39,760 Maybe it's a 200. 849 00:43:39,760 --> 00:43:41,240 Maybe it's something else. 850 00:43:41,240 --> 00:43:42,460 [CHUCKLES] All right. 851 00:43:42,460 --> 00:43:44,590 It looks like-- forgive me-- 852 00:43:44,590 --> 00:43:49,570 that safetyschool.org has moved permanently, per this 301, 853 00:43:49,570 --> 00:43:53,290 to this new location www.Yale.edu. 854 00:43:53,290 --> 00:43:55,180 sorry. 855 00:43:55,180 --> 00:43:56,470 And in fact, we can do this. 856 00:43:56,470 --> 00:43:58,900 If I copy this URL-- 857 00:43:58,900 --> 00:44:00,530 and let me go into a browser. 858 00:44:00,530 --> 00:44:04,060 I'll use Incognito again so that I don't have any past history. 859 00:44:04,060 --> 00:44:05,560 I'm going to go ahead and hit Enter. 860 00:44:05,560 --> 00:44:11,020 And voila, the visual effect is just as real as the headers would imply. 861 00:44:11,020 --> 00:44:15,400 So indeed, the funny thing about this joke is that someone on the internet 862 00:44:15,400 --> 00:44:18,730 has been paying for the domain name safetyschool.org for, like, 863 00:44:18,730 --> 00:44:22,870 20 years now for this joke, and the only thing it does 864 00:44:22,870 --> 00:44:25,820 is redirect one domain name to another. 865 00:44:25,820 --> 00:44:26,800 Now, fair is fair. 866 00:44:26,800 --> 00:44:29,350 Let me go ahead and transition away from safetyschool.org 867 00:44:29,350 --> 00:44:33,700 or to harvardsucks.org, which also exists, and someone on the other side 868 00:44:33,700 --> 00:44:36,950 has been hosting this website for some time. 869 00:44:36,950 --> 00:44:40,150 And in fact, if you visit that URL-- 870 00:44:40,150 --> 00:44:43,600 let's go to harvardsucks.org, Enter. 871 00:44:43,600 --> 00:44:45,610 You'll actually see a whole website. 872 00:44:45,610 --> 00:44:48,220 So the Yalies really went all-out here. 873 00:44:48,220 --> 00:44:51,010 And you can actually see an amazing hack here 874 00:44:51,010 --> 00:44:55,240 whereby at harvardsucks.org there's an old YouTube video of an amazing hack 875 00:44:55,240 --> 00:44:58,570 or prank that was pulled at one of the Harvard-Yale football games 876 00:44:58,570 --> 00:45:04,060 some years ago where Yale, to their credit, tricked us into spelling out, 877 00:45:04,060 --> 00:45:08,230 with a bitmap, if-- of all things, we suck. 878 00:45:08,230 --> 00:45:09,220 So fair's fair. 879 00:45:09,220 --> 00:45:12,040 So in anyhow, bit of a stretch to connect those 880 00:45:12,040 --> 00:45:14,620 to underlying HTTP messages, but it all, indeed, 881 00:45:14,620 --> 00:45:17,320 relates to these very simple primitives. 882 00:45:17,320 --> 00:45:19,430 Let me point out one other thing as well. 883 00:45:19,430 --> 00:45:22,300 We might also see in the form of HTTP requests 884 00:45:22,300 --> 00:45:25,990 even more sophisticated first lines where you're not requesting 885 00:45:25,990 --> 00:45:27,850 just slash, the default homepage. 886 00:45:27,850 --> 00:45:32,890 You're not requesting /cat.jpg or /index.html. 887 00:45:32,890 --> 00:45:36,010 There might also be question marks and equal signs. 888 00:45:36,010 --> 00:45:40,090 And notice, this is an excerpt from an envelope my Mac or PC or phone 889 00:45:40,090 --> 00:45:44,440 might send to google.com requesting pictures of cats. 890 00:45:44,440 --> 00:45:46,930 And in fact, let me go ahead and do this on my browser. 891 00:45:46,930 --> 00:45:48,760 Let me go to HTTPS-- 892 00:45:48,760 --> 00:45:51,220 I'm not going to bother using the insecure version at all. 893 00:45:51,220 --> 00:45:58,060 I'm going to go explicitly to google.com/search?q=cats. 894 00:45:58,060 --> 00:46:01,780 So this is the human version of the URL that my Mac 895 00:46:01,780 --> 00:46:05,247 will translate into this lower-level message that's 896 00:46:05,247 --> 00:46:07,330 going to be shoved inside of the virtual envelope. 897 00:46:07,330 --> 00:46:08,980 So I'm going to go ahead and hit Enter. 898 00:46:08,980 --> 00:46:11,680 And voila, I now see, indeed, a whole bunch 899 00:46:11,680 --> 00:46:15,370 of pictures of cats, including some more horrific photos from a movie that 900 00:46:15,370 --> 00:46:17,270 didn't fare well as well. 901 00:46:17,270 --> 00:46:21,100 So that is to say that it seems that once you understand URL formats, 902 00:46:21,100 --> 00:46:24,220 you can begin to pass input to servers. 903 00:46:24,220 --> 00:46:27,880 And here's now where we bridge past weeks to future weeks. 904 00:46:27,880 --> 00:46:31,930 Thus far, when we visited web pages like Harvard.edu and Yale.edu and the like, 905 00:46:31,930 --> 00:46:33,920 we're just visiting static web content. 906 00:46:33,920 --> 00:46:35,920 We're not actually providing user input like you 907 00:46:35,920 --> 00:46:41,230 would using GET string or input or any kinds of command line programs 908 00:46:41,230 --> 00:46:42,010 we've written. 909 00:46:42,010 --> 00:46:45,040 But it turns out that you URLs do support user input, 910 00:46:45,040 --> 00:46:46,640 and they are standardized. 911 00:46:46,640 --> 00:46:50,725 If you see a question mark and then the name of a variable like q 912 00:46:50,725 --> 00:46:52,720 and then an equal sign and then a word like 913 00:46:52,720 --> 00:46:58,600 "cat," that's the web-based analog of a command line program having asked you 914 00:46:58,600 --> 00:47:01,840 what is the value of q, and the human typing in cats. 915 00:47:01,840 --> 00:47:05,470 So this is to say there is a way using URLs that will actually 916 00:47:05,470 --> 00:47:08,830 allow us to pass input to a web server. 917 00:47:08,830 --> 00:47:11,680 And indeed, that's what's happening when you're visiting google.com, 918 00:47:11,680 --> 00:47:14,680 but it just boils down to understanding these URLs. 919 00:47:14,680 --> 00:47:17,380 And before we begin to build some of our own solutions 920 00:47:17,380 --> 00:47:23,920 on top of this infrastructure, any questions now or confusion on HTTP 921 00:47:23,920 --> 00:47:30,460 or status codes or anything we've seen thus far? 922 00:47:30,460 --> 00:47:31,540 Anything at all? 923 00:47:31,540 --> 00:47:34,520 Yeah, over to Santiago. 924 00:47:34,520 --> 00:47:38,990 AUDIENCE: When you want to, for example, publish a web page, 925 00:47:38,990 --> 00:47:41,460 why is it that you have to buy a domain name? 926 00:47:41,460 --> 00:47:44,523 Is that because you're using memory in some server? 927 00:47:44,523 --> 00:47:46,690 DAVID J. MALAN: Yeah, that's a really good question. 928 00:47:46,690 --> 00:47:48,860 Why do you have to buy a domain name? 929 00:47:48,860 --> 00:47:52,040 It kind of boils down to capitalism, to be honest. 930 00:47:52,040 --> 00:47:54,840 There is a non-zero cost to running certain aspects 931 00:47:54,840 --> 00:47:57,590 of the internet, certainly, or really all aspects of the internet. 932 00:47:57,590 --> 00:48:00,085 There are some nonprofit and volunteers-- 933 00:48:00,085 --> 00:48:02,960 non-profit organizations and volunteers that have historically helped 934 00:48:02,960 --> 00:48:03,500 govern it. 935 00:48:03,500 --> 00:48:07,460 Increasingly, though, there's overhead to operationalizing the internet, 936 00:48:07,460 --> 00:48:10,610 running things like the main DNS servers and other features. 937 00:48:10,610 --> 00:48:14,120 And so there are what are called internet registrars, much 938 00:48:14,120 --> 00:48:16,790 like a university registrar, whose purpose in life 939 00:48:16,790 --> 00:48:21,710 is to allow people to essentially rent domain names on an annual basis. 940 00:48:21,710 --> 00:48:24,710 And indeed, when you buy a domain name, it's not yours permanently. 941 00:48:24,710 --> 00:48:28,030 Instead, you're paying a yearly fee once-- 942 00:48:28,030 --> 00:48:30,920 a renewal fee every one or two or three years or the like. 943 00:48:30,920 --> 00:48:33,350 It might range from a couple of dollars to hundreds 944 00:48:33,350 --> 00:48:35,120 or even thousands of dollars. 945 00:48:35,120 --> 00:48:38,300 We can go down the rabbit hole talking about domain name squatting, whereby 946 00:48:38,300 --> 00:48:41,600 if you think of a really cool word and you buy the domain name and someone 947 00:48:41,600 --> 00:48:44,060 else comes along and wants it, there's capitalism at play 948 00:48:44,060 --> 00:48:46,250 there, potentially an opportunity for you 949 00:48:46,250 --> 00:48:48,410 to sell a domain name to someone else. 950 00:48:48,410 --> 00:48:53,270 But in part, it helps just regulate exactly who can sign up 951 00:48:53,270 --> 00:48:55,790 for domain names and presumably put some downward pressure 952 00:48:55,790 --> 00:48:59,330 on all of them just disappearing if you could just sign up for free for as many 953 00:48:59,330 --> 00:49:00,650 as you want. 954 00:49:00,650 --> 00:49:04,130 Other questions or clarifications on not just 955 00:49:04,130 --> 00:49:11,167 HTTP but also TCP, IP, DNS, or anything else from today's alphabet soup? 956 00:49:11,167 --> 00:49:12,750 BRIAN YU: A question came in the chat. 957 00:49:12,750 --> 00:49:15,480 If you have multiple packets that you're trying to send from one place 958 00:49:15,480 --> 00:49:18,090 to the other, do they have to be sent out one after the other, 959 00:49:18,090 --> 00:49:20,280 or can you send all of the packets out at the same time? 960 00:49:20,280 --> 00:49:21,822 DAVID J. MALAN: Really good question. 961 00:49:21,822 --> 00:49:26,400 We did not think that we humans could do that very well choreographically using 962 00:49:26,400 --> 00:49:32,430 Zoom a bit ago, so we sent one packet a time through the teaching fellows. 963 00:49:32,430 --> 00:49:35,310 But yes, a computer would typically dump all of those packets 964 00:49:35,310 --> 00:49:36,370 out at the same time. 965 00:49:36,370 --> 00:49:38,310 They would be serialized one after the other, 966 00:49:38,310 --> 00:49:39,760 but it would happen very quickly. 967 00:49:39,760 --> 00:49:41,910 And by chance, they might all follow the same route 968 00:49:41,910 --> 00:49:44,070 through the teaching fellows as routers, or they 969 00:49:44,070 --> 00:49:46,830 might go in different directions depending on just how congested 970 00:49:46,830 --> 00:49:49,620 or how busy the internet is at that moment in time. 971 00:49:49,620 --> 00:49:52,320 They might arrive out of order, but indeed, that's 972 00:49:52,320 --> 00:49:54,690 why Brian needs to know what the sequence number is 973 00:49:54,690 --> 00:49:59,290 on the outside of the envelope so he can rearrange them in the correct order. 974 00:49:59,290 --> 00:50:02,230 Anything else on your end, Brian? 975 00:50:02,230 --> 00:50:04,150 BRIAN YU: How do the rooters know which way 976 00:50:04,150 --> 00:50:05,738 to send any particular packet of data? 977 00:50:05,738 --> 00:50:07,280 DAVID J. MALAN: Really good question. 978 00:50:07,280 --> 00:50:08,280 How do the routers know? 979 00:50:08,280 --> 00:50:13,240 So back in the day-- and in some cases, it's literally hardcoded. 980 00:50:13,240 --> 00:50:16,780 You can think of a router as having essentially an Excel spreadsheet 981 00:50:16,780 --> 00:50:20,050 in its memory with at least two columns, one of which 982 00:50:20,050 --> 00:50:24,400 is an IP address, the other of which is the direction it should go out on, 983 00:50:24,400 --> 00:50:25,893 like right, left, up and down. 984 00:50:25,893 --> 00:50:28,810 Like, the cables aren't going in four different directions, certainly, 985 00:50:28,810 --> 00:50:31,240 but you can think of it in-- metaphorically, in that way. 986 00:50:31,240 --> 00:50:35,300 It tells the router that if you receive data for this IP address, 987 00:50:35,300 --> 00:50:37,807 send it out on this cable, or if it's for this IP address, 988 00:50:37,807 --> 00:50:38,890 send it out on that cable. 989 00:50:38,890 --> 00:50:41,860 And all of these cables are connected to other routers 990 00:50:41,860 --> 00:50:44,680 in the same city, in different cities, across an ocean, 991 00:50:44,680 --> 00:50:46,330 to some other endpoint. 992 00:50:46,330 --> 00:50:48,340 That would be very painful, though, if humans 993 00:50:48,340 --> 00:50:51,200 had to manually configure all of the interconnections 994 00:50:51,200 --> 00:50:53,270 we saw on MIT's map just a bit ago. 995 00:50:53,270 --> 00:50:55,083 And so it turns out there's other protocols 996 00:50:55,083 --> 00:50:57,250 out there that we won't spend time on in this class, 997 00:50:57,250 --> 00:51:02,110 but that routers rely on in order to dynamically adapt. 998 00:51:02,110 --> 00:51:04,150 So long story short, there are protocols that 999 00:51:04,150 --> 00:51:07,060 will figure out if all of a sudden my packets 1000 00:51:07,060 --> 00:51:09,280 are not getting through to Brian, I'm going 1001 00:51:09,280 --> 00:51:11,230 to start routing around that, dynamically, 1002 00:51:11,230 --> 00:51:12,940 and the routers are going to figure out, that does not 1003 00:51:12,940 --> 00:51:15,880 seem to be a good destination because I'm not getting any response, 1004 00:51:15,880 --> 00:51:18,150 or it's just taking way too long to hear back. 1005 00:51:18,150 --> 00:51:19,900 So there are protocols that govern how you 1006 00:51:19,900 --> 00:51:24,280 can decide whether to start dynamically changing those so-called routing 1007 00:51:24,280 --> 00:51:28,210 tables, the spreadsheet to which I referred earlier. 1008 00:51:28,210 --> 00:51:31,750 All right, so we have now, at this point, an infrastructure known 1009 00:51:31,750 --> 00:51:35,350 as the internet that allows us to send packets of information from point A 1010 00:51:35,350 --> 00:51:38,043 to point B by writing addresses and port numbers 1011 00:51:38,043 --> 00:51:39,460 on the outside of those envelopes. 1012 00:51:39,460 --> 00:51:42,820 We have another protocol called HTTP which is specifically 1013 00:51:42,820 --> 00:51:46,960 used for web browsers and web servers, separate from videoconferencing 1014 00:51:46,960 --> 00:51:49,780 and chat, which have their own set of conventions and protocols, 1015 00:51:49,780 --> 00:51:51,670 but we have a mechanism for get-- 1016 00:51:51,670 --> 00:51:54,610 requesting information and responding with information. 1017 00:51:54,610 --> 00:51:59,020 And we know from problem set 4 how you can respond with a cat. 1018 00:51:59,020 --> 00:52:00,910 It's just a sequence of bits, whether it's 1019 00:52:00,910 --> 00:52:03,760 a bitmap or a jpg or something else, but we haven't yet 1020 00:52:03,760 --> 00:52:05,830 seen what an actual page looks like. 1021 00:52:05,830 --> 00:52:08,920 And indeed, if we look a little deeper in the envelope 1022 00:52:08,920 --> 00:52:11,205 that I'm sending to Brian and he's sending to me 1023 00:52:11,205 --> 00:52:14,080 and we're getting back from Harvard and we're getting back from Yale, 1024 00:52:14,080 --> 00:52:16,170 we're going to see another language altogether. 1025 00:52:16,170 --> 00:52:17,590 It's not a programming language, per se. 1026 00:52:17,590 --> 00:52:19,540 It's what's known as a markup language, which 1027 00:52:19,540 --> 00:52:22,310 just means it's more about aesthetics than it is about logic. 1028 00:52:22,310 --> 00:52:25,352 And there's going to be a couple of other languages tucked in there, CSS, 1029 00:52:25,352 --> 00:52:28,510 Cascading Style Sheets, JavaScript, which is a proper programming language. 1030 00:52:28,510 --> 00:52:30,718 But let's go ahead and take a five-minute break here. 1031 00:52:30,718 --> 00:52:34,830 And when we come back, we'll learn to make web pages themselves. 1032 00:52:34,830 --> 00:52:35,680 All right. 1033 00:52:35,680 --> 00:52:40,920 So when you visit a website requesting the home page or a specific file 1034 00:52:40,920 --> 00:52:44,460 on the website, exactly what is inside of the virtual envelope 1035 00:52:44,460 --> 00:52:47,340 a little deeper down below the HTTP headers 1036 00:52:47,340 --> 00:52:48,810 that you get back from the server? 1037 00:52:48,810 --> 00:52:52,058 Well, that language is known as HTML, HyperText Markup 1038 00:52:52,058 --> 00:52:53,850 Language, which indeed is not a programming 1039 00:52:53,850 --> 00:52:55,650 language, which means there's no loops. 1040 00:52:55,650 --> 00:52:56,790 There's no conditions. 1041 00:52:56,790 --> 00:52:59,010 There's no functions or variables per se. 1042 00:52:59,010 --> 00:53:03,220 It's just text that tells a browser fairly pedantically, top to bottom, 1043 00:53:03,220 --> 00:53:06,270 left to right, what to display and how. 1044 00:53:06,270 --> 00:53:08,110 So let's take a look at some examples. 1045 00:53:08,110 --> 00:53:12,210 An HTML page is going to contain really two different concepts inside of it, 1046 00:53:12,210 --> 00:53:15,635 what we'll call tags or elements, and also attributes. 1047 00:53:15,635 --> 00:53:16,510 Well, what are those? 1048 00:53:16,510 --> 00:53:19,530 Well, here is perhaps the simplest web page we can make. 1049 00:53:19,530 --> 00:53:21,600 And this is HTML itself. 1050 00:53:21,600 --> 00:53:25,500 And you'll see that it's structured in kind of a symmetric way. 1051 00:53:25,500 --> 00:53:28,485 Some things are indented like in a proper programming language, 1052 00:53:28,485 --> 00:53:30,610 but there is some symmetry to what's going on here. 1053 00:53:30,610 --> 00:53:34,380 So let's tease apart top to bottom exactly what we're looking at here. 1054 00:53:34,380 --> 00:53:37,920 This very first line is known as a document type declaration. 1055 00:53:37,920 --> 00:53:40,410 Long story short, whenever making a modern web page, 1056 00:53:40,410 --> 00:53:44,100 this should just be the very first line of your file, no matter what. 1057 00:53:44,100 --> 00:53:46,320 It signifies that you and I are using the latest 1058 00:53:46,320 --> 00:53:48,570 version of HTML, which is version 5. 1059 00:53:48,570 --> 00:53:52,440 In the future, this line will probably change as HTML itself, the language, 1060 00:53:52,440 --> 00:53:55,110 evolves as humans add more and more features to it. 1061 00:53:55,110 --> 00:53:59,070 Below that, notice, is a pair of what we're going to call tags. 1062 00:53:59,070 --> 00:54:04,230 Tags are things between open brackets that start with a word like HTML 1063 00:54:04,230 --> 00:54:06,810 or some succinct phrase like that, optionally 1064 00:54:06,810 --> 00:54:09,030 with something like this word and an equal sign 1065 00:54:09,030 --> 00:54:10,960 and maybe something in quotes after that. 1066 00:54:10,960 --> 00:54:14,550 But highlighted in yellow here is the first of our HTML tags. 1067 00:54:14,550 --> 00:54:17,940 And coincidentally, this tag is the HTML tag. 1068 00:54:17,940 --> 00:54:19,620 And the way it works is as follows. 1069 00:54:19,620 --> 00:54:23,670 When a browser receives an envelope containing text like this, 1070 00:54:23,670 --> 00:54:28,320 it first reads that first line and says OK, this file contains HTML version 5. 1071 00:54:28,320 --> 00:54:30,010 What comes after it? 1072 00:54:30,010 --> 00:54:33,000 Oh, here is the content of the web page. 1073 00:54:33,000 --> 00:54:35,760 It says, hey, browser, here comes some HTML. 1074 00:54:35,760 --> 00:54:38,890 Notice down here is the opposite of that statement. 1075 00:54:38,890 --> 00:54:42,720 When you get to the end of this file, you'll see a similar-looking tag, 1076 00:54:42,720 --> 00:54:46,050 but there's a forward slash front of the same word, HTML. 1077 00:54:46,050 --> 00:54:49,830 That's what we'll call a close tag if we think of this as an open tag. 1078 00:54:49,830 --> 00:54:52,650 Or if you think of this as a start tag, this is an end tag. 1079 00:54:52,650 --> 00:54:56,280 And most tags indeed have that symmetry whereby when you open them once, 1080 00:54:56,280 --> 00:54:59,800 you should eventually close them, ideally in the appropriate order. 1081 00:54:59,800 --> 00:55:01,950 Notice that you don't have to repeat other stuff. 1082 00:55:01,950 --> 00:55:04,230 When you close a tag, you just mentioned the name 1083 00:55:04,230 --> 00:55:06,000 of the tag to keep it fairly succinct. 1084 00:55:06,000 --> 00:55:08,880 And that means, hey, browser, that's it for the HTML. 1085 00:55:08,880 --> 00:55:10,290 All right, what's inside of that? 1086 00:55:10,290 --> 00:55:13,720 If we look down below this, you'll see that there's this thing here, 1087 00:55:13,720 --> 00:55:15,720 which is what's going to be called an attribute. 1088 00:55:15,720 --> 00:55:18,510 Attributes tend to be short, succinct phrases that 1089 00:55:18,510 --> 00:55:21,000 have some special meaning for that particular tag. 1090 00:55:21,000 --> 00:55:24,300 This particular attribute, if you read the documentation for the language 1091 00:55:24,300 --> 00:55:29,130 HTML, will say that if you add lang= quote-unquote "something" 1092 00:55:29,130 --> 00:55:32,670 to your HTML tag, that's going to be a clue to the browser that says, hey, 1093 00:55:32,670 --> 00:55:35,670 browser, here comes HTML, and by the way, 1094 00:55:35,670 --> 00:55:38,910 the contents of this web page are going to be in English, 1095 00:55:38,910 --> 00:55:41,280 at least in this case, by default, for en. 1096 00:55:41,280 --> 00:55:44,610 Every language in the world has its own two-digit or three-digit-- three 1097 00:55:44,610 --> 00:55:46,980 character-- two-character or three-character code 1098 00:55:46,980 --> 00:55:50,963 that can be placed inside these quotes that will standardize exactly 1099 00:55:50,963 --> 00:55:52,380 what the browser interprets it as. 1100 00:55:52,380 --> 00:55:55,500 Useful these days if you have translation enabled in your browser. 1101 00:55:55,500 --> 00:55:57,630 It knows what language the page is written in so 1102 00:55:57,630 --> 00:56:00,660 that it can help you translate it to your own spoken language. 1103 00:56:00,660 --> 00:56:03,780 All right, below that, there's two sets-- 1104 00:56:03,780 --> 00:56:07,540 two pairs of tags, the head tag here and the body tag here. 1105 00:56:07,540 --> 00:56:09,540 And I've highlighted them both at the same time, 1106 00:56:09,540 --> 00:56:13,750 because you can think of these as both children of the HTML tag. 1107 00:56:13,750 --> 00:56:18,670 So if we borrow our metaphor of a family tree and some kind of hierarchy here. 1108 00:56:18,670 --> 00:56:23,340 If you think of the HTML tag as being like the parent, so to speak, 1109 00:56:23,340 --> 00:56:27,690 this parent has two children, a head tag and a body tag, each of which 1110 00:56:27,690 --> 00:56:29,460 is respectively opened and closed. 1111 00:56:29,460 --> 00:56:31,470 Let's consider the first one, the head tag. 1112 00:56:31,470 --> 00:56:33,490 What's inside of that, so to speak? 1113 00:56:33,490 --> 00:56:37,590 Inside of that is the title tag which as you might guess by now 1114 00:56:37,590 --> 00:56:40,530 is going to represent the title of the web page we're writing. 1115 00:56:40,530 --> 00:56:43,410 Specifically, the title of this web page is going to be literally-- 1116 00:56:43,410 --> 00:56:45,030 and just goofily-- 1117 00:56:45,030 --> 00:56:46,530 hello comma title. 1118 00:56:46,530 --> 00:56:49,620 So that's what you would see in the tab of this page. 1119 00:56:49,620 --> 00:56:53,340 Let's back up a little bit and look now with the second child of the HTML tag, 1120 00:56:53,340 --> 00:56:54,600 the so-called body tag. 1121 00:56:54,600 --> 00:56:57,750 This is going to be the big, rectangular region of the web page, 1122 00:56:57,750 --> 00:56:59,730 otherwise known as the body or viewport. 1123 00:56:59,730 --> 00:57:03,600 And here, we see that the contents of that rectangular region of the page 1124 00:57:03,600 --> 00:57:06,010 is going to be literally hello comma body. 1125 00:57:06,010 --> 00:57:11,820 So that is to say this is the HTML for a fairly simplistic page whose title bar 1126 00:57:11,820 --> 00:57:14,460 in the tab is hello comma title and whose 1127 00:57:14,460 --> 00:57:19,380 body in the big rectangular region is quite simply hello comma body. 1128 00:57:19,380 --> 00:57:22,800 And it's perhaps helpful now to call out explicitly 1129 00:57:22,800 --> 00:57:26,520 that we can think of this, a la week 5, as really a data structure. 1130 00:57:26,520 --> 00:57:30,060 Even though it's just text inside of that envelope that gets read top 1131 00:57:30,060 --> 00:57:33,030 to bottom, left to right, what the browser is actually 1132 00:57:33,030 --> 00:57:35,680 going to do on your laptop or desktop or phone 1133 00:57:35,680 --> 00:57:38,200 is actually build a data structure in memory. 1134 00:57:38,200 --> 00:57:40,810 So Microsoft, who wrote Edge, or Google, who 1135 00:57:40,810 --> 00:57:44,380 wrote Chrome, or Apple who wrote Safari, wrote 1136 00:57:44,380 --> 00:57:48,910 code that reads HTML top to bottom, left to right, like a big, long string, 1137 00:57:48,910 --> 00:57:52,690 parses it-- that is, analyzes it-- and builds up into the computer's memory 1138 00:57:52,690 --> 00:57:56,050 a tree-like data structure like this, much like for problem set 5, 1139 00:57:56,050 --> 00:57:59,860 you built up your own hash table in memory for what was otherwise 1140 00:57:59,860 --> 00:58:02,260 just a big text file of words. 1141 00:58:02,260 --> 00:58:03,830 So you can see the hierarchy here. 1142 00:58:03,830 --> 00:58:06,460 If you think of the whole file as being a so-called document, 1143 00:58:06,460 --> 00:58:09,580 we'll draw a node, so to speak, in this tree here. 1144 00:58:09,580 --> 00:58:12,820 The very first and only child of that is the HTML tag. 1145 00:58:12,820 --> 00:58:15,580 Indeed, every page has to start with that HTML tag. 1146 00:58:15,580 --> 00:58:19,280 It has two children, as I proposed, head and body respectively. 1147 00:58:19,280 --> 00:58:23,990 And then head has a title child, and that has a child itself, 1148 00:58:23,990 --> 00:58:25,000 which is just text. 1149 00:58:25,000 --> 00:58:28,600 And just to be a little nit-picky, I've deliberately drawn these nodes 1150 00:58:28,600 --> 00:58:33,880 in slightly different shapes just to connote that HTML, head, title, 1151 00:58:33,880 --> 00:58:38,680 and body are indeed all tags, opened and closed. 1152 00:58:38,680 --> 00:58:41,110 These ovals here are just text. 1153 00:58:41,110 --> 00:58:42,970 Those are not inside of-- 1154 00:58:42,970 --> 00:58:44,500 those are not tags themselves. 1155 00:58:44,500 --> 00:58:46,540 That's just raw text here and here. 1156 00:58:46,540 --> 00:58:48,970 And then the document node is the one random one. 1157 00:58:48,970 --> 00:58:52,630 This is the only thing that's going to start with an exclamation point, 1158 00:58:52,630 --> 00:58:55,240 typically, unless you have what we'll call comments 1159 00:58:55,240 --> 00:58:58,690 in HTML, which are just notes to self that we saw in C and in Python. 1160 00:58:58,690 --> 00:59:01,250 There's similar syntax for those. 1161 00:59:01,250 --> 00:59:01,750 All right. 1162 00:59:01,750 --> 00:59:05,500 With that said, if this is the simplest web page we can make, 1163 00:59:05,500 --> 00:59:06,580 where do we make it? 1164 00:59:06,580 --> 00:59:07,330 How do we make it? 1165 00:59:07,330 --> 00:59:10,000 So you could certainly just open up your Mac or PC 1166 00:59:10,000 --> 00:59:12,910 and open up something like Text Edit or Notepad.exe 1167 00:59:12,910 --> 00:59:15,400 and type this out, copy and paste it, save the file, 1168 00:59:15,400 --> 00:59:16,630 and open it in your browser. 1169 00:59:16,630 --> 00:59:18,797 But that's not that interesting, because if you just 1170 00:59:18,797 --> 00:59:22,120 save an HTML file on your Mac or PC, you are 1171 00:59:22,120 --> 00:59:25,040 going to be literally the only one in the world who can visit it. 1172 00:59:25,040 --> 00:59:28,270 So ideally, you want a server on which you can write and save 1173 00:59:28,270 --> 00:59:31,540 your HTML so that other people, your users, your customers, 1174 00:59:31,540 --> 00:59:34,270 can visit the file via the internet. 1175 00:59:34,270 --> 00:59:36,370 Now, thankfully, we all have access to a tool 1176 00:59:36,370 --> 00:59:41,380 already called CS50 IDE, which itself is a web-based tool for writing code, 1177 00:59:41,380 --> 00:59:44,598 and the code we'll start writing now just happens to be in HTML. 1178 00:59:44,598 --> 00:59:45,890 So let me go ahead and do that. 1179 00:59:45,890 --> 00:59:48,470 Let me go ahead and open up a new file. 1180 00:59:48,470 --> 00:59:52,815 I'll go ahead and call this, say, hello.html, 1181 00:59:52,815 --> 00:59:55,960 dot html being the conventional file extension, and let me just go ahead 1182 00:59:55,960 --> 00:59:57,010 and retype. 1183 00:59:57,010 --> 01:00:01,150 That so !DOCTYPE HTML says, hey, browser, here comes version five. 1184 01:00:01,150 --> 01:00:03,850 html lang="en". 1185 01:00:03,850 --> 01:00:05,830 And now notice what the IDE is doing for me. 1186 01:00:05,830 --> 01:00:08,468 For better or for worse, depending on your preferences, 1187 01:00:08,468 --> 01:00:11,260 it's going to try to complete your thoughts for you so you can just 1188 01:00:11,260 --> 01:00:11,920 type less. 1189 01:00:11,920 --> 01:00:15,760 This is increasingly a feature of IDEs, Integrated Development Environments, 1190 01:00:15,760 --> 01:00:18,005 because now I can type roughly half as much. 1191 01:00:18,005 --> 01:00:20,380 Now, I'm going to go ahead and open the head of the page. 1192 01:00:20,380 --> 01:00:22,240 Notice it got automatically closed. 1193 01:00:22,240 --> 01:00:24,550 I'm going to go ahead and open the title of the page. 1194 01:00:24,550 --> 01:00:27,470 That will automatically close as well. 1195 01:00:27,470 --> 01:00:30,580 And let me go ahead and just do something like hello, title. 1196 01:00:30,580 --> 01:00:34,990 And then down here, outside of the head tag, I'll do my body tag 1197 01:00:34,990 --> 01:00:37,090 and do hello comma body. 1198 01:00:37,090 --> 01:00:41,290 Now, strictly speaking, this indentation is not necessary. 1199 01:00:41,290 --> 01:00:44,620 If I wanted to be a little more terse and not use this many lines, 1200 01:00:44,620 --> 01:00:46,138 this is totally reasonable as well. 1201 01:00:46,138 --> 01:00:47,930 And it's probably reasonable up to a point. 1202 01:00:47,930 --> 01:00:51,670 If I had a crazy long title, I probably should move it to a line of its own. 1203 01:00:51,670 --> 01:00:54,692 But again, these details are not going to matter to the computer, 1204 01:00:54,692 --> 01:00:56,650 to the browser reading this, but they certainly 1205 01:00:56,650 --> 01:00:58,570 make it prettier and easier for me, the human, 1206 01:00:58,570 --> 01:01:00,560 and presumably you to read as well. 1207 01:01:00,560 --> 01:01:02,420 So I've gone ahead and saved this file. 1208 01:01:02,420 --> 01:01:05,170 And in the past, I would have used like make for C 1209 01:01:05,170 --> 01:01:08,530 or would have used python for Python, but neither of those 1210 01:01:08,530 --> 01:01:11,200 is applicable, because we're not writing or running code. 1211 01:01:11,200 --> 01:01:13,480 I now want to visit this web page. 1212 01:01:13,480 --> 01:01:14,660 And how do I do that? 1213 01:01:14,660 --> 01:01:16,600 Well, I need a browser, and I'm all set there. 1214 01:01:16,600 --> 01:01:19,420 Obviously, I can use Chrome, Safari, whatever on my own Mac. 1215 01:01:19,420 --> 01:01:20,740 But I also need a server. 1216 01:01:20,740 --> 01:01:25,780 And it turns out that CS50 IDE, insofar as it is already a web 1217 01:01:25,780 --> 01:01:29,200 server that we use to write code, we can use it as a web server 1218 01:01:29,200 --> 01:01:31,460 to serve our HTML as well. 1219 01:01:31,460 --> 01:01:35,120 So a little bit ago, when I played the role of a web server, 1220 01:01:35,120 --> 01:01:37,240 I need to essentially implement in the IDE 1221 01:01:37,240 --> 01:01:39,910 that same notion, of some program that's just 1222 01:01:39,910 --> 01:01:43,210 going to listen and listen and listen, like I was waiting for Brian, 1223 01:01:43,210 --> 01:01:46,270 and any time I get an HTTP request from anyone's browser, 1224 01:01:46,270 --> 01:01:48,228 I'm going to respond with the appropriate file. 1225 01:01:48,228 --> 01:01:50,603 Now, we're not going to implement a web server ourselves. 1226 01:01:50,603 --> 01:01:52,510 Web servers are kind of commodity these days. 1227 01:01:52,510 --> 01:01:55,210 Anyone can just download or pay for one and use one. 1228 01:01:55,210 --> 01:02:00,530 And indeed, the IDE comes with one quite simply called http-server. 1229 01:02:00,530 --> 01:02:03,130 So this is a program preinstalled in the IDE. 1230 01:02:03,130 --> 01:02:04,270 It's free and open source. 1231 01:02:04,270 --> 01:02:06,610 You can use it on Linux or Macs or PCs as well. 1232 01:02:06,610 --> 01:02:08,260 But it's preinstalled in the IDE. 1233 01:02:08,260 --> 01:02:11,530 And when I run it, what it's going to do for me is start, 1234 01:02:11,530 --> 01:02:13,960 curiously, a second web server. 1235 01:02:13,960 --> 01:02:18,230 Because the IDE itself is already running on CS50's own web server, 1236 01:02:18,230 --> 01:02:20,950 I need to now run my own server. 1237 01:02:20,950 --> 01:02:23,420 But in order to distinguish one from the other, 1238 01:02:23,420 --> 01:02:25,180 I'm just going to use a different port. 1239 01:02:25,180 --> 01:02:29,770 And by default, the port that the CS50 IDE uses is this one 8080. 1240 01:02:29,770 --> 01:02:33,220 So again, by default, most web servers in the world 1241 01:02:33,220 --> 01:02:38,160 use port 80 if insecure and port 443 if secure. 1242 01:02:38,160 --> 01:02:40,990 But those are, unfortunately, already used by CS50 IDE 1243 01:02:40,990 --> 01:02:43,810 itself, which is running already on CS50's web server. 1244 01:02:43,810 --> 01:02:48,300 So if I want to use the same server, the same computer in the cloud, 1245 01:02:48,300 --> 01:02:51,480 to listen for other requests of my own, I'm 1246 01:02:51,480 --> 01:02:54,567 just going to start my own second web server in parallel 1247 01:02:54,567 --> 01:02:56,400 and just have it listen on a different port. 1248 01:02:56,400 --> 01:02:59,220 And that's just so that you and I can run our own web 1249 01:02:59,220 --> 01:03:02,220 server even though we don't have control over the IDE 1250 01:03:02,220 --> 01:03:04,110 itself outside of our own accounts. 1251 01:03:04,110 --> 01:03:07,020 Now, it's a pretty cryptic looking hostname, if you will. 1252 01:03:07,020 --> 01:03:11,680 It's this random thing, 0cda3813 and so forth. 1253 01:03:11,680 --> 01:03:14,430 But at the end of the day, it's just a URL. 1254 01:03:14,430 --> 01:03:18,780 Notice that it ends in CS50.xyz, which is a domain name that we bought 1255 01:03:18,780 --> 01:03:23,670 and we use solely for this purpose of running web servers on CS50 IDE. 1256 01:03:23,670 --> 01:03:27,270 So if I go ahead and click that and click Open, voila, 1257 01:03:27,270 --> 01:03:32,580 I will now see a fairly arcane textual listing of all of the files 1258 01:03:32,580 --> 01:03:35,295 in the folder in which I just ran HTTP server. 1259 01:03:35,295 --> 01:03:37,170 And let me go ahead and zoom in a little bit, 1260 01:03:37,170 --> 01:03:39,253 and you'll see that there's only one file on there 1261 01:03:39,253 --> 01:03:41,400 thus far that we've written, hello.html. 1262 01:03:41,400 --> 01:03:43,500 So let me go ahead and click on that file. 1263 01:03:43,500 --> 01:03:46,657 And voila, there it is, hello, body, my very first page. 1264 01:03:46,657 --> 01:03:49,740 I don't see the title because I'm in full-screen mode, but let me go ahead 1265 01:03:49,740 --> 01:03:52,180 and un-full-screen myself, and sure enough, 1266 01:03:52,180 --> 01:03:58,300 if I zoom in on the title in the tab of this page, it's hello comma title. 1267 01:03:58,300 --> 01:03:59,760 So what has just happened? 1268 01:03:59,760 --> 01:04:02,910 I happened to be using CS50 IDE just because it's convenient. 1269 01:04:02,910 --> 01:04:04,740 You and I already have accounts on it. 1270 01:04:04,740 --> 01:04:07,020 We're running our own web server, implementing 1271 01:04:07,020 --> 01:04:10,560 the software version of the role I was humanly playing earlier. 1272 01:04:10,560 --> 01:04:14,760 I'm using Chrome as my browser, just like Brian was our browser in the story 1273 01:04:14,760 --> 01:04:15,420 before. 1274 01:04:15,420 --> 01:04:20,340 And so when I visit this long URL in my browser's bar that the server told me 1275 01:04:20,340 --> 01:04:24,840 to visit, notice that it ends with /hello.html. 1276 01:04:24,840 --> 01:04:29,535 So all in one environment, I'm serving web pages and requesting web pages. 1277 01:04:29,535 --> 01:04:32,160 And this is perfect, because this is what a real-world software 1278 01:04:32,160 --> 01:04:35,850 developer would do when building their own websites or web applications. 1279 01:04:35,850 --> 01:04:38,550 They want to actually keep everything local and work on it 1280 01:04:38,550 --> 01:04:42,360 and work on it until they're ready to release it to the world. 1281 01:04:42,360 --> 01:04:46,560 Well, let me go ahead here and point out one thing in the tab here. 1282 01:04:46,560 --> 01:04:49,320 And in fact, some of you very cleverly are-- actually, amazingly, 1283 01:04:49,320 --> 01:04:52,830 transcribed that URL, because I'm seeing more HTTP requests coming in right now 1284 01:04:52,830 --> 01:04:53,400 live. 1285 01:04:53,400 --> 01:04:58,290 Notice that in the terminal window of my IDE where I ran HTTP server, 1286 01:04:58,290 --> 01:05:02,520 I'm seeing, row by row, the requests coming in. 1287 01:05:02,520 --> 01:05:05,640 And so this is kind of a log, because my web server is still running, 1288 01:05:05,640 --> 01:05:08,850 and if any of you actually want to type out that same URL again, 1289 01:05:08,850 --> 01:05:13,305 if you rewind in time in the video, you can actually visit my hello.html file 1290 01:05:13,305 --> 01:05:15,930 right now on the internet, assuming you're watching the lecture 1291 01:05:15,930 --> 01:05:19,660 live, and you can see new rows appearing in my output here. 1292 01:05:19,660 --> 01:05:22,102 But that's just to say it's useful for us diagnostically. 1293 01:05:22,102 --> 01:05:24,810 But let me go ahead and do something else here for just a moment. 1294 01:05:24,810 --> 01:05:27,990 I'm going to go ahead, and in a moment, create another file, 1295 01:05:27,990 --> 01:05:30,970 this time to demonstrate some other HTML tags. 1296 01:05:30,970 --> 01:05:35,850 So let's go back here and in my-- 1297 01:05:35,850 --> 01:05:37,680 and I'll keep my terminal window running, 1298 01:05:37,680 --> 01:05:39,210 but I don't really care about the output now, 1299 01:05:39,210 --> 01:05:41,585 so I'm just going to go ahead and minimize it down there. 1300 01:05:41,585 --> 01:05:46,140 I'm going to go ahead and create another file up here called paragraphs.html. 1301 01:05:46,140 --> 01:05:48,990 And let's see if we can't introduce some other features of HTML. 1302 01:05:48,990 --> 01:05:52,200 I'll go ahead and type out the same as before, !DOCTYPE HTML, 1303 01:05:52,200 --> 01:05:55,950 my HTML tag with my lang for English attributes. 1304 01:05:55,950 --> 01:05:59,340 Sometimes, admittedly, the IDE will get confused if I start a thought, 1305 01:05:59,340 --> 01:06:01,650 don't finish my thought, then try to finish it again. 1306 01:06:01,650 --> 01:06:02,380 And that's fine. 1307 01:06:02,380 --> 01:06:05,220 You might just have to clean up what the IDE is trying to do for you 1308 01:06:05,220 --> 01:06:06,215 to be helpful. 1309 01:06:06,215 --> 01:06:08,340 I'm going to go ahead and create the head tag here. 1310 01:06:08,340 --> 01:06:09,923 I'm going to give myself a title here. 1311 01:06:09,923 --> 01:06:11,250 I'll call this page paragraphs. 1312 01:06:11,250 --> 01:06:13,500 I'll keep it all in one line just to keep it succinct. 1313 01:06:13,500 --> 01:06:15,270 I'll open up my body. 1314 01:06:15,270 --> 01:06:20,010 And now I'm going to go ahead and type out five paragraphs of Latin text 1315 01:06:20,010 --> 01:06:22,350 that I'll just go ahead and put right here. 1316 01:06:22,350 --> 01:06:24,600 And let me go ahead and indent this nicely just 1317 01:06:24,600 --> 01:06:26,160 to make it nice and readable. 1318 01:06:26,160 --> 01:06:30,180 This is your lorem ipsum text, which is just Latin-like nonsense. 1319 01:06:30,180 --> 01:06:32,695 And here I have five paragraphs of text now. 1320 01:06:32,695 --> 01:06:33,570 So this is different. 1321 01:06:33,570 --> 01:06:35,470 It's way more than just hello, body. 1322 01:06:35,470 --> 01:06:37,660 So let me go ahead and save this file. 1323 01:06:37,660 --> 01:06:40,050 Let me go back to my other tab here. 1324 01:06:40,050 --> 01:06:43,410 Notice that nothing has changed until I click 1325 01:06:43,410 --> 01:06:47,430 reload, which will reveal the latest contents of my folder. 1326 01:06:47,430 --> 01:06:49,410 So let me click paragraphs.html, and I should 1327 01:06:49,410 --> 01:06:53,196 see five paragraphs of Latin-like text. 1328 01:06:53,196 --> 01:06:59,840 Huh, no, that's just a big mess, one massive, long paragraph. 1329 01:06:59,840 --> 01:07:03,980 Any instincts for what the bug here might be? 1330 01:07:03,980 --> 01:07:08,650 Any thoughts on the chat or with a raised hand? 1331 01:07:08,650 --> 01:07:10,807 Yeah, over to Ryan. 1332 01:07:10,807 --> 01:07:12,640 AUDIENCE: At least from the way it's set up, 1333 01:07:12,640 --> 01:07:17,140 it doesn't look like HTML has auto line spacing by default, 1334 01:07:17,140 --> 01:07:20,470 so it's going to collect them all into this one big string 1335 01:07:20,470 --> 01:07:23,880 unless you somehow create a space in between each paragraph. 1336 01:07:23,880 --> 01:07:24,880 DAVID J. MALAN: Exactly. 1337 01:07:24,880 --> 01:07:28,960 HTML, like most any computer language, programming or otherwise, 1338 01:07:28,960 --> 01:07:31,630 is going to take you literally, and if you don't tell it 1339 01:07:31,630 --> 01:07:34,490 what to do using, in HTML cases, these tags, 1340 01:07:34,490 --> 01:07:37,370 it's just going to do some default behavior instead. 1341 01:07:37,370 --> 01:07:41,290 So let me actually go back to CS50 IDE-- 1342 01:07:41,290 --> 01:07:41,950 and you know? 1343 01:07:41,950 --> 01:07:43,560 Let me introduce another tag here. 1344 01:07:43,560 --> 01:07:45,760 It turns out there's a tag called the paragraph tag. 1345 01:07:45,760 --> 01:07:48,910 And the shorthand notation for that is quite simply 1346 01:07:48,910 --> 01:07:50,515 open bracket p closed bracket. 1347 01:07:50,515 --> 01:07:52,390 The IDE is going to try to finish my thought, 1348 01:07:52,390 --> 01:07:54,098 but because I already have the paragraph, 1349 01:07:54,098 --> 01:07:56,150 I'm going to need to manually fix this myself. 1350 01:07:56,150 --> 01:07:57,860 So let me go ahead and open it there. 1351 01:07:57,860 --> 01:08:00,530 And let me go ahead now and just insert a few of these. 1352 01:08:00,530 --> 01:08:03,828 So one there, one there, one there, one there. 1353 01:08:03,828 --> 01:08:05,620 And let me go ahead and copy the close tag. 1354 01:08:05,620 --> 01:08:09,010 One there, one there, one there, and one there. 1355 01:08:09,010 --> 01:08:12,190 And now, let me just, for style's sake, indent further. 1356 01:08:12,190 --> 01:08:14,440 And I know that pretty much in every past week 1357 01:08:14,440 --> 01:08:16,899 I've claimed that copy paste is bad-- 1358 01:08:16,899 --> 01:08:20,529 not really the case with HTML, because if you want multiple paragraphs, 1359 01:08:20,529 --> 01:08:21,850 there's no notion of a loop. 1360 01:08:21,850 --> 01:08:25,720 You can't create five paragraphs of Latin-like text with HTML alone, 1361 01:08:25,720 --> 01:08:29,060 so copy paste, in this case, is the right solution. 1362 01:08:29,060 --> 01:08:29,560 All right. 1363 01:08:29,560 --> 01:08:34,038 Let me go ahead now and go back to my other tab and now hit reload. 1364 01:08:34,038 --> 01:08:35,830 Nothing's going to change until you tell it 1365 01:08:35,830 --> 01:08:39,310 to, so just like you would reload a normal website, let me reload my own. 1366 01:08:39,310 --> 01:08:43,479 And voila, we fixed the problem that Ryan identified by now explicitly using 1367 01:08:43,479 --> 01:08:44,830 HTML's paragraph tag. 1368 01:08:44,830 --> 01:08:48,550 And it's deliberately the p tag because HTML tags tend to be succinct. 1369 01:08:48,550 --> 01:08:50,080 It's fewer characters to type. 1370 01:08:50,080 --> 01:08:51,760 And how do I know it's the p tag? 1371 01:08:51,760 --> 01:08:55,120 You just have to learn it at some point, in a class, in a book, in a website. 1372 01:08:55,120 --> 01:08:57,819 And indeed, much like with Python, as with C, we're 1373 01:08:57,819 --> 01:09:03,310 not going to aspire to teach you the laundry list of HTML tags 1374 01:09:03,310 --> 01:09:06,790 and attributes that are out there, but focus today particularly 1375 01:09:06,790 --> 01:09:08,920 on concepts and fundamentals so that you can 1376 01:09:08,920 --> 01:09:12,700 add to your vocabulary quite quickly via any number of online resources 1377 01:09:12,700 --> 01:09:13,727 that we'll point you to. 1378 01:09:13,727 --> 01:09:15,310 All right, let's go ahead and do this. 1379 01:09:15,310 --> 01:09:17,602 Rather than do everything from scratch, let me go ahead 1380 01:09:17,602 --> 01:09:21,490 and copy this and create another file that I'll call headings.html. 1381 01:09:21,490 --> 01:09:24,740 When writing a paper or when writing or reading a book, 1382 01:09:24,740 --> 01:09:28,479 it's very common to have chapter headings or section or subsection 1383 01:09:28,479 --> 01:09:31,265 headings, and indeed, you can do this in HTML as well. 1384 01:09:31,265 --> 01:09:33,640 So I'm going to go ahead and introduce a couple more tags 1385 01:09:33,640 --> 01:09:37,995 here, namely the H1 tag, which is like the biggest heading tag. 1386 01:09:37,995 --> 01:09:40,870 And I'm just going to write the word one here just to keep it simple. 1387 01:09:40,870 --> 01:09:43,840 Over here, I'm going to do H2, and I'll say two. 1388 01:09:43,840 --> 01:09:47,290 Down here, I'm going to go ahead and say H3, and I'll say three. 1389 01:09:47,290 --> 01:09:52,600 And down here, I'll do H4, and then four. 1390 01:09:52,600 --> 01:09:55,630 And then down here, I'll do H5-- 1391 01:09:55,630 --> 01:09:57,370 here, five. 1392 01:09:57,370 --> 01:09:59,900 And then down here, I've ran out of paragraphs, 1393 01:09:59,900 --> 01:10:03,310 but there is a six, so I'm going to go ahead and give myself one duplicated 1394 01:10:03,310 --> 01:10:07,180 paragraph just for demonstration's sake so that we have all six here 1395 01:10:07,180 --> 01:10:10,280 and go ahead and save it there. 1396 01:10:10,280 --> 01:10:10,780 All right. 1397 01:10:10,780 --> 01:10:15,250 So if I go back now to my browser and reload, it's looking-- 1398 01:10:15,250 --> 01:10:18,160 nothing happens because I'm in the wrong file, but if I go back, 1399 01:10:18,160 --> 01:10:20,590 I now have a file called headings.html. 1400 01:10:20,590 --> 01:10:21,640 Let's click that. 1401 01:10:21,640 --> 01:10:24,790 And it's the same content, but now, it's getting a little prettier, right? 1402 01:10:24,790 --> 01:10:28,330 It's big and bold headings, one, two, three, four-- notice 1403 01:10:28,330 --> 01:10:30,320 those headings are getting smaller and smaller, 1404 01:10:30,320 --> 01:10:32,860 but that's the convention in a book or an academic paper 1405 01:10:32,860 --> 01:10:35,680 where your sections and subsections and subsubsections, get 1406 01:10:35,680 --> 01:10:36,550 smaller and smaller. 1407 01:10:36,550 --> 01:10:38,800 And we can customize this if we really want, but out 1408 01:10:38,800 --> 01:10:41,740 of the box HTML gives us the ability to even format things 1409 01:10:41,740 --> 01:10:44,250 like headings like that as well. 1410 01:10:44,250 --> 01:10:45,860 Well, what else can we do in HTML? 1411 01:10:45,860 --> 01:10:47,740 Well, let me go back to my IDE. 1412 01:10:47,740 --> 01:10:50,980 Let me go ahead and copy paste some of this just to save some time. 1413 01:10:50,980 --> 01:10:55,630 And let me create another file called, say, list.html. 1414 01:10:55,630 --> 01:10:58,240 Turns out HTML makes it really easy to write lists. 1415 01:10:58,240 --> 01:11:00,563 So here, let me change my title to lists. 1416 01:11:00,563 --> 01:11:02,980 And down here, if I wanted to have a list of three things, 1417 01:11:02,980 --> 01:11:07,270 like foo, bar, and baz, which are generic computer science terms whatever 1418 01:11:07,270 --> 01:11:10,810 you just need placeholders like x, y, and z in math, foo, bar, and baz 1419 01:11:10,810 --> 01:11:12,250 are what people tend to reach for. 1420 01:11:12,250 --> 01:11:14,600 All right, I have a nice clean list there. 1421 01:11:14,600 --> 01:11:18,590 Let me go back to my other tab, go back to my directory index here, 1422 01:11:18,590 --> 01:11:20,075 and there's list.html. 1423 01:11:20,075 --> 01:11:20,950 Let me click on that. 1424 01:11:20,950 --> 01:11:24,130 And voila, same problem as Ryan identified. 1425 01:11:24,130 --> 01:11:27,700 Again, if I don't pedantically tell the browser, start a list, 1426 01:11:27,700 --> 01:11:30,070 continue the list, keep going, end the list, 1427 01:11:30,070 --> 01:11:33,520 it's just going to assume that I just want one big block of text. 1428 01:11:33,520 --> 01:11:35,320 In fact, it preserved white space. 1429 01:11:35,320 --> 01:11:39,190 It collapsed all of those new lines and tabs into single spaces. 1430 01:11:39,190 --> 01:11:40,670 But that's not what I want. 1431 01:11:40,670 --> 01:11:41,960 So how can I fix this? 1432 01:11:41,960 --> 01:11:43,430 I need some kind of additional tag. 1433 01:11:43,430 --> 01:11:45,430 And it turns out there's a couple of approaches. 1434 01:11:45,430 --> 01:11:49,890 There's the unordered list tag, so ul, for Unordered List, 1435 01:11:49,890 --> 01:11:51,140 which means it's not numbered. 1436 01:11:51,140 --> 01:11:58,030 And then inside of that, you can have child tags called the li, or List Item. 1437 01:11:58,030 --> 01:12:03,580 Foo, let me give myself another one, bar, and give myself another one, baz. 1438 01:12:03,580 --> 01:12:05,710 So it's more to type, and definitely there's 1439 01:12:05,710 --> 01:12:08,260 almost as many red characters, the HTML, which 1440 01:12:08,260 --> 01:12:10,990 is just being nicely syntax highlighted for me by the IDE, 1441 01:12:10,990 --> 01:12:13,060 than there is actual content, foo, bar, baz. 1442 01:12:13,060 --> 01:12:16,830 But if I now go back here and reload, I get a much cleaner, bulleted list. 1443 01:12:16,830 --> 01:12:18,580 And if you looked at the course's website, 1444 01:12:18,580 --> 01:12:21,820 we actually make heavy use of bulleted lists for content and indentation 1445 01:12:21,820 --> 01:12:22,930 and so forth. 1446 01:12:22,930 --> 01:12:25,540 We're just using a whole bunch of ul tags. 1447 01:12:25,540 --> 01:12:28,465 If, by contrast, you wanted the computer to number of things for you, 1448 01:12:28,465 --> 01:12:32,573 you could certainly do it like this, 1, 2, 3, 1449 01:12:32,573 --> 01:12:34,990 but you can imagine that getting a little annoying quickly 1450 01:12:34,990 --> 01:12:37,780 if you want to reorder things or add things in between. 1451 01:12:37,780 --> 01:12:40,310 So computers are really good at doing tedious things. 1452 01:12:40,310 --> 01:12:45,350 So let me change this unordered list to an ordered list using ol instead. 1453 01:12:45,350 --> 01:12:49,900 And if I go back to the other tab, reload, voila, now it's 1, 2, 3, 1454 01:12:49,900 --> 01:12:51,650 and it's automatically numbered for me. 1455 01:12:51,650 --> 01:12:54,110 I don't have to worry about it at all. 1456 01:12:54,110 --> 01:12:56,860 Well, let's do one other that speaks to the structure of the page. 1457 01:12:56,860 --> 01:12:59,050 Let me go ahead and copy my starting point, hello, 1458 01:12:59,050 --> 01:13:02,740 and create a file called table.html. 1459 01:13:02,740 --> 01:13:07,150 If you ever want to layout tabular data where you have rows and columns 1460 01:13:07,150 --> 01:13:10,540 because you want to make sense of some financial information or just 1461 01:13:10,540 --> 01:13:13,120 something akin to a spreadsheet in your own website-- 1462 01:13:13,120 --> 01:13:14,410 well, how can we do this? 1463 01:13:14,410 --> 01:13:16,360 Let me go ahead and call this table. 1464 01:13:16,360 --> 01:13:19,600 And down here in my body, let me introduce the table tag. 1465 01:13:19,600 --> 01:13:21,850 And the table tag is a little more involved 1466 01:13:21,850 --> 01:13:24,610 because you have to define what are called table rows. 1467 01:13:24,610 --> 01:13:26,900 So I can do a tr tag there. 1468 01:13:26,900 --> 01:13:31,330 And then inside of table rows I can have data, so td for Table Data. 1469 01:13:31,330 --> 01:13:32,957 Let me just put the number one. 1470 01:13:32,957 --> 01:13:36,040 And let me go ahead and make-- let me mock up something a little familiar, 1471 01:13:36,040 --> 01:13:39,040 like a phone keypad, 2, and 3. 1472 01:13:39,040 --> 01:13:41,740 Then let me go ahead and copy this once more 1473 01:13:41,740 --> 01:13:47,140 and give myself another row with, say, 4, 5, 6, and let me 1474 01:13:47,140 --> 01:13:53,350 give myself one more of those with, how about, 7, 8, 9. 1475 01:13:53,350 --> 01:13:57,430 And then lastly, one more of those just to give myself 1476 01:13:57,430 --> 01:14:01,120 the equivalent of a keypad and do the asterisk and then zero 1477 01:14:01,120 --> 01:14:02,500 and then the pound key. 1478 01:14:02,500 --> 01:14:10,170 Let me save this, go to my other browser tab, open up table.html, and voila, 1479 01:14:10,170 --> 01:14:13,860 you see something akin to an old-school phone keypad there. 1480 01:14:13,860 --> 01:14:15,900 And there is implicit rows and columns. 1481 01:14:15,900 --> 01:14:19,470 If I wanted to, I can make it a little prettier with actual lines or borders 1482 01:14:19,470 --> 01:14:21,270 in between and around these things. 1483 01:14:21,270 --> 01:14:26,910 But HTML gives me the ability to lay out tabular data using trs for table rows 1484 01:14:26,910 --> 01:14:29,580 and tds for the columns therein. 1485 01:14:29,580 --> 01:14:32,700 All right this is all pretty boring and textual, and really not the web 1486 01:14:32,700 --> 01:14:35,668 that you and I all know, so let me go back here, 1487 01:14:35,668 --> 01:14:37,710 and let's do something a little more interesting. 1488 01:14:37,710 --> 01:14:42,480 Let me go ahead and start off a file called maybe image.html. 1489 01:14:42,480 --> 01:14:45,360 And let me go ahead and start with our boilerplate as before. 1490 01:14:45,360 --> 01:14:47,460 I'll rename this title image. 1491 01:14:47,460 --> 01:14:51,760 And down here, let me go ahead and do something like this. 1492 01:14:51,760 --> 01:14:54,150 Let me go ahead and do image-- 1493 01:14:54,150 --> 01:14:58,470 how about source equals quote-unquote "harvard.jpg". 1494 01:14:58,470 --> 01:15:02,518 It turns out I came with an image of Harvard in my IDE. 1495 01:15:02,518 --> 01:15:04,560 And let me go ahead and describe it as much, too. 1496 01:15:04,560 --> 01:15:07,605 Let me add this alt attribute here, Harvard University. 1497 01:15:07,605 --> 01:15:09,730 And we'll come back to what this means in a moment, 1498 01:15:09,730 --> 01:15:14,400 but here we have this second tag thus far that actually shows us 1499 01:15:14,400 --> 01:15:16,830 how to customize the behavior of a tag. 1500 01:15:16,830 --> 01:15:20,820 So the lang attribute earlier customized the behavior of the whole web page 1501 01:15:20,820 --> 01:15:24,270 by telling the browser here comes a web page written in English. 1502 01:15:24,270 --> 01:15:27,540 And down here, we have two attributes, alt, 1503 01:15:27,540 --> 01:15:31,170 which has a value after the equal sign, and then src, S-R-C, 1504 01:15:31,170 --> 01:15:33,760 which itself has a value after the equal sign. 1505 01:15:33,760 --> 01:15:38,970 You can use single quotes or double quotes, but you should be consistent. 1506 01:15:38,970 --> 01:15:41,220 But each of these attributes should have an equal sign 1507 01:15:41,220 --> 01:15:44,120 in between the key and the value there. 1508 01:15:44,120 --> 01:15:45,640 So how might I go about doing this? 1509 01:15:45,640 --> 01:15:48,900 Well, let me go ahead and open up this file now. 1510 01:15:48,900 --> 01:15:51,240 Let me go ahead and reload. 1511 01:15:51,240 --> 01:15:54,480 We should see now image.html and Harvard.jpg, 1512 01:15:54,480 --> 01:15:56,160 which I just grabbed from my IDE. 1513 01:15:56,160 --> 01:15:59,670 And voila, image.html is the original painting 1514 01:15:59,670 --> 01:16:02,833 of what's adorned our backdrop here for the past several weeks. 1515 01:16:02,833 --> 01:16:03,750 So that's interesting. 1516 01:16:03,750 --> 01:16:06,330 You can link to a specific image like that. 1517 01:16:06,330 --> 01:16:08,260 And what's the role of the alt attribute? 1518 01:16:08,260 --> 01:16:10,110 So the alt attribute is all too overlooked 1519 01:16:10,110 --> 01:16:12,450 by new and experienced programmers alike, 1520 01:16:12,450 --> 01:16:13,980 but this speaks to accessibility. 1521 01:16:13,980 --> 01:16:17,700 Not all of us can necessarily see and hear and interact with media 1522 01:16:17,700 --> 01:16:21,330 in the same way as others, and so those who have difficulty with sight or with 1523 01:16:21,330 --> 01:16:25,890 sound or the like, the alt attribute is a wonderfully powerful and so simple 1524 01:16:25,890 --> 01:16:29,730 mechanism to include on your image tags that literally just describes 1525 01:16:29,730 --> 01:16:34,080 in English or your own spoken language what it is a human would otherwise be 1526 01:16:34,080 --> 01:16:37,708 looking at, even if they are perhaps blind and cannot actually see 1527 01:16:37,708 --> 01:16:38,250 what's there. 1528 01:16:38,250 --> 01:16:41,000 And if they have a screen reader, installed software that actually 1529 01:16:41,000 --> 01:16:44,280 can vocalize text on the screen, this incredibly usefully 1530 01:16:44,280 --> 01:16:48,360 helps people hear what it is that you and I might otherwise only 1531 01:16:48,360 --> 01:16:49,360 be looking at. 1532 01:16:49,360 --> 01:16:51,360 So be sure to be mindful of those kinds of tags, 1533 01:16:51,360 --> 01:16:54,240 and you would only know that these tags exist by, again, taking a class, 1534 01:16:54,240 --> 01:16:56,240 reading a book, looking at our online reference. 1535 01:16:56,240 --> 01:17:00,103 We're just beginning to add to now our vocabulary. 1536 01:17:00,103 --> 01:17:03,270 And in fact, let's take this one step further and do something a little more 1537 01:17:03,270 --> 01:17:05,490 powerfully and familiar still. 1538 01:17:05,490 --> 01:17:08,520 Let me go ahead and create a file called link.html. 1539 01:17:08,520 --> 01:17:10,080 Let me paste my starting point there. 1540 01:17:10,080 --> 01:17:11,850 I'll retitle this as link. 1541 01:17:11,850 --> 01:17:14,430 The web, of course, is filled with links, 1542 01:17:14,430 --> 01:17:19,510 and indeed, HyperText Markup Language is all about hypertext, 1543 01:17:19,510 --> 01:17:21,780 which is an arcane allusion to links. 1544 01:17:21,780 --> 01:17:25,420 Hypertext is text with links that link elsewhere. 1545 01:17:25,420 --> 01:17:27,870 So how might I implement a link in a web page? 1546 01:17:27,870 --> 01:17:30,600 Well, let me go ahead and, in this page, initially just encourage 1547 01:17:30,600 --> 01:17:32,820 people to visit Harvard, period. 1548 01:17:32,820 --> 01:17:37,140 Let me go back to my other browser window, open up now link.html. 1549 01:17:37,140 --> 01:17:39,510 And of course, this does not really do anything. 1550 01:17:39,510 --> 01:17:42,870 I can't click on visit Harvard or anything else and have it do anything, 1551 01:17:42,870 --> 01:17:44,680 because it's obviously just text. 1552 01:17:44,680 --> 01:17:48,000 So how can I actually link the user to some destination? 1553 01:17:48,000 --> 01:17:50,850 Well, we need another tag. 1554 01:17:50,850 --> 01:17:55,440 It is called the anchor tag, abbreviated with a single letter a, 1555 01:17:55,440 --> 01:17:58,380 it has an attribute of href, for Hyper Reference. 1556 01:17:58,380 --> 01:18:01,123 And hyper reference just means, what do you want to link to? 1557 01:18:01,123 --> 01:18:02,790 Well, let's go ahead and keep it simple. 1558 01:18:02,790 --> 01:18:07,050 Let's link to a file I already created, image.html. 1559 01:18:07,050 --> 01:18:10,050 And the word I want to link is literally Harvard. 1560 01:18:10,050 --> 01:18:14,910 So on the left of the word "Harvard," I have a href="image.html", 1561 01:18:14,910 --> 01:18:17,140 on the right of Harvard, I have the close tag. 1562 01:18:17,140 --> 01:18:19,677 And again, notice just because I had an attribute 1563 01:18:19,677 --> 01:18:22,260 on the tag does not mean you need to redundantly copy paste it 1564 01:18:22,260 --> 01:18:23,460 in the close tag. 1565 01:18:23,460 --> 01:18:26,820 It suffices to close only the name of the tag. 1566 01:18:26,820 --> 01:18:29,400 Let me save the file, go back to this page now. 1567 01:18:29,400 --> 01:18:31,650 Let me zoom in a little bit and reload. 1568 01:18:31,650 --> 01:18:35,220 And voila, now you see the familiar hyperlink 1569 01:18:35,220 --> 01:18:38,130 that you might see on many web pages where it's actually underlined. 1570 01:18:38,130 --> 01:18:41,210 And indeed, if I hover over that-- 1571 01:18:41,210 --> 01:18:44,570 if I hover over that and then click, voila, 1572 01:18:44,570 --> 01:18:48,440 we'll find ourself at Harvard University back in 1792, 1573 01:18:48,440 --> 01:18:51,380 because now what I'm looking at is image.html. 1574 01:18:51,380 --> 01:18:54,440 And in fact, let me go out of full screen mode for just a moment to make 1575 01:18:54,440 --> 01:18:58,310 clear that the URL at this point in the story where I see just Visit Harvard 1576 01:18:58,310 --> 01:19:02,240 in the page, is something/link.html. 1577 01:19:02,240 --> 01:19:04,400 You URL will differ from mine, but mine happens 1578 01:19:04,400 --> 01:19:09,170 to be this long, cryptic string, because it's my account slash link.html. 1579 01:19:09,170 --> 01:19:13,820 When I click on the link, though, notice that I end up at image.html, 1580 01:19:13,820 --> 01:19:18,823 thereby taking me to a relative URL that is a file in my own account. 1581 01:19:18,823 --> 01:19:20,990 If I don't want to link to that file, though-- maybe 1582 01:19:20,990 --> 01:19:23,000 I want to link to Harvard itself. 1583 01:19:23,000 --> 01:19:25,430 It's not sufficient to just do Harvard.edu. 1584 01:19:25,430 --> 01:19:26,800 That is not a URL. 1585 01:19:26,800 --> 01:19:28,910 www is not a URL. 1586 01:19:28,910 --> 01:19:33,800 I need my protocol, so to speak, either HTTP, or, better yet, HTTPS. 1587 01:19:33,800 --> 01:19:37,760 If I save that file now and reload and go back here, 1588 01:19:37,760 --> 01:19:42,710 the text looks exactly the same, but notice, if I hover over it, 1589 01:19:42,710 --> 01:19:46,340 there's a tiny, tiny, tiny, tiny little visual clue 1590 01:19:46,340 --> 01:19:49,430 at the bottom of the screen that says where I'm going to end up. 1591 01:19:49,430 --> 01:19:53,810 And indeed, if I click this now, notice that my URL bar is not going 1592 01:19:53,810 --> 01:19:57,140 to stay as my IDE slash link.html. 1593 01:19:57,140 --> 01:19:59,930 It's going to whisk me away to the actual Harvard.edu. 1594 01:19:59,930 --> 01:20:04,490 And here, it's worth noting that Chrome and Safari and browsers, for better 1595 01:20:04,490 --> 01:20:07,010 or for worse, are increasingly simplifying 1596 01:20:07,010 --> 01:20:09,540 the user experience or UX of browsers. 1597 01:20:09,540 --> 01:20:11,405 I am not literally at Harvard.edu. 1598 01:20:11,405 --> 01:20:14,670 If you click or double-click on the address bar, 1599 01:20:14,670 --> 01:20:16,520 you'll see where you actually are. 1600 01:20:16,520 --> 01:20:18,860 And this is, for developers, a worse. 1601 01:20:18,860 --> 01:20:22,880 For regular users, it's probably cleaner just to see the domain name. 1602 01:20:22,880 --> 01:20:25,010 But all of the information is indeed there 1603 01:20:25,010 --> 01:20:27,830 if you dig for it just a little bit. 1604 01:20:27,830 --> 01:20:31,220 But there's kind of an exploit here, possible. 1605 01:20:31,220 --> 01:20:33,080 There's kind of an exploit here. 1606 01:20:33,080 --> 01:20:36,830 What if I were to do something somewhat maliciously, like this. 1607 01:20:36,830 --> 01:20:42,560 Like, let me change this to Yale.edu leave the word "Harvard" unchanged? 1608 01:20:42,560 --> 01:20:45,290 If I go back now to my other tab and reload, 1609 01:20:45,290 --> 01:20:48,602 it looks different at the moment because it's blue instead of purple. 1610 01:20:48,602 --> 01:20:50,810 Purple by default means I've been there before, which 1611 01:20:50,810 --> 01:20:52,010 we were a few minutes ago. 1612 01:20:52,010 --> 01:20:53,570 Blue means I haven't visited before. 1613 01:20:53,570 --> 01:20:55,280 But if I don't really notice that subtlety, 1614 01:20:55,280 --> 01:20:58,322 I might very well think that, oh, this is the university I want to go to. 1615 01:20:58,322 --> 01:21:02,000 But voila, when I click on that, wrong place. 1616 01:21:02,000 --> 01:21:07,760 All right, silly example, but this can really be exploited for ill purposes. 1617 01:21:07,760 --> 01:21:11,000 What comes to mind, or what threats come to mind 1618 01:21:11,000 --> 01:21:14,660 with this very simple mechanism? 1619 01:21:14,660 --> 01:21:17,390 Right, now that you have the ability to make web pages, 1620 01:21:17,390 --> 01:21:20,750 you have the ability to say you're going one place 1621 01:21:20,750 --> 01:21:22,530 but really lead the user elsewhere. 1622 01:21:22,530 --> 01:21:24,320 Can you see how this might be abused? 1623 01:21:24,320 --> 01:21:25,340 Santiago? 1624 01:21:25,340 --> 01:21:30,310 AUDIENCE: I think it maybe could be used by so-called hackers who 1625 01:21:30,310 --> 01:21:34,185 can break in and insert malicious software into your computer? 1626 01:21:34,185 --> 01:21:35,060 DAVID J. MALAN: Yeah. 1627 01:21:35,060 --> 01:21:37,005 AUDIENCE: And they trick you into doing that. 1628 01:21:37,005 --> 01:21:37,880 DAVID J. MALAN: Yeah. 1629 01:21:37,880 --> 01:21:39,320 And "trick" is the operative word. 1630 01:21:39,320 --> 01:21:43,040 I mean, most of us are probably not in the habit of opening up-- 1631 01:21:43,040 --> 01:21:47,130 before clicking on a link, hovering over it, like I did a moment ago, 1632 01:21:47,130 --> 01:21:51,758 and then very paranoiacly, looking down here to see if-- 1633 01:21:51,758 --> 01:21:53,300 am I really going to the right place? 1634 01:21:53,300 --> 01:21:55,070 And even this can be spoofed. 1635 01:21:55,070 --> 01:21:58,160 You can trick the user into thinking they're going to the right place 1636 01:21:58,160 --> 01:22:00,180 but still override this behavior. 1637 01:22:00,180 --> 01:22:05,152 And so if you've ever been the victim of or the near victim of phishing attack, 1638 01:22:05,152 --> 01:22:07,490 P-H-I-S-H-I-N-G-- 1639 01:22:07,490 --> 01:22:11,510 "phishing" refers to trying to trick humans, as Santiago says, 1640 01:22:11,510 --> 01:22:13,880 via social engineering into doing something 1641 01:22:13,880 --> 01:22:15,560 that they didn't actually intend. 1642 01:22:15,560 --> 01:22:19,910 And so you can imagine receiving spam in your email inbox that says, 1643 01:22:19,910 --> 01:22:22,310 click this link to visit PayPal.com, because you 1644 01:22:22,310 --> 01:22:24,620 need to verify your password, or click here 1645 01:22:24,620 --> 01:22:26,610 to tell us your social security number. 1646 01:22:26,610 --> 01:22:29,450 This is so common these days to get emails 1647 01:22:29,450 --> 01:22:33,050 which themselves these days are-- if they're not just text, 1648 01:22:33,050 --> 01:22:34,940 they are HTML itself. 1649 01:22:34,940 --> 01:22:36,980 When you're looking at any email in Gmail that 1650 01:22:36,980 --> 01:22:39,740 has clickable links or images, that email 1651 01:22:39,740 --> 01:22:42,260 contains HTML like we're writing here. 1652 01:22:42,260 --> 01:22:47,120 It is trivial to trick users into going places 1653 01:22:47,120 --> 01:22:48,633 that they didn't actually intend. 1654 01:22:48,633 --> 01:22:51,050 And so among the takeaways for today, beyond the mechanics 1655 01:22:51,050 --> 01:22:53,133 of how to do these things, should be consideration 1656 01:22:53,133 --> 01:22:57,020 for your own personal security, as to how distrusting you 1657 01:22:57,020 --> 01:23:01,160 should really be of websites because of how simple these mechanisms are 1658 01:23:01,160 --> 01:23:04,220 and how they can lead you, indeed, to the wrong place. 1659 01:23:04,220 --> 01:23:08,000 And recall that a bit ago, we wrote this link.html example, which 1660 01:23:08,000 --> 01:23:13,130 had, in the correct version, a link to www.Harvard.edu whose text was the word 1661 01:23:13,130 --> 01:23:13,880 "Harvard". 1662 01:23:13,880 --> 01:23:16,640 Suppose now that we want to override the browser's default 1663 01:23:16,640 --> 01:23:21,890 stylization of links-- which, recall, if I now visit in my other tab, link.html, 1664 01:23:21,890 --> 01:23:22,760 is pretty boring. 1665 01:23:22,760 --> 01:23:26,720 By default, and this has been true for like 20 years, links tend to be blue 1666 01:23:26,720 --> 01:23:30,500 and underlined before you visit them, or purple and underlined 1667 01:23:30,500 --> 01:23:33,860 after you visited them at least once, a visual cue. 1668 01:23:33,860 --> 01:23:36,380 But most websites today, including CS50's own, 1669 01:23:36,380 --> 01:23:40,380 use different colors and different aesthetics for links on a web page, 1670 01:23:40,380 --> 01:23:42,870 with or without underlining, different colors, maybe even 1671 01:23:42,870 --> 01:23:44,037 different background colors. 1672 01:23:44,037 --> 01:23:46,960 You can style these things using CSS in bunches of ways. 1673 01:23:46,960 --> 01:23:47,980 So how might we do this? 1674 01:23:47,980 --> 01:23:51,240 Well, let's go ahead and be fair here and say Visit Harvard, 1675 01:23:51,240 --> 01:23:57,540 or, for instance, a href="http://www.yale.edu" 1676 01:23:57,540 --> 01:23:59,010 question mark-- 1677 01:23:59,010 --> 01:24:01,590 no, nope, close bracket Yale. 1678 01:24:01,590 --> 01:24:04,075 Let's give myself two links that, of course, if I reload, 1679 01:24:04,075 --> 01:24:04,950 just looks like this. 1680 01:24:04,950 --> 01:24:08,010 Both of them are now boring and purple because we've been to both places 1681 01:24:08,010 --> 01:24:08,800 already. 1682 01:24:08,800 --> 01:24:12,000 So let me go ahead and add a style tag up here. 1683 01:24:12,000 --> 01:24:15,300 Just to keep us in the same file, I'm going to go back to using a style tag 1684 01:24:15,300 --> 01:24:17,650 rather than introduce a separate file. 1685 01:24:17,650 --> 01:24:19,890 So to keep things simple in my style tag, 1686 01:24:19,890 --> 01:24:24,120 let me go ahead and change these links, for instance, to have a color of-- 1687 01:24:24,120 --> 01:24:29,100 maybe let's make them all red initially, ff0000. 1688 01:24:29,100 --> 01:24:31,050 And let's go ahead and save that. 1689 01:24:31,050 --> 01:24:34,230 Let me reload, and you'll see that now both of the links 1690 01:24:34,230 --> 01:24:35,710 are red and underlined. 1691 01:24:35,710 --> 01:24:38,290 I don't really like the underline, so let's get rid of that. 1692 01:24:38,290 --> 01:24:41,512 Let's change the text decoration of my a tags to be none. 1693 01:24:41,512 --> 01:24:43,470 And again, you would only know these properties 1694 01:24:43,470 --> 01:24:45,150 exist from some form of reference. 1695 01:24:45,150 --> 01:24:47,440 But again, just adding to our vocabulary. 1696 01:24:47,440 --> 01:24:48,480 Let's reload now. 1697 01:24:48,480 --> 01:24:50,370 And now the underlines are gone. 1698 01:24:50,370 --> 01:24:52,740 But it would be kind of cool, like some websites, 1699 01:24:52,740 --> 01:24:56,610 if when you hover over the link-- at least on a laptop or desktop-- 1700 01:24:56,610 --> 01:25:00,250 the link then underlines, drawing your attention all the more to it. 1701 01:25:00,250 --> 01:25:01,510 How can we do that? 1702 01:25:01,510 --> 01:25:06,450 Well, it turns out that you can use what are called pseudo selectors, which 1703 01:25:06,450 --> 01:25:07,770 are-- work like this. 1704 01:25:07,770 --> 01:25:10,140 If I want to change the behavior of the a tag 1705 01:25:10,140 --> 01:25:12,450 but only when our user is hovering over it, 1706 01:25:12,450 --> 01:25:15,480 you literally write the name of the tag colon hover. 1707 01:25:15,480 --> 01:25:18,450 And then inside of this block, I'm going to go ahead and say 1708 01:25:18,450 --> 01:25:21,750 text-decoration underline. 1709 01:25:21,750 --> 01:25:27,070 So this will say, make everything red and not underlined by default, 1710 01:25:27,070 --> 01:25:30,600 but when the user hovers, go ahead and decorate it with an underline. 1711 01:25:30,600 --> 01:25:33,150 So let's go back to the file after saving, reload. 1712 01:25:33,150 --> 01:25:35,640 No visual change yet until I move my cursor up here, 1713 01:25:35,640 --> 01:25:39,690 and voila, now it's getting a little more like modern websites. 1714 01:25:39,690 --> 01:25:42,750 Now, this isn't quite fair to Yale that both of the links are red, 1715 01:25:42,750 --> 01:25:45,990 so what if we change the colors of different types of links? 1716 01:25:45,990 --> 01:25:49,260 Well, let me go down here, and I need to distinguish these links 1717 01:25:49,260 --> 01:25:50,350 in different ways. 1718 01:25:50,350 --> 01:25:52,150 And I could use classes for that. 1719 01:25:52,150 --> 01:25:54,840 But if I've only got one Harvard link and one Yale link, 1720 01:25:54,840 --> 01:25:56,880 I might as well uniquely identify them. 1721 01:25:56,880 --> 01:26:00,690 Let me go ahead and add an attribute called id of quote-unquote Harvard, 1722 01:26:00,690 --> 01:26:03,550 and I'll keep it all lowercase, kind of like a variable. 1723 01:26:03,550 --> 01:26:06,270 And that then here I'm going to say id="yale". 1724 01:26:06,270 --> 01:26:08,220 I could call these things anything I want, 1725 01:26:08,220 --> 01:26:10,720 but because there's only one Harvard link and one Yale link, 1726 01:26:10,720 --> 01:26:14,430 I'm going to add an attribute in HTML that just lets me verbally 1727 01:26:14,430 --> 01:26:18,100 uniquely identify each of those links. 1728 01:26:18,100 --> 01:26:20,790 But up here, notice what I can do now. 1729 01:26:20,790 --> 01:26:24,060 Let me go ahead and remove the color from here 1730 01:26:24,060 --> 01:26:28,380 and let me instead say that for any tag that-- 1731 01:26:28,380 --> 01:26:35,160 for the tag that has an ID of Harvard, go ahead and color it as ff0000, 1732 01:26:35,160 --> 01:26:42,960 but if it has an ID of Yale, go ahead and have a color of 0000ff, 1733 01:26:42,960 --> 01:26:45,930 so that should give me my blue in RGB. 1734 01:26:45,930 --> 01:26:48,520 And notice the new symbol here is the hash symbol. 1735 01:26:48,520 --> 01:26:51,660 So in the world of CSS, a hash symbol before a word 1736 01:26:51,660 --> 01:26:55,680 means the unique identifier Harvard or the unique identifier Yale. 1737 01:26:55,680 --> 01:26:59,220 A dot before a word means the class centered, 1738 01:26:59,220 --> 01:27:01,810 the class large or medium or small. 1739 01:27:01,810 --> 01:27:06,120 And if you don't have any symbol before the word, like a hash or a dot, 1740 01:27:06,120 --> 01:27:09,570 means literally the tag called a or literally 1741 01:27:09,570 --> 01:27:12,930 the tag called a when it's being hovered over it. 1742 01:27:12,930 --> 01:27:14,490 So again, a few pieces of syntax. 1743 01:27:14,490 --> 01:27:18,090 It's not programming code, but it is code of some sort here. 1744 01:27:18,090 --> 01:27:18,960 Let me save this. 1745 01:27:18,960 --> 01:27:20,760 Let me go back to my tab and reload. 1746 01:27:20,760 --> 01:27:25,200 And voila, now I have the beginnings of a prettier website where 1747 01:27:25,200 --> 01:27:28,410 I'm distinguishing Harvard with its underline in red and Yale 1748 01:27:28,410 --> 01:27:32,110 with its underline in blue, but only under those certain conditions. 1749 01:27:32,110 --> 01:27:37,380 So we have with CSS the ability to much more precisely control 1750 01:27:37,380 --> 01:27:40,200 the aesthetics of our web pages. 1751 01:27:40,200 --> 01:27:43,470 All right, let's go ahead and clarify just a couple of things here. 1752 01:27:43,470 --> 01:27:48,630 Let me go up to one final example and see if we can't now 1753 01:27:48,630 --> 01:27:50,960 come back to that idea of user input. 1754 01:27:50,960 --> 01:27:53,040 So let me go back to the IDE here and let 1755 01:27:53,040 --> 01:27:57,060 me grab a little bit of starter code from my hello file as before 1756 01:27:57,060 --> 01:28:02,758 and create one final example here called search.html that's purely HTML indeed. 1757 01:28:02,758 --> 01:28:04,800 I'm going to name this thing search, and then I'm 1758 01:28:04,800 --> 01:28:08,910 going to go, down in my body of the page, use another new tag. 1759 01:28:08,910 --> 01:28:13,230 Turns out HTML also supports a form tag, and that form tag 1760 01:28:13,230 --> 01:28:16,540 can take a couple of attributes, one of which is action. 1761 01:28:16,540 --> 01:28:20,530 And this is where you want to have the form lead the user. 1762 01:28:20,530 --> 01:28:23,080 I'm going to go ahead and come back to that in just a moment. 1763 01:28:23,080 --> 01:28:26,360 The other is method, and the method is the HTTP verb to use. 1764 01:28:26,360 --> 01:28:27,610 For now, I'm going to use get. 1765 01:28:27,610 --> 01:28:31,380 And here, inconsistently, it should be lowercase, even though we've previously 1766 01:28:31,380 --> 01:28:32,730 seen it in uppercase. 1767 01:28:32,730 --> 01:28:35,970 Inside of the form tag, I'm going to have a couple of inputs, an input 1768 01:28:35,970 --> 01:28:41,790 whose name is going to be q and whose type is going to be search. 1769 01:28:41,790 --> 01:28:43,920 And then down here, I'm going to have another input 1770 01:28:43,920 --> 01:28:47,670 whose type is going to be submit and whose value is going 1771 01:28:47,670 --> 01:28:49,945 to be quote-unquote "search" as well. 1772 01:28:49,945 --> 01:28:51,070 They're a little different. 1773 01:28:51,070 --> 01:28:54,360 I'm deliberately omitting the name because it's not strictly necessary. 1774 01:28:54,360 --> 01:28:56,380 But where am I going with this? 1775 01:28:56,380 --> 01:28:59,280 Well, I haven't actually implemented a search engine. 1776 01:28:59,280 --> 01:29:02,490 All I'm doing at the moment is implementing a front end to a search 1777 01:29:02,490 --> 01:29:04,385 engine, a front end to google.com. 1778 01:29:04,385 --> 01:29:07,260 I'm going to let Google itself do the hard work of actually searching 1779 01:29:07,260 --> 01:29:09,000 the data-- the internet for me. 1780 01:29:09,000 --> 01:29:14,440 So I'm going to specify an action of www.google.com/search. 1781 01:29:14,440 --> 01:29:18,780 So here we have what is about to be a form, 1782 01:29:18,780 --> 01:29:21,780 text boxes and buttons that the user can interact with, 1783 01:29:21,780 --> 01:29:27,480 the action of which is going to be to send the user to this URL using get. 1784 01:29:27,480 --> 01:29:31,230 But that URL is going to have automatically added 1785 01:29:31,230 --> 01:29:35,760 to it by my browser one HTTP parameter, so to speak, 1786 01:29:35,760 --> 01:29:38,250 a variable of sorts, called q. 1787 01:29:38,250 --> 01:29:39,030 And why this? 1788 01:29:39,030 --> 01:29:42,410 Well, recall earlier that when I visited google.com, 1789 01:29:42,410 --> 01:29:45,210 I was able to simulate a search by literally 1790 01:29:45,210 --> 01:29:52,230 going to https://www.google.com/search?q=cats. 1791 01:29:52,230 --> 01:29:56,280 I claimed that Google is designed by the software engineers there 1792 01:29:56,280 --> 01:29:58,560 to take user input via the URL. 1793 01:29:58,560 --> 01:30:02,340 Well, you and I do not search for things by typing out long URLs 1794 01:30:02,340 --> 01:30:04,200 like that with q equals anything. 1795 01:30:04,200 --> 01:30:06,150 That would be incredibly poor experience. 1796 01:30:06,150 --> 01:30:09,660 You and I just type things into search boxes or forms. 1797 01:30:09,660 --> 01:30:14,730 So indeed, if I now go into my other tab here for search.html, 1798 01:30:14,730 --> 01:30:18,270 you're not going to be very impressed by the aesthetics of my form right 1799 01:30:18,270 --> 01:30:22,230 now-- it's just a rectangular text box and a search button. 1800 01:30:22,230 --> 01:30:23,580 But watch what happens. 1801 01:30:23,580 --> 01:30:27,540 My URL at the moment ends in search.html. 1802 01:30:27,540 --> 01:30:30,960 I'm going to go ahead and type in something literally like cats. 1803 01:30:30,960 --> 01:30:35,520 And now notice, if I hit Enter or manually click on the Search button, 1804 01:30:35,520 --> 01:30:38,250 my web page, which contains an HTML form-- 1805 01:30:38,250 --> 01:30:42,390 because it has an action that's Google's URL and a method of get, 1806 01:30:42,390 --> 01:30:47,460 my browser is going to convert that into the corresponding HTTP request 1807 01:30:47,460 --> 01:30:50,580 and in turn URL so that the user is automatically 1808 01:30:50,580 --> 01:30:54,930 sent to, if I double-click on it, this full URL here. 1809 01:30:54,930 --> 01:31:00,660 And the user's input is automatically by the browser appended to the URL via 1810 01:31:00,660 --> 01:31:02,910 question q=cat. 1811 01:31:02,910 --> 01:31:04,050 And it's not just cats. 1812 01:31:04,050 --> 01:31:06,570 We now have our own very simple Google search engine 1813 01:31:06,570 --> 01:31:08,650 where we can search for dogs, too, if we want. 1814 01:31:08,650 --> 01:31:13,380 And notice that the URL here changes to be ?=dogs. 1815 01:31:13,380 --> 01:31:16,202 So, like, this is how the web now works. 1816 01:31:16,202 --> 01:31:18,160 We talked earlier about how the internet works, 1817 01:31:18,160 --> 01:31:21,360 how you just get raw data, zeros and ones, packets of info from point A 1818 01:31:21,360 --> 01:31:23,340 to point B. This is now how the web works. 1819 01:31:23,340 --> 01:31:25,230 When you visit a website and don't just want 1820 01:31:25,230 --> 01:31:29,460 a specific picture of a cat or a dog, you want to search for cats or dogs, 1821 01:31:29,460 --> 01:31:33,450 or you want to log into a website, or you want to check out of amazon.com, 1822 01:31:33,450 --> 01:31:38,010 providing user input, you are always filling out HTML forms 1823 01:31:38,010 --> 01:31:40,890 which look essentially just like this. 1824 01:31:40,890 --> 01:31:44,400 They might have more inputs and they might be a little more complicated, 1825 01:31:44,400 --> 01:31:47,840 but they are form tag on amazon.com, on Facebook.com, 1826 01:31:47,840 --> 01:31:50,850 on any website with one or more inputs, that when 1827 01:31:50,850 --> 01:31:55,620 submitted, so to speak, via you hitting Enter or clicking Submit or Search 1828 01:31:55,620 --> 01:31:59,520 or whatever the button is labeled, that's how the next request gets 1829 01:31:59,520 --> 01:32:03,216 submitted to the server. 1830 01:32:03,216 --> 01:32:04,550 Whew. 1831 01:32:04,550 --> 01:32:07,610 So that's a lot, and that's not all the HTML tags out there, 1832 01:32:07,610 --> 01:32:09,550 but that's all the ideas of HTML, right? 1833 01:32:09,550 --> 01:32:12,910 It really is like open tags and close tags, some of which 1834 01:32:12,910 --> 01:32:16,240 can have zero or more attributes, and just understanding 1835 01:32:16,240 --> 01:32:18,820 that mental model, and now, via forms, we 1836 01:32:18,820 --> 01:32:21,250 have the mechanism for submitting, so to speak, 1837 01:32:21,250 --> 01:32:25,150 user input to search to websites, to web servers. 1838 01:32:25,150 --> 01:32:27,520 And just to call out that other verb here, 1839 01:32:27,520 --> 01:32:31,150 turns out Google only supports get for its search program. 1840 01:32:31,150 --> 01:32:36,560 At www.google.com/search, you can only use get, but POST is also very common. 1841 01:32:36,560 --> 01:32:38,327 And in fact, POST is a different verb that 1842 01:32:38,327 --> 01:32:39,910 can be tucked inside of that envelope. 1843 01:32:39,910 --> 01:32:46,390 And POST actually changes what happens in the browser so that q=cats 1844 01:32:46,390 --> 01:32:50,470 and q=dogs does not show up in the URL, because this is actually one other 1845 01:32:50,470 --> 01:32:51,728 threat to our privacy, right? 1846 01:32:51,728 --> 01:32:54,520 If you're little sibling comes over to your browser or your parents 1847 01:32:54,520 --> 01:32:56,353 after you've been searching on the web, they 1848 01:32:56,353 --> 01:32:59,650 can scroll through, often, your entire history of your browser. 1849 01:32:59,650 --> 01:33:00,190 Why? 1850 01:33:00,190 --> 01:33:02,980 Because literally everything you search for on Google or Bing 1851 01:33:02,980 --> 01:33:06,400 or whatever ended up in the URL because of this mechanism. 1852 01:33:06,400 --> 01:33:08,680 And for user convenience, your browser tends 1853 01:33:08,680 --> 01:33:11,170 to cache or save all of those URLs. 1854 01:33:11,170 --> 01:33:13,720 Now, that's marginally intrusive, certainly, 1855 01:33:13,720 --> 01:33:16,840 when you have roommates or family members of the like to your privacy, 1856 01:33:16,840 --> 01:33:20,080 but it's especially concerning if you are registering for websites 1857 01:33:20,080 --> 01:33:22,900 or checking out with usernames and passwords and credit card 1858 01:33:22,900 --> 01:33:25,240 numbers and things that are even more sensitive. 1859 01:33:25,240 --> 01:33:28,870 Long story short, POST, which is just a different verb that you can use 1860 01:33:28,870 --> 01:33:32,920 in HTTP, that hides the q=cats. 1861 01:33:32,920 --> 01:33:35,320 That hides the credit card number equals this. 1862 01:33:35,320 --> 01:33:39,130 That hides the password equals that, essentially, metaphorically, deeper 1863 01:33:39,130 --> 01:33:39,820 in the envelope. 1864 01:33:39,820 --> 01:33:42,760 It does not put it into the URL bar, but it still sends it 1865 01:33:42,760 --> 01:33:46,150 to the server a little more privately. 1866 01:33:46,150 --> 01:33:46,960 All right. 1867 01:33:46,960 --> 01:33:48,350 That was a lot. 1868 01:33:48,350 --> 01:33:52,600 That was a lot of tags all at once culminating in this ability to get-- 1869 01:33:52,600 --> 01:33:53,560 to submit user input. 1870 01:33:53,560 --> 01:33:57,460 But any questions, then, on the ideas, the syntax, 1871 01:33:57,460 --> 01:34:02,600 or the implications of making web pages with this language HTML? 1872 01:34:02,600 --> 01:34:04,025 Nothing from you, Brian? 1873 01:34:04,025 --> 01:34:05,070 BRIAN YU: All good here. 1874 01:34:05,070 --> 01:34:06,560 DAVID J. MALAN: All right, well, I'm kind of 1875 01:34:06,560 --> 01:34:09,768 embarrassed by all of the work I've done thus far, because all of these pages 1876 01:34:09,768 --> 01:34:13,520 are incredibly boring and very underwhelming and nowhere close 1877 01:34:13,520 --> 01:34:17,210 to the sort of user interfaces that you and I are familiar with day-to-day 1878 01:34:17,210 --> 01:34:18,830 when using the actual web. 1879 01:34:18,830 --> 01:34:22,280 So let me go ahead and close most of these tabs, and let's transition 1880 01:34:22,280 --> 01:34:24,950 to not focusing on the structure of web pages 1881 01:34:24,950 --> 01:34:28,010 alone, but now focusing on the aesthetics of web 1882 01:34:28,010 --> 01:34:32,570 pages, the stylization of web pages, where now your artistic flair can 1883 01:34:32,570 --> 01:34:33,500 really come out. 1884 01:34:33,500 --> 01:34:36,920 And we can begin to recreate user interfaces ultimately 1885 01:34:36,920 --> 01:34:39,350 more like our world of scratch, where you actually see 1886 01:34:39,350 --> 01:34:43,980 colors and shapes and images and sounds, but still using these basic building 1887 01:34:43,980 --> 01:34:44,480 blocks. 1888 01:34:44,480 --> 01:34:48,680 And for this, we need a language called CSS or Cascading Style Sheets. 1889 01:34:48,680 --> 01:34:53,060 This, too, not a programming language, but it is an additional language 1890 01:34:53,060 --> 01:34:57,860 that you can use in conjunction with HTML in order to stylize your pages 1891 01:34:57,860 --> 01:34:59,330 and make them prettier. 1892 01:34:59,330 --> 01:35:02,510 CSS boils down to the use of what we'll call properties. 1893 01:35:02,510 --> 01:35:06,110 Properties are similar in spirit to variables, or more generally, 1894 01:35:06,110 --> 01:35:07,730 they're just more key value pairs. 1895 01:35:07,730 --> 01:35:09,620 And again, notice this recurring theme. 1896 01:35:09,620 --> 01:35:13,910 Like, we introduced dictionaries or dicts in Python a couple of weeks ago. 1897 01:35:13,910 --> 01:35:17,300 Those are just collections of key value pairs in the form of a hash table, 1898 01:35:17,300 --> 01:35:18,110 essentially. 1899 01:35:18,110 --> 01:35:21,110 We saw just a moment ago attributes in HTML 1900 01:35:21,110 --> 01:35:23,150 which essentially are key value pairs. 1901 01:35:23,150 --> 01:35:28,820 q=cats is a key equals a value. q=dogs is a key equals a value. 1902 01:35:28,820 --> 01:35:32,570 CSS has the same idea, but because different people invented this, 1903 01:35:32,570 --> 01:35:35,450 they call these things properties instead of attributes. 1904 01:35:35,450 --> 01:35:38,060 But it's the same idea, just a different vocabulary. 1905 01:35:38,060 --> 01:35:40,730 And there's going to be different ways to apply 1906 01:35:40,730 --> 01:35:44,300 different properties, like color and font size and positioning, 1907 01:35:44,300 --> 01:35:48,330 to HTML tags using CSS. 1908 01:35:48,330 --> 01:35:49,470 So how do we get there? 1909 01:35:49,470 --> 01:35:51,710 Well, it turns out that CSS is a language 1910 01:35:51,710 --> 01:35:55,370 that you can use in conjunction with HTML, 1911 01:35:55,370 --> 01:35:57,590 which is to say you can start with an HTML page 1912 01:35:57,590 --> 01:36:00,830 like this, like we've already created, saying hello, title and hello, body, 1913 01:36:00,830 --> 01:36:03,530 but you can add some additional attributes 1914 01:36:03,530 --> 01:36:06,440 and/or tags to it to begin to stylize it. 1915 01:36:06,440 --> 01:36:10,580 You can actually add a style tag in the head of the web page, 1916 01:36:10,580 --> 01:36:14,270 here, pictured here, which is another thing we could put inside the head, 1917 01:36:14,270 --> 01:36:17,130 though strictly speaking, it can go elsewhere in the body as well. 1918 01:36:17,130 --> 01:36:20,420 Alternatively, you can link to a file in a separate file. 1919 01:36:20,420 --> 01:36:22,920 And so we'll see a couple of different approaches there. 1920 01:36:22,920 --> 01:36:26,630 But before we do that, let's make this more real with some concrete examples. 1921 01:36:26,630 --> 01:36:28,460 Let me go ahead and whip up a new example 1922 01:36:28,460 --> 01:36:33,590 here in a file called css.html just to demonstrate this new language. 1923 01:36:33,590 --> 01:36:37,460 Let me go ahead and start, as always, with just my raw HTML, 1924 01:36:37,460 --> 01:36:39,560 with my !DOCTYPE html. 1925 01:36:39,560 --> 01:36:42,620 Let me go ahead and do my html lang=en. 1926 01:36:42,620 --> 01:36:45,860 Then down here, I'll do the head of my page, the title of my page. 1927 01:36:45,860 --> 01:36:48,020 I'll just title it simply css. 1928 01:36:48,020 --> 01:36:51,680 The body of my web page-- and now let's actually do something interesting. 1929 01:36:51,680 --> 01:36:56,240 Let me introduce a few more HTML tags that are available in the language. 1930 01:36:56,240 --> 01:36:57,487 One is called header. 1931 01:36:57,487 --> 01:37:00,320 And here, I'm going to go ahead and say something like John Harvard. 1932 01:37:00,320 --> 01:37:03,950 I'm going to make a homepage for John Harvard, the founder of Harvard. 1933 01:37:03,950 --> 01:37:07,130 And let me go ahead here and do a main section of my page. 1934 01:37:07,130 --> 01:37:10,460 And I'm going to say welcome to my home page. 1935 01:37:10,460 --> 01:37:12,890 And then down here, I'm going to have a so-called footer. 1936 01:37:12,890 --> 01:37:15,830 And inside of here, I'm going to say copyright, 1937 01:37:15,830 --> 01:37:18,620 and I'll write copyright symbol John Harvard. 1938 01:37:18,620 --> 01:37:20,960 So super simple web page, three lines. 1939 01:37:20,960 --> 01:37:22,640 And just here's three new HTML tags. 1940 01:37:22,640 --> 01:37:25,890 You would only know this, again, from a class, a book, or an online reference, 1941 01:37:25,890 --> 01:37:29,240 but there are tags called header, main, and footer 1942 01:37:29,240 --> 01:37:30,770 that don't do anything special. 1943 01:37:30,770 --> 01:37:35,030 They don't make things big and bold like the heading tags did, H1 through H6. 1944 01:37:35,030 --> 01:37:37,520 They are just what are called semantic tags. 1945 01:37:37,520 --> 01:37:40,138 They are more than generic paragraph tags, 1946 01:37:40,138 --> 01:37:41,930 but they help you, the programmer, and they 1947 01:37:41,930 --> 01:37:44,880 help the browser know that, oh, this is the header of your page. 1948 01:37:44,880 --> 01:37:46,380 This is the main part of your page. 1949 01:37:46,380 --> 01:37:48,050 This is the footer, which can help, again, 1950 01:37:48,050 --> 01:37:51,050 with screen readers, distinguishing what's really important on the page. 1951 01:37:51,050 --> 01:37:53,470 It can help with translation tools, like Google Translate, 1952 01:37:53,470 --> 01:37:55,220 to know what you actually want translated, 1953 01:37:55,220 --> 01:37:58,340 like the main part of the page and not less important info, 1954 01:37:58,340 --> 01:37:59,720 like the header or footer. 1955 01:37:59,720 --> 01:38:03,270 So just three HTTP tags, but you can think of them like paragraph tags 1956 01:38:03,270 --> 01:38:06,090 but with more specific names. 1957 01:38:06,090 --> 01:38:06,590 All right. 1958 01:38:06,590 --> 01:38:10,130 So let me go ahead and save this file, open up-- not my dogs here, 1959 01:38:10,130 --> 01:38:11,300 but go back to the index. 1960 01:38:11,300 --> 01:38:13,670 And now I have a new file, css.html. 1961 01:38:13,670 --> 01:38:15,650 Let's click it, and voila. 1962 01:38:15,650 --> 01:38:18,920 You know, it's pretty underwhelming, but it does what it says. 1963 01:38:18,920 --> 01:38:20,780 It's got three lines with this content. 1964 01:38:20,780 --> 01:38:25,490 Let's begin to stylize this and try to make it a little more inviting. 1965 01:38:25,490 --> 01:38:28,820 So to do this, let me go ahead and add a style attribute 1966 01:38:28,820 --> 01:38:30,347 with equals quote unquote. 1967 01:38:30,347 --> 01:38:32,180 Now, here's where things get a little weird. 1968 01:38:32,180 --> 01:38:35,870 In the world of HTML and CSS, you do actually, 1969 01:38:35,870 --> 01:38:38,730 or can actually, commingle the two languages. 1970 01:38:38,730 --> 01:38:40,100 And we kind of saw this already. 1971 01:38:40,100 --> 01:38:43,880 We saw Python code with SQL inside of it. 1972 01:38:43,880 --> 01:38:47,780 Today, we're seeing HTML code with CSS inside of it. 1973 01:38:47,780 --> 01:38:49,670 So inside of these quotes, I'm going to put 1974 01:38:49,670 --> 01:38:52,430 some of those so-called properties, key value pairs. 1975 01:38:52,430 --> 01:38:56,270 Let me go ahead and change the font size of my header to be large 1976 01:38:56,270 --> 01:38:59,570 and let me go ahead and align the text as centered. 1977 01:38:59,570 --> 01:39:00,830 Notice the pattern here. 1978 01:39:00,830 --> 01:39:01,550 It's new. 1979 01:39:01,550 --> 01:39:02,570 It's not equal sign. 1980 01:39:02,570 --> 01:39:03,820 There's not additional quotes. 1981 01:39:03,820 --> 01:39:06,320 It's because, again, left hand wasn't talking to right hand, 1982 01:39:06,320 --> 01:39:09,310 and different people invented HTML and CSS, essentially. 1983 01:39:09,310 --> 01:39:13,960 But font-size is the name of a CSS property, an aesthetic detail. 1984 01:39:13,960 --> 01:39:18,040 Colon is what separates the key from the value, and the value in this case 1985 01:39:18,040 --> 01:39:18,640 is large. 1986 01:39:18,640 --> 01:39:21,223 And I'm choosing large because it's one of the available ones. 1987 01:39:21,223 --> 01:39:24,650 You've got small, medium, large, extra large, and a bunch of others as well. 1988 01:39:24,650 --> 01:39:28,420 You can also use specific font sizes or pixel sizes as well. 1989 01:39:28,420 --> 01:39:32,030 text-align is going to align text colon in the center. 1990 01:39:32,030 --> 01:39:34,210 Now, let me go ahead and do something similar here. 1991 01:39:34,210 --> 01:39:40,690 On the main tag, let's do font-size medium, and then text-align center. 1992 01:39:40,690 --> 01:39:45,070 And then down here, let's do style="font-size small, 1993 01:39:45,070 --> 01:39:46,070 because it's the footer. 1994 01:39:46,070 --> 01:39:48,790 It's less important. text-align center. 1995 01:39:48,790 --> 01:39:50,530 All right, saving the file. 1996 01:39:50,530 --> 01:39:52,810 And I'm sad to say the semicolons are back. 1997 01:39:52,810 --> 01:39:54,890 They're not strictly necessary in all places, 1998 01:39:54,890 --> 01:39:56,290 but I'm doing it for consistency. 1999 01:39:56,290 --> 01:40:00,130 They're definitely needed here to separate keys from other keys. 2000 01:40:00,130 --> 01:40:01,570 Let me open up this page again. 2001 01:40:01,570 --> 01:40:03,220 Let me hit reload. 2002 01:40:03,220 --> 01:40:05,480 And voila, it's a little prettier. 2003 01:40:05,480 --> 01:40:07,420 It's nothing to write home about, really, 2004 01:40:07,420 --> 01:40:10,900 but it has John Harvard as large, "Welcome to my home page" as medium, 2005 01:40:10,900 --> 01:40:13,630 and the footer as something small. 2006 01:40:13,630 --> 01:40:14,500 So that's not bad. 2007 01:40:14,500 --> 01:40:15,750 And let me clean this up, too. 2008 01:40:15,750 --> 01:40:18,070 This open parentheses c close parentheses 2009 01:40:18,070 --> 01:40:19,870 isn't necessarily that pretty. 2010 01:40:19,870 --> 01:40:24,070 I don't know where the symbol is on my screen, but let me go ahead here 2011 01:40:24,070 --> 01:40:30,680 and let me type out this, ampersand hash 169 semicolon. 2012 01:40:30,680 --> 01:40:34,930 This is weird, but this is a feature of HTML called an HTML entity, which 2013 01:40:34,930 --> 01:40:40,570 is a numeric code that identifies a symbol that is often not 2014 01:40:40,570 --> 01:40:43,420 on your keyboard but you might want to display anyway. 2015 01:40:43,420 --> 01:40:45,040 Let me go ahead here and reload. 2016 01:40:45,040 --> 01:40:48,760 And voila, if I zoom in, now we have a proper copyright symbol. 2017 01:40:48,760 --> 01:40:52,180 And there's other HTML entities for other symbols 2018 01:40:52,180 --> 01:40:54,650 as well, especially if you can't see them on your keyboard. 2019 01:40:54,650 --> 01:40:55,150 All right. 2020 01:40:55,150 --> 01:40:56,470 What happens after this? 2021 01:40:56,470 --> 01:41:00,110 That's not bad, but I feel like there's an inelegance here. 2022 01:41:00,110 --> 01:41:02,620 Can anyone recognize in the code I've written thus far, 2023 01:41:02,620 --> 01:41:04,970 even if you've never seen HTML before-- 2024 01:41:04,970 --> 01:41:08,660 is there an opportunity for better design? 2025 01:41:08,660 --> 01:41:12,260 I claim it's correct, but feel free to chime in the chat. 2026 01:41:12,260 --> 01:41:14,690 Can I improve the design? 2027 01:41:14,690 --> 01:41:17,660 And even though I said earlier that copy paste is bad, 2028 01:41:17,660 --> 01:41:19,670 that doesn't mean we can't-- 2029 01:41:19,670 --> 01:41:22,460 or is necessary in HTML, that doesn't mean we 2030 01:41:22,460 --> 01:41:26,760 can't chip away at it in some places. 2031 01:41:26,760 --> 01:41:29,575 Brian, anything jumping out? 2032 01:41:29,575 --> 01:41:32,200 BRIAN YU: Some people are saying that your style attributes are 2033 01:41:32,200 --> 01:41:33,970 starting to get very long. 2034 01:41:33,970 --> 01:41:36,640 DAVID J. MALAN: They are getting long, and I dare say redundant. 2035 01:41:36,640 --> 01:41:38,950 Even though the font size is changing, so that 2036 01:41:38,950 --> 01:41:42,010 seems kind of necessary, text-align center, text-align center, 2037 01:41:42,010 --> 01:41:44,510 text-align center-- that seems unnecessary, right? 2038 01:41:44,510 --> 01:41:46,570 Like, why am I doing that again and again? 2039 01:41:46,570 --> 01:41:49,240 But here's where the C in CSS comes in. 2040 01:41:49,240 --> 01:41:53,650 CSS is Cascading Style Sheets, which literally refers to a waterfall 2041 01:41:53,650 --> 01:41:55,573 effect of these properties. 2042 01:41:55,573 --> 01:41:57,490 So what I can actually do is-- let me go ahead 2043 01:41:57,490 --> 01:42:03,610 and remove text-align center from each of header, main, and footer. 2044 01:42:03,610 --> 01:42:05,090 And let me be a little smarter. 2045 01:42:05,090 --> 01:42:08,350 Let me go up to my body tag, which is the so-called parent tag, 2046 01:42:08,350 --> 01:42:13,270 for those three, add a style attribute there, and put text-align center there, 2047 01:42:13,270 --> 01:42:17,200 and trust that because body is the parent, any properties it 2048 01:42:17,200 --> 01:42:20,950 has will cascade down onto, so to speak, its children, 2049 01:42:20,950 --> 01:42:24,610 thereby allowing me to define text-align in one place instead of three. 2050 01:42:24,610 --> 01:42:28,330 Let me go ahead and reload the page, and voila, nothing has changed, 2051 01:42:28,330 --> 01:42:31,480 but I claim now that my page is better designed 2052 01:42:31,480 --> 01:42:35,170 because I've eliminated that redundancy and made my lines, to Brian's 2053 01:42:35,170 --> 01:42:38,050 point, a little shorter as well. 2054 01:42:38,050 --> 01:42:41,050 So that's pretty clean, but this seems a little bit of a slippery slope. 2055 01:42:41,050 --> 01:42:43,510 If I wanted to make a larger home page, which surely I 2056 01:42:43,510 --> 01:42:46,060 might, with lots more content, having all of these style 2057 01:42:46,060 --> 01:42:48,470 attributes all over the place very quickly gets messy. 2058 01:42:48,470 --> 01:42:50,678 And in the real world, it makes it hard for you and I 2059 01:42:50,678 --> 01:42:54,220 to collaborate with better artists than you or I might be. 2060 01:42:54,220 --> 01:42:56,560 It might be nice for one of us, if working on a team, 2061 01:42:56,560 --> 01:42:58,630 maybe for even a CS50 final project-- 2062 01:42:58,630 --> 01:43:01,720 one of us does the HTML, one of us does the CSS. 2063 01:43:01,720 --> 01:43:04,240 This would be a mess if you and I were trying 2064 01:43:04,240 --> 01:43:06,800 to collaborate on the same exact file. 2065 01:43:06,800 --> 01:43:11,050 So let's see if we can't take a step toward factoring these out and keeping 2066 01:43:11,050 --> 01:43:12,770 HTML and CSS separate. 2067 01:43:12,770 --> 01:43:14,150 So how might I do this? 2068 01:43:14,150 --> 01:43:17,620 Well, let me go ahead here and get rid of all of this. 2069 01:43:17,620 --> 01:43:20,260 Let me get rid of all of these style attributes, which, again, 2070 01:43:20,260 --> 01:43:24,280 just doesn't feel very maintainable, certainly as my page gets longer. 2071 01:43:24,280 --> 01:43:27,640 And let me transition to that other format we saw a teaser for before, 2072 01:43:27,640 --> 01:43:29,470 a style tag. 2073 01:43:29,470 --> 01:43:33,490 Not an attribute, but a tag that can go in the head of the web page here. 2074 01:43:33,490 --> 01:43:36,740 And let me go ahead and do something a little different here. 2075 01:43:36,740 --> 01:43:44,020 Let me go ahead and say my header should be text-align center. 2076 01:43:44,020 --> 01:43:48,730 My main part should be text-align-- 2077 01:43:48,730 --> 01:43:50,650 let me do this just like we did in C-- 2078 01:43:50,650 --> 01:43:52,720 text-align center. 2079 01:43:52,720 --> 01:43:57,280 And then my footer will be text-align center. 2080 01:43:57,280 --> 01:44:02,440 And then just for consistency, with before, font-size large. 2081 01:44:02,440 --> 01:44:05,620 Down here in main, font-size medium. 2082 01:44:05,620 --> 01:44:09,428 Down here, font-size small. 2083 01:44:09,428 --> 01:44:11,470 The IDE is not recognizing all of these keywords, 2084 01:44:11,470 --> 01:44:14,020 but it's OK that some are white, some are blue here. 2085 01:44:14,020 --> 01:44:17,740 So there's still some redundancy here, but notice what I'm doing now. 2086 01:44:17,740 --> 01:44:22,990 Inside of my style tag, it is allowed to use what's called a CSS selector. 2087 01:44:22,990 --> 01:44:26,200 And there's different types of selectors, but the one we're seeing now 2088 01:44:26,200 --> 01:44:27,880 is what's called the type selector. 2089 01:44:27,880 --> 01:44:31,660 And it's a bit arcanely named, but this just means that if you want to style 2090 01:44:31,660 --> 01:44:36,190 every instance of a certain tag, every header tag, every main tag, 2091 01:44:36,190 --> 01:44:40,030 every footer tag, you can literally, inside of a style tag, 2092 01:44:40,030 --> 01:44:44,920 put the name of that tag, then a pair of curly braces-- apologies, 2093 01:44:44,920 --> 01:44:46,750 they are back for CSS-- 2094 01:44:46,750 --> 01:44:48,730 and then inside of those curly braces, you just 2095 01:44:48,730 --> 01:44:53,470 put those key value pairs, the properties separated by semicolons. 2096 01:44:53,470 --> 01:44:55,900 And I'm stylizing it nice on separate lines 2097 01:44:55,900 --> 01:44:57,580 just so that it's a lot more readable. 2098 01:44:57,580 --> 01:44:59,413 The effect is not going to be any different. 2099 01:44:59,413 --> 01:45:02,710 If I go back to my other tab and reload, nothing has changed, 2100 01:45:02,710 --> 01:45:07,300 but I've begun to tease out the CSS from the rest of my page. 2101 01:45:07,300 --> 01:45:09,520 But notice there's still some redundancy here, 2102 01:45:09,520 --> 01:45:12,940 and I could remove, for instance, text-align center from here, 2103 01:45:12,940 --> 01:45:15,430 text-align center from here, text-align center from here, 2104 01:45:15,430 --> 01:45:17,530 and maybe apply it to the body instead. 2105 01:45:17,530 --> 01:45:19,600 But there's other types of selectors I can use. 2106 01:45:19,600 --> 01:45:23,650 If you want to define one or more properties in a reusable way 2107 01:45:23,650 --> 01:45:27,280 such that you can use them on all sorts of tags, turns out CSS 2108 01:45:27,280 --> 01:45:29,080 supports what are called classes. 2109 01:45:29,080 --> 01:45:31,140 And I'm going to go ahead and do this instead. 2110 01:45:31,140 --> 01:45:34,600 Instead of just saying my header is going to have a font size of large, 2111 01:45:34,600 --> 01:45:37,240 I'm going to introduce what's called a class in CSS, 2112 01:45:37,240 --> 01:45:42,020 the syntax for which is to use a dot and then a keyword of your own choice. 2113 01:45:42,020 --> 01:45:45,130 And I'm going to call this first set of properties .large, 2114 01:45:45,130 --> 01:45:52,420 this next set of properties .medium, and this next set of properties .small. 2115 01:45:52,420 --> 01:45:55,000 And this is a little weird that it's starting with a dot. 2116 01:45:55,000 --> 01:45:57,340 That's just because humans decided that when 2117 01:45:57,340 --> 01:46:00,670 you define what's called a class, a reuseable set of properties, 2118 01:46:00,670 --> 01:46:02,440 you start your keyword with a dot. 2119 01:46:02,440 --> 01:46:04,232 And I'm going to give myself one other one. 2120 01:46:04,232 --> 01:46:08,980 .centered is going to be text-align center. 2121 01:46:08,980 --> 01:46:13,720 So none of these classes, centered, large, medium, or small 2122 01:46:13,720 --> 01:46:17,810 are in use yet until I now apply them to my HTML tags. 2123 01:46:17,810 --> 01:46:20,170 So let me scroll back down to my HTML where 2124 01:46:20,170 --> 01:46:22,810 I removed earlier all of those style attributes, 2125 01:46:22,810 --> 01:46:26,270 and I'm going to use a different attribute now called class. 2126 01:46:26,270 --> 01:46:33,940 I'm going to go ahead and add to this header centered large. 2127 01:46:33,940 --> 01:46:38,710 I'm going to add class to the main tag as centered medium. 2128 01:46:38,710 --> 01:46:43,060 And down here I'm going to say class="centered small". 2129 01:46:43,060 --> 01:46:47,260 So I can have inside of the attributes called class a value 2130 01:46:47,260 --> 01:46:49,540 that's just a space-separated list of words. 2131 01:46:49,540 --> 01:46:51,790 And strictly speaking, it can be any number of spaces, 2132 01:46:51,790 --> 01:46:53,582 but that's just looks stupid and is stupid, 2133 01:46:53,582 --> 01:46:56,230 stylistically, so just one space suffices. 2134 01:46:56,230 --> 01:47:01,060 But this just means, hey, browser, apply the centered class and the medium class 2135 01:47:01,060 --> 01:47:02,530 to the following contents. 2136 01:47:02,530 --> 01:47:06,400 And again, if I go back to the tab and reload, nothing, still, has changed. 2137 01:47:06,400 --> 01:47:07,750 I'm just changing the design. 2138 01:47:07,750 --> 01:47:09,400 I'm hopefully improving the design. 2139 01:47:09,400 --> 01:47:12,730 But here, too, you can probably note that using centered again and again 2140 01:47:12,730 --> 01:47:14,470 is also, again, dumb. 2141 01:47:14,470 --> 01:47:16,330 Let me remove that redundancy. 2142 01:47:16,330 --> 01:47:18,790 Let me add to my body a class of centered. 2143 01:47:18,790 --> 01:47:20,740 And now things are getting a little tight. 2144 01:47:20,740 --> 01:47:23,185 Like, I've reintroduced some attributes, but now, 2145 01:47:23,185 --> 01:47:25,060 if I'm collaborating with someone, I can say, 2146 01:47:25,060 --> 01:47:28,180 can you go ahead and create me CSS classes for large text, medium 2147 01:47:28,180 --> 01:47:29,020 text, small text? 2148 01:47:29,020 --> 01:47:31,390 I'll just assume that you're going to do that correctly, 2149 01:47:31,390 --> 01:47:34,390 and I can just use those terms, those classes, 2150 01:47:34,390 --> 01:47:39,130 and assume that you have defined code in CSS like this stuff here. 2151 01:47:39,130 --> 01:47:39,880 But you know what? 2152 01:47:39,880 --> 01:47:41,470 I can do one step better. 2153 01:47:41,470 --> 01:47:44,680 I don't need you to even touch this same file. 2154 01:47:44,680 --> 01:47:47,080 You and I can work pretty independently. 2155 01:47:47,080 --> 01:47:49,090 In fact, let me go ahead and propose this. 2156 01:47:49,090 --> 01:47:53,800 Let me highlight all of the code I just wrote up here and cut it. 2157 01:47:53,800 --> 01:47:56,650 Let me get rid of this style tag all together. 2158 01:47:56,650 --> 01:48:02,650 Let me create a new file called, let's say, styles.css, just by convention, 2159 01:48:02,650 --> 01:48:07,728 but I could call it anything I want .css, paste it into there, and save it. 2160 01:48:07,728 --> 01:48:08,770 And let me go ahead and-- 2161 01:48:08,770 --> 01:48:10,603 I don't need any of the indentation anymore, 2162 01:48:10,603 --> 01:48:14,350 so let me just shift everything over there using a fancy keyboard shortcut. 2163 01:48:14,350 --> 01:48:16,060 This could be the file you're working on. 2164 01:48:16,060 --> 01:48:19,180 You create all of these properties and these classes for me 2165 01:48:19,180 --> 01:48:20,350 in a separate file. 2166 01:48:20,350 --> 01:48:25,000 Then in my HTML file, if you and I are collaborating, I can use a link tag-- 2167 01:48:25,000 --> 01:48:30,130 a hyper reference value of styles.css, the relationship of which 2168 01:48:30,130 --> 01:48:32,965 is that of stylesheet to your file. 2169 01:48:32,965 --> 01:48:35,590 Now, here's where you just kind of have to throw up your hands. 2170 01:48:35,590 --> 01:48:39,190 In an ideal world, we would have called links in web pages the link tag, 2171 01:48:39,190 --> 01:48:41,830 and we wouldn't have used open bracket a for anchor. 2172 01:48:41,830 --> 01:48:43,960 This is not a link in the clickable sense. 2173 01:48:43,960 --> 01:48:47,620 This just means link this HTML file to this CSS file 2174 01:48:47,620 --> 01:48:50,260 with a relationship of stylesheet. 2175 01:48:50,260 --> 01:48:51,550 What is the stylesheet? 2176 01:48:51,550 --> 01:48:53,410 It is a sheet of styles. 2177 01:48:53,410 --> 01:48:56,530 It is a file of properties. 2178 01:48:56,530 --> 01:49:02,920 And those properties can be inside of types or classes or what we'll soon see 2179 01:49:02,920 --> 01:49:05,540 are unique IDs as well. 2180 01:49:05,540 --> 01:49:07,793 And there's other types for that as well. 2181 01:49:07,793 --> 01:49:10,210 But here we have, now, arguably, the best-designed version 2182 01:49:10,210 --> 01:49:12,190 in that this is pretty compact. 2183 01:49:12,190 --> 01:49:13,270 It's pretty succinct. 2184 01:49:13,270 --> 01:49:17,470 There's only HTML and HTML values and attributes, 2185 01:49:17,470 --> 01:49:19,690 but all the CSS is in this second file. 2186 01:49:19,690 --> 01:49:23,710 Now you and I can really collaborate independently. 2187 01:49:23,710 --> 01:49:28,680 Any questions then on CSS and what we can do with it? 2188 01:49:28,680 --> 01:49:32,940 We have only scratched the surface of CSS thus far, but suffice it to say-- 2189 01:49:32,940 --> 01:49:35,910 and actually, just to tease just how bad at this I might be, 2190 01:49:35,910 --> 01:49:38,850 suppose you really want to have a colorful background. 2191 01:49:38,850 --> 01:49:42,180 Well, let me go into my CSS file here, styles.css, 2192 01:49:42,180 --> 01:49:43,833 and I don't have to use only classes. 2193 01:49:43,833 --> 01:49:45,750 I can say something like, well, let's go ahead 2194 01:49:45,750 --> 01:49:50,790 and make my body tag have a background color of-- 2195 01:49:50,790 --> 01:49:52,800 how about red semicolon? 2196 01:49:52,800 --> 01:49:55,190 Let's go back to the browser, reload. 2197 01:49:55,190 --> 01:49:57,180 OK, it's getting ugly pretty fast. 2198 01:49:57,180 --> 01:49:59,700 Let me go ahead and change the color of my text 2199 01:49:59,700 --> 01:50:02,550 maybe to white to make it stand out a little more on the red. 2200 01:50:02,550 --> 01:50:03,540 Reload. 2201 01:50:03,540 --> 01:50:05,430 All right, it's back to something there. 2202 01:50:05,430 --> 01:50:08,940 I can change this to any color, maybe a little Yale blue over here. 2203 01:50:08,940 --> 01:50:09,520 Reload. 2204 01:50:09,520 --> 01:50:10,950 Voila, it's now blue. 2205 01:50:10,950 --> 01:50:18,300 Or if you really want to be fancy, per week four, how about we make it 00ff00, 2206 01:50:18,300 --> 01:50:22,110 speaking hexadecimal, which, of course, is going to make it green for me 2207 01:50:22,110 --> 01:50:23,170 instead? 2208 01:50:23,170 --> 01:50:26,490 So this is to say there's so many different CSS properties out there. 2209 01:50:26,490 --> 01:50:29,720 And again, we're focusing here only on the list-- 2210 01:50:29,720 --> 01:50:30,630 the ideas. 2211 01:50:30,630 --> 01:50:32,880 When it comes time to actually using these properties, 2212 01:50:32,880 --> 01:50:36,450 we'll point you at the appropriate reference, just to flesh out your vocab 2213 01:50:36,450 --> 01:50:37,630 all the more. 2214 01:50:37,630 --> 01:50:38,130 All right. 2215 01:50:38,130 --> 01:50:47,480 Any questions, then, on the capabilities of CSS and its relationship with HTML? 2216 01:50:47,480 --> 01:50:49,100 Anything on your end, Brian? 2217 01:50:49,100 --> 01:50:50,100 BRIAN YU: All good here. 2218 01:50:50,100 --> 01:50:53,030 DAVID J. MALAN: So the one thing we haven't done any of today at all 2219 01:50:53,030 --> 01:50:54,020 is programming. 2220 01:50:54,020 --> 01:50:57,950 And for that, we actually need a third and final language, that of JavaScript. 2221 01:50:57,950 --> 01:51:00,590 And in the past weeks of the course, we've 2222 01:51:00,590 --> 01:51:03,350 used what we would describe as really server-side programming. 2223 01:51:03,350 --> 01:51:04,400 You have written C code. 2224 01:51:04,400 --> 01:51:06,890 You've written Python code on the server, 2225 01:51:06,890 --> 01:51:11,240 specifically on CS50 IDE, which is, by nature, in the cloud, a server. 2226 01:51:11,240 --> 01:51:13,880 But it turns out that all this time you haven't really 2227 01:51:13,880 --> 01:51:17,420 been using your own Mac or your own PC or your own phone, 2228 01:51:17,420 --> 01:51:21,770 for that matter, other than it's just a very expensive display, a very 2229 01:51:21,770 --> 01:51:22,880 expensive screen. 2230 01:51:22,880 --> 01:51:25,040 All of the code is written, all of the code 2231 01:51:25,040 --> 01:51:27,260 is running, on this backend server. 2232 01:51:27,260 --> 01:51:30,830 And that's a missed opportunity, because all of your users, all of your friends, 2233 01:51:30,830 --> 01:51:35,630 all of us are on our own pretty fancy Macs and PCs or phones these days. 2234 01:51:35,630 --> 01:51:37,880 It's kind of a shame that those devices all 2235 01:51:37,880 --> 01:51:41,180 have CPUs and RAM and storage space, yet we're not 2236 01:51:41,180 --> 01:51:43,010 using any of those capabilities. 2237 01:51:43,010 --> 01:51:47,480 We're really just using the glass screen to see what's elsewhere on a server. 2238 01:51:47,480 --> 01:51:49,760 But with JavaScript, we have another language 2239 01:51:49,760 --> 01:51:53,630 that we'll see in a bit that will allow us to write code, save it 2240 01:51:53,630 --> 01:51:57,680 on the server, but run it on users' computers 2241 01:51:57,680 --> 01:52:00,320 and do what's called client-side programming, so we'll still 2242 01:52:00,320 --> 01:52:03,980 save the code we write on the server, but we're going to include the code 2243 01:52:03,980 --> 01:52:07,818 inside of these virtual envelopes that get downloaded by users' browsers, 2244 01:52:07,818 --> 01:52:10,610 and instead of just reading the code, top to bottom, left to right, 2245 01:52:10,610 --> 01:52:13,790 and displaying information, as is the case with HTTP and CSS, 2246 01:52:13,790 --> 01:52:18,110 will additionally read the JavaScript code deeper in the envelope 2247 01:52:18,110 --> 01:52:21,470 and execute that on users' Macs and PCS and phones. 2248 01:52:21,470 --> 01:52:24,950 And here's where web programming gets really interesting, because you now 2249 01:52:24,950 --> 01:52:28,543 have a full-fledged computer at your disposal that's not even your own. 2250 01:52:28,543 --> 01:52:30,960 So let's go ahead and take another five-minute break here, 2251 01:52:30,960 --> 01:52:34,770 and when we come back, we'll conclude with a look at JavaScript. 2252 01:52:34,770 --> 01:52:35,670 All right. 2253 01:52:35,670 --> 01:52:40,500 We are back and we're about to introduce a programmatic way of controlling web 2254 01:52:40,500 --> 01:52:43,320 pages and even adding to web pages and changing the content 2255 01:52:43,320 --> 01:52:46,830 users see, thereby making our websites no longer just static-- 2256 01:52:46,830 --> 01:52:50,100 that is, written once and viewable the same way forever, 2257 01:52:50,100 --> 01:52:52,350 but dynamic, somehow changing in response 2258 01:52:52,350 --> 01:52:54,430 to user interactions or user input. 2259 01:52:54,430 --> 01:52:57,990 Let's go ahead and now consider how we can make our pages all the more dynamic 2260 01:52:57,990 --> 01:52:59,460 by introducing JavaScript. 2261 01:52:59,460 --> 01:53:03,540 So let's go ahead quickly and introduce just some of the syntax of JavaScript. 2262 01:53:03,540 --> 01:53:06,090 And wonderfully, JavaScript syntactically 2263 01:53:06,090 --> 01:53:10,715 is pretty similar to C and Python, a little more syntactically similar to C, 2264 01:53:10,715 --> 01:53:12,090 but there's no memory management. 2265 01:53:12,090 --> 01:53:13,140 There's no pointers. 2266 01:53:13,140 --> 01:53:17,130 So it's kind of like somewhere in between C and Python syntax. 2267 01:53:17,130 --> 01:53:20,010 But it should all come fairly familiar-- 2268 01:53:20,010 --> 01:53:21,210 fairly easily now. 2269 01:53:21,210 --> 01:53:23,460 In Scratch, recall when we had a variable called 2270 01:53:23,460 --> 01:53:27,150 counter initialized to zero, how do we now declare the same in JavaScript? 2271 01:53:27,150 --> 01:53:28,448 It's going to look like this. 2272 01:53:28,448 --> 01:53:29,490 So it's not quite Python. 2273 01:53:29,490 --> 01:53:32,760 It's not quite C. You literally use the keyword let, which 2274 01:53:32,760 --> 01:53:35,280 means let the following variable exist. 2275 01:53:35,280 --> 01:53:38,730 The variable's called counter = 0;. 2276 01:53:38,730 --> 01:53:41,550 Strictly speaking, these semicolons aren't always necessary, 2277 01:53:41,550 --> 01:53:44,128 but for consistency, I'll keep using them here. 2278 01:53:44,128 --> 01:53:46,170 Suppose you want to change the counter by one, as 2279 01:53:46,170 --> 01:53:47,730 in Scratch, incremented by one. 2280 01:53:47,730 --> 01:53:51,810 In JavaScript, you can do it very verbosely like this. 2281 01:53:51,810 --> 01:53:55,350 You can do it a little more succinctly like this, like in Python in C, 2282 01:53:55,350 --> 01:53:57,150 or the plus-plus is back. 2283 01:53:57,150 --> 01:54:01,740 So if you've been missing that in Python, the-- as Nicholas seems to be, 2284 01:54:01,740 --> 01:54:04,208 the plus-plus is now back as well. 2285 01:54:04,208 --> 01:54:06,000 How about something like this, a condition? 2286 01:54:06,000 --> 01:54:08,880 So if you want to say if x less than y, in JavaScript, 2287 01:54:08,880 --> 01:54:10,800 it's going to say if x less than y. 2288 01:54:10,800 --> 01:54:13,170 So here, we have the curly braces are back. 2289 01:54:13,170 --> 01:54:14,490 The parentheses are back. 2290 01:54:14,490 --> 01:54:16,680 But the ideas are still the same. 2291 01:54:16,680 --> 01:54:18,540 If else in Scratch looked like this. 2292 01:54:18,540 --> 01:54:20,580 In JavaScript, it's going to look like that. 2293 01:54:20,580 --> 01:54:23,850 In Scratch, if else if else looks like this. 2294 01:54:23,850 --> 01:54:26,850 In JavaScript, it's going to look like this, so more like C. 2295 01:54:26,850 --> 01:54:29,340 There's no weird l if abbreviation. 2296 01:54:29,340 --> 01:54:32,907 It's literally else if again, but with the parentheses 2297 01:54:32,907 --> 01:54:33,990 and with the curly braces. 2298 01:54:33,990 --> 01:54:37,032 And honestly, if you get hung up early on in these next few weeks-- like, 2299 01:54:37,032 --> 01:54:39,490 these are the stupid details of learning some new language. 2300 01:54:39,490 --> 01:54:41,157 You've got to develop the muscle memory. 2301 01:54:41,157 --> 01:54:43,560 You've got to start remembering what language is what. 2302 01:54:43,560 --> 01:54:47,790 But don't stress when you get hung up on curly braces and parentheses. 2303 01:54:47,790 --> 01:54:50,032 Like, those things have never fundamentally mattered, 2304 01:54:50,032 --> 01:54:51,990 but they do, of course, matter to the computer. 2305 01:54:51,990 --> 01:54:54,930 But not to us, certainly intellectually, as we 2306 01:54:54,930 --> 01:54:57,970 introduce the new compelling features of this language. 2307 01:54:57,970 --> 01:55:01,230 How about something like a for loop or while loop, for that matter? 2308 01:55:01,230 --> 01:55:03,450 In Scratch, if you wanted to do something forever, 2309 01:55:03,450 --> 01:55:07,200 you can convert that now in JavaScript, similar to C, while true, 2310 01:55:07,200 --> 01:55:09,420 or while any expression is true. 2311 01:55:09,420 --> 01:55:12,600 If you want to repeat something three times, almost the same as C, 2312 01:55:12,600 --> 01:55:15,150 but I'm using let here instead of int. 2313 01:55:15,150 --> 01:55:18,240 So JavaScript, like Python, is loosely typed. 2314 01:55:18,240 --> 01:55:20,490 It has types, but you, the programmer, don't 2315 01:55:20,490 --> 01:55:22,230 need to stress over specifying them. 2316 01:55:22,230 --> 01:55:23,830 The computer will figure it out. 2317 01:55:23,830 --> 01:55:26,040 So let is how you would declare a keyword. 2318 01:55:26,040 --> 01:55:30,030 And with that said, there are other ways to declare variables in JavaScript, 2319 01:55:30,030 --> 01:55:32,970 including constants, but for now, we'll keep things simple 2320 01:55:32,970 --> 01:55:35,650 and focus only on this keyword here. 2321 01:55:35,650 --> 01:55:39,240 So here's that page again and the tree representation thereof. 2322 01:55:39,240 --> 01:55:41,550 And this tree is useful only as a mental model 2323 01:55:41,550 --> 01:55:47,460 for what the computer is doing inside of its memory after having loaded a page. 2324 01:55:47,460 --> 01:55:50,250 With JavaScript, now, we have the ability 2325 01:55:50,250 --> 01:55:52,950 to change this tree in real time. 2326 01:55:52,950 --> 01:55:55,830 When the user clicks something, drags something, types something 2327 01:55:55,830 --> 01:55:59,040 in, with JavaScript, we will now have a programming language 2328 01:55:59,040 --> 01:56:02,380 that allows us to mutate this tree in real time, 2329 01:56:02,380 --> 01:56:07,420 thereby making our pages no longer static or fixed in one state, 2330 01:56:07,420 --> 01:56:10,140 but dynamic and changing instead. 2331 01:56:10,140 --> 01:56:11,500 So how might we do this? 2332 01:56:11,500 --> 01:56:13,560 Well, let's consider exactly where we can 2333 01:56:13,560 --> 01:56:15,630 go about writing some JavaScript code. 2334 01:56:15,630 --> 01:56:19,080 We can do that by adding a script tag in the head like this. 2335 01:56:19,080 --> 01:56:21,420 Strictly speaking, it can also go in the body like this, 2336 01:56:21,420 --> 01:56:24,030 and there are some logical implications of those choices. 2337 01:56:24,030 --> 01:56:27,510 Or we can even factor it out to a file like scripts.js, 2338 01:56:27,510 --> 01:56:29,207 just as we did with CSS. 2339 01:56:29,207 --> 01:56:31,290 So even though the tag is different, it's scripts, 2340 01:56:31,290 --> 01:56:32,582 and the attribute is different. 2341 01:56:32,582 --> 01:56:33,360 It's source. 2342 01:56:33,360 --> 01:56:35,880 And it's stupidly written like this. 2343 01:56:35,880 --> 01:56:38,730 If you are using an external file, you literally 2344 01:56:38,730 --> 01:56:42,150 close the tag, even though there's nothing inside of it. 2345 01:56:42,150 --> 01:56:43,305 That's one of these-- 2346 01:56:43,305 --> 01:56:47,100 a reality of using this particular tag. 2347 01:56:47,100 --> 01:56:49,590 Well, let me go ahead and propose that we 2348 01:56:49,590 --> 01:56:51,510 write an actual program in JavaScript. 2349 01:56:51,510 --> 01:56:53,460 Let me go back over to my IDE. 2350 01:56:53,460 --> 01:56:55,920 Let's create a new file called-- 2351 01:56:55,920 --> 01:57:00,150 actually, let's go ahead and open up our old one, hello.html, 2352 01:57:00,150 --> 01:57:01,590 and let's make it interactive. 2353 01:57:01,590 --> 01:57:03,730 Rather than say hello, body all the time, 2354 01:57:03,730 --> 01:57:07,380 let's see if we can't make it say a little something to me and to you. 2355 01:57:07,380 --> 01:57:11,340 So down here in the body of my page, let me go ahead and change this 2356 01:57:11,340 --> 01:57:17,070 and do something like this, form, close form, input-- 2357 01:57:17,070 --> 01:57:27,240 how about let's do ID of quote-unquote "name", and type is going to be text. 2358 01:57:27,240 --> 01:57:30,540 And then let me go ahead and give myself a submit button, type="submit". 2359 01:57:30,540 --> 01:57:31,900 So super simple. 2360 01:57:31,900 --> 01:57:34,260 The only difference now is I want a generic text box. 2361 01:57:34,260 --> 01:57:36,540 I don't want one that's specific to searching. 2362 01:57:36,540 --> 01:57:38,760 And I want a submit button, a generic one. 2363 01:57:38,760 --> 01:57:40,030 I don't care what it says. 2364 01:57:40,030 --> 01:57:43,140 Let me go back to my other tab, click hello.html, 2365 01:57:43,140 --> 01:57:46,080 and we have a form similar to the Google search example, 2366 01:57:46,080 --> 01:57:51,797 but now, I am going to use a web form in my own HTML file 2367 01:57:51,797 --> 01:57:53,880 to interact with the user, because after all, this 2368 01:57:53,880 --> 01:57:57,060 is how humans interact with web pages, typically, is via these forms. 2369 01:57:57,060 --> 01:58:00,390 I want to enable the user to type in their name, click Submit, 2370 01:58:00,390 --> 01:58:04,020 and then I want my web page now, not Google, to say Hello, David, Hello, 2371 01:58:04,020 --> 01:58:06,720 Brian hello to whoever types this in. 2372 01:58:06,720 --> 01:58:10,140 So I'm not going to use a form in quite the same way as before. 2373 01:58:10,140 --> 01:58:12,240 There's not going to be an action, because I'm not 2374 01:58:12,240 --> 01:58:14,075 going to send it to Google. 2375 01:58:14,075 --> 01:58:15,700 I'm not going to send it anywhere else. 2376 01:58:15,700 --> 01:58:20,230 I'm going to write code that's entirely client side in the browser itself. 2377 01:58:20,230 --> 01:58:22,290 So what do I want the form to do? 2378 01:58:22,290 --> 01:58:27,860 When this form is submitted, I want it to call a function called greet. 2379 01:58:27,860 --> 01:58:29,610 And at the moment, this is a little messy. 2380 01:58:29,610 --> 01:58:31,630 We're going to clean this up in a moment. 2381 01:58:31,630 --> 01:58:36,060 But there is this attribute in HTTP called alt onsubmit, the value of which 2382 01:58:36,060 --> 01:58:37,440 is not HTML per se. 2383 01:58:37,440 --> 01:58:38,400 It's not CSS. 2384 01:58:38,400 --> 01:58:40,170 It's now JavaScript code. 2385 01:58:40,170 --> 01:58:42,360 I want to call the function called greet. 2386 01:58:42,360 --> 01:58:46,050 This function doesn't exist yet, but it will soon. 2387 01:58:46,050 --> 01:58:48,580 How do I go about doing that? 2388 01:58:48,580 --> 01:58:52,200 Well, let me go ahead and go up here and add my script tag. 2389 01:58:52,200 --> 01:58:55,530 And up here, let me go ahead and define a function in JavaScript. 2390 01:58:55,530 --> 01:58:58,470 It's a little similar to C. It's a little similar to Python. 2391 01:58:58,470 --> 01:59:00,960 You literally, though, in JavaScript say function. 2392 01:59:00,960 --> 01:59:04,410 You write the name of your function and the arguments in parentheses. 2393 01:59:04,410 --> 01:59:06,930 And then in curly braces, you define the function. 2394 01:59:06,930 --> 01:59:13,170 I'm going to go ahead and just say alert quote-unquote 'hello, body' for now. 2395 01:59:13,170 --> 01:59:17,140 I'm going to keep it simple and just goofily output hello, body. 2396 01:59:17,140 --> 01:59:21,360 And because this form, by default, as with all forms, 2397 01:59:21,360 --> 01:59:24,000 typically does gets submitted to a server, 2398 01:59:24,000 --> 01:59:25,920 I'm going to add one other curiosity. 2399 01:59:25,920 --> 01:59:30,075 I'm going to say return false also inside of this onsubmit attribute. 2400 01:59:30,075 --> 01:59:32,700 So I realize things are escalating quickly here because there's 2401 01:59:32,700 --> 01:59:35,760 a lot of pieces in motion, but focus again on the basics. 2402 01:59:35,760 --> 01:59:37,335 The attribute is onsubmit. 2403 01:59:37,335 --> 01:59:39,210 What do you want to do when the user submits? 2404 01:59:39,210 --> 01:59:42,330 I want to execute these two lines of JavaScript code called 2405 01:59:42,330 --> 01:59:44,670 the greet function and then return false. 2406 01:59:44,670 --> 01:59:48,000 Return false in this context means don't submit the form. 2407 01:59:48,000 --> 01:59:50,550 Call the function, but don't submit the form anywhere. 2408 01:59:50,550 --> 01:59:55,260 I just want to use it as a client-side tool for interacting with the user. 2409 01:59:55,260 --> 01:59:58,500 I don't need to send it to the server or to Google to anyone else. 2410 01:59:58,500 --> 02:00:02,730 Let me go ahead now and specify this. 2411 02:00:02,730 --> 02:00:06,570 I deliberately gave this text field an ID of name, 2412 02:00:06,570 --> 02:00:08,580 but we'll use that in just a moment. 2413 02:00:08,580 --> 02:00:12,930 Let me go over to my other tab now, reload, because I've made changes. 2414 02:00:12,930 --> 02:00:15,730 I can type in David, but I'm going to be ignored for the moment. 2415 02:00:15,730 --> 02:00:19,590 But when I click Submit now, notice, it's not the best user interface, 2416 02:00:19,590 --> 02:00:26,010 but there is an alert on my screen from my specific URL that says hello, body. 2417 02:00:26,010 --> 02:00:27,810 But I'd like it to say hello comma David. 2418 02:00:27,810 --> 02:00:29,110 So how can I do that? 2419 02:00:29,110 --> 02:00:31,800 Well, let me go back into my code here and let me go ahead 2420 02:00:31,800 --> 02:00:36,120 and define a variable called name, but I could call it anything I want. 2421 02:00:36,120 --> 02:00:41,910 And let me use this special function, document.querySelector(). 2422 02:00:41,910 --> 02:00:44,840 And this is a function that comes with JavaScript that 2423 02:00:44,840 --> 02:00:48,230 allows you to select any HTML element. 2424 02:00:48,230 --> 02:00:52,610 But you need to be able to identify it using some kind of selector. 2425 02:00:52,610 --> 02:00:56,450 And here's where, for better or for worse, CSS and HTML and JavaScript 2426 02:00:56,450 --> 02:00:58,590 start borrowing ideas from each other. 2427 02:00:58,590 --> 02:01:02,420 If I want to get the value of the user's text box, 2428 02:01:02,420 --> 02:01:06,620 I bet I could give it a unique ID, like quote-unquote "name", 2429 02:01:06,620 --> 02:01:11,360 and I can select it by using my CSS syntax of name. 2430 02:01:11,360 --> 02:01:15,860 And once I've selected that HTML element, so to speak, that tag, 2431 02:01:15,860 --> 02:01:18,420 I'm going to go inside of it and get its value. 2432 02:01:18,420 --> 02:01:21,720 So this syntax is a little familiar, a little unfamiliar. 2433 02:01:21,720 --> 02:01:25,010 We've seen the dot notation before in C when it came to structs. 2434 02:01:25,010 --> 02:01:29,150 We've seen the dot notation in Python when it came to libraries, like the CSV 2435 02:01:29,150 --> 02:01:30,050 library. 2436 02:01:30,050 --> 02:01:31,970 We're using it in a similar way. 2437 02:01:31,970 --> 02:01:34,490 Document is this special global variable that 2438 02:01:34,490 --> 02:01:36,960 just comes with JavaScript in the browser, 2439 02:01:36,960 --> 02:01:38,900 and it gives you access to all things related 2440 02:01:38,900 --> 02:01:40,880 to your document, your web page. 2441 02:01:40,880 --> 02:01:45,440 querySelector is a function that comes with that document 2442 02:01:45,440 --> 02:01:51,110 that Google and Microsoft and Apple wrote for you called querySelector 2443 02:01:51,110 --> 02:01:55,010 whose purpose in life is to take a CSS selector in quotes 2444 02:01:55,010 --> 02:02:02,330 that identifies one or more nodes that is nodes from the tree. 2445 02:02:02,330 --> 02:02:05,450 And this tree actually has a name, though I've not used it before. 2446 02:02:05,450 --> 02:02:08,030 This tree that we keep referring to is technically 2447 02:02:08,030 --> 02:02:11,120 called a DOM, a Document Object Model, which 2448 02:02:11,120 --> 02:02:15,380 is just a fancy way of saying that document, this global variable, 2449 02:02:15,380 --> 02:02:18,980 gives you access to this DOM, this tree. 2450 02:02:18,980 --> 02:02:23,030 So when you call document.querySelector, that induces your browser for you 2451 02:02:23,030 --> 02:02:26,720 to search the whole tree, all of those nodes and parents and children 2452 02:02:26,720 --> 02:02:29,390 and grandchildren and so forth-- all of those nodes, 2453 02:02:29,390 --> 02:02:32,000 looking for the one with the unique identifier of name 2454 02:02:32,000 --> 02:02:35,570 and then looking inside of that node, inside that rectangle, if you will, 2455 02:02:35,570 --> 02:02:38,310 getting the actual value that the human typed in. 2456 02:02:38,310 --> 02:02:40,460 So if I want to now output this value, I'm 2457 02:02:40,460 --> 02:02:42,650 just going to use some old-school concatenation. 2458 02:02:42,650 --> 02:02:46,720 Let me add to that string, hello name. 2459 02:02:46,720 --> 02:02:47,920 And I can use double quotes. 2460 02:02:47,920 --> 02:02:48,820 I can use single quotes. 2461 02:02:48,820 --> 02:02:51,695 Does not matter so long as you're consistent in the JavaScript world. 2462 02:02:51,695 --> 02:02:55,780 For whatever reasons, the convention tends to be single quotes if only 2463 02:02:55,780 --> 02:02:58,450 because you can type it almost twice as fast because you don't 2464 02:02:58,450 --> 02:03:01,090 have to hold the stupid Shift key to type a double quote-- 2465 02:03:01,090 --> 02:03:03,430 or to type a single quote as you would a double quote. 2466 02:03:03,430 --> 02:03:03,670 All right. 2467 02:03:03,670 --> 02:03:06,400 Let me go back to this page, reload, because I've made changes. 2468 02:03:06,400 --> 02:03:07,960 Let me type in my name again. 2469 02:03:07,960 --> 02:03:10,270 Autocomplete is popping up nicely. 2470 02:03:10,270 --> 02:03:11,560 Click Submit. 2471 02:03:11,560 --> 02:03:13,660 And voila, Hello, David. 2472 02:03:13,660 --> 02:03:19,030 The user interface is still kind of lame, but it's at least now dynamic. 2473 02:03:19,030 --> 02:03:23,080 And I can type in anyone's name, as you could, Brian, Submit. 2474 02:03:23,080 --> 02:03:24,670 Hello, Brian. 2475 02:03:24,670 --> 02:03:26,920 And you can change other things about the web page. 2476 02:03:26,920 --> 02:03:29,050 And some of this is just implementation details, 2477 02:03:29,050 --> 02:03:31,090 but recall that you can give a button a value, 2478 02:03:31,090 --> 02:03:33,070 and you can say something like greet me. 2479 02:03:33,070 --> 02:03:36,070 Now, if I go back here and reload, my button now says greet me. 2480 02:03:36,070 --> 02:03:40,540 Turns out that your input for text can have a placeholder, 2481 02:03:40,540 --> 02:03:45,340 like what's your name, and then saving that file and reloading, 2482 02:03:45,340 --> 02:03:49,030 you see in grayed-out text a prompt on the box that's not actually there, 2483 02:03:49,030 --> 02:03:51,640 because once you start clicking, it goes away. 2484 02:03:51,640 --> 02:03:55,240 I can also disable that somewhat annoying autocomplete by saying 2485 02:03:55,240 --> 02:03:57,850 autocomplete="off". 2486 02:03:57,850 --> 02:04:00,850 And then I can go back to my page and reload, and now notice, 2487 02:04:00,850 --> 02:04:03,070 even when I click in there, it doesn't autocomplete, 2488 02:04:03,070 --> 02:04:05,080 which is maybe good for privacy's sake. 2489 02:04:05,080 --> 02:04:07,850 And notice, too, I can do one other thing. 2490 02:04:07,850 --> 02:04:10,090 Let me go ahead and add autofocus. 2491 02:04:10,090 --> 02:04:14,170 Notice that every time I reload the page, I had to click in the box. 2492 02:04:14,170 --> 02:04:16,330 But now when I reload the page, the cursor 2493 02:04:16,330 --> 02:04:21,140 is already there, blinking and ready to go, thereby saving your users one step. 2494 02:04:21,140 --> 02:04:25,210 So again, another vote in favor of accessibility and usability 2495 02:04:25,210 --> 02:04:29,880 by just putting the user where they probably want to be anyway. 2496 02:04:29,880 --> 02:04:30,660 All right. 2497 02:04:30,660 --> 02:04:35,190 Any questions thus far on this introduction of JavaScript 2498 02:04:35,190 --> 02:04:39,060 by way of this function greet inside of our new script tag 2499 02:04:39,060 --> 02:04:43,230 and using this new onsubmit attribute that calls that function 2500 02:04:43,230 --> 02:04:46,800 and then short-circuits the form submission by just saying return false, 2501 02:04:46,800 --> 02:04:49,800 call the function but don't submit the form to the server, 2502 02:04:49,800 --> 02:04:51,920 like we did with Google? 2503 02:04:51,920 --> 02:04:55,380 All right, well, let me-- at the risk of making it look more complicated, 2504 02:04:55,380 --> 02:04:57,535 let me make it more complicated, but in a way 2505 02:04:57,535 --> 02:04:59,660 that will be familiar over the next couple of weeks 2506 02:04:59,660 --> 02:05:02,570 when you've seen more and more examples and you've used third-party libraries-- 2507 02:05:02,570 --> 02:05:03,950 you've seen some building blocks. 2508 02:05:03,950 --> 02:05:08,450 We would not expect you to write this week, tonight, based on these examples, 2509 02:05:08,450 --> 02:05:11,840 but just to give you the mental model for how JavaScript is typically 2510 02:05:11,840 --> 02:05:12,570 written. 2511 02:05:12,570 --> 02:05:16,400 So this with, like with CSS, tends to be a little poorly designed. 2512 02:05:16,400 --> 02:05:18,200 When you start commingling your languages, 2513 02:05:18,200 --> 02:05:20,825 like, ugh, that makes it hard to collaborate with someone else. 2514 02:05:20,825 --> 02:05:23,910 It makes it hard to maintain one language independent of another. 2515 02:05:23,910 --> 02:05:26,848 So it tends to be a good thing to keep these things separate. 2516 02:05:26,848 --> 02:05:28,140 And that's not always the case. 2517 02:05:28,140 --> 02:05:30,260 There's actually now a trend, especially in mobile app development, 2518 02:05:30,260 --> 02:05:31,950 of putting these things back together. 2519 02:05:31,950 --> 02:05:35,850 But this tends to keep things clean, at least when we're first starting out. 2520 02:05:35,850 --> 02:05:41,910 So let me go ahead and actually go ahead and get rid of my code up here for now. 2521 02:05:41,910 --> 02:05:44,840 And let me go ahead and get rid of this onsubmit handler. 2522 02:05:44,840 --> 02:05:48,350 And let me go ahead now and down here-- 2523 02:05:48,350 --> 02:05:51,230 actually, up here, give myself a script tag. 2524 02:05:51,230 --> 02:05:53,960 And let me go ahead and do the same thing a little differently. 2525 02:05:53,960 --> 02:05:57,410 document.querySelector-- 2526 02:05:57,410 --> 02:05:59,240 this time, let me select the form. 2527 02:05:59,240 --> 02:06:01,115 And I'm not going to bother giving it a name. 2528 02:06:01,115 --> 02:06:04,160 There's only one form, so if I just select form, that'll give me my form. 2529 02:06:04,160 --> 02:06:08,060 And let me use this fancy function, addEventListener. 2530 02:06:08,060 --> 02:06:10,370 It turns out that the world of web programming 2531 02:06:10,370 --> 02:06:12,590 is filled with what we would call events. 2532 02:06:12,590 --> 02:06:14,480 When you click on a page, that's an event. 2533 02:06:14,480 --> 02:06:16,340 When you drag on a page, that's an event. 2534 02:06:16,340 --> 02:06:18,950 On a phone, when you touch a page, that's an event. 2535 02:06:18,950 --> 02:06:21,890 Turns out, using JavaScript, you now, the programmer, 2536 02:06:21,890 --> 02:06:24,530 can write code that listens for these events 2537 02:06:24,530 --> 02:06:27,127 and responds to them by doing something. 2538 02:06:27,127 --> 02:06:29,960 So I'm going to go ahead and add an event listener on my form that's 2539 02:06:29,960 --> 02:06:32,540 listening for the Submit event. 2540 02:06:32,540 --> 02:06:37,760 What do I want my code to do when the form is submitted? 2541 02:06:37,760 --> 02:06:39,397 I want to call the greet function. 2542 02:06:39,397 --> 02:06:42,230 All right, for the greet function to work, I need to reintroduce it. 2543 02:06:42,230 --> 02:06:44,630 So let me quickly whip up the greet function. 2544 02:06:44,630 --> 02:06:49,040 Let me go ahead and do an alert of hello and then plus name. 2545 02:06:49,040 --> 02:06:53,892 I need to get the name node, so let me say let name = document.querySelector. 2546 02:06:53,892 --> 02:06:57,620 2547 02:06:57,620 --> 02:07:00,360 And now let me go ahead-- and I still have the ID there, 2548 02:07:00,360 --> 02:07:04,050 so let's say quote-unquote hash name dot value. 2549 02:07:04,050 --> 02:07:05,900 So I think greet now exists. 2550 02:07:05,900 --> 02:07:08,030 But now this line of code, notice, does this. 2551 02:07:08,030 --> 02:07:11,000 It says, hey, browser, find me the form, then 2552 02:07:11,000 --> 02:07:14,580 add an event listener listening for the Submit event, 2553 02:07:14,580 --> 02:07:16,490 and when that event is call-- 2554 02:07:16,490 --> 02:07:19,250 when that event happens, call this function. 2555 02:07:19,250 --> 02:07:20,570 This is very similar-- 2556 02:07:20,570 --> 02:07:23,630 well, somewhat similar to our lambda example last week 2557 02:07:23,630 --> 02:07:26,870 when we passed a function into the sorted 2558 02:07:26,870 --> 02:07:30,740 function so as to tell what to sort by value instead of by key. 2559 02:07:30,740 --> 02:07:36,170 Remember that syntax when we define a function just to help us sort things. 2560 02:07:36,170 --> 02:07:38,390 Notice that I do not want to call greet. 2561 02:07:38,390 --> 02:07:41,180 I do not want to call greet on line 13. 2562 02:07:41,180 --> 02:07:45,500 I want to tell the browser to call greet when it is ready. 2563 02:07:45,500 --> 02:07:48,410 Therefore, I pass the function in by name. 2564 02:07:48,410 --> 02:07:51,230 Let me go ahead now and save and reload. 2565 02:07:51,230 --> 02:07:54,830 OK, nothing visually has changed, but when I type in David and greet me-- 2566 02:07:54,830 --> 02:07:57,050 [GASPS] huh. 2567 02:07:57,050 --> 02:07:57,980 Nothing happened. 2568 02:07:57,980 --> 02:07:58,740 Let me say David. 2569 02:07:58,740 --> 02:07:59,240 Greet. 2570 02:07:59,240 --> 02:08:00,350 Nothing happened. 2571 02:08:00,350 --> 02:08:02,420 When in doubt, if something's acting up, let's 2572 02:08:02,420 --> 02:08:06,320 go back to those developer tools, Developer, Developer Tools. 2573 02:08:06,320 --> 02:08:09,110 And let's not look at network, but look at console. 2574 02:08:09,110 --> 02:08:13,010 And here is where your new friend is going to show you all of the mistakes 2575 02:08:13,010 --> 02:08:14,750 that you've made in JavaScript code. 2576 02:08:14,750 --> 02:08:18,410 Just like in Python and C, you see the errors in your terminal window. 2577 02:08:18,410 --> 02:08:23,627 Because JavaScript is being run on the client's side, in the user's browser, 2578 02:08:23,627 --> 02:08:25,460 you can't just look at your terminal window. 2579 02:08:25,460 --> 02:08:26,450 There won't be any errors there. 2580 02:08:26,450 --> 02:08:29,570 You need to look in your own browser if you're the one testing things. 2581 02:08:29,570 --> 02:08:36,150 And sure enough, notice here, cannot read property addEventListener of null. 2582 02:08:36,150 --> 02:08:40,070 So this is a subtle one, but I did it deliberately, because it's so common-- 2583 02:08:40,070 --> 02:08:41,660 and I promise I did it deliberately. 2584 02:08:41,660 --> 02:08:44,510 Let me go back here and point out this. 2585 02:08:44,510 --> 02:08:45,980 Browsers are pretty naive. 2586 02:08:45,980 --> 02:08:48,320 As fancy and as powerful as they seem to be getting, 2587 02:08:48,320 --> 02:08:52,230 they still take us literally, just like Python and C did, top to bottom, 2588 02:08:52,230 --> 02:08:53,340 left to right. 2589 02:08:53,340 --> 02:08:59,450 And if on line 13 I am saying query for the form tag, 2590 02:08:59,450 --> 02:09:03,950 but the form tag doesn't exist until line 21, it's not going to work, 2591 02:09:03,950 --> 02:09:06,500 and therefore the error message I'm seeing makes sense. 2592 02:09:06,500 --> 02:09:09,830 You cannot read property addEventListener of null. 2593 02:09:09,830 --> 02:09:11,660 Where is null coming from? 2594 02:09:11,660 --> 02:09:15,020 Form is currently null as of line 13. 2595 02:09:15,020 --> 02:09:18,800 It does not exist until line 21. 2596 02:09:18,800 --> 02:09:20,010 So how do we fix this? 2597 02:09:20,010 --> 02:09:22,880 Well, one way, the quick and dirty way, would be, well, 2598 02:09:22,880 --> 02:09:28,280 let's just move this down below, inside of the body now but below the form tag. 2599 02:09:28,280 --> 02:09:29,610 And I think this will work. 2600 02:09:29,610 --> 02:09:31,190 Let me go ahead and reload now. 2601 02:09:31,190 --> 02:09:33,440 The error goes away, but I haven't done anything yet. 2602 02:09:33,440 --> 02:09:36,650 Let me click in the box and say David, greet me. 2603 02:09:36,650 --> 02:09:38,480 OK, it's back to working. 2604 02:09:38,480 --> 02:09:41,245 But much like in Python and C, this is kind of a slippery slope. 2605 02:09:41,245 --> 02:09:44,120 Like, the solution to our problems can't just be, well, move it down. 2606 02:09:44,120 --> 02:09:44,868 Move it down. 2607 02:09:44,868 --> 02:09:46,160 There's got to be a better way. 2608 02:09:46,160 --> 02:09:49,940 Similar in spirit to prototypes, but not quite in the same way. 2609 02:09:49,940 --> 02:09:52,680 The way JavaScript handles this problem is as follows. 2610 02:09:52,680 --> 02:09:56,780 If I undo that and go back to the top where I have my script now, 2611 02:09:56,780 --> 02:09:58,850 I can actually do this instead. 2612 02:09:58,850 --> 02:10:02,660 I can do something like this. 2613 02:10:02,660 --> 02:10:07,310 I can do this document.addEventListener-- 2614 02:10:07,310 --> 02:10:13,090 and this is a weird one-- but DOMContentLoaded, 2615 02:10:13,090 --> 02:10:15,910 call this function listen. 2616 02:10:15,910 --> 02:10:21,970 And let me go here and give myself a second function, function listen. 2617 02:10:21,970 --> 02:10:25,070 And inside of this function will be that one line of code. 2618 02:10:25,070 --> 02:10:27,160 So I've got two functions now, one of which 2619 02:10:27,160 --> 02:10:30,010 handles the greeting, no changes there, a new one called 2620 02:10:30,010 --> 02:10:34,240 listen whose purpose in life is just to add that event listener. 2621 02:10:34,240 --> 02:10:35,200 That's all. 2622 02:10:35,200 --> 02:10:38,290 But notice here on line 18, now, I'm adding an event 2623 02:10:38,290 --> 02:10:43,030 listener to the document itself saying when the DOM content is loaded-- that 2624 02:10:43,030 --> 02:10:46,060 is to say, when this whole tree has been loaded 2625 02:10:46,060 --> 02:10:49,220 and therefore the form tag has been loaded and everything else, 2626 02:10:49,220 --> 02:10:52,240 go ahead and call the listen function. 2627 02:10:52,240 --> 02:10:56,740 The listen function is just going to add another listener to the form 2628 02:10:56,740 --> 02:10:59,110 tag listening for submissions. 2629 02:10:59,110 --> 02:11:02,770 And so now, if I go ahead and save this, reload, 2630 02:11:02,770 --> 02:11:05,980 I'll keep my developer tools open, and type in David and greet me, 2631 02:11:05,980 --> 02:11:09,490 still works, but I haven't had to do this stupid resort 2632 02:11:09,490 --> 02:11:13,060 of moving my code down to the bottom and solving the problem that way. 2633 02:11:13,060 --> 02:11:16,090 I'm just telling the browser, don't do the following 2634 02:11:16,090 --> 02:11:19,660 until the DOMs content has loaded. 2635 02:11:19,660 --> 02:11:21,730 All right, questions on any of this? 2636 02:11:21,730 --> 02:11:23,530 And this is absolutely the more-- 2637 02:11:23,530 --> 02:11:26,980 the most sophisticated, I think, of the syntax and the logic we've done today. 2638 02:11:26,980 --> 02:11:30,550 But again, we're just planting the seeds for understanding this in the weeks 2639 02:11:30,550 --> 02:11:33,130 to come. 2640 02:11:33,130 --> 02:11:33,940 No? 2641 02:11:33,940 --> 02:11:35,800 Well, let me go ahead and blow your minds 2642 02:11:35,800 --> 02:11:37,630 with one other feature of JavaScript that 2643 02:11:37,630 --> 02:11:41,260 actually has similarities with Python. 2644 02:11:41,260 --> 02:11:45,520 Recall that any time we define a function in one place and then 2645 02:11:45,520 --> 02:11:48,190 use it in one place, that's generally been kind of lame. 2646 02:11:48,190 --> 02:11:51,520 Like, why are you bothering to create a function, adding lines of code 2647 02:11:51,520 --> 02:11:54,070 to write a function that you're only going to call once? 2648 02:11:54,070 --> 02:11:57,250 Last week with Python recall that-- 2649 02:11:57,250 --> 02:12:00,865 two weeks ago, with Python, recall we defined a function f, 2650 02:12:00,865 --> 02:12:02,740 and then we said, no, no, no, this is stupid, 2651 02:12:02,740 --> 02:12:05,532 let's just use a lambda function, an anonymous function, basically, 2652 02:12:05,532 --> 02:12:07,730 because it's only being used in one place. 2653 02:12:07,730 --> 02:12:11,720 So this is going to be the ugliest we see, but here we go. 2654 02:12:11,720 --> 02:12:14,320 If I know that I want to call a function called 2655 02:12:14,320 --> 02:12:17,260 listen when the DOM's content is loaded, I 2656 02:12:17,260 --> 02:12:19,330 don't need to give that function a name. 2657 02:12:19,330 --> 02:12:22,420 I can actually just put the function right there. 2658 02:12:22,420 --> 02:12:25,240 I'm going to literally copy and paste this over here. 2659 02:12:25,240 --> 02:12:27,740 Let me remove the excess white space here. 2660 02:12:27,740 --> 02:12:31,840 Let me go ahead and now point out-- 2661 02:12:31,840 --> 02:12:34,340 and I'm going to do this a little stylistically differently, 2662 02:12:34,340 --> 02:12:36,710 just to be consistent with what other people do. 2663 02:12:36,710 --> 02:12:38,780 Notice now I've done this. 2664 02:12:38,780 --> 02:12:43,070 I've literally moved that function as the second argument 2665 02:12:43,070 --> 02:12:46,560 to addEventListener, and I don't need its name at this point. 2666 02:12:46,560 --> 02:12:48,290 I'm going to go ahead and just do this. 2667 02:12:48,290 --> 02:12:51,830 The equivalent in JavaScript of a lambda function 2668 02:12:51,830 --> 02:12:54,980 is to literally just say function with no name 2669 02:12:54,980 --> 02:12:58,410 and still have open parentheses, with or without a space in between them. 2670 02:12:58,410 --> 02:13:00,800 And so what this is now saying a little more elegantly, 2671 02:13:00,800 --> 02:13:04,400 even though more cryptically, on the document object, your global variable, 2672 02:13:04,400 --> 02:13:07,130 add the event listener listening for the DOM content loaded. 2673 02:13:07,130 --> 02:13:09,860 Well, what do you want to do when the DOM's content has loaded? 2674 02:13:09,860 --> 02:13:14,390 Call this anonymous function, otherwise known as a lambda function. 2675 02:13:14,390 --> 02:13:15,958 But notice what we're going to do. 2676 02:13:15,958 --> 02:13:17,750 We're going to query for the form and we're 2677 02:13:17,750 --> 02:13:21,230 going to add an event listener on Submit by calling the greet function. 2678 02:13:21,230 --> 02:13:23,100 Well, we don't need to do that. 2679 02:13:23,100 --> 02:13:25,400 Let's go ahead and remove that. 2680 02:13:25,400 --> 02:13:28,905 Let's go ahead and delete the greet function name and get rid of it. 2681 02:13:28,905 --> 02:13:30,530 Let's make one more anonymous function. 2682 02:13:30,530 --> 02:13:31,842 Let me paste this in here. 2683 02:13:31,842 --> 02:13:34,550 I've got to clean up my formatting real quick, so let me go ahead 2684 02:13:34,550 --> 02:13:39,200 and remove some whitespace here, remove the function name, 2685 02:13:39,200 --> 02:13:42,050 put my curly brace over there, get rid of this one 2686 02:13:42,050 --> 02:13:45,980 here, indent that, indent this, close this. 2687 02:13:45,980 --> 02:13:50,453 Whew, scary looking, to be sure, or at least cryptic looking, 2688 02:13:50,453 --> 02:13:53,370 or maybe delightful, depending on whether you like this kind of thing. 2689 02:13:53,370 --> 02:13:55,670 But again, it's just basic building blocks, right? 2690 02:13:55,670 --> 02:13:58,130 In Python, you can define functions that don't have names. 2691 02:13:58,130 --> 02:14:01,700 That's great because if you want to pass one function to another function, 2692 02:14:01,700 --> 02:14:05,570 you can literally just write the code using the supported syntax, which 2693 02:14:05,570 --> 02:14:08,480 in JavaScript does not use the word lambda, but to use the word 2694 02:14:08,480 --> 02:14:11,960 function no name but still parentheses, and then 2695 02:14:11,960 --> 02:14:15,350 making sure it's still well-formed function with an open curly brace here 2696 02:14:15,350 --> 02:14:18,530 and a closed curly brace here, you can then write out your code. 2697 02:14:18,530 --> 02:14:22,010 And the only reason I have this other parenthesis over here 2698 02:14:22,010 --> 02:14:27,620 is because I'm already inside of a function called addEventListener. 2699 02:14:27,620 --> 02:14:29,270 So again, if uncomfortable with that-- 2700 02:14:29,270 --> 02:14:31,490 not a problem, certainly at this stage. 2701 02:14:31,490 --> 02:14:37,100 But again, we're just now stacking these different ideas on top, on top, 2702 02:14:37,100 --> 02:14:39,320 on top of one another. 2703 02:14:39,320 --> 02:14:43,940 All right, well, let me show you now a premade example that shows you exactly 2704 02:14:43,940 --> 02:14:45,950 what you can do now with these events. 2705 02:14:45,950 --> 02:14:48,110 Here's a nonexhaustive list of events that you 2706 02:14:48,110 --> 02:14:50,480 can listen for in a browser, not just things 2707 02:14:50,480 --> 02:14:56,660 like submitting, but also clicking and dragging, 2708 02:14:56,660 --> 02:14:59,930 key pressing, moving your mouse over, moving your mouse down, 2709 02:14:59,930 --> 02:15:03,183 the button up and down, touching and moving, and other such events. 2710 02:15:03,183 --> 02:15:06,350 There's this whole list of events that you can do such that you can actually 2711 02:15:06,350 --> 02:15:07,220 do things like this. 2712 02:15:07,220 --> 02:15:10,730 Let me go back to my IDE, and let me open up a premade example, 2713 02:15:10,730 --> 02:15:13,670 this one called hello5.html. 2714 02:15:13,670 --> 02:15:16,700 And in hello5.html, I've got this example already 2715 02:15:16,700 --> 02:15:18,200 that-- it's just doing a few things. 2716 02:15:18,200 --> 02:15:22,910 It's listening for DOMContentLoaded, but it's then listening for key up. 2717 02:15:22,910 --> 02:15:24,703 And what's it going to do with key up? 2718 02:15:24,703 --> 02:15:25,370 Well, let's see. 2719 02:15:25,370 --> 02:15:27,350 Let me go over here into my index. 2720 02:15:27,350 --> 02:15:29,540 I'm going to close the debugging tools. 2721 02:15:29,540 --> 02:15:33,150 Let me reload my directory index here. 2722 02:15:33,150 --> 02:15:39,590 And that gives me this other file in source eight called hello5.html. 2723 02:15:39,590 --> 02:15:42,770 Now, notice here, I'm going to go ahead and type in David-- 2724 02:15:42,770 --> 02:15:43,580 oh. 2725 02:15:43,580 --> 02:15:46,960 Notice, the web page itself is immediately interacting with me, 2726 02:15:46,960 --> 02:15:49,460 and as soon as I delete it, it says, hello, whoever you are. 2727 02:15:49,460 --> 02:15:51,335 So with JavaScript, you have the ability even 2728 02:15:51,335 --> 02:15:55,580 to change the contents of the web page, not just by throwing an ugly alert. 2729 02:15:55,580 --> 02:15:59,300 You can use code like you see here, which we won't get into the details of, 2730 02:15:59,300 --> 02:16:01,460 but allows you to change the page itself. 2731 02:16:01,460 --> 02:16:04,130 And notice here-- this is kind of ugly-looking syntax. 2732 02:16:04,130 --> 02:16:05,750 You don't even have to concatenate. 2733 02:16:05,750 --> 02:16:08,960 Just like Python has f strings, in JavaScript, 2734 02:16:08,960 --> 02:16:12,530 you can use backticks plus a dollar sign and stupid curly braces 2735 02:16:12,530 --> 02:16:13,520 and do the same thing. 2736 02:16:13,520 --> 02:16:16,970 And I'm showing some bias here. 2737 02:16:16,970 --> 02:16:20,297 Stupid syntax, I think, but same exact idea as it was in Python. 2738 02:16:20,297 --> 02:16:22,880 And again, these are the kinds of things that will trip you up 2739 02:16:22,880 --> 02:16:26,570 early on, inevitably, but again, as you get more comfortable with the language, 2740 02:16:26,570 --> 02:16:31,090 all of the ideas will outshine the particular syntax. 2741 02:16:31,090 --> 02:16:31,590 All right. 2742 02:16:31,590 --> 02:16:33,709 Let's look at a few other premade examples 2743 02:16:33,709 --> 02:16:36,469 just to give you a sense of the capabilities of JavaScript. 2744 02:16:36,469 --> 02:16:39,260 Here's a program called background.html. 2745 02:16:39,260 --> 02:16:42,392 And this web page you'll see is going to have three buttons. 2746 02:16:42,392 --> 02:16:45,350 It turns out you can implement buttons on a web page in different ways. 2747 02:16:45,350 --> 02:16:48,110 You can literally use the button tag. 2748 02:16:48,110 --> 02:16:51,350 Down here, I have a whole bunch of code using querySelector 2749 02:16:51,350 --> 02:16:54,770 again, but more powerfully, notice what you can also do. 2750 02:16:54,770 --> 02:16:57,830 If you go ahead in JavaScript and select your body 2751 02:16:57,830 --> 02:17:00,770 by saying document.querySelector body, you 2752 02:17:00,770 --> 02:17:06,440 can actually then access a special variable inside of the page's body-- 2753 02:17:06,440 --> 02:17:08,570 or any tag for that matter-- called style. 2754 02:17:08,570 --> 02:17:14,330 And then you can change, with JavaScript, the style of a CSS property 2755 02:17:14,330 --> 02:17:15,379 using code. 2756 02:17:15,379 --> 02:17:18,139 And unfortunately, left hand was not talking to right hand. 2757 02:17:18,139 --> 02:17:21,230 In CSS, it would be background dash color, as we saw. 2758 02:17:21,230 --> 02:17:24,150 Unfortunately, in JavaScript, a proper programming language, 2759 02:17:24,150 --> 02:17:28,010 this would be background minus color, like literally arithmetic. 2760 02:17:28,010 --> 02:17:31,700 So the world decided that any CSS properties with hyphens 2761 02:17:31,700 --> 02:17:35,282 would instead become something like background capital color 2762 02:17:35,282 --> 02:17:36,240 to distinguish the two. 2763 02:17:36,240 --> 02:17:37,850 But it's the same exact idea. 2764 02:17:37,850 --> 02:17:41,629 If I go now into this file here, background.html-- 2765 02:17:41,629 --> 02:17:45,110 well, now I have a very simple page with three buttons, R, G, and B. 2766 02:17:45,110 --> 02:17:48,320 But notice when I click on them, I have defined in advance, 2767 02:17:48,320 --> 02:17:50,719 I claim, some event listeners for click. 2768 02:17:50,719 --> 02:17:54,990 And every time I hear the click, I change the CSS of the page. 2769 02:17:54,990 --> 02:17:59,719 And if this weren't cool already, let me open up View, Developer Tools, 2770 02:17:59,719 --> 02:18:01,340 developer tools here. 2771 02:18:01,340 --> 02:18:04,219 Notice the third and final tab today is elements. 2772 02:18:04,219 --> 02:18:08,209 No matter how ugly your HTML is, the developer tag-- 2773 02:18:08,209 --> 02:18:10,309 the developer tools elements tab will always 2774 02:18:10,309 --> 02:18:13,850 show it to you in a very pretty, printed, colorful fashion. 2775 02:18:13,850 --> 02:18:17,930 But it will also show you the actual CSS as it's changing in real time. 2776 02:18:17,930 --> 02:18:19,549 So let me reload the page. 2777 02:18:19,549 --> 02:18:22,400 By default, notice the whole page has a white background. 2778 02:18:22,400 --> 02:18:26,570 And notice down here, indeed, the body has no style attributes on it. 2779 02:18:26,570 --> 02:18:29,000 But if I zoom out for a moment and now click R, 2780 02:18:29,000 --> 02:18:32,629 watch the HTML on the bottom of the page. 2781 02:18:32,629 --> 02:18:35,930 Chrome just dynamically added background-color red. 2782 02:18:35,930 --> 02:18:40,100 If I click green, background-color green is now there, and blue-- 2783 02:18:40,100 --> 02:18:44,120 so using these developer tools, you can interact with your own website 2784 02:18:44,120 --> 02:18:47,389 and see what's changing in the DOM. 2785 02:18:47,389 --> 02:18:51,200 We are changing in real time the attributes of this tree, 2786 02:18:51,200 --> 02:18:54,480 thereby making the page all the more dynamic. 2787 02:18:54,480 --> 02:18:55,400 This is powerful, too. 2788 02:18:55,400 --> 02:18:59,299 Let me go to Harvard.edu, for instance, open up developer tools, 2789 02:18:59,299 --> 02:19:05,420 and notice here, we can see all of Harvard.edu's HTML in the Elements tab. 2790 02:19:05,420 --> 02:19:07,670 Notice it's a lot of HTML here, but there's 2791 02:19:07,670 --> 02:19:09,940 all of these triangles that expand it-- 2792 02:19:09,940 --> 02:19:12,320 rather, that collapse it, just to make it more succinct. 2793 02:19:12,320 --> 02:19:15,440 If you want to look at specific things, let's go ahead 2794 02:19:15,440 --> 02:19:18,900 and say something like this. 2795 02:19:18,900 --> 02:19:19,490 Let's see. 2796 02:19:19,490 --> 02:19:22,950 What could be fun to change here? 2797 02:19:22,950 --> 02:19:23,780 How about this? 2798 02:19:23,780 --> 02:19:26,809 I'm going to go ahead and right-click or Control-click on About Harvard, 2799 02:19:26,809 --> 02:19:29,809 because this I'm finding not what I want. 2800 02:19:29,809 --> 02:19:33,139 It's going to automatically open in the Elements tab 2801 02:19:33,139 --> 02:19:37,309 the actual HTML that Harvard used to create About Harvard. 2802 02:19:37,309 --> 02:19:38,570 It's got some other tags here. 2803 02:19:38,570 --> 02:19:39,690 Span is another thing. 2804 02:19:39,690 --> 02:19:41,750 It's like a mini paragraph, all on one line. 2805 02:19:41,750 --> 02:19:42,860 Class we've seen before. 2806 02:19:42,860 --> 02:19:44,299 I don't know what lg-nav-txt-- 2807 02:19:44,299 --> 02:19:48,110 it's probably large navigational text that Harvard invented as a class name. 2808 02:19:48,110 --> 02:19:49,920 But notice what I can do here. 2809 02:19:49,920 --> 02:19:53,750 How about we change this to Yale and then hit Enter? 2810 02:19:53,750 --> 02:19:56,270 And voila, hacking Harvard.edu. 2811 02:19:56,270 --> 02:20:00,170 So of course understanding what's going on here is important. 2812 02:20:00,170 --> 02:20:03,170 I'm only changing my local copy of Harvard.edu 2813 02:20:03,170 --> 02:20:05,150 that's been downloaded onto my page. 2814 02:20:05,150 --> 02:20:08,220 If you go to Harvard.edu now, those changes are not persistent, 2815 02:20:08,220 --> 02:20:09,740 so it's not hacking per se. 2816 02:20:09,740 --> 02:20:13,190 But this is really, too, how you can learn how to design web pages. 2817 02:20:13,190 --> 02:20:17,540 If I go to Yale.edu, I can similarly look at all of Yale's HTML and change 2818 02:20:17,540 --> 02:20:18,050 things here. 2819 02:20:18,050 --> 02:20:19,820 Let me right-click on About Yale. 2820 02:20:19,820 --> 02:20:21,260 Click on Inspect. 2821 02:20:21,260 --> 02:20:24,200 Let me go ahead and change this to Harvard, Enter. 2822 02:20:24,200 --> 02:20:27,830 And I can be really malicious, too, but only on my own machine. 2823 02:20:27,830 --> 02:20:30,800 Notice over here at right, in the developer tools, 2824 02:20:30,800 --> 02:20:33,320 you can see all of the CSS styles that are currently 2825 02:20:33,320 --> 02:20:35,960 being applied to that particular tag. 2826 02:20:35,960 --> 02:20:36,800 And notice this. 2827 02:20:36,800 --> 02:20:39,530 If I change color down here at top-- 2828 02:20:39,530 --> 02:20:43,820 bottom right, let me change it to ff0000 and hit Enter. 2829 02:20:43,820 --> 02:20:44,450 Voila. 2830 02:20:44,450 --> 02:20:48,710 I've changed all of Yale's tags along that row to be red. 2831 02:20:48,710 --> 02:20:51,110 So this isn't, again, about hacking some website, 2832 02:20:51,110 --> 02:20:53,030 because it has no effect on the actual server, 2833 02:20:53,030 --> 02:20:57,950 but it is so much easier and faster to fine-tune your own page's aesthetics 2834 02:20:57,950 --> 02:20:59,990 by just using your browser, tinker with things, 2835 02:20:59,990 --> 02:21:03,170 try new properties, and so forth, and then when you're ready to save it, 2836 02:21:03,170 --> 02:21:06,200 then go into your text editor and type out 2837 02:21:06,200 --> 02:21:09,740 or copy paste those particular attributes. 2838 02:21:09,740 --> 02:21:10,650 What else can we do? 2839 02:21:10,650 --> 02:21:12,858 Well, let me show you a few final examples here, too. 2840 02:21:12,858 --> 02:21:16,640 Let me go ahead and go into size.html. 2841 02:21:16,640 --> 02:21:20,240 Notice here-- here's some sample Latin text in an initial font size, 2842 02:21:20,240 --> 02:21:23,780 but I'm using a little drop-down menu that you see commonly on web forms. 2843 02:21:23,780 --> 02:21:25,610 Let me make the text larger. 2844 02:21:25,610 --> 02:21:27,590 Let me make it extra, extra large. 2845 02:21:27,590 --> 02:21:32,090 This is just using JavaScript, listening for change events to this drop 2846 02:21:32,090 --> 02:21:37,010 down menu, and correspondingly changing the style's size 2847 02:21:37,010 --> 02:21:39,380 of that particular paragraph of text. 2848 02:21:39,380 --> 02:21:40,700 Let me do this other thing. 2849 02:21:40,700 --> 02:21:44,210 Back in my day when I learned HTML, HTML 1.0-- 2850 02:21:44,210 --> 02:21:45,500 we're up to five now-- 2851 02:21:45,500 --> 02:21:49,280 there was literally an HTML tag called blink and that would literally do this. 2852 02:21:49,280 --> 02:21:51,350 My first home page probably greeted visitors 2853 02:21:51,350 --> 02:21:55,100 with, like, "Welcome to my web page" in this hideous, hideous blinking 2854 02:21:55,100 --> 02:21:55,820 aesthetic. 2855 02:21:55,820 --> 02:21:57,920 But with JavaScript, we can do the same thing. 2856 02:21:57,920 --> 02:22:01,940 And let me go open and-- oh, let me go ahead and open Inspect here. 2857 02:22:01,940 --> 02:22:04,310 And let me move this up here and zoom in. 2858 02:22:04,310 --> 02:22:05,690 Notice what's happening. 2859 02:22:05,690 --> 02:22:08,330 I wrote some JavaScript code in this file 2860 02:22:08,330 --> 02:22:12,920 called blink.html that every half a second or second 2861 02:22:12,920 --> 02:22:18,980 is changing the style of my body to be visible or hidden, visible or hidden. 2862 02:22:18,980 --> 02:22:22,640 And if you want a little teaser of that, if I actually look at that HTML 2863 02:22:22,640 --> 02:22:26,270 in blink.html, that's because in JavaScript there's 2864 02:22:26,270 --> 02:22:29,450 this cool function called window.setInterval 2865 02:22:29,450 --> 02:22:32,960 that lets you call a function every number of milliseconds. 2866 02:22:32,960 --> 02:22:35,110 So if I were to change this to be even faster-- 2867 02:22:35,110 --> 02:22:38,650 let's do it every 100 milliseconds and save and reload, 2868 02:22:38,650 --> 02:22:41,270 you'll see now it's flashing even faster. 2869 02:22:41,270 --> 02:22:44,980 So you can do things again and again by registering 2870 02:22:44,980 --> 02:22:47,530 these kinds of intervals in code. 2871 02:22:47,530 --> 02:22:52,260 Even cooler, let me go ahead and grab another URL here. 2872 02:22:52,260 --> 02:22:54,010 And just because of my browser's settings, 2873 02:22:54,010 --> 02:22:58,180 I'm going to go ahead and open this one in Safari instead of Chrome right now. 2874 02:22:58,180 --> 02:23:00,820 This is called geolocation.html. 2875 02:23:00,820 --> 02:23:03,010 In this file, we've written some code in advance 2876 02:23:03,010 --> 02:23:05,560 that's actually going to try to figure out where in the world you are. 2877 02:23:05,560 --> 02:23:07,600 And notice, for privacy's sake, we can't just 2878 02:23:07,600 --> 02:23:09,580 presume to figure out where you all are. 2879 02:23:09,580 --> 02:23:13,098 We're instead going to prompt you, like this-- the browser is 2880 02:23:13,098 --> 02:23:14,140 going to do that for you. 2881 02:23:14,140 --> 02:23:15,970 I'm going to go ahead and allow this query. 2882 02:23:15,970 --> 02:23:21,970 And voila, this file, geolocation.html, just prints out your GPS coordinates. 2883 02:23:21,970 --> 02:23:26,770 Not particularly interesting, but if I go to, like, Google Maps, 2884 02:23:26,770 --> 02:23:29,140 I can literally search for those GPS coordinates. 2885 02:23:29,140 --> 02:23:31,870 And if you're curious as to where I am right now at this moment-- 2886 02:23:31,870 --> 02:23:35,890 that's not me, but if I go into satellite mode and zoom in, 2887 02:23:35,890 --> 02:23:39,910 we are indeed roughly and that part of the American Repertory 2888 02:23:39,910 --> 02:23:43,300 Theater on Brattle Street in Cambridge, Massachusetts, USA. 2889 02:23:43,300 --> 02:23:46,150 So pretty creepy that using JavaScript, you can even 2890 02:23:46,150 --> 02:23:47,590 figure out where your users are. 2891 02:23:47,590 --> 02:23:51,100 Now, creepy at first glance, but if you've used Uber Eats or Grubhub 2892 02:23:51,100 --> 02:23:53,950 or really any website, like, for the weather that 2893 02:23:53,950 --> 02:23:56,690 asks you for your location, how is it doing that? 2894 02:23:56,690 --> 02:23:59,650 Well, the programmer of those websites has written some code, 2895 02:23:59,650 --> 02:24:04,240 as we did in geolocation.html, that has a line of code like this, 2896 02:24:04,240 --> 02:24:07,630 navigator.geolocatio n.getCurrentPosition, 2897 02:24:07,630 --> 02:24:10,450 and then it's a function built into your browser that, 2898 02:24:10,450 --> 02:24:13,840 with the user's permission, will tell you the user's latitude 2899 02:24:13,840 --> 02:24:20,260 and longitude, using, again, just some built-in functionality to the browser. 2900 02:24:20,260 --> 02:24:22,750 And then one final example here in JavaScript. 2901 02:24:22,750 --> 02:24:25,990 It turns out that you can implement autocomplete in an even fancier way. 2902 02:24:25,990 --> 02:24:30,160 In advance of today, we converted problem set 5, spellchecker, 2903 02:24:30,160 --> 02:24:33,400 the 140,000-plus words, the text file called large, 2904 02:24:33,400 --> 02:24:36,820 into a corresponding JavaScript file called large.js, 2905 02:24:36,820 --> 02:24:38,900 and we wrote autocomplete here. 2906 02:24:38,900 --> 02:24:43,270 So let me go ahead and type in A, and I will instantaneously see an unordered 2907 02:24:43,270 --> 02:24:46,720 list of all of the words that start with A. Let me type in A-P, 2908 02:24:46,720 --> 02:24:51,520 Now it's changing to all the words that start with A-P. A-P-P-L-E-- 2909 02:24:51,520 --> 02:24:53,530 this is how autocomplete works. 2910 02:24:53,530 --> 02:24:55,840 Using JavaScript, what am I listening for? 2911 02:24:55,840 --> 02:24:59,320 Well, if I go back to this laundry list of events from a moment ago, 2912 02:24:59,320 --> 02:25:03,250 I bet I'm listening for one of these key presses or key up events, 2913 02:25:03,250 --> 02:25:05,800 so listening for the user hitting their key, 2914 02:25:05,800 --> 02:25:10,085 and as soon as they type their key, I'm using probably that .value syntax 2915 02:25:10,085 --> 02:25:13,210 to get the value of whatever the human typed in, and then I'm displaying it 2916 02:25:13,210 --> 02:25:18,160 in the page, and then dynamically adding or removing li elements from the page 2917 02:25:18,160 --> 02:25:18,790 dynamically. 2918 02:25:18,790 --> 02:25:21,273 So again, we've not seen hands-on how to do this, 2919 02:25:21,273 --> 02:25:22,690 but the building blocks are there. 2920 02:25:22,690 --> 02:25:24,520 You can change the web page's style. 2921 02:25:24,520 --> 02:25:26,320 You can add HTML to the page. 2922 02:25:26,320 --> 02:25:30,080 And you can listen for these kinds of events. 2923 02:25:30,080 --> 02:25:35,320 Now, it turns out that it is not only JavaScript that can make use of URLs 2924 02:25:35,320 --> 02:25:36,040 in this way. 2925 02:25:36,040 --> 02:25:38,320 And we thought we'd do one final demo here, 2926 02:25:38,320 --> 02:25:43,960 this one calling back into play Python, whereby I'm going to do a little 2927 02:25:43,960 --> 02:25:45,730 something with our jack-o'-lantern here. 2928 02:25:45,730 --> 02:25:48,820 Let me bring him over closer to me. 2929 02:25:48,820 --> 02:25:53,290 And you'll see that he's got a light bulb tucked inside of him. 2930 02:25:53,290 --> 02:25:58,180 And let's go ahead and face him forward. 2931 02:25:58,180 --> 02:26:03,430 It turns out that the light bulb inside of this jack-o'-lantern here is 2932 02:26:03,430 --> 02:26:06,860 actually one of these fancier modern LED light bulbs that has an internet 2933 02:26:06,860 --> 02:26:07,360 connection. 2934 02:26:07,360 --> 02:26:09,910 It's an internet of things device, an IoT device. 2935 02:26:09,910 --> 02:26:12,940 And it happens to be talking to this little wireless 2936 02:26:12,940 --> 02:26:16,240 device here that I have on the lectern so that the light bulb is literally 2937 02:26:16,240 --> 02:26:19,480 communicating wirelessly to that device on the lectern. 2938 02:26:19,480 --> 02:26:22,292 And that device, in turn, is plugged into Harvard's network. 2939 02:26:22,292 --> 02:26:25,000 And my laptop, of course, is plugged into Harvard's network, too, 2940 02:26:25,000 --> 02:26:27,520 and so we have the ability now, it would seem, 2941 02:26:27,520 --> 02:26:32,080 to write code on my Mac or your PC that somehow talks to this light bulb 2942 02:26:32,080 --> 02:26:35,810 by using our local internet, our local network, if you will, 2943 02:26:35,810 --> 02:26:37,900 to connect those two devices. 2944 02:26:37,900 --> 02:26:40,810 And it turns out that devices like this very often 2945 02:26:40,810 --> 02:26:44,890 have APIs, Application Programming Interfaces, that for simplicity, are 2946 02:26:44,890 --> 02:26:46,780 actually based on URLs. 2947 02:26:46,780 --> 02:26:50,050 They're simple URLs so that if I send a certain HTTP 2948 02:26:50,050 --> 02:26:54,500 request to this light bulb, it will turn itself off or on or do something else. 2949 02:26:54,500 --> 02:26:57,830 And if I send another request, it will do that thing as well. 2950 02:26:57,830 --> 02:27:00,557 Now, that's not how all APIs work, but indeed, 2951 02:27:00,557 --> 02:27:02,890 just because we're transitioning now to web programming, 2952 02:27:02,890 --> 02:27:04,598 doesn't mean we're leaving Python behind. 2953 02:27:04,598 --> 02:27:07,720 In fact, next week we'll bring Python back all the more, and SQL, 2954 02:27:07,720 --> 02:27:13,090 combine all five of these technologies, HTML, CSS, JavaScript, Python, and SQL, 2955 02:27:13,090 --> 02:27:16,360 and tie them all together into a full-fledged web application. 2956 02:27:16,360 --> 02:27:19,990 But to do this, let me go ahead and create a program here 2957 02:27:19,990 --> 02:27:22,170 called light.py in Python. 2958 02:27:22,170 --> 02:27:24,670 And I'm doing it on my own Mac so that I'm not in the cloud. 2959 02:27:24,670 --> 02:27:26,980 I'm actually on Harvard's local network here. 2960 02:27:26,980 --> 02:27:31,288 Let me import a couple of libraries, import os and import requests. 2961 02:27:31,288 --> 02:27:33,330 We've not seen this before, but there's a library 2962 02:27:33,330 --> 02:27:35,580 that's available with Python called requests, 2963 02:27:35,580 --> 02:27:41,310 which allows you to make, with Python, HTTP requests, just like a browser. 2964 02:27:41,310 --> 02:27:44,497 Let me go ahead and declare a variable called username 2965 02:27:44,497 --> 02:27:47,580 that's going to be the result of just getting what's called an environment 2966 02:27:47,580 --> 02:27:48,810 variable called username. 2967 02:27:48,810 --> 02:27:51,270 So for privacy's sake I didn't want to type my own username 2968 02:27:51,270 --> 02:27:53,850 and password for Harvard's network into this program, 2969 02:27:53,850 --> 02:27:56,340 so there exist what are called environment variables 2970 02:27:56,340 --> 02:28:01,380 on Macs and PCs and Linux computers that you can store values secretly 2971 02:28:01,380 --> 02:28:02,010 elsewhere. 2972 02:28:02,010 --> 02:28:05,550 And using Python's os.genenv function, you 2973 02:28:05,550 --> 02:28:08,760 can load those into the computer's memory somewhat privately. 2974 02:28:08,760 --> 02:28:11,160 Let me go ahead and get the IP address of the light bulb 2975 02:28:11,160 --> 02:28:14,160 by doing os.getenv quote-unquote "IP". 2976 02:28:14,160 --> 02:28:16,950 And then lastly, let me go ahead and construct a URL. 2977 02:28:16,950 --> 02:28:22,200 By having read the documentation, thankfully a colleague constructed URLs 2978 02:28:22,200 --> 02:28:29,175 that looks like this, http://, the IP address of the light bulb, 2979 02:28:29,175 --> 02:28:33,390 slash API slash My username, personally, in case different people want 2980 02:28:33,390 --> 02:28:37,230 to control the light bulb, slash light slash one slash state. 2981 02:28:37,230 --> 02:28:41,640 So this is a weird-looking URL, but it's essentially going to be http:// 2982 02:28:41,640 --> 02:28:45,810 whatever the numeric IP address is of this light bulb slash IP slash 2983 02:28:45,810 --> 02:28:49,140 my username slash light slash one slash state. 2984 02:28:49,140 --> 02:28:52,140 So I could literally copy and paste that into a browser 2985 02:28:52,140 --> 02:28:54,210 if I knew what those values were offhand, 2986 02:28:54,210 --> 02:28:56,580 but I'm going to do this programmatically instead. 2987 02:28:56,580 --> 02:28:59,910 I'm going to go ahead and write requests-- 2988 02:28:59,910 --> 02:29:03,547 and I could say get if I want to send a get request, which is not what I want, 2989 02:29:03,547 --> 02:29:05,880 because I don't want to get the value of the light bulb. 2990 02:29:05,880 --> 02:29:07,922 I don't want to post the value of the light bulb. 2991 02:29:07,922 --> 02:29:10,840 It turns out there's a third HTTP verb that we've not seen before, 2992 02:29:10,840 --> 02:29:13,410 but it's often used for APIs, called put. 2993 02:29:13,410 --> 02:29:18,520 Technically it's all caps, P-U-T, but in code, it's written in lowercase, .put. 2994 02:29:18,520 --> 02:29:19,680 So this is going to send-- 2995 02:29:19,680 --> 02:29:22,950 it's going to send a message from my Mac to this light bulb. 2996 02:29:22,950 --> 02:29:28,720 So let me go ahead and put to this URL the following Python dictionary. 2997 02:29:28,720 --> 02:29:31,050 I'm going to go ahead and put a value of quote-unquote 2998 02:29:31,050 --> 02:29:35,040 "on" to the Python Boolean value of false. 2999 02:29:35,040 --> 02:29:36,370 Now, what is json? 3000 02:29:36,370 --> 02:29:39,540 Json stands for JavaScript Object Notation, 3001 02:29:39,540 --> 02:29:41,520 which is just a conventional way of sending 3002 02:29:41,520 --> 02:29:44,020 textual messages across the internet. 3003 02:29:44,020 --> 02:29:45,270 So we'll see that before long. 3004 02:29:45,270 --> 02:29:48,120 But for now, this is just sending to the light bulb 3005 02:29:48,120 --> 02:29:53,290 a dictionary which has a key of on and a value of false. 3006 02:29:53,290 --> 02:29:57,600 And if I didn't do anything wrong, let me go ahead and close this file, 3007 02:29:57,600 --> 02:30:03,390 run Python of light.py, cross my fingers, as always-- 3008 02:30:03,390 --> 02:30:04,620 voila. 3009 02:30:04,620 --> 02:30:07,020 Now, this light bulb doesn't have to be one foot from me. 3010 02:30:07,020 --> 02:30:08,940 It can be literally elsewhere on the internet 3011 02:30:08,940 --> 02:30:12,905 so long as I have an internet connection and I have access to that IP address 3012 02:30:12,905 --> 02:30:15,030 over the internet, which I didn't want to do today, 3013 02:30:15,030 --> 02:30:18,300 lest we have hundreds of people turning the light bulb on and off for me. 3014 02:30:18,300 --> 02:30:20,910 But let me go ahead and change the code a little bit now. 3015 02:30:20,910 --> 02:30:24,390 Let me go ahead and turn it back on, and change on, of course, 3016 02:30:24,390 --> 02:30:26,250 to true, as you might guess. 3017 02:30:26,250 --> 02:30:27,870 So almost the same code. 3018 02:30:27,870 --> 02:30:32,230 Let me go ahead now and run Python of light.py again. 3019 02:30:32,230 --> 02:30:33,220 On. 3020 02:30:33,220 --> 02:30:34,930 And let's make it a little fancier. 3021 02:30:34,930 --> 02:30:37,840 Let's go ahead and get a little more logical here, 3022 02:30:37,840 --> 02:30:41,780 doing things a little more interestingly than we have thus far. 3023 02:30:41,780 --> 02:30:44,600 And let's see if we can't bring that blink to life as well. 3024 02:30:44,600 --> 02:30:47,860 Let me go down here, and let's do something infinitely this time. 3025 02:30:47,860 --> 02:30:50,120 How about while true-- 3026 02:30:50,120 --> 02:30:52,780 so forever, this demo will go on-- whoops-- 3027 02:30:52,780 --> 02:30:59,410 while true, go ahead and put to that URL not just on and off. 3028 02:30:59,410 --> 02:31:03,810 Let's go ahead and change the brightness to a value of 254, so really bright, 3029 02:31:03,810 --> 02:31:07,830 and let's go ahead and change on to true, as before. 3030 02:31:07,830 --> 02:31:13,120 But then let's go ahead and sleep for a moment, so time.sleep for one second. 3031 02:31:13,120 --> 02:31:15,120 And then let's go ahead and send another request 3032 02:31:15,120 --> 02:31:19,140 after a second to that same URL, sending in a Python dictionary 3033 02:31:19,140 --> 02:31:22,470 where on is now false. 3034 02:31:22,470 --> 02:31:25,473 And then let's go ahead and sleep for one second. 3035 02:31:25,473 --> 02:31:27,390 You might have noticed I need another library. 3036 02:31:27,390 --> 02:31:29,730 I need to import time, which sounds amazing, 3037 02:31:29,730 --> 02:31:31,560 but it's just the library called time. 3038 02:31:31,560 --> 02:31:33,810 I've saved the file, and I'm forever going 3039 02:31:33,810 --> 02:31:38,080 to send one request turning it on, another request sending it off. 3040 02:31:38,080 --> 02:31:41,490 And now, the climactic finish, Python of light.py. 3041 02:31:41,490 --> 02:31:46,930 3042 02:31:46,930 --> 02:31:48,323 All right, woo! 3043 02:31:48,323 --> 02:31:49,430 [CHUCKLES] 3044 02:31:49,430 --> 02:31:50,230 OK. 3045 02:31:50,230 --> 02:31:51,880 That's it for CS50. 3046 02:31:51,880 --> 02:31:53,891 We will see you next time. 3047 02:31:53,891 --> 02:31:57,567 [MUSIC PLAYING] 3048 02:31:57,567 --> 02:31:58,400 Phyllis, number two. 3049 02:31:58,400 --> 02:31:59,483 Number two from your left. 3050 02:31:59,483 --> 02:32:01,722 [LAUGHS] 3051 02:32:01,722 --> 02:32:04,026 [LAUGHTER] 3052 02:32:04,026 --> 02:32:05,090 OK, this one we can fix. 3053 02:32:05,090 --> 02:32:10,000 3054 02:32:10,000 --> 02:32:11,473 That was amazing, Josh. 3055 02:32:11,473 --> 02:32:15,883 3056 02:32:15,883 --> 02:32:16,383 Sophie? 3057 02:32:16,383 --> 02:32:20,311 [LAUGHS] 3058 02:32:20,311 --> 02:32:21,784 SPEAKER: I really tried to hide it. 3059 02:32:21,784 --> 02:32:28,167 3060 02:32:28,167 --> 02:32:29,720 DAVID J. MALAN: [INAUDIBLE]-- 3061 02:32:29,720 --> 02:32:30,320 oh! 3062 02:32:30,320 --> 02:32:32,420 [LAUGHTER] 3063 02:32:32,420 --> 02:32:34,220 3064 02:32:34,220 --> 02:32:35,228 SPEAKER: So close. 3065 02:32:35,228 --> 02:32:36,020 DAVID J. MALAN: OK. 3066 02:32:36,020 --> 02:32:36,687 We'll try again. 3067 02:32:36,687 --> 02:32:38,770 Here we go. 3068 02:32:38,770 --> 02:32:54,000