>> All right, welcome back. This is CS50 and this is the end of week 10, and amazingly we're almost done all right? We have lecture today, we have lecture Monday, we have a little Quiz 1 on Wednesday, one lecture thereafter on Monday the 21st and then Thanksgiving and the end with final projects the only last thing on the horizon there. So do keep this in mind, the details for Quiz 1 are already on the home page CS50.net. There's gonna be a review session as usual this Sunday. The sections on Sunday, Monday, Tuesday will be quiz review and notice on the PDF that's posted on CS50.net the same locations as last time. Know that the quiz is cumulative from week zero on up, can't really forget some of the stuff we learned back then, but realize we will emphasize material since Quiz 0. So a word on P Set 8, so a number of you have been tripping over an unfortunate issue with the Google plug-in which unfortunately has gotten worse over the last several months whereby on Firefox and amazingly Chrome itself, especially on Windows, it doesn't actually work properly unless you per- potentially tweak your settings. So if you're having an issue whereby you're getting some kind of Google Earth plug-in error in the bottom left-hand corner of CS50 Shuttle, go to CS50.net and one of the top announcements today is a link to a post I made last night with some troubleshooting tips. But if those do not help you, whether you're a PC or Mac user, catch me during break today or after or post back to that same thread and we will figure out how to get you up and running. And another troubleshooting tip too is just to diagnose things, quit as many programs as you're running including the appliance just in case it's a RAM issue. The Google Earth plug-in seems to be very memory intensive so that seems to help too. And then just a word on Submit 50. So I kinda screwed up last week and didn't foresee a bug in Submit 50, the result of which were some of the headaches you encountered, so let me just broadly apologize for any technical issues you've encountered during the term. Given the course's size and given our interest in trying to enhance things every year, we try to roll out things like the appliance and submit 50 and other tools to make the course, sort of bigger and better, but inevitably, statistically, we run into every possible technical issue thanks to such a large user base, but any such technical mistakes have been mine, so apologize for any frustration. It used to drive me nuts in college if there were bugs or problems with P Sets so I definitely empathize and sympathize and even grammatical mistakes drive me nuts so, apologies for any lack of perfection. So, speaking of lack of per- perfection too, in the interest of making us better next year, it's almost time to start applying. So if you ha- fancy the idea of TF-ing or CA-ing for CS50, the difference being TF's lead sections and grade and such and work with you on a weekly basis, CA's offer office hours one on one with students in need of P Set help. Know that you can head to that URL over the next couple of months, we'll likely start interviews in January and we try to lock in the team by spring break, so that's the trajectory we're on. Typically we look for in CF's folks who have taken at least two classes, so something this fall and some CS class in the spring. CA's are almost always alumni who have taken CS50 and maybe one or more other classes. So we would love to grow the teams ranks next year. So this was fun, this past Monday Mark and company were in fact on campus. This is a screen shot of Facebook when I was your age, or a little older when it came out when I was in grad school, and it's evolved certainly over time. But it was actually quite fun prepping for this talk that Mark and Mike and Jocelyn gave on Monday and asking them questions 'cause it's really remarkable how quickly this thing caught on, right? It's sort of become part of our lexicon, and certainly part of Harvard's history but Mark released Facebook, version 1.0 which didn't even have this list of schools, in February of 2004, and at the end of 2004, he had 1 million users using the site. By the end of 2005, he had 5.5 million users. And certainly this is not the typical case for projects that you pore a week of effort into initially, and thus was born Facebook after just a week or mores initial effort, he's certainly poring more time into it thereafter, but it really is quite remarkable what he achieved. He then, this is a Crimson shot from years ago of Mark looking quite young, working in Kirkland House I believe at his computer. So this is apparently how Facebook was made, and then a shot, if you're unfamiliar with these guys, of Dustin Moskovitz and Chris Hughes, two of his roommates who worked with him early on on this site. But Mark also returned to CS50 in 2005, he never actually took the course, he jumped right into CS51 and 121 and other courses, but he gave a guest lecture in CS50 on December 7th, 2005, so just over a year and a half or so after having launched this initiative. And this was actually not even a lecture, this was a topic session to which students could optionally attend, much like a seminar. And at the time certainly, Facebook was catching on but it definitely didn't have the draw of some 250 person classroom that we had this past Monday, and I thought I would give you the screen shot here of Mark guest lecturing in Science Center C I think it was way back then, and we, we pulled the clip of course. So this is a clip of Mark talking to CS50 back in the day and it really does testify to just how much you can accomplish either one, with the sort of skills he came into Harvard with, but testament to his roommates savvy and the speed with which Dustin and these other guys caught on to new technologies after having just, as in Dustin's case, taken CS50 is really quite striking, and hopefully perhaps, empowering here. So I give you 2005. If we could dim the lights for just a moment Perry. [ Pause ] >> When I was here I started off taking 121, I never actually took 50 so I'm probably, you know you should've gotten the other guy who was doing Facebook, Dustin Moskovitz who is my roommate. When we got started, the site was written in PHP which isn't something that you learn in one of these classes, but fortunately if you have a good background in C, the syntax is very similar and you can pick it up in like, you know like a day or two. [laughter] And I was taking 161 at the time so I don't know if you guys know like the reputation of that course but I mean it was kinda heavy. It was a really fun course but it didn't leave me with much time to do anything else with Facebook so my roommate Dustin who I guess had just finished CS50 was like hey I I wanna help out, I wanna do the expansion and like, and help you figure out how to do this stuff. So I was like, you know that's pretty cool dude but you don't really know any PHP or anything like that, so that weekend he went home, bought the book Perl for Dummies, came back and was like, all right I'm ready to go. I was like dude, the site's written in PHP, not Perl. [laughter] >> But Dustin's doing quite well now, as is Facebook so realize therein lies the origins at Harvard of a little site called Facebook. So today we continue and really finish our conversation about JavaScript and some of the cool things that you can do. Recall that JavaScript, unlike PHP is client side and it really is JavaScript that's been driving a lot of the innovations in user interface over the past few years. The earliest version of Facebook very much was this sort of 1990's style website where you click on a link, it takes you to a new page and then the http connection completes. But now you have chat built in, you have status updates that get pushed to the browser, all thanks to this technology called AJAX, Asynchronous JavaScript in XML which is really just a fancy way of saying you've got some code running in the browser that was downloaded from the web server that is constantly asking the server for more information, more chat messages, more status updates, more photos and the like. And so you have much more seamless user interfaces on Google Maps, on Gmail and all of these very popular websites these days. Back in the day when I learned HTML, there was a wonderful tag called the blink tag. The world sort of collectively put an end to this tag years ago but thanks to JavaScript, you can actually resurrect an annoying little feature of the web like this. And just to kind of tie together some of the syntax we looked at on Monday and prior, I thought we would resurrect briefly, this blink tag, see how we can do that, but really by extension how we can control the aesthetics of a page by way of CSS and JavaScript working together and then we'll dive into this technology itself called AJAX. So this web page, if I pull up its source here and scroll down to the very bottom, you'll see that I've indeed used the blink tag, but 99% of browsers today-- it's a made-up statistic-- do not support the blink tag anymore. It's one of the few instances where the world has collectively decided to kill support for a tag 'cause it was simply annoying. So here we have a blink tag inside of which is an H1 tag. That just typically makes text big and bold. So it turns out that it's because of JavaScript that this code is actually, that this tag is actually now blinking. Let me go into my appliance here and actually I'm gonna use my terminal window. So let me remind you of one feature of using Mac OS or Windows or really any operating system with the appliance, and we'll continue this conversation at the very last lecture. When you exit this course, you're not gonna need necessarily or even want to use the CS50 appliance to do programming and you don't need to. It's really been a sand box that's been pre-configured for all of us to have the same uniform environment but it's representative of a typical web server, it's representative of a typical Linux and indeed even I and the TF's and CA's, very often when we're writing out own programming projects, we actually do use virtual machines. We might not use the CS50 appliance, but we install Windows in a virtual machines, we might install Linux in a virtual machine. Now with Mac OS Lion we might install Mac OS in a virtual machine, because in terms of designing software and testing software, it's wonderfully useful if I can sit at home with my big like LCD monitor on my desktop but have Windows here and another version of Mac OS here and Linux here and some other flavor of Linux w- all with different browsers, i.e. Chrome, Firefox each in their own little environments. So realize the appliance is meant to be representative of this opportunity to design websites and other projects in nicely controlled testing environments. So we will discuss in a couple of weeks how you can transition off this environment altogether. But for now what I'm going to do is use my own Mac's terminal program, so this is under your applications folder in utilities on Mac OS. In Windows the comparable program is called PuTTY, P-U-T-T-Y, and on manual.cs50.net we have a nice screen shot based tutorial on how to do the same thing but on Windows. But for now I'm gonna do SSHJHarvard@192.168.50 and that's my appliance's IP Address. When I hit enter, I'm prompted to log in, so I'm gonna go ahead and type crimson and then I have my prompt. So this is giving me a terminal window on the appliance but outside of the appliance. And this, by extension, is representative of how you can start after CS50, or even for your final projects, paying some random third party company to give you an account on some remote server that has web s- web server, it has a my SQL server, has an email server and the like and you, sitting in your own dorm room or Starbucks, can connect via this tool called SSH to that remote server and get this familiar terminal window. So that's all I've done here. I just simply have a terminal window i- on the appliance but running on my own Mac, and the nice thing about this it's just a little more zippy, it's a little more responsive and it's in my own comfortable operating system. So I'm gonna go into public HTML and I'm gonna go ahead and open with another program that we've not really used or preached this term called nano. So it turns out when you use SSH, you can't necessarily run something like gedit because when you're using SSH in a terminal window, all you have is this command line environment. So if I ran gedit and then the name of a file, I'd likely get some kind of error because when you're using a program like this it can't just send the colorful, graphical user interface over the internet to your screen without special software. So we need a simpler text editor if I want to look at this file blink.HTML and a very popular and very simple text editor is called nano. And if you ever read through 2010's CS50 P Sets, this is what your predecessors used for quite some time, gedit was a new thing this year. And you'll see just kind of a Linux version of what we'd call like notepad on a PC or text edit on a Mac. And for now, this color scheme is awful so I'm going to cheat and use another program called Vim which is we have seminar on online, but here we have it. This is all text-based, right, I can't actually click or copy and paste in the same way so there's some limitations. But for now, all I want to do is look at this code. So there's my same blink tag. There is some CSS which is putting a margin of white space around it 'cause I wanted it roughly centered in the screen. So let's actually look at the script tag up top. I appear to have written inside of a script tag, a function called blinker, just an arbitrary name here. Takes no argument, and it does the following. It's using a few features of JavaScript we haven't seen yet but they're relatively straightforward. So document recalls this special global variable, this document object that represents the DOM, document object model. What is that? Just the tree that represents your HTML. So inside of this document object, there's apparently a function, more properly called a method, called get element by tag name, and this really does what it says. When you call this function, it is going to get all of the elements, all of the tags on the page whose name is blank. So in this case there's only one such tag, but the implication here is that this function is generalized so I could actually enable multiple blink tags all over my website. So what is this return? It's going to return an array, by definition. Get elements by tag name, returns an array of all of those blank elements, the rectangles from last Monday's picture. So this is just a four loop, it's gonna iterate from 0 on up to the length of that array. In this case the length is gonna be one so this loop's only gonna execute once, and then we have this branch. So if blink's bracket I, so if the [inaudible] blink tag has a CSS style of visibility equal to quote unquote hidden, I wanna go ahead and change that style to visible. So just to back up a bit, there are CSS properties involving invisibility and display of information so you can turn things on or off, you can show or hide them. And in general, the code for that would be something like this, an element's name like ad- you might have a div- with an ID of fu and if you want to hide it on the web page even though it's still actually there on the source code, you could say visibility hidden, semicolon. So you would put that in the appropriate place on your web page for CSS. What this is doing here in JavaScript is exactly that. So one of the additional features we get from JavaScript is the ability programmatically to change the CSS in our page- to add classes, remove classes, to add styles, remove styles. So all this branch is doing is it's saying if the blink element is visible, rather is hidden, make it visible, otherwise make it hidden. And because we've never even talked about visibility, all elements by default are visible. They are not hidden. So by default, this tag is gonna display. So the first line of code that's gonna execute is gonna be this one because if it's not hidden, which it's not in our HTML, this is going to make it hidden. And that's it. So this function on its own seems to just make something that's sh- that's visible hidden, or vice versa. But now there's this one other line of code and this is another special JavaScript object that has a lot of functionality packed into it. Window is another global object that really represents what it sounds like, the browser window itself. And there's some special functionality associated with your window among which is timers, the ability to set timers that go off every some number of milliseconds. So window.setinterval does exactly that. This says set timer whereby the blinker function will get called every 500 milliseconds. So the implication of that is that here's the function blinker, here's its name repeated down here. Notice-- this is important-- that this is not a function call 'cause that would mean call it here. Instead we want to pass the name of the function into set interval. So it turns out you can do this in C. We never once did this, but just as in C, there are pointers to variables, pointers to memory and such. You can also treat function names as pointers and pass them around. But we typically, well we haven't done that in any examples thus far, but JavaScript allows this too. So I can pass a function by its name, conceptually by pointer, to this other function so that sent interval now has the ability to go there, via that pointer, and call that function every half a second, every 500 milliseconds. So the end result is the following: if I go back to my browser and watch this load, that is indeed blinking every half second because every half second that timer's going off, blinker's getting called, it's very rapidly getting all the blink elements on the page. If they're visible it makes them hidden. If they're hidden, it makes them visible, and then repeats. And so now we have the ability to control the CSS of the page and that's all it's doing is its changing the CSS on and off. Any questions about this trick? Yeah. >> [ Inaudible audience question ] >> Um hum. >> [Inaudible] >> Good question. If you had an actual CSS file, like styles.css inside of which was an explicit declaration that this tag be hidden or visible, which would have priority? The JavaScript code would override that. So the static file that you downloaded is the default, but with JavaScript code, you can change thing entirely. And so the connection here to something like Facebook and the chat window or the status updates that are automatically pushed is akin to this feature where there's some line of code that Facebook has written that is effectively equivalent to calling an interval-- calling some function every few seconds or every minute checking for more data. But in reality there's even more fancy things going on with these huge websites. It would actually hammer the heck out of Facebook's server if every half second every one of its 800 million users were hitting their servers like this. And so better typically is for a browser to maintain a longer connection and listen to, talk to the web server for say 30 seconds at a time-- this is a technology known as long pulling, whereby you don't keep making these http requests, you make them every 30 seconds and the server pushes information to you within that window of 30 seconds when it has more information. But we would have to really look underneath the hood to figure out exactly how Facebook implements this particular feature now. But Gmail too, how does your inbox automatically get new mail? It's because the JavaScript code Google has written is pulling their server, some number of seconds and checking if you have new mail and updating the HTML accordingly. So that's blinker, but we can only do so much if we're just doing things with aesthetics. So here's a complex looking picture that really just describes what you can really do now with JavaScript. So over here on the left we have a rectangle representing a browser and on the right we have another rectangle representing a server. But AJAX essentially does the following: if you have down- if you visited something like Gmail.com and you've gotten your default inbox and your labels and all of that and you've got your email at that moment in time, what happens thereafter? Well, the user interface of Gmail, or Facebook, or any of these big websites these days can in step one, make a JavaScript call just like the blinker function and it can use a special object that we've not talked about yet called XML http request. So just as document is an object, just as window is an object, this is just another type of object in JavaScript, and what this feature can do-- and it was only introduced several years ago-- it has the ability to make additional http requests from browser to server in order to request more data. So Google Maps, when you click and drag on the map and all of the sudden you get more tiles, more squares of the map, that's thanks to this XML http request object making, in step three, another request and getting back more data. Now this picture's actually a bit data- dated. It says XML data because indeed, AJAX, Asynchronous JavaScript and XML i- was, XML was typically the transport mechanism used to get more data from servers to browsers. What is XML? It's super simple. XML is sort of like make your own HTML. Whereas in HTML you have a fixed number of elements, you have the HTML element, you have the head element, you have H1 and so forth, all of those were decided upon by a group of people in a room saying this is what makes up HTML 5. But with XML, you can have anything. You can have for instance element called Class and then closed class. You might have an element called students, and then closed students. And then you might have in here an XML element called students and maybe this student has an ID of 123, and then closed students. And then in here we might have an element like name, so open bracket name David, closed bracket name, and so forth. In other words, XML is like make your own HTML. And the motivation for this is because you have the ability now to create this very simple text format structured however you want, but you can include both data, and let's call it metadata, the data here is david and one two three, like those are arguably the most interesting and information bearing pieces of content in this file. The other stuff like class, students, student, name, this is metadata. It's useful because it's like the names of the keys, but generally we care about the value. So XML allows you to kind of wrap up some data, key value pairs if you will, and send them from server to browser. But frankly this is verbose right? This is very, this is a lot of code, a lot of, a lot of syntax just to send the word david and the number one two three. So there's another format all together that we'll see in much more detail today and this is something called JSON and we talked about this briefly the other day and saw little snippets of it, J-S-O-N, JavaScript Object Notation. If I instead wanted to send a whole bunch of students, I don't want to have to necessarily send all of these bytes across the internet 'cause in a big file this is just gonna waste time, it's gonna waste bits. So I might instead use my JavaScript syntax for an array and then in there I might say okay, here comes a student object, and I'm not gonna give it a name this time. There's no mention of student, but that's okay because inside of this object I can then say something like name is David and comma and then ID is, actually this can be a number it doesn't have to be quoted, one two three, and that's it. And now if I want another such object, I can repeat the process for Monday. Name equals Matt and then let's say ID equals four five six and so forth. Now this is a little harder to read in that you have to kind of know what to expect but it turns out this is what's increasingly popular and common because it's much succinct and there exist functions in PHP that can take a PHP array, like an associative array, even something as big as our dictionary from the PHP implementation of speller and you can call a special function in PHP's case called JSON encode and this takes some argument, and whatever that argument is, it'll convert it to a JSON object. And so this is wonderfully useful 'cause now you can write server side code, you can structure it in your nice, familiar Java- PHP associative arrays and the like, and then you can just say turn this into JSON. And then you can return the result of that function which is gonna look like stuff like this, to the browser. And so we'll see today too that CS50's own API's uses this format because it's so much easier to parse as we'll see, to analyze, and also to generate. So now when people talk about AJAX, they don't really talk about the X anymore as being XML, they now just say AJAX and it refers to this just a capability of grabbing more data from server to clients. And again that's what drives Gmail and Facebook and all of these guys these days. So let's actually do something with this. Let me go into our directory from this week called AJAX and we have a few examples here that actually steals some ideas from Yahoo Finance and P Set 7. So I'm gonna go up to AJAX1.html here and let me go ahead and open up my appliance, and I'm gonna go ahead and open up one of these files in gedit just so we can see it in a familiar context. But I could use, keep using SSH for this. So I'm gonna go into AJAX1.html and let's see what's in here. So this thing is gonna get a stock quote from a file called quote1.php but via AJAX and then it's gonna display the result in the page. So first let's scroll down to the HTML just to get a sense of what this looks like, and the HTML is very, very simple. Apparently I've got a form who upon submission is gonna execute some JavaScript code, a function called quote apparently. That's not built into JavaScript, it's something I wrote. And then it's gonna always return false upon submission. And why? What is that gonna do for me when a form returns false? What is that impede? >> [Inaudible] >> It won't actually send it to the server. So here's sort of an interesting paradox, like we want the forms data, what the user types in to get submitted, but we want to do it now via JavaScript code, we don't want to rely on the browser sending it in http fashion to the server, we'll do it ourselves. So I've simply hard coded return false so that clicking the submit button does trigger my quote function to get called, but nothing else. I'm in control thereafter. So what is this form gonna look like? It's apparently got one input, a field whose ID is symbol, whose type is text, and then it's got a button whose value is get quote. Indeed if we go back to my browser, this is exactly what it looks like and I can type into this form something like G-O-O-G for Google stock ticker symbol and I claim in a moment when I click get quote, I'm going to get Google's pr- stock quote. So let's try this, get quote. All right, so as of this moment in time, or roughly 10 minutes ago, Google stock is valued at $605.93. Now this is kind of an annoying way of displaying it, this is not a very user friendly website, but notice what did not change. My URL did not change and yet I did get data from the server I promise. I didn't hard code 605 into my source code as we'll see, and so somehow I've triggered an http request behind the scenes, gotten this data, and it's then being displayed in the browser. And let me go ahead and-- whoops that's a bug. Let's go, let me open up Firefox so we can actually see this. So I'm opening up Firefox, I'm gonna open the same URL. I'm gonna open up Firebug, this little debugging tool at the bottom, and notice that I'm on the net tab. This is gonna show me all of the network traffic that this page sends. So I'm gonna go ahead and type in Goog again, get quote, and sure enough here's a little pop-up, it looks different in Firefox, that's just 'cause Mozilla made it that way, but if I scroll down over here, I'll see that an http get request was actually sent to the server. So what was actually sent? Well it looks like I sent --let me click params -- you can actually see thanks to Firebug exactly what you sent. So I apparently sent a parameter called symbol with the value of Goog which is what the user typed in, and where did I send that to? This URL, quote1.php. But notice again, the URL in the page did not change. And therein lies the asynchronicity of this. That request got forked off so to speak in the background, it did its thing, it only took a split second to talk to the server, then it came back with 605 and my JavaScript code displayed it. So let's see how we can piece this together. So here we go. This is my HTML at the bottom. Notice at the top now is the rest of my head element and what's inside there? It's gonna look a little complex at first but we'll simplify before long. So here is my head element, here is my script element and here's what I'll call a global variable. So variable XHR just for XML http request. I'm gonna initialize it to null just so know what it is and it doesn't have some random value. Now I'm gonna go, and that's not strictly true in JavaScript, it would actually be undefined in this case but I'll just do it to null to be, for good measure. So here's my quote function. So unfortunately, with XML http request, not all the browser manufacturers agreed back in the day on how to implement this thing, and you can perhaps infer who didn't cooperate here, and so we have to write a bunch of lines of code just to create one of these XML http request objects. So my goal quite simply is, I don't really understand this thing yet, but I want this object called XML http request 'cause I know it has this power to make more http requests to the server to get more data, and the data I care about now is just the stock price. Google Maps cares about more tiles. Facebook cares about more status updates, I just care about stock prices right now. So we won't go into great detail as to the syntax here, but JavaScript is again this object oriented programming language. For more on this take CS51, 164, 161 or other lang- other courses. But for now, know that in a lot of these object oriented languages, there's the notion of exception handling. This is a technique whereby you can return error messages and error codes without actually using the key word return. You instead use a special key word called throw, and so we are not throwing errors here, we want to try to catch errors because I'm using code that was supported by the browser, either this line of code or this line of code. And long story short what this try catch block means is try to execute this line of code, if it doesn't work, prepare to catch an error, call it E or really an exception, call it E, and then try this line of code. So what does this really mean? This is kind of a hack and thankfully libraries hide these details soon as we soon will, but this mean if you're using any browser other than Microsoft's browser, go ahead and run this first line of code, but otherwise if that fails because you're on IE version 6 typically, go ahead and execute this line of code. And now if you're using like mozil- if you're using like Mozilla 1.0, if you're using a really old browser and none of this even worked, then I'm falling back on my default value. If this thing still equals null, something's really wrong here, I'm just gonna yell at the user that their browser's not supported, it's just too old for some reason. Or maybe it's like a mobile browser that just doesn't support this yet. Otherwise I'm gonna do this, I'm gonna construct a URL with a, a JavaScript variable, so var URl just gives me a variable called URL and I'm gonna set that equal to quote1.php but recall from two weeks ago we talked about how get requests are made. So I can just hard code a question mark, symbol equals, and then the plus operator here, you might be able to guess what it is. PHP uses a dot to concatenate two strings together, to append one to the other. JavaScript uses a plus. The language Java also uses a plus for those familiar. So this just means append whatever this value is onto the end of that partial URL. So what am I appending? Well note, remember this function from Monday, get element by ID. I want to get the element whose ID is symbol and I want to get its value. And if I scroll down to html, recall what that looked like. Down here is this input element whose ID equals quote unquote symbol. So this is just my way of getting whatever the user typed in and appending it to a string that I pre-created. So the last three lines of code are kind of copy paste. I first have to execute this line of code, XHR.onreadystatechange, another one of these poorly named variables but it's kind of the standard. And what this means is this is a special property, it's like, think of XHR again like a struct in C, and we had student structs that had names and ID's and so forth, so onreadystatechange is just a field inside of this structure called XHR and I'm setting it equal to the word handler. Well a handler is just a function that handles something and indeed if I scroll down a little bit, we're gonna see in just a moment, another function called handler. So effectively what I'm doing is I'm telling this special, magical object XHR, to go ahead and call this function any time his state changes. And what does state mean here? There's a bunch of things that happen behind the scenes. When you actually tell this magical object go get me more data, it's going to start doing it. It's going to g- make a request to the server. It's gonna wait for that request. It's gonna get it back. It's gonna analyze the request. So in short there's multiple steps that happen just like the slide suggested. Step one and two and three and four. So this just means call this function any time something interesting happens so I can check in on things. This next line opens a network connection to this URL using a method of get, and this true argument just means make this asynchronous, give us the A in AJAX for reasons I'll wave my hands at here. And then this last line just means send the request, you've connected to the server, send my request to it. So what happens every ti- when the server responds or anytime something interesting happens? This function is actually pretty simple. First it checks every tine it's called, are you in state four? Now this is just something I've hard coded. Four means done. Four means you got a response from the server, the server did not give you a 404 or a 500 or a [inaudible] any of those crazy error messages, nothing bad happened, and so indeed, I double checked, make sure it equals 200-- the response-- 200 means good. And then all I do is this, I call alert passing in this object XHR, and dot response text. So again just like in a C struct, there's multiple fields, response text-- and you have to capitalize it like that-- is another field inside of this object that once the server has responded, it contains whatever the server spit out. So let's see what he server spit out. Let me just go to my browser and let me manually change the URL to pretend to be this program. I'm gonna go to quote1.php question mark symbol equals msft, this time for Microsoft, just to prove that this, nothing's hard coded here, and hit enter and let's see what the server actually returns. Hopef- there it is. So right now Microsoft stock is at $26.51 and look, if I [inaudible] the source code, this isn't even a web page. This is literally just a number. So apparently, all quote1.php is doing is returning this line of text. So let's go ahead and look. This is quote1.php. Let me scroll up. And even though we we won't spend much time on this code, I pretty much stole this from P Set 7's common.php file, or rather helpers.php file where we had the quote function, recall that you were using in P Set 7 to get stock quotes? I pretty much copied and pasted some of those lines of code using Yahoo Finance's URL appending to it the value of symbol parameter, and then I'm just doing some lines of code that again were stolen from the P Set and printing out the answer, and that's why I'm not getting back html 'cause all I'm printing out is one of the fields from the CSV file that we just downloaded. All right, so taking this all together and sexing it up, let's see where we can go with this. Let's go to quote AJAX2.html. And now notice, this is still not all that impressive, but notice that we don't just have to plug in our value to some arbitrary place on the page with an alert popping up and distracting the user, we can actually imbed the response in the page. So now this time let's go ahead and do msft, let's click get quote and hit enter. And now I've mutated the actual web page. So even though if I view the p- source of this page, notice that what I got back from the server originally is literally this, price to be determined. So my html originally looks like this, but notice, let me reload now, let me open up Firebug, let's use our html tab 'cause Firebug does not show you necessarily what was downloaded, it instead shows you the current state of your world. So if I go into this span element --a span is like a div but it doesn't move the cursor to the next line-- this span has an ID of price and there is that default text. So it's gonna be a little small when I zoom out but let's go ahead and click get quote again and keep your eye sort of at the bottom and even though it's tiny, you should see that something changes on the page. Here we go, get quote. Get quote. Okay there we go. And nicely enough, Firebug briefly highlighted what just changed in yellow, and if I scroll down, now notice the Dom has been mutated. So this begs the question, how do you mu- how do you change what the actual structure of the page is? In alert it's pretty simple, but this is kind of fancy. I mean this is indeed what Gmail does, the fact that you get another row representing a new email is because another element has been inserted to the page. The fact that you get a little chat box that pops up is because more html has been injected into the Facebook page. So here, all of this is the same. The quote function is uninteresting and unchanged right now, but if I scroll down to my handler function, notice that rather than call alert this time, I'm instead calling document.getelementbyid.price-- that's the span tag that we looked at a moment ago-- and then it turns out that these elements have another property inside of them called inner html capitalized exactly as follows, and what I can do this time is rather than pass the servers response to alert, I can instead just plug it into this property and you can infer now from affect what it does, it changes the html in the web page and therefore changes the Dom for you. And again, the original page just said to be determined, in bold no less, and we even lost that boldfacing because what we changed is the contents of this span tag. So we can do a little more than this. Let me go into version 3 of this, AJAX3.html. Let me zoom in here, and notice the following behavior. This is AJAX 3 and I wanted to get a little fancier now. I've made a little more space at the top of the page, and now notice if I do the source down here with Firebug, notice that I have a few things waiting. I have, well rather, this time I have a quote, but notice what I've kind of secretly hid in there. What's this new div? Well just above quote is apparently a div whose ID is progress but notice what I did here. Just as there's a visibility element, rather CSS property, there's another related one called display. And so if I say display none, what do you see? Well you see nothing. You just see this big, blank space here. But this allows for something kind of neat. Let me now type in msft and click get quote. Ooh, fancy. [laughter] And now a few things have happened. So one, I got back more data. So now things are getting more interesting. Now I just got three new mails or three new friend status updates, not just one single number. And also it looks like hmm, this div is back to being invisible. So a couple of things just happened. Let's actually see what's inside this div. Turns out I'm kind of cheating but I'm doing exactly what most every website does to simulate progress. That was not some fancy animation I just made for you. Rather, that was some Gif graphic that I downloaded off the internet that looks a little something like please wait.Gif. It does this all day long. All it does is that, [laughter] right? But by revealing it to you when I wanted to create the illusion of progress, it displays. And then when I'm done loading the data, I just turn it off. And that's what a lot of these websites are doing, right again with [inaudible] status updates, Gmail, any of these websites that show some kind of progress bar almost always, that's just an animated Gif that is spinning all day long but they're only showing it to you once in a while. So let's see how we can do that, and we can actually steal some ideas from our blink example. So in this case here, this is AJAX 3, notice just a couple differences. One, this time I'm calling quote2.php and we'll see why in just a moment. And then notice here this one other line of code, show progress. So I can steal the inspiration from the blink example and I can get the element whose idea's progress, that was the hidden div. I can change its CSS style, property called display, to not be none, but instead to be block. So the CSS people weren't really good at coming up with opposite words so there's none and there's block, there's visible and there's hidden. You, so they're not opposites but they function oppositely and so block means m- make it not none anymore, show this actual div. So this is what's turning on the progress bar so to speak, and then if I go to my handler function, I just have to do slightly more work. As soon as I get a response from the server, I'm going to first change the progress divs style to display equals none again. So that's just the opposite so to speak of what I just did, and then the rest is the same. Document [inaudible] of quotes inner html gets the servers response. But the server absolutely did something differently this time right, 'cause I got back more data. So if I do t his, let me go to quote2.php question mark symbol equals msft. I'll zoom in and hit enter. It's spinning, so apparently quote 2 is a little slower which is good 'cause now we have a progress bar to handle that. And that progress bar is on the side. That's Firefox, that is not my own code. And wallah, now it's embedded in the page. What did I get back? Well it looks like what I got back kind of hackish, I just got back [inaudible] a snippet of html. I got price colon number BR, high colon number BR and so forth. So let's just look underneath the hood here as to how we did this. Well one, I was kind of cheating you. In quote2.php I used a fancy new function called sleep to pretend that the server is slow and that's what allowed us to actually see the progress bar. Otherwise it would've been so fast it wouldn't have been as much fun. But the rest of this is almost the same, except notice what I'm doing. Recall that Yahoo Finance per P Set 7 returns a whole CSV like in Excel spreadsheet and in Excel spreadsheet you have multiple columns or cells, and just as in P Set 7, we extracted for you the name of the stock and the price of the stock and we even gave you the high and low even though you didn't necessarily need it. What I'm simply doing is getting that same data. So I'm literally printing in quote2.php price colon and then data, the curly braces, recall, any time you try to cr- put a variable inside of a php string and it's syntactically a little ugly, a little dangerous, well the curly braces don't get displayed literally, they just mean here is a variable that might otherwise confuse the php program, and then I do the same for high and for low. And why? Well this is in column one, this is in column two, this is in column three. Why? How do I know that? I looked at the CSV file in advance and they're always gonna be in the same spot. So that's version 3, we can do something even better until we have something really fancy. Notice now that in my handler function here it's kind of silly that I've been defining this handler function all this time if as of Monday I have the ability actually to create anonymous functions, otherwise known as lambda functions, and this is a little more sophisticated. Syntactically it's a little slicker, if you will, but it's a very, very, very common paradigm in the JavaScript world. And undoubtedly, if you're Googling around especially for final projects, reading JavaScript code, you're gonna see this paradigm a lot. So if on ready state change, that property inside of the XHR struct, and again this, its purpose in life is to get called any time something interesting happens with the network. Well, I recall that I can call function, and function without a name after it just means give me an anonymous function. Curly brace means here comes the code that composes that function, and now it's the exact same thing. If the read state is four and I just hard coded that after reading the documentation and the status is 200 which means all is well, go ahead and call alert. So I've kind of regressed back to version 1 here, but notice I've not defined a function called handler. In fact if I scroll down, that's it, I have no more JavaScript code. So why is this better? You know it's just, partly it's a matter of style, partly it's a matter of design. Right, I don't need to bother creating a var- a function called handler if it's only gonna be called in one particular place, and on ready state change is the only guy who needs to know about it, so I can do simply this in line. But notice the syntax, function with no name, open paren closed paren, curly brace, and then at the very bottom follow the white space, I put the closed curly brace there and the semicolon so that's all sort of one huge line of code. But inside of that one huge line of code is multiple lines of actual code that constitute that function. All right so that is gonna behave the same as before so let's just make this slightly fancier. So now we're actually doing it the right way, right? Just printing out a price with a colon and then saying hi and low and price is not all that compelling and it results in a fairly ugly web page. So let's try to wrap up together the response from the server. So let me go ahead and look in quote3.php and I'm gonna do this this time. So notice this is some PHP code and it's a l- this stuff is stolen again from P Set 7, P Set 7, P Set 7, P Set 7, three lines of code are new. So notice what I'm doing this time. At the very four lines-- notice what I'm doing-- at the very top I'm declaring an array called dollar sign quote and it's initially empty. So that's an empty array. Then in these three lines of code, I'm inserting three keys. So array, this is actually an associate of array 'cause I'm actually using keys and I'm saying dollar sign quote, do- dollar sign quote in square brackets quote unquote price and quote unquote high and quote unquote low, those are my three keys, put these values. So this is giving me an associative array, a hash table if you will with three keys, price high and low, each of which has a numeric value. And that's all I'm doing in this code here, and in this F close and F open, this just relates to the network connection so that I'm actually talking to Yahoo Finance. But here's the promised feature. So notice this last line of code, I'm not printing out literally price or high or low, I'm printing out my quote array but I'm first passing it to this other function called JSON encode. So JavaScript, PHP, not the same thing. In fact they have different syntax even for things like variables. Ja- PHP has dollar signs, JavaScript does not. But PHP can create out of its own objects, the right syntax, square brackets, curly braces, quotes, colons, and all of that messiness, it can do all of that automatically for you so that what ultimately gets printed out is a JSON version of this associative array. So let me actually do this, let me go to a browser again. Let me go to quote3.php, and whereas last time I just spit out some partial html, this time it's gonna spit out this. So open curly brace, quote unquote price colon, 2650, comma, high and then low, same exact structure. So this is some JSON data. If I actually look at this in my source code, it looks exactly like that. Now this might look a little cryptic. If I clean it up a bit, you can read it a bit better perhaps, let me zoom out, go to my text editor. So before I said this is JSON code, now I can also just paste in this thing. So let me create a new document, paste this in. And again this is only gonna benefit us humans for readability but this is the exact same structure, and it turns out JSON encode is just being a little anal. These quotes are not necessarily required, in fact especially around the numbers they're not. So we could actually get rid of these quotes. We could get rid of these quotes. We could get rid of the other quotes, but that's fine, because all the server's going to be doing is sending these three keys and values. So if this is what the server's sending back and this is what it looks like in a browser, I somehow have to parse this JSON in my JavaScript code. I don't want to see the quote marks, I don't want to see the curly braces when I display this data to the user. I want to actually get at the price and the high and the low individually so that the end result actually looks like this. So this is AJAX5.html. Let me go ahead and click msft and now notice I have a few placeholders, price high and low-- let me look at this-- view page source. Look at my html, so now I have preemptively put three placeholders, price colon and then a span with a unique ID, but no content. There's nothing in between the start and end tag. Same thing for high, same thing for low. So my goal programmatically is gonna get that JSON object, grab the three fields I care about and only insert the numbers where I want them. So here we go, this is AJAX5.html. It's probably gonna be my handler function that changes, and sure enough, here we go. I didn't bother giving it a name handler. I'm instead using this anonymous trick but this is just a matter of design or style, it's not really functionally different from before. I got this copied and pasted from before. This is copy pasted from before so ready state and status are good. So here we go. So this is the one stupid aspect of JSON, at least when you're not using a library like JQuery. When you get back XHR response text, and you know it is JSON data, you have to unfortunately concatenate to the left of it a parenthesis, concatenate to the right of it another parenthesis, and then pass it to a special function called eval. The eval function will take what is literally a string that looks again like this and it will convert it to a data structure in RAM that represents this hash table just like P Set 6. So a long story short, this cryptic line of code simply takes what is literally a string and loads it into memory just like you did with the dictionary in P Set 6. And after that it's easy. I can then update the inner html of my price span to be quote, which is an object, dot price. So here's one difference too with PHP, whereas in PHP we dollar sign quote, and then literally price, that's in PHP. In JavaScript, we're gonna do it like that. It's a little more elegant. It's a little more readable, though however in JavaScript you could also do this, but without the dollar sign. So realize there's different syntaxes possible but this is kind of a nice clean one. And so what this has the effect of doing is plugging into each of those spots the data I got back. And these collectively, let's now see the results by clicking submit with Microsoft there, is exactly how sites like-- come on work so I don't have to walk back; there we go-- is exactly how sites, like again Facebook and Gmail and the like are doing all of today's dynamisms. So we can clean this up significantly, we don't have to write so much syntax, but let's take a five minute break and we'll do just that. >> We are back, so I have to scare you with some slightly even more cryptic syntax, however, in the long run this will make your life much better. So this last version of the AJAX demos, this is AJAX6.html uses that same library from Monday that we talked about briefly called jQuery. So jQuery is just a library. It's written in JavaScript and if you'll recall from Monday, I scrolled for like 30 seconds to see how much code people have actually written in this library called jQuery. But among the things it does, frankly, is it gets rid of so much of this junk that we just had to write, right, this try and this catch and this equals equals four equals equals 200. There was so many copy and paste in the past several examples, and so these days when actually writing sophisticated, interesting websites, you typically don't write all of this code from scratch, you again leverage libraries that other people have written so that you can focus on the interesting aspect of your final project or your own website, and not on the nitty gritty details. So now hopefully, even if it went fast, you understand some of those fundamentals syntactically and conceptually, but let's now throw a lot of that code away. So in AJAX6.html, the end result is going to be the same, but the code is going to be different. Everything we just did is now simplified into this chunk of code, which admittedly looks more cryptic, but it steels all of the basic ideas. So, the very first line here inside of my script tag is jQuery's way of getting at that special document global object. As an aside, the fact that dollar sign is laced throughout jQuery code has nothing to do with PHP, it has nothing to do with variables, it has to do with the fact that the dollar sign in JavaScript-- this is not typical-- is a valid character in a variable name. So what the jQuery folks have actually done is, they have a special object called jQuery, it's like a special function called jQuery but they just decided, frankly, to be a little slick because they didn't want all of their users to be typing jQuery all the time when using their library, they leveraged this feature of JavaScript that even dollar sign can be the name of a function. So what they essentially did was something like this, bar dollar sign gets jQuery so that they made a variable called dollar sign, set it equal to their fancy library so that hence forth you can just say dollar sign. So that's it, there's no relation to PHP, there's nothing fancy going on. This could've been called X. This could be F. This could be A. It could be any stupid character, just dollar sign looks a little interesting and thus was born the popularization of jQuery and this dollar sign. So this first line of code means get me the global document object. This dot ready means when the whole page is ready, call the following code. Now if I want to call the following code in the future, recall that I have to wrap it in an anonymous functions it's not executed now, but this function will be executed later. So now what do I want to do when the page is ready? Dollar sign quote unquote form. So remember the sharp sign means go to the i- the element whose ID is form. So this means give me the element whose thing is form. So let me scroll down. Ah, this is all it's referring to. There's an html element here. ID equals quote unquote form. So this first line of code means go find the element in the page whose ID is form. And we saw this on Monday, when that form is submitted, this is the event handler, call the following function. It doesn't have a name, it's also anonymous so this just means here comes some code. And now here's the new magical stuff. All that junk we wrote to get AJAX working, to make an http request which try and catch and Microsoft and all that messiness, you can just let it melt away because you can instead just say dollar sign dot AJAX open parenthesis closed parenthesis. And this is a function, AJAX is a function that comes in this special library called jQuery and what it does is it takes a few arguments and this is hard to see visually here because of the way I've written in, because of the way it's indented, but what I've really done is I'm passing in open curly brace and then down here closed curly brace to this function called AJAX. So this function apparently takes one big argument which his just an object, otherwise known as an associative array, hash table, call it whatever you want. Well what is inside of this object? Sorry, I lied, it takes at least two arguments here. So what's actually inside of this? So here is a key, URL, so it means go talk to quote3.php. Here is some data and datas value is itself an object. So what this means, and this is only the case because the jQuery folks decided you have to call this function in this way, I'm gonna pass the following data to quote3.php. I'm gonna pass a parameter called symbol and I'm pa- put a value of dollar sign quote unquote symbol. So this is again for Monday. Go fine me the div or the input whose ID is symbol and then now in jQuery you don't say v- dot value, you instead say val, and it's a function call, so get me its value. So a long story short, this is just a more dynamic way of doing what we did earlier, question mark symbol equals fu or whatever the stock symbol name was. This is just doing it a little more elegantly because now all of our symbols and parameters can be grabbed from code, we don't have to hard code the strings in that slightly messier way. Now notice this, there's the comma here and then the word success, and this is important because according to the documentation for jQuery, specifically its AJAX function, the documentation told me write the word success because that is the name of a parameter that I want to send in, and it's value should be a function, and we haven't seen this before, so I'm gonna wave my hands at some of the details here, but this is going to be an anonymous function that nonetheless takes an argument. And when this function is called upon the success of the AJAX http call, execute these three lines of code. And syntactically they're new but they're doing the same thing. Dollar sign quote unquote price with the sharp sign means go get me the div or the span or whatever it is in the html whose idea's price. Let's do a quick sanity check. All right it's a span, here it is right here in the html. So this means go find that input and then just as before we did it the old fashioned way dot inner html, instead I'm gonna call it function.html which is a jQuery function and I'm gonna pass it data dot price. So this is what I can say about this argument. Even though this function is anonymous, it has no name like handler, it can still be called. And because of the way jQuery's implemented, when your AJAX request is successful, it will call this function and it will pass to you an argument. You can call that argument, again, X or Y or Z, anything you want. I called it data. But what will be inside of that argument, thanks to jQuery, will be the server's response. And you don't have to do a val, you don't need those parenthesis. If you get back JSON data, it will just hand it to you in a variable called data. And thus can I do data dot price, data dot high, data dot low. And so the end result in AJAX 6 if I go now to this page in my browser, is aesthetically it's very unchanged. But if I type in let's try go back to goog here and then click get quote and wait just a few seconds 'cause of the artificial server delay, we should see soon, cross your fingers-- that's a slightly longer delay than intended. Let's click get quote again. Okay, something's wrong. [ Laughter ] Standby. My demos are going really well this week. I didn't get the job at Facebook. Okay, so it is returning the right data, price high low but it's not inserting it into the page like I want it to. Did I screw up the code somewhere? I am going to wave my hand and say I will-- I know that laugh-- and what you would see is. . . standby. [laughter] This is totally legitimate. All right. Wallah! Okay let's pretend that worked, all right, I'll fix that later. So this magical library will make your lives this much better if you actually use it, and it will simplify the code as well. I'm actually not sure and I don't fix bugs under pressure under hundreds of eyes, so I will fix that shortly. So what a nice note to move onto the next topic with [laughs] [inaudible] Ok- this is really frust- hold on one sec. [laughter] success, function, data, [inaudible] html data [inaudible] [ Pause ] All right. Save. Okay. [ Pause ] Oh my God! [laughter] val, um hum, response. That's right. Document ready. Okay, let's turn this into a learning exercise 'cause now I'm getting stubborn so, let's see if I go in here, alert, oh hi class, save, reload my source code. Okay so that line works. We're gonna do this then. Um hum. Document [inaudible] element by ID quote unquote price dot inner html gets data dot price. I'm gonna kill these lines, reload, source code, Google, damn it! [laughter] Okay, I can't recover from this live so we'll move on. So we recommend using jQuery for your final project. So toward that end, let's see if we can't clean up one other issue. So thus far on your appliance you've had obviously these internal URL's, http colon slash slash local host or http colon slash slash 192 dot 168 dot 56 dot 50. These are not even publicly accessible nor are they elegant, and so recall at the end of P Set 7 and now also P Set 8, we have some instructions for how to move your code to the so-called CS50. So the CS50 cloud is just a b- collection of servers that run [inaudible]. But they, unlike your appliance have a public IP address, and they allow you to connect via SSH, via a protocol called sftp documentation for which is linked on the page that each P Set 7 and 8 allude to. And you have the ability to upload your code to those servers to move your databases from appliance to server so that then you can have your websites live at an address like, like an address like http colon slash slash cloud dot CS50 dot net slash tilde username slash P Set 7. So this is really not getting any better but you can do even better than this, and one of the things that we try to do for CS50 especially at terms end is make sure you know in the future how you can transition your work off of some isolated [inaudible] sandbox like the appliance to a real server. And so that real server can be cloud dot CS50 dot net, but if you go to this URL here which is also linked on manual CS50 dot net, you can create if you would like for your final project, something called a virtual host. So Tasia [inaudible] did this a couple years ago. Her website IsawyouHarvard.com originally lived on cloud dot CS50 dot net slash tilde and then Tasia's username. So not a very elegant destination for her users to actually visit, so she signed up for a domain name. She went to a place like GoDaddy.com or NetworkSolutions.com, someplace where you could buy a domain name for maybe $10 or $20. She then configured that domain name via whoever she bought it from, to have an IP address identical to cloud dot CS50 dot net, so that henceforth if people went to IsawyouHarvard.com and hit enter in their browsers, thanks to DNS which we talked about a couple of weeks ago, that I- that name IsawyouHarvard.com would resolve to an IP address that starts with 140 dot 247 dot something, so somewhere on campus, and that IP address is identical to that of the cloud. She then filled out a Google form on the FS URL here. She then told us, CS50 staff, hey I just bought IsawyouHarvard.com, can you reconfigure the cloud's web server to know that cl- IsawyouHarvard.com should map to my personal public html directory and we ran a command and wallah, IsawyouHarvard.com was born, originally on CS50's own servers. So you too can do this. There is a cost, it's not required, but buying a domain name is usually a few dollars, but thereafter you can use your CS50 cloud accounts as web hosting accounts until terms end. And you'll see at terms end we'll provide you with some places to then move your code to. HCS can provide free hosting. There's big companies like DreamHost which can provide hosting as well as other features and the like. But a quick tour now of some of the things you can take advantage of now that we have this ability to program web side, both on the server and on the client with PHP, JavaScript and even stored data. So CS50 over the years has developed a whole bunch of API's, application programming interfaces, that allow you to query data from each of these tools. You can get course catalog data, event data, dining hall menu and the like, in a whole bunch of formats. For instance if I go to manual.CS50.net and go to Harvard food API, what you'll see is pretty extensive documentation examples for a mechanism whereby you can get from HUDS website programmatically nutritional facts, dining hall menus, and even the individual recipes for things in the dining hall. And you can get them back in a whole bunch of formats suggested here. So CSV is comma separated values. So if you actually visit a URL like this, food dot CS50 dot net slash API slash and so forth, and then pass in some http parameters like meal equals breakfast, start date time equals 2011-03-21 which was the day I wrote this documentation, what you will get back is essentially an Excel file with all of this data, and you can parse it just like we did in P Set 7 for you with the quote function, or as of today, if you want a little more flexibility, CSV is not a very fancy format and it has problems if you want to actually have commas for instance in your own data. Well you can get back JSON data, so you can get back the dining hall's menu from March 21st in this format instead with all these key value pairs. And there's yet other ways you can get at this information. But let me draw your attention now too to some documentation. So we've been using JavaScript but you can in PHP grab JSON data or CSV data and, as we keep saying, parse it. To parse it means to read it, top down, left to right, and actually convert what is literally just a huge string of text from a website into some kind of data structure whereby you have in memory some kind of tree structure representing that object. And so I would refer you to this URL here for some quick tutorials on how to load JSON data or CSV data which I myself should perhaps read soon on how to load those into your own web pages or your own PHP files. But sometimes you have to resort to this mechanism, so screen scraping is a technique that involves pretending to be a browser like we do for Harvard food, going to the dining.harvard.edu and screen scraping HUDS website. They have a very s- html laden website where you can see all of the nutritional facts and all of the menus, but in html. They don't let us just click a link and get a CSV file, so we instead wrote a PHP program that every night at midnight visits HUDS website, pretends to be Firefox or some such browser, grabs all of the html from their website and then analyzes it looking for keywords that look like food and look like nutritional contents and look for portion sizes and the like. We then store them in our own se- my sequel database and then re-expose it to you with just text and no fluffy html so that you can then do something more interesting with it and you don't have to screen scrape it yourself. However, every year people want to do things with like ESPN scores or stock data or any amount of interesting data that's just out there on the internet and they want to load it into their own database so realize we have put a tutorial at this URL so you can learn. If you have to have to have to resort to screen scraping, which is not recommended, you can at least learn from this example. And I warn against it only because if HUDS one day, they haven't done this in like five years, one day changes their website, that means we are gonna have to go and twi- change our code to adapt to whatever their new website looks like. And so in that sense it's a little fragile, but they have a habit of never updating their website which is good for us. [laughter] So authenticating users-- so this is a popular one too. You obviously log into CS50's own website, you log into all sorts of things across campus, but for your own final projects, you might want to restrict usage to just Harvard people or anyone affiliated with Harvard.edu or just college students, anyone with an at college dot Harvard dot edu account. So know that at this URL here, there's a bunch of techniques whereby you can do exactly that. In particular, CS50 provides, as of this year, a service that we call CS50 ID which is documented on the course's website and this picture just paints a fairly complex picture to say that if you want to authenticate a user on the left, and your website's there on the right, by using this free service CS50 ID with PHP code or Ruby code or others, you can authenticate users with their Harvard ID and PIN, with their at college address, with their FAS address, with their at post address, any of these mechanisms, but you yourself never have to ask the user for their password. And this is good for security. Rather, you'll redirect them to CS50 ID just like we redirect you to Facebook for the harvar- the CS50 shopping app whereby we will authenticate the user and then we will hand them back to you and tell you what their email address is typically. But we won't tell you their HUID or their password or PIN or anything sensitive like that. So for CS50 ID, realize there's documentation online as well. And then lastly, I wanted to address one technique that some of you might have run into some issues with on P Set 7 depending on where you developed your code. Long story short, sending email is increasingly difficult these days because of spam prevention. For instance, the Harvard dorms I believe are firewalled in such a way that if you try to send mail using PHP's mail function, it will often not go out. It will wor- your code will work but no one will ever get the email and this is typically because Harvard is blocking, in this case TCP port 25. Think back to that video on how the internet works and the firewall and how you can prevent certain numbers from going through, they let you access the web but they don't necessarily allow you to use port 25 which is outbound email access unless you actually use their server. So you'll see at this URL some documentation that not only reminds you how to use PHP's mail function, but if you scroll down below, you will see documentation on this. This is a PHP class, it's like a library that allows you to, with a little more complexity, send email using an SMTP server. So an SMTP just means outgoing mail, and in this case Harvard has an SMTP server that all of us can use on campus called SMTP dot fas dot Harvard dot edu. If you're off campus you might need to use like Comcast, SMTP dot Comcast dot net, but you'll see here a bunch of lines of code that allow you to programmatically send emails, even attachments, and avoid some of the firewalling issues you might encounter. But even more fun is this ability to send text messages. So there's bunches of ways to do this but if your final project wants to remind or alert users, you can also send text messages using very simple syntax. If you already know how to send emails, you can also send text messages via email. So it turns out all these popular US phone carriers allow you to send a text message to someone whose number is maybe fi- 617-555-1212 to an email address that ends in at vtext.com if they're a Verizon customer, or at tmomail.net if they're T-Mobil or at text.att.net. So if we combine all of these features as I did here in advance, let me see if I can get this all to work here. Let me pull up a browser, let me just make sure my internet connection's working inside of my appliance which it isn't but I promise this- oh there it is, good. So my internet is working inside the appliance. I went ahead in advance and I wrote this little program here called email.php, and this is pretty much copied and pasted from the documentation I just alluded to but then I also remember back in like week 0, we asked you all what your cell phone numbers are and who your carrier is, so I wrote a little program that went through CS50's database and I generated a big Excel spreadsheet, a CSV file containing all of your first names and all of your cell phone numbers concatenated with tmomail.net or vtext.com or the like, and then I stole this code here which has a nice little four loop. That first F opens students dot CSV that then calls f get CSV, that then calls add address. And I'm gonna go ahead and add the address here, not JHarvard@CS50.net, but I'm gonna go ahead and add column one from this CSV file, and I wrote a little email to you, why aren't you at CS50 [inaudible] 0. Let me scroll down. Then I'm gonna say send and then I'm gonna sleep for a tenth of a second just so that the email server doesn't blacklist me. And then I'm gonna get this here so if I didn't make any mistakes, this is a wonderful example of how to send text messages programmatically for final projects-- don't do this at home to this many people-- but if I did this right, let me open my terminal window, I'm sorry about to cost some of you a dime. I'm going to go into my email directory. I'm going to-- if you gave us your number. I'm gonna run, so here's the script, email dot PHP to run a PHP program at the command line I have to call the interpreter and then call it on PHP, email dot PHP enter. Uh-oh. Wait a minute. Wait a minute. Oh please don't die on us. [laughter] Let's see, okay hold on [inaudible]. Okay. [laughter] Okay. Yes? Yes! [applause] All right! [applause] Vindicated! We will see you next week and please explain to those not present why we just text messaged them. [laughter]