>> 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]