[ no speaking ]
>> Unknown: All right, welcome to CS50.
This is the start of week 9.
So one announcement, if you haven't RSVP'd already and would
like to join us, Wednesday, Mather [assumed spelling], 6 pm.
[Inaudible] just RSVP.
One new handout today and this is a bug of sort or a feature
if you will, that's actually been circulated a bit
on various blogs this past week.
So it's been around for some time.
I thought I'd replicate it here
with this website called, Google.
I was wanting to do some math the other day
and it turns out Google does math.
For instance, if I want to know what 3 - 2 is, hit enter,
well we'll actually do that kind of math for you.
But that I can do in my head, but I can't really do
in my head very well something like this, this,
that's a big number and then let's just minus,
actually let's try to be creative here.
Let's put almost the same number but 998.
OK, so for anyone who's taken like Math 55, what's the answer?
[ laughter ]
Seven. Excellent.
So it's pretty close, it should be 1 right.
Pretty big numbers, but one's just 1 bigger than the other,
but if you do a little Google search
for this, the Google fails us.
So.
[ booing ]
I know.
[ laughter ]
So this went around a while.
So this isn't a bug per say because otherwise someone
at Google would have addressed it.
Because it's been blogged about at nauseum.
So what might the explanation be?
What's that?
So rounding or there's some kind of imprecision here.
So even though we talk mostly about this in the context
of floating point values, so even with integers,
we've seen in C at least, that there are upper bounds
on the kinds of math that we can actually compute.
So if you like this kind of thing,
so there's really no big lesson here, this is in fact a feature
of the way math is implemented at least by Google here,
but there's actually a neat article that's
been recirculated.
It's called, Why Computers Suck at Math.
It's an interesting article and it discusses this
and other such things.
So we've linked that on the course's website
if you would like.
Also on the course's website now,
we've replaced the old big board with the new big board.
The old big board in still linked there.
You'll see that your classmate Charles has already figured
out how to exploit financial opportunity perhaps,
more likely bugs or weaknesses
in our own implementation of this big board.
This is sort of this funny thing,
especially about teaching a Harvard class right, you know,
you just want to do something nice and fun
that gets the students excited about this and that.
It's completely ancillary to the piece
and then there's always one or more people who decide,
let's see what we can break.
And of course, there are weaknesses in this
and that's fine, Charles is up 4000%
since like 9 am this morning.
If you actually look at his history by clicking his name,
you'll see exactly how he did this and what he bought
and things we probably shouldn't have let him buy.
And again, you can essentially see into the future
if you simply watch your own eTrade account or CNN.com
and then make your purchases within the 15 minute window
that is the delay that Yahoo Finance imposes.
But that's OK.
Why don't we just throw down the gauntlet and say
that Charles is now the person to be.
So 433,000 is currently the number one position.
I think I'm doing rather the opposite.
Oh actually, we're only down 1%.
But one takeaway that's worth nothing here is
and you may have glimpsed it really fast just now,
is this is actually an Ajax implementation
of this big board.
Ajax is kind of a buzz word, but it refers to websites
that are more dynamic and that's to update the page's content,
the whole thing doesn't have to reload.
You can just reload portions of the page,
thereby creating a much more seamless interface
and that's going to be one of the topics for this week.
How can we move away, even just one week later,
from this very mechanical but very reliable approach
of implementing websites where one page leads to another leads
to another and can we make this user experience a lot more
seamless like this?
And if you watch this over the course of several minutes,
you'll see that these numbers do in fact fluctuate
and I wouldn't be surprised if by the end of today's lecture,
someone is already contesting Charles.
So we shall, we shall see.
Oh and also back is, Ceiling Cat.
Ceiling Cat is one of the most famous of all cats.
I know that the feelings on this topic in the course are mixed,
but seeing as in the remaining surveys that were submitted
for Peace at 5, we just finished reading through,
one student actually said that he or she registered
for the course because my god, the syllabus was online
in advance and so few courses do that.
And another student literally wrote that he or she enrolled
in the course because he or she saw Ceiling Cat
on version 1 of the website.
So we actually removed that, worrying that it would work
against us this year, but we'll put him back
since this is now the web week of the course.
And if you actually click him, you can read about the beginning
of the earth from Ceiling Cat's perspective.
So this is another famous link there.
Anyhow, all right, so what have we got in store today?
So last week we talked about, last week we talked about php
and a little bit of My SQL and HTML and pset 7 is really going
to enforce this stuff.
So we're going to forge ahead this week
and give you the conceptual framework for both pset 8
and probably for many of you, final projects.
And as much as we've kind
of promoted taking a web based approach for final projects,
realize you absolutely do not have to.
We just know historically in recent years,
60% plus of students
in the course tackle web based final projects,
even though we spend but two weeks
of it officially in the semester.
But you are welcome to pursue most anything per the pset,
per the final project specifications.
So I thought I would either try to really excite you
or really crush you with the following promise which is
that we can implement the entirety of problem set 6,
essentially in one line of code.
So that's a bit of an oversimplification
but it does speak to this issue
of choosing the right tool for the job.
So what I went ahead and did was the following
and included among your printouts
for today is this file called, speller.
So notice a couple of things.
Speller 1 had no file extension.
So even in the course we've had this habit
of using file extensions like .c and .h,
for the most part those are just conventions.
Now with that said, some operating systems like Windows,
rely on file extensions so that when you double-click it,
it knows what program to load.
But operating systems like Linux and Unix and MacOS,
are a bit more, a bit smarter than that
and they actually look inside the file to figure
out what program to launch.
But there's still disconvention
of naming things with file extensions.
But it's not necessary.
I proceeded to write this program called, speller.
No file extension but notice, no 0's and 1's.
This is not a compiled program because I wrote this one in php.
So the catch when you write a program in php,
especially if you just want to run it at the command line
like I did early last week when we did
that very simple quote check, stock quote checking program.
Four or so lines of code.
I ran it at the command line as php quote.php, because I wanted
to use the php interpreted,
a program that may executes php code
and I gave it a command line argument,
the name of the file I wanted to execute.
But that's a little bit annoying because now your users have
to realize, oh this program happens to be written
in a language called php, even though I don't care.
But just to run this program I need
to know to run php filename.
Well you can avoid that altogether on a Mac
or on a typically Linux or Unix system
by including this thing atop the file.
So this is what's sort of goofily called a shebang,
S H E B A N G, which just means put the sharp symbol at the top,
followed by bang or exclamation point, followed by the path
of the program that you want to use
to interpret the following lines of code.
So simply by including this at the top of my file
and by running this command, chamod, change mode 700
of speller and this command chamod is discussed,
if you haven't read it already, in pset 7.
This is going to make my file executable and what this means,
if I do an LS and this is an aesthetic thing,
speller is shown to me in green and with a star,
at least within Putty [assumed spelling],
the program I'm using on this PC.
So that just means it's executable,
so that means I can run at the command line, speller,
or more specifically just to be really security conscience, .
/speller. Run this copy of speller.
So what the OS, Linux in this case,
is going to do is it's going to see ah,
top line of this file says use the following
interpreter user/bin/php.
That's just where it is on the hard drive.
Let me load that program
and then feed the following lines to it.
So the same goal is accomplished of executing the code,
but it's a little bit more user friendly that now I don't have
to know or care what language this is written in.
So I implemented speller and if I run it like this,
I see output identical to pset 6's framework
that you guys were handed.
So we won't walk in great detail through this.
You're welcome to do it sort of at your leisure at home,
but notice I pretty much tried to look at my C code
on the left hand side in a window
and then I had another window open for this file and I tried
to literally translate C code to php code.
Partly so that you guys, if you want to curl up with this
at some point with your old pset 6, or pset 6 still in progress,
you can actually see how you would implement the same program
but in a different language.
And most of the syntax is familiar.
So at the very top here, I have require.
So require is similar in spirit to that sharp include.
In C it means require the following file,
copy and paste it's contents here.
So this thing here is a little php specific.
Php like a lot of languages,
have different levels of error reporting.
If you really want to get your hands dirty
with the feedback from the program.
So I'm just saying turn on, suppress things called notices
and warnings and a lot of languages there's
at least three types of bad things that an happen.
Notices, which are like eh, you really shouldn't do that.
Warnings, which are something bad could probably happen,
but I'm going to proceed nonetheless.
And errors, which means sorry, really bad stuff happened,
I can't even run your code.
So there's different levels.
In C, we've pretty much turned everything into errors
for you guys, to force you to actually deal with them.
So for now you can just kind of take this one on faith.
This is stole from the problem sets.
I defined a constant in php.
Syntax is different.
It's not sharp define.
It's define and define is actually a function
that takes two arguments.
The name of the constant and then a value on [inaudible]
but otherwise it's the same idea.
Same deal for the second constant here, words.
And then down here notice that just like in C,
I can have command line arguments.
So if [inaudible] does not equal 2 or 3,
tell the user how to run this program.
So it's pretty much been a copy paste, from C to php,
but I've changed my variables to have dollar signs
and I've changed how I declare constants.
But pretty much it's a pretty good translation.
Now this thing here I did just to be a little bit anal.
So these are the variables we had in speller as well, tiload,
ticheck and I've initialized them just
to be a little fancy to 0.
now this is just me thinking I'm being clever
by just saving a character.
By not doing 0.0, but it's the same thing.
As soon as you append a period to a number,
it becomes a floating point value so
and I also just didn't want to waste 4 lines of code.
So again, stylistic decision.
I just put them all on the same line separated by semi-colons.
But it's the same approach as in C. But notice I did not have
to specify for any of these variables what?
A type. So again, php is loosely typed,
which means there are data types underneath the hood,
but php gives you so much automatic conversion or casting
from one to the other, that you the programmer don't have
to worry as much about it.
So this is our little Tertiary operator question mark
and colon, which just says if arcC is 3 assign dict
to the value of ardv1 else assign
if the default value in that constant.
And then for the most part the rest of this you can play with
or look through on your own if you want,
but it's pretty much a translation
of the benchmarking code that you guys used for problem set 6
and the end result and the end of this program is
that it prints this output,
which should be vaguely familiar at this point.
So in short, I reimplemented speller in php,
but of course you didn't implement speller,
you implemented dictionary.c and maybe .h,
so you implemented only the data structure.
So I thought we would kind of do that here.
Let me go ahead and move this one aside for just a moment.
I'm going to create a file called dictionary.php.
It's automatically going to be included when I run speller,
because of that require line.
Every php file has to begin and end with this
or anytime you write php code specifically,
you need to encase it in these things, so it's not conflated
for HTML or something like that.
So let's see.
I need to implement a whole dictionary
and let's see, what was in there?
So I had a function that I had to implement called,
load and it has to return a value.
I had a function called, check and it took a word
and now I'm going to have to write that.
I had a function called, there were two more,
size and that's probably pretty easy, but let's see.
And then finally a function called, unload.
So these were the four functions I implemented
and pretty much we gave them to as blank,
maybe a return value here or there.
But I need to implement the data structure first.
In php and some of these high level languages
and scripting languages, you can implement data
structures yourself.
You can implement trees and tries and hash tables.
But the thing is you don't' have to, because in a lot
of higher level languages, you're handed this stuff
for free, out of the box.
It's a feature of the language.
And in fact, we mentioned this briefly last time,
that thing called dollar_, $_post or $_gets,
that's super-global as I labeled it last week,
that's what's called associative array.
The syntax for that recall looked a little something
like this.
Post and then I could say something like name and what
that variable gave me is the value that the user typed
into a form called, name.
Now we're mostly familiar with arrays in a numeric sense.
In C we always did something like this or like this
or like this, but what's nice about an associative array is
that it's a generalization of the idea of an array
and you can index into the array using things other than numbers.
You can use arbitrary strings.
So in fact, what an associative array is,
it's kind of like a two column table in memory,
where on the left hand column are keys
and the right hand column are values, but what's really nice
about the language itself is
that it doesn't search these things linearly.
What an associative array is implemented as,
underneath the hood, is something like a hash table
with chains, which is what many of you, but not all of you use,
to implement your implementation of pset 6.
So long story short, if I want an associative array,
aka hash table, I simply have to do something like this.
Give me an array.
So this is going to be my hash table.
It's as simple as that.
So now I can put stuff into this array and I can get stuff
out of this array, just by using net square bracket notation.
So let's see, what else am I going to need?
I'm also going to declare a global variable called,
hashtablesize and I'm just going to call this, size and I'm going
to initialize it to 0.
So notice this is outside the scope of those functions
so now all I have to do is implement the
remaining functions.
Well let's kind of impress just
by being quick here, all right, done.
So we're done with that function there.
So we have three functions left.
What about load?
Well to get in load, oh and actually I forgot one thing
in load, it did take a command line argument.
The name of the dictionary to load.
My goal here has to be to load the dictionary into memory
and then iterate over the files and then insert each
of the files into my data structure.
Well how can I do that?
Well it turns out that in php, there is a function called file,
which returns to you an array such that every element
of the array is a word from the file.
So it's literally gives you that.
In fact, let me do a quick, little, let's see,
what do I want to do here?
Let's do a quick sanity check?
I'm going to go ahead and do this and I'm going to say,
call this a variable called, lines equals file of dict,
and this is going to get me again an array,
whereby each element is a word from that file.
And again, now this is sort of debugging mode.
I'm going to use that recursive print function from last week,
I'm going to print lines and then I'm just going to exit.
So this is not a working implementation
but I know speller is going to call load and I just want
to see what's inside this variable temporarily
and then we'll throw away these 2 lines of debugging code.
So let me go ahead and save this and let me go ahead
and run speller, on a very small file.
Something like the Ralph Wiggim [assumed spelling] quote.
And hit, enter.
And in fact, that's what I see.
So what you're seeing being spit out again and again,
because I'm recursively printing the array, is a list of all
of the words in the given dict file.
In that default dictionary.
You probably remember at least the last one.
If you ever saw these things flow on the screen.
Well there's a weird artifact here.
Whereby every, there's a space between every line and that's
because there are new lines in the file so, well we'll deal
with that in just a moment.
Well it turns out if I'm getting back an array here,
I'm not even going to bother assigning it to a variable
because I'm going to immediately launch
into a for each construct.
For each word from the file and the syntax
for doing this, is this.
This is a nice little piece of syntax that doesn't exist
in C. Not this user friendly like and it's going to say,
for each of the words in that array, so it takes an array
in parenthesis, then the keyword, as, and then the name
of a variable that you want to update
on every iteration being the current word from that array.
So this is going to induce you know, the equivalent
of a wild loop or a forward loop, but it's kind of nice
and compact in what it's going to do for me.
So what do I want to do?
Well I need to remember that each of these words is
in the dictionary, but let's see how I can do that.
Here's my hash table, dictionary,
well I pretty much just want to do this.
I don't want to index into an I location,
because there's no variable I
and I don't' want a hard coded number.
What I want to use is the word, as a key and you know what,
it suffices to say this, OK insert this word, word,
into my dictionary but just say true.
So I'm treating word as a key, true as a value,
so that if you've now fast forwarded in your mind
to the check function, how is check going
to check whether there's a word in the dictionary?
It's just going to check in the given word exists in dictionary,
because if it gets back an answer of true, I put it there.
And if nothing comes back that means I didn't put it there,
which means it's not in fact a word in the dictionary.
So before we clean up this function,
let's fast forward and just do this.
Return dictionary, bracket word
and actually let's be a little more anal than this.
So if I find a true value at the location in dictionary, go ahead
and return true else go ahead and return, return false.
So this function is actually done.
If the given word is in the dictionary,
return true else false.
Now let me just clean this up.
Because I did say that there were these new lines
at the end of the file, right.
Because the default dictionary word, new line, word, new line.
So there's this other function and this is really just useful.
Chop, the behavior of chop is
to eliminate the last character from a word.
Or I could use something called trim,
which eliminates white space from the end
or the beginning of a word.
So I'm just going to clean up my word in this way
and actually let's go ahead and use trim,
just because it's a little more thorough
and I know it's just going to get rid of white space
on the beginning and end of a word.
All right, so I'm pretty much done.
Actually you know what, let me do this.
I now need to save, return true.
OK. Turns out I don't' really need these things.
Let's make the code look even smaller
and let me do one reasonable sanity check.
So if file exists, this variable,
actually if this file does not exist or this file is not,
is readable, these are literally functions in php, what do I want
to do if the file neither exists
or is readable or is not readable?
Yes, so return false.
So now I'm adding a modicum of error checking here.
But I'm pretty thorough here.
So if the file doesn't exist or it's not readable, return false
because I can't load the dictionary.
Otherwise, iterate over each word in the file and then insert
into my hash table, every word, and just assign it a value
of true so that later I can ask a billion questions.
Is the word there?
Yes or no?
Yes or no, iteratively in my check function.
Now I need to change one thing.
There's one nuisance of php,
which is that even though dictionary looks
like it's a global variable at the top of the file,
you actually can't access global variables inside
of functions unless you say, hey php,
dictionary is a global variable, just so you realize.
And so I need to do this in here.
I need to do it in here and I need
to do one other, one other place.
I need to do this here.
So it's stupid frankly.
This is an annoying feature of php,
but at least now we have access to that global variable.
Unload. Is there anything to do?
No, not really.
Already unload.
In php you don't have to manage your memory.
The php interpreter does it for you.
No malloc, no free, none of that.
It's all done for you.
So any concerns?
Did I make any mistakes?
Because I literally am doing this on the fly here.
Good, it doesn't.
It's always going to be 0 right now.
So what do we want to do to fix this?
Yes, might as well go in here.
Guess I've got to put my brackets again
and then I'm going to do size++ and then I just have
to make one other change here.
I have to specify that size is global.
Yes? Good?
OK and we can do this any number of ways.
So let's save this.
Let's run speller on text and now run it
on the Ralph [assumed spelling] file and that's wrong isn't it.
Let's do, do I want to do this right now on the fly?
File exists for each file is word, dictionary, trim, word.
That's OK.
Size gets true.
Can you see the bug?
What? Capitalization.
Oh, yes. Thank you, thank you very much.
Capitalization.
OK, so that I can fix.
Stir to lower.
[ laughter ]
I mean, frankly you laugh, but this is one
of the biggest sources of bugs in your C code right?
Was given the check function, most of you probably made a copy
of the word, then had to force it to lower case, then you had
to chase down all these stupid memory bugs.
But I mean, this is actually very reasonable,
I'm passed the word, it could be in any type of capitalization.
I want to force it to lowercase, so stir to lower is
in fact the function for that.
Let's go ahead and rerun Ralph and yes, it actually works.
So what was that?
Eight minutes of coding to implement problem set 6
in the better choice of languages.
But surely there must be a catch.
So in fact there is.
So let me actually not run Ralph
Because recall Ralph is a terribly short file.
Right? This is and if you've never actually looked
in this file, this is the, this is from the lab,
so you can actually look in this file.
Some of you have seen it.
So that's OK.
So let's take a look at speller though
on something much longer like the Holmes file.
So this is like 6 megabytes.
So this was a very large file.
It's going ahead and spell checking, spitting out all
of the bogus words and let's give it a little bit here.
There are a lot of misspelled, quote unquote, words,
because this was an unfamiliar text.
All right, so words misspelled, 17,000 out of 140,
out of actually a million words in the file.
So this is a big file and it took roughly 2.19 seconds
to totally spell check that file.
So now let me shift gears to my other window here.
Same server.
I'm on logged in as myself and I'm actually going to run,
not the php version but the staff solution
from pset 6 itself, which was called, speller here.
I'm going to pass it the same text file,
which is misspellings, text,
Holmes So again I'm just running the C implementation
of the staff's implementation of dictionary and I'm going
to hit, enter and wow.
So maybe it's that the staff is much better at writing code
than I am right, especially since I just wrote this
on the fly or maybe it also has a little something to do
with the choice of language.
So this is one of the trade offs and again this theme
of you don't' get anything for free.
So yes, I really whittled down my development time from what?
Ten hours, fifteen hours, twenty plus hours for some
of you, took eight minutes.
Which might be a little disheartening certainly,
but look at the price I'm going to pay in the long run
if I use this thing to spell check very large bodies of text.
So development time when down,
but running time significantly went up.
You notice the difference here?
Notice the bug here.
[ laughter ]
OK, well we'll ignore that little detail
that the words misspelled is slightly different.
Because there is in fact a little bug somewhere.
But trust me that it's the choice of language.
I should get credit for pointing out the bug
and letting you realize it.
Maybe? So notice the order of magnitude though, 2.19 seconds
versus .4 seconds and this was still a relatively small file.
It's only 6 megabytes and we deal
with much larger data sets these days.
So what's the takeaway?
Well the theme in interpreted languages like php or JavaScript
or pearl or ruby or python, there's a whole bunch
of popular interpreted languages.
They are very convenient and they give you a lot of features
out of the box for free, so that you don't have
to reinvent the wheels you guys have been implementing
all semester.
But you really pay for it.
One, you have no idea how things are implemented underneath the
hood, which may or may not be a bad thing.
But certainly you can't fine tune your code very effectively
and if the goal, especially you know, for a job
or for your research is really to maximize performance,
you really need to pick up the right tool for the job.
Yes?
>> So when you run a reference and place it in the table in C,
there [inaudible] and here you're basically referencing
this table and not there [inaudible]?
>> That's correct.
So and I'm also taking advantage of certain features
of the language So the point here is
that in my own dictionary implementation
and let me open my commented one
which you guys have a printout of.
So in my implementation notice
that in my check function I'm kind of blindly checking
if there is in fact a word at a give location in my dictionary,
but there might not be anything there.
And as you can point out in C, very bad things happen
if you just index into an array, anywhere you want.
So in php and in a lot of language
like this, that's not a problem.
You will simply by default get back a value of false
or it will trigger a warning or some kind of notice
and in fact I'm being a little tricky here in that the line
of code that I mentioned at the very beginning of speller
that suppresses notices and warnings,
what you just described, indexing into an array
where you should not, that in php actually triggers usually
what's called a notice.
You will see printed on the screen, notice,
indexing into an array, not wise or something to that effect.
But with this line of code, I'm actually suppressing that notice
because I'm very comfortable knowing,
accepting that I know there might not be anything there.
So with this case I'm telling php, quiet, I don't want to know
about these notices, this is OK.
But there are other ways to deal with this.
You could actually do something like this.
So let me make one last comment on this
and then we'll forge ahead.
You could, I could have done this.
If dictionary stir to, stir to lower word is set.
So there's a function in php called, is set,
that solves exactly the problem you are worried
about which is a check before actually going there,
is there anything there and only
if there is does it return a value.
Yes? So I wouldn't.
I would replace one with the other at that point.
I would replace one with the other.
So, but I made the conscious decision to kind of gloss
over some of these details just in the interest of simplicity,
but frankly it's reasonable to do
such if you know what you're doing, as a design decision.
Other questions?
OK, so then a word on why did we just put you
through problem set 6 and problem set 5
and problem set 4 right?
So one, there are different tools for the job.
Like when you are doing various research things
or you are trying to actually you know,
implement the next best search engine or what not,
you really do sometimes want to get very low level,
closer to the operating system, into the hardware,
so you can actually eek
out as much performance as you might want.
But there's also something to be said
for actually understanding what this thing is.
I would argue that there's a lot of software developers out there
who completely take for granted
that there is this thing called an array, you can access
into it, with no appreciation
of how it's actually implemented underneath the hood
and therefore when to use it and when not to use it as well.
And also it's around this time of the semester,
especially with pset 6, where late day usage really spikes,
so not to worry if you're kind of still working hard
on pset 6, it's typical.
Especially at the end of the semester.
But realize, the common sentiment at this point
in the term is you know, my god like, thank god the end is
in sight and you know, you might feel
like you've learned something, you might feel fairly gratified
at 4 am after finishing these things,
but many of you might think eh, this isn't' really for me.
I don't want to go through that again.
But realize, that is not necessarily what programming is
and what programming computers is all about.
So now that we're finally taking this step up,
realize that there is this great element of fun, I think,
of programming, that allows you to solve real world problems.
Whether it's some new site, again or events site,
the Twitter site, relatively easily including simple things
like the spell checker.
So you simply have to pick the right tool for the job.
And that's why I think final projects around this time
of the year tend to be particularly fun
because you can finally, actually bite off something
at your choosing and not us.
So that was a lot.
Why don't we take our five minute break now.
All right.
So it's kind of spooky that it's already time
for this little announcement, but indeed, even though a month
or so remains in the semester, do realize that we'll already be
on the search for TF's and for CA's for next fall, 2010.
Know that the role of TF involves leading section,
working with your students, grading their problem sets,
office hours and the like and CA'ing by contrast is a role
that we've targeted particularly at alumni at CS50.
So almost all of the CA's that you may have met in the lab
or on email lists this year, are former CS50 students
who have offered to contribute 2 hours, only 2 hours
of work per week, on a volunteer basis working
with their fellow classmates and their successors in this class
and the lab in what is pretty much the most intense,
fun part of the course and office hours.
Realize that if you do choose to join us next year,
it's a little more fun being on the other side of things
and actually running the white board
and not running to the white board.
So more, just go, we'll post a link
on the course's homepage before long via which you can apply
by telling us a little something about yourself
and what you plan for next term.
So in the time that has passed, Charles has made let's see
about $60,000, so he's doing quite well.
So we give him our official blessing
and challenge you to best him.
But realize, this thing exists one just for fun,
but also so that you can actually play
with the staff's own implementation of CS50 finance,
which you can get
to by following the appropriate link here.
But realize too, you need not implement your version
of pset 7 exactly as the staff has.
We have simply offered it for consideration.
And you may have realized already, you can look at some
of the code for the site.
You're welcome to look at the HTML and the CSS.
What you'll find is that you don't have access to the php
and this is kind of a rule of thumb with web development.
It's pretty reasonable and it's technologically completely
possible these days to look at other people's source code
with regard to HTML and CSS and even, unless they've jumped
through some hoops, JavaScript as well.
And I can't emphasize enough, if you like this kind of stuff,
the best way to learn about how to do new things is to look
at a site you like and even though it might be a little
complicated at first glance, start poking
around with it's source code and learn from someone else's sites.
There's really not much intellectual property
when it comes to XHTML and the layout of the site.
The juicy stuff is in the JavaScript,
which we'll see today and also in the php.
The former of which we can actually obviewskate in some way
to make it harder for people to take your intellectual property.
But let me bring your attention to this thing here.
So pset 7 recommends that you install a few free tools
and we encourage you to use Firefox only
because it's really useful for development purposes,
but ultimately you should be testing
as the spec says your code on multiple browsers.
Because this is a very common thing for,
you will find the hard way unfortunately,
that the web browser manufacturers have always been
at odds for years, 10, 15 years now,
where Microsoft interprets something in the specification
for XHTML one way, Mozilla interprets it another way,
Apple interprets it another way,
so you will see slight differences,
even on your relatively simple websites
across multiple browsers.
And one of the things that drives us nuts
for the course's website is making it look
as best we can the same, no matter the OS
and no matter the browser that your user is using.
So we do expect that you play with at least two browsers
for your project, but with Firefox you have some really
useful tools.
So I had this little bug at the bottom of my window,
because I installed an extension.
It's free software for Firefox called Firebug
and it's a few different things.
It is a, it allows you to view the websites, whether it's your
or someone else's, XHTML or HTML,
in a much more user friendly way.
So notice what I've done.
After clicking the bug, this little pop up opened up
and what it's showing me with much nicer indentation
and nesting, the structure of this webpage.
By contrast, if you look at the course's website,
it's an absolute mess underneath the hood,
not because we were lazy
and didn't really practice good style, but because a lot
of the website is dynamically generated by php scripts
that we wrote and even though we kept our php code
and our JavaScript code pretty neat, when you start
to combine all of these things, things just get messy
and there's really no point trying to make this look clean,
because for the most part it's only a browser
that has to understand this.
So we elaborated on this in the pset spec, but for learning,
this is frankly a bit of a nightmare trying
to find your way around this and even
when we reimplemented Google last week,
I relied on control F, just to find things in the document.
But Firebug is useful for XHTML and HTML for this reason.
You get a much nicer view of the world.
Which means if I want to see what's going on in here,
I can actually dive in and click on these pluses.
So it looks like the body
of my page has this thing called the div, which I've given an ID
of raprum, there's a table in there that's laying things out,
a table body, a bunch of table rows
and more interesting is this.
If you start to hover over tags, you'll see top left, in blue,
what it is I'm hovering over.
So apparently we are actually using very deliberately,
an invisible table who's border is 0,
thereby making it invisible.
So notice, this TD, this table data element,
is the white space at top right.
If I scroll down a little further,
this guy here is apparently that bar in the top middle
and as you might guess over here, that's the guy
on the right hand side.
If I dive into the next table row, notice ah,
there's the left hand side of the page,
here's the middle, here's the right.
And so if you see something on a website that you like
or you wonder, wow how did they implement this it's really cool,
this is a wonderful way of actually wrapping your mind
around how they did it.
Now CSS isn't something you need to worry so much
about for the course, but if you're coming to the course
with some background, realize too
that Firefox lets you see the CSS that's being applied
to a site.
If you click on an individual element like this one
in the middle, on the right hand side you will see all
of the CSS rules that have been applied to that element
and from top to bottom you'll see how they cascade.
So again, I won't spend much time on this,
only because it's not all that enlightening intellectually
for the course's purposes,
but this is a very common technology,
but for the most part it's not necessary
for our two problem sets.
But realize this is there.
And finally, which we'll start using on Wednesday this week,
we have a script tag which actually lets you debug things
that happen to be written in a language called JavaScript.
So this will be invaluable too, to think of this
as a GDB substitute and also useful is one other thing.
So on the course's website, we have this link here, to web.
Firebug is what I just mentioned,
Firefox is the browser.
Then there's this other debugger, which we may talk
about a bit on Wednesday, then there's this thing
which we will talk about today.
Live HTTP headers and then web developer.
This web developer toolbar is what gives me this menu here.
And it also appears under your tools menu.
So very important these days or very common, is for a website
to be designed with a specific browser size
or window size in mind.
Most common these days is probably to assume
that a user's screen is 1024 pixels wide by 768 pixels tall.
And this wasn't always the case.
Facebook, a couple of years ago,
actually assumed a different monitor size
which was 800 pixels by 600 pixels and a lot
of websites did that, including maybe even CNN
up until a couple of years ago.
Well as technology proceeds and as a lot of us start
to acquire widescreen laptops, your screen resolution,
the number of pixels left to right, top to bottom, increases.
So even Facebook a year or two ago,
expanded it's site somewhat to be wider.
So why is this relevant?
Well at home I'm sort of you know, indulgent enough
to have a 30 inch LCD,
which means if I designed CS50's website on my monitor,
like you'd be scrolling left and right all day long.
Because I would just assume that you have my monitor.
But tools like this, web developer,
lets you do little tricks like this.
I can click in the resize menu, 800x600
and it will just make my window be the size
of an older monitor 800x600.
So realize these kinds of tools can just save your,
help keep you sane, but actually in this pset 5 survey,
one or more of you commented that you did have
to scroll rightward on the course's website and only
by having that pointed out to us did we realize it.
Frankly I don't notice some of these bugs on my own monitor
and it was because we had made a mistake
down below and it was too wide.
But look, we fixed it.
Now it looks better.
Anyhow.
[ laughter ]
So let's actually do something here.
So last week we looked at XHTML and php
and that gives us this ability to have a client interface
with the server, back and forth
and the server could generate dynamic output,
thereby influencing the user's experience.
And that's what pset 7 is all about.
But we had no form of validation really, other than a couple
of quick and dirty checks on the server side
and in pset 7 you'll know that it's a little annoying
that if the user provides a bogus input,
we encourage you just to say, to apologize to them
with the apology function.
Where you're saying, the message saying,
invalid username, go back.
Well that's kind of annoying on a modern website if you have
to again, per last week's discussion, you have to go back
and risk your form not even being filled out for you.
You lose all of that data.
So one of the very common approaches these days is
for websites to use a bit of JavaScript.
So JavaScript is also an interpreted language.
So an interpreted language again is one that's executed line
by line, top to bottom, left to right.
It's not compiled into 0's and 1's.
So it looks like English or it looks like actual source code.
So in this case, JavaScript is a client side
programming language.
Php is typically server side,
but there's no reason you can't run it on your own Mac or PC,
but typically it's server side.
JavaScript is client side.
Which means when you visit a webpage
that has some JavaScript code inside of it,
that JavaScript code gets downloaded to your browser along
with the gifs and the jpgs, along with the HTML and the CSS,
all of it comes to your browser.
So it's your browser's job to render,
to display not only the XHTML and the graphics and all that,
but also to execute the JavaScript code,
top to bottom, left to right.
And so it's with JavaScript
that you can actually enhance the user's experience client
side and many of you probably these days completely take
for granted a website like Google Maps.
Right? We can go up here and search for we're at 33,
all right let's do the science center, 1 Oxford Street, 02138.
So this was a huge leap forward a few years ago
when you didn't have to click these stupid up, down, left,
right buttons, which then reload the whole page
and show you a new rectangle.
Reload the whole page, show you a new rectangle.
I mean frankly most of us and rightfully so, probably take
for granted the fact that I can click and drag like this.
But notice if I do it fast enough,
what seems to be happening in the top left corner?
It's yes, so it's gray for a moment and then it downloads.
Well this is what's called Ajax.
So Ajax, asynchronous JavaScript in XML,
it's more of a buzz phrase than anything, but it refers
to the use of JavaScript, this interpreted client side language
to fetching more information from a server
and inserting it inside of the webpage instead
of forcing the user to reload their whole screen.
So we actually do this again, on the course's homepage right now
with regard to the big board.
This thing updates itself every 30, Charles, doing well again.
[ laughter ]
This thing updates itself I think every 30 seconds
or minute.
I forget what timer I set for it.
But I thought it would be annoying
if a student visiting the webpage all
of a sudden has the whole page refresh and it redownloads all
of that content, which can be slow just
to update a couple of values.
So in fact, if we leave this page running, which I will
in the background, it's going to keep updating itself in line.
It's going to use Ajax and do this more seamlessly.
So this was a huge leap forward because Google,
when it's competitors at the time were like MapQuest
and Yahoo, completely left them in the dust with this feature
and you're coming to expect this.
Facebook is much more laden with Ajax these days, for better
or for worse and what this means is that you don't' have to click
and reload as many pages.
Things just kind of update.
A lot of people freaked out I'm told over this new live feed
or something like that.
Well that's Ajax.
The fact that you can see your friends like status updates
in real time and they just kind of, I think they,
I'm told they get inserted into the page and then kind
of move the rest of the status updates downward.
That's all happening in line because some people
at Facebook wrote some code in JavaScript, they downloaded
to your browser by embedding it in Facebook.com's webpages
and it's getting executed by your browser.
So let's see if we can't take a step toward that.
Because problem set 8 is going to have you play an exactly
that seamless world of Ajax and JavaScript with php and MySQL.
So here is a terribly simple form, really didn't care so much
about aesthetics this time, just functionality.
I want it to collect a user's email, their password,
I want it to get their password again and I wanted them to agree
to some terms and conditions.
Why? I wanted a few different form elements here.
But you'll notice if I fill this out,
it's going to lead me nowhere very interesting.
Let me go ahead and pull up Firebug,
just because it's a little cleaner than looking
at my own source code here.
I'm going to go into body, I'm going to go into form
and notice, where does the form go?
I'll zoom in here.
What file does it submit to?
What's the value of it's action line?
[Inaudible].php, all right, so kind of a stupid name.
It's meant to mimic a function we wrote for you for pset 7.
So let me go into this.
This is dump.php.
This is not valid XHTML.
This is not a legitimate webpage per say, but for now I just want
to kind of experiment with this form submission
to really understand how it works.
So what I did is this quick and dirty, as we keep saying,
script that apparently outputs a pre-tag
which means here comes some pre-formatted text.
Display it in a mono spaced font that looks
like a typewriter instead of like an English essay.
And then I have this
and actually I don't' need this right now.
I have print recursively the contents of $_gets.
So recall there's two ways essentially to submit data
to a website from a form.
Via get, which puts all your data in the url and via post.
So what was a rule of thumb here?
When would you want to use post instead of get?
Any thoughts?
So for privacy.
Right? So if you use get, by definition of it,
remember that the query's end up in the url
and that's how we sort of bootstrapped ourselves
into reimplementing Google.
We combined our user's input with their get string.
With their url.
But that's not so good if you're typing in private information,
if you're typing in a username and password or credit card,
so post hides all of that information.
Post can also handle much larger submissions.
So if you're uploading a photo, it's kind of hard
to imagine uploading a photo to Facebook via just a url
and converting it to 0's and 1's,
that's also done by a post as well.
And as an aside, in case you've seen it in any of my code,
request is another super global variable as they're called.
This has both the contents of get and post in them.
So if you're being a little lazy or you want to support both get
and post, you can access the same variables inside
of request.
But it's better designed generally to pick get or post,
so that you know what to expect.
So that's all dump.php is.
It's going to show me the contents of what was submitted
by the form and therefore automatically put
into that super global called gets.
So let's go ahead and do this.
I'm going to type
in mailin@post.harvard.edu 1234512345,
I'm going to check the box and I'm going to click submit
and what I get back here is this output.
So again, this sort of indented output is the result of print R
and this is just what it does.
It dumps the contents of an array.
So what you have been received server side,
four variables inside of get.
So if I really wanted to get to do something more interesting,
rather dump to do something more interesting,
I could do something like this.
I could do let's say, name: and then let's duplicate this.
Let's say password 1.
Let's change this to password 2.
And then we'll change this to check box.
So just to make clear what I'm doing,
let's now put not the value of the whole array
but let's just print out $_get quote unquote email.
Sorry I wrote something down that didn't exist.
I meant to say email.
And then here I want to say quote open bracket ?print$,
so this is a little tedious.
It turns out that if all you want to do is print a value,
php has a shorthand notation which is open bracket ?=
and then just put the variable that you want to put there
which in this case is going to be password 1, so quote unquote
and you probably get the idea.
So I won't bother finishing the rest.
But the point is, the top version is really
just debugging.
Dumping the whole array.
If you actually care about individual values,
you go after them using this associative array syntax.
This square bracket notation.
If I reload this page, thereby resubmitting the form,
after saving my file, notice that what I get down here,
oh I'm cheating, I'm on the wrong server.
Dammit. How best to fix?
Cloud.CS50.net, mailin source forms.
OK, let's resubmit, mailin@post, 12345 12345,
check the box and submit.
OK and it's a mess.
Why is it all on one line like this?
Yes so no line break.
So no BR's.
Right? So the quick fix here
and then we'll move forward is put this there, put this there,
this there, this there and now finally if I reload, OK.
So again, sort of a refresher of what we did last week.
So now let's take things up a notch.
Because right now this program, if I actually go in here
and change things around like, if I just say mailin
or something like this or mailin@fast or mailin@post,
I don't give a valid email address,
I just submit this well nothing bad happens.
It just gets submitted to the server.
So now the server has to do all of the validation of this data.
So that might necessarily be such a bad thing,
because at the end of the day that's the safest approach.
Actually having your server defend against bogus user input,
is by far the most robust approach.
But it's kind of annoying.
Because now the user have to go back, if I'm yelled
at then I have to fix my form.
Can't we give the user more dynamic, more immediate feedback
and save them the time and the trouble of going
to a whole new page, then going back
and forth and back and forth?
Well yes, we can.
So in form2.html, we have the same form
but a little bit of magic.
For instance, if I decide eh, you don't' need to know this
about me, I am going to proceed nonetheless,
notice I immediately get yelled at.
So it's a little small here, so let me zoom in.
This is an alert window.
It says, you must provide an email address.
All right.
Well where did this come from?
Well let's take a look at the page's source in Firebug.
But again you can go to view source and see the same thing.
So open the body, open the form, oh this is interesting,
what is a new attribute on the form element here
that we didn't have a moment ago?
So on submit.
So on submit kind of self explanatory.
Because it says, on submit.
So when this form gets submitted, do the following.
Well it turns out that what should be done
when the form is submitted is the following line
of code should be executed.
It's just long so it wraps on two lines, but the line
of code is, returnvalidopenparencloseparen;.
So that's a snippet of code.
It's not php code, it is in fact JavaScript code.
So let's take a look.
This is form2.html.
So I'm just using HTML files.
I'm not bothering with php.
This is purely client side static content right now.
So let me scroll down all the way to the bottom.
Here is the same form.
So that is my form tag, my email word, password, password again.
This is sort of, this is pretty much all old school now
from last week, but the only difference is I added this
attribute here and again from last week,
web browsers don't' care about white space.
I decided ugh, this feels a little messy having it all
on one line, so I just decided stylistically to put it
on a new line and that's fine.
White space inside of tags like this is OK.
So what is this validate function?
Well let's take a look.
Well even though last week we said the only thing that belongs
in your head element is the title tag,
kind of a simplification because you can also put a script tag.
So this tag up here is kind of new.
It says, open bracket script.
It then says,
type=text/JavaScript That's just telling the browser hey,
here comes some JavaScript So JavaScript is kind
of the only language that people embed in webpages.
There are other languages.
There's VB script which is a Windows thing,
but pretty much these days people only use this tag
as follows.
This is just a bit of syntax to ward off confusion.
So long story short, there's certain characters
on the keyboard that can confuse browsers very easily.
For instance, if I wanted to say 2 less than 3,
well why is this kind of expression,
if I type this inside a webpage,
potentially confusing to a browser?
Just 2<3. What's the scary letter there?
So it's this thing right?
Because this is the special tag, this special symbol we seem
to use everywhere to tell the browser here comes a tag.
Interpret this as XHTML, not as actual text.
So for now just know that this crazy syntax here,
which is intentionally crazy because they figured
who is ever going to need to write a sentence
with these characters in it, so this thing here,
who is ever going to need to write this in a sentence.
So that's why it looks as crazy as it does.
This just means ignore the following stuff.
It is not XHTML, it's probably code or something else.
So here's my first JavaScript function.
Just like php, I say literally function,
then I give the thing a name, then parenthesis and inside
of those can be any parameters.
This time there is none.
So what am I doing?
Well this function's purpose in life is
to validate the user's input.
So I could have done any number of things but let's consider
for a second, what could go wrong.
What could the user do that might annoy me,
the person trying to trap this information?
They might do what?
Leave something blank.
So leaving their email address blank kind of useless
if the point is to register them for something.
What might they also do that's wrong?
Passwords might differ.
They might be too short,
they might be not have fancy enough characters
or more simply, they might not match.
Or third thing that we can pick on pretty easily?
They didn't check the box right?
They didn't check the box.
They need to check the box if I'm going to register them.
So can we detect these things client side?
We can server side.
And even last week recall, I used a couple of lines
of php code to say, if this thing is empty,
yell at the user.
Make them go back.
Well here we're going to give them more immediate feedback.
So here's the syntax.
It's a little long, but that's OK.
So it's I say if document document is the webpage.
It's a special global variable if you will that refers
to the webpage itself, document.
forms. Document.forms is an array essentially of all
of the forms on the webpage.
Right now there's just one so this is pretty simple.
Registration is the name of the form that I care about.
Well where does this come?
Well if you fast forward here,
actually there was one other attribute I added to the form,
which we haven't used previously.
I gave it a name.
An arbitrary name, but one that's memorable to me.
So now notice,
document.forms.registration is simply the JavaScript way
of saying, go examine that specific form.
What do you want to examine inside of it?
Well that registration form has a field called email.
Where does this come from?
Well fast forward to the bottom and notice the name I gave
to the input for email, it's just email.
So careful, the casing is important,
but I did copy it literally so we're good.
And then finally, that's just the form field.
If I want to check the value, I do .value.
So document.
forms. registration.
email. value, it's kind of like stepping through a tree from top
to bottom, deeper and deeper and deeper until you hit this value.
And I'm just saying, if it is blank,
if it equals the empty string what do it do?
Well this is exactly what I got yelled at for before.
Javascript has built in an alert function.
Looks a little different on different browsers
but at the end of the day, accomplishes the same task.
It triggers a little pop up with an OK button or the equivalent
and then just says something to the user.
But I still want to ensure that the form does not get submitted.
And so I return false here and that's important
because if you look back at the form tag,
notice I didn't just call validate,
I returned the return value of validate,
so the browser realizes oh,
if validate the function returns false,
I should not submit this form.
Like let's just short circuit the operation
and not let things pass.
Well what else am I checking for?
Well here's one thing.
If the password is blank, I catch it there.
If the first password 1 does not equal the second password,
I catch that.
If this, notice this is another property,
so if the agreement input is not true for it's checked property,
then I have to say you must agree
to our terms and conditions.
So it's all fairly straightforward.
You know, kind of along these lines so I've allowed them
to wrap but pretty simple in the end.
And finally, I return true.
None of these problems exist.
So if I go back here and I do provide an email addresses,
mailin@post.harvard.edu 12345 12345,
but oh I don't want to agree.
Submit, it still catches that, but I'm left on the same page
and notice, the url has not changed.
I'm still at form2.html, I am not at dump.php
because I've short circuited that process.
So any gotcha's?
Is there a problem with using JavaScript in this way?
What do you think?
Especially if you're among those more comfortable
or those familiar with web programming.
Can I get away with just JavaScript and skip all
that php stuff from last time?
You know what the answers
to these questions are the same right?
No. Why? Right?
So it turns out that just because you tell the browser
to do something, doesn't mean it has to do it
and a very common way of attacking
or compromising websites is to take advantage
of foolish assumptions programmers have made.
If you only validate the user's input client side or rather
if you only validate the user's input client side using
JavaScript, well what if the user you know, is mildly clever
and realizes they can go to Safari and they can go
to disable JavaScript They've essentially disabled all
of your validation completely.
So we can post on the bulletin, oh Charles, you're not doing,
oh wait, oh, my internet connection is dead there.
Let's see actually how Charles is doing.
[ laughter ]
Very nice.
OK. OK. So anyhow, this is not a menu that comes
by default with Safari.
You have to enable it.
It's very easy.
Just email [inaudible].net or I'll look it up at some point.
I forget how to do it.
But it's there now.
So this is bad.
Just using JavaScript not such a good idea and in fact,
some bad things happen.
If you disable JavaScript and try to visit any number
of popular websites, they might work,
though they might be a bit shot in the foot,
certain features might not work
or they might just not work at all.
So people have started making assumptions these days
when designing websites, if you don't have JavaScript enabled,
like to hell with you.
Like it's not worth frankly, the time trying
to implement two different versions of a website
and it's actually kind of a fun experiment.
At least if you're so inclined, to disable JavaScript
and visit your favorite websites and see which ones break.
Which ones take for granted JavaScript Now it's not all
that silly to ask this, because even though Safari
on the iPhone is actually pretty good, it is a real web browser.
Before this I had a Blackberry who's web browser sucks frankly
and they didn't support JavaScript fully, so there were
so many websites I couldn't pull
up because they just didn't work.
So though I make fun of this you know, this trade off,
it's actually a very real world concern
because who do you want to cater to?
People who have JavaScript enabled and don't even know
that you can turn it off or do you actually want to cater
to other devices that might not support JavaScript fully
or do you want to deal with the really paranoid types out there
who intentionally turn JavaScript off and hope
and expect that the world continues to function properly?
So these are the kinds of things that evolve over time.
These mentalities and these features.
So realize that validation client side,
very useful in that it's saved me some cycles.
I don't have to go reload the page and all of this,
but it can be very easily circumvented
and you can take advantage of these assumptions.
So this other tool I mentioned
and showed very briefly last week is called,
live http headers.
So when you request a webpage,
what the browser essentially sends across the wire,
across the internet, is literally something like this.
Let me go ahead and use this program.
Just to type something big.
What a browser sent, if you go
to www.let's say www.facebook.com/home.php right.
This is one of their common url's.
Well what the browser really does when you hit enter,
is it opens an internet connection, tcpip connection
to facebook.com and it sends it a request like this,
getme/home.php and use version like 1.1 of http, the language
that browsers and servers speak.
There's 1.1, there's 1.0.
That's doesn't matter so much.
So this is the message that's sent.
Well if you submit some variables to a website,
now let's consider Google.
So Google we've seen, so that was http://www.Google.com/search
and then /q=foo.
So this is something I'm searching for.
Well what gets sent then to the website is this,
/search?q=foohttp/1.1.
Well notice this.
It looks like I can submit anything I want to the server,
just by sending that message to the server.
So if I don't care to execute JavaScript
or I outright disable it, nothing is stopping me
from still sending bogus data to a website.
So let's take a look at this registration form.
So this registration form lives at form2.html and actually,
let's actually go back to the first version,
because it won't get in our way
with JavaScript I now have this tool up.
I'm going to clear it's window and now notice.
Let me move one to the side here.
I'm going to go ahead and type in, let's clear this,
I'm going to go ahead and type in mailin@post1234512345,
I'm going to check the box and click submit.
Notice this page got updated
because what this little program is doing for me,
this Firefox plugin, it's sniffing my web traffic
and it's showing me what is the browser really sending
to the server.
So at the very top is the url that was just submitted to
and as we expected, it ends in dump.php.
We knew it was going to go there.
Then there's a question mark.
So I'm at the very top middle of my screen, ?email=mailin@post,
the funky encoding is a browser's way of making
of escaping input, to make sure it's not confused
for special characters, %40 is just special character
than means the @ sign.
So no worries there, but ampersand is important.
Because ampersand separates remember,
parameters from other parameters.
So it looks like via gets, what's been requested is
that url which means if I now look at the line below,
ah that is literally what the browser is sending
to the server.
It's this thing here.
Gets/ until the mailin and all of this and notice,
all of the form elements are submitted via the url.
So what's the take away?
Well if you have for instance a website,
a banks website that's just checking people's usernames
and passwords with JavaScript and then
if they're correct they let them see
that person's account balance,
well clearly could you circumvent that either
by turning off JavaScript or just by sending data
to the server, actually I'm telling the wrong story.
I'm confusing my two stories.
You can still send anything you want to the server
and if the server just assumes
that the data has already been validated,
they're in for some trouble.
Because clearly can you send most anything you want
and in fact, even though I'm still just using a plug
in to look at this content,
I can very easily request a website.
In fact, let me do just this.
So minor aside, just to show you how simple the internet
really is.
We use SSH a lot, but there's also a program called TelNet.
So TelNet is like an unencrypted version of a browser.
I can actually do TelNet and then I can do a server's name.
Let's see, I haven't done this before, so let's just try it.
Facebook.com.
But TelNet, by default, has it's own special port, it's 23,
but I want port 80, because port 80, this is an internet thing,
is a number that uniquely identifies the service we know
as http.
Web traffic has a port number called 80,
as the cell traffic is 443, SSH which some
of you have even noticed, is what number?
22. So we've seen these kinds of numbers before,
but just taken them for granted.
I hit, enter.
Oh I am connected to www.facebook.com.
Now I have an interactive session.
So what do I want to do?
Well let me go ahead and get/home.php
and I don't know much about the language.
I'm just going to use version 1 and I'm going
to hit enter twice and OK, interesting.
It looks like Facebook has responded with this.
So this is an http thing.
If the server sends back that line,
location:, that's a redirect.
That tells the browser, go to this url.
Well I'm not a browser so I'm going
to have to do this manually.
So let me go ahead and copy and put that in my clipboard.
Now I'm going to rerun TelNet, so let's TelNet.
This time I'm, oh wait let me, I've got to fix one thing.
Come on. Quit.
Let's see that once more.
I copied too much of it.
So I just want to get /common/browser.php.
All right, so now I've copied that because that's
where it's telling me to go.
Let's rerun TelNet, get this now, http, oops, enter.
Ah, look at that, facebook.com's html.
So this is the mess that your website,
that your web browser would download and let's just try
and scroll up, right, like so Mark's really made a mess
of their website here.
So look at all this stuff.
Look, OK. Let's find something familiar.
Oh my god, OK.
[ laughter ]
But notice, so this is actually JavaScript
So this is intellectual property.
Because Facebook is pretty sophisticated
with what it does client side, all the fancy animation
and all that, but they don't really want CS50 students
or anyone out there, just copying their website,
as has actually been done in other countries.
And taking their code.
So this actually is JavaScript code
but it's been quote unquote obviewskated or compressed.
So there are ways of not turning your JavaScript into 0's
and 1's, which is a lot harder to reverse engineer,
but you change all the variables to funky names
so that it's really confusing what they represent.
You eliminate obviously almost all the white space.
There's no new lines, there's no indentation.
Now frankly, this is only a slight measure of protection.
So you can obviewskate your code in this way,
but frankly a smart person who really knows their stuff,
could certainly figure out what this code is doing.
And there's plenty of tools that will convert this back
to cleaner JavaScript,
even though it can't recover the variable names.
But this is the trade off here.
If you're sort of smart enough and adroit enough
with JavaScript to figure out what this is doing,
odds are you could reimplement Facebook in less time,
just by starting from scratch.
So it's a trade off.
It just raises the bar.
But his is another matter of security.
Ah, here we go.
Finally. So it looks
like Facebook is using XHTML 1.0 strict,
which is a certain flavor of it.
Here is the tag we've been telling you guys to use.
There's a couple more things there.
Here is the head.
There's some meta tags here
which were tags we don't care about.
Oh, here's actually today's topic.
So embedded in Facebook.com is all of this JavaScript
So long story short, what we sort of take for granted
because we're pointing and clicking all the time
with browser's these days is all very low level and all
of these details can be interesting
and can be again exploited if you know how
to send inputs to the server.
So let's see if we can't be a little more clever here.
That was form1.html, we saw form2,
let's take a look at form3.
So form3 looks like this, in source code.
This is the pretty code.
The only thing I did differently is actually I'm going
to skip back because it's not that interesting.
Let's look at 4.
I veto 3. All right, so form 4.
So the difference in form 4 is
that something just got grayed out,
even though it's a little subtle on the screen.
Yes, so this is kind of annoying.
Can't even submit.
So right, this really annoys the user.
Oh but wait a minute.
Oh I checked that box and now I can submit.
So how can you do things like this?
Well let's introduce one more little building block
and then see where we can go with this.
So this is form 4.
It turns out that this is the XHTML.
It's pretty much copy and paste as before
and notice again here I am calling return validate
on submission, but there's this other one here and it's wrapping
because my font is a little big,
but notice you can also have an event handler as it's called,
a special attribute, that actually responds not
to form submission, but to clicking.
So this says, when the user clicks this check box, go ahead
and call a function called toggle.
Well what does toggle do?
Well let's scroll back up to the top.
There's a validate function.
We're going to ignore that for now, but here's toggle.
Interesting.
So again, pretty robust, but if document.
forms. registration.
button, that's the name I gave to the check box.disabled,
so if that is true go ahead
and make it false else go ahead and make it true.
So it turns out that some form elements have properties not
just value, which we used before for validation,
they also have bullion properties like disabled.
If disabled is true, it means you cannot click
on that form field.
You cannot fill out that box because it's disabled.
So we can toggle it just
by reassigning it a different truth value, false or true.
So again, a tiny, little building block there,
but let's us create again a more robust
or more seamless interface.
So why does this then get interesting
that we can do things client side?
Well this was just form validation.
That's kind of an exercise in JavaScript syntax.
Nothing more than that.
Well it turns out we can use JavaScript
to also go fetch more information ala Google Maps.
So let's go ahead and type
in here our favorite stock quote like, GOOG and click, get quote.
And every previous lecture and example,
this form would get submitted to a php file
and present the result and I'd see the answer.
Let me go ahead and click get quote.
Oh, a pop up.
So still not all that impressive,
so let's just look at version 2.
As a little teaser here.
Now OK, price to be determined.
Now again, I'm cutting corners on aesthetics but GOOG,
let me go down here click, get quote.
And now I'm updating the page dynamically
and my url has not changed.
And it's this very basic building block
that really drives the fanciest, sexiest of websites today,
whether it's maps or whether it's Facebook
or most any other site you visit.
So more on this on Wednesday.