[ Silence ]
>> Alright everybody, welcome to out last and final walkthrough
for our PSET 8 CS50 Shuttle.
So this I would say is actually one of the hardest PSETs,
not because, you know, the program behind is difficult,
because this game is so fun that you can't stop playing it
to actually finish the PSET.
And you'll see what I mean once you actually get down to this.
So this is the music for today.
I really thought, "Oh, I'll just like play all my favorite songs
and then realize that it's been Tommy's [phonetic] choice
all semester."
So I guess that's kind of redundant.
So one more thing, if you have not join team Boden yet,
I would highly recommend doing so at store.cs50.net
and pick yourself up a Boden fever, a team Boden.
Some part of this clothing, we have t-shirts, sweatshirts,
we're expanding the team Boden line with everyday.
So today, I will be covering JavaScripts
so if I'm overly excited, that's why,
as well as the district code for this PSET
and the three things you'll need to do to implement CS50 Shuttle.
So just full disclaimer,
JavaScript is literally the best programming language ever.
As you're writing it you'll be so happy it just feels so good
to write JavaScript and if anyone ever tries you
to tell you, otherwise, they're completely wrong,
and you learn that here in CS50.
So a little bit of history because I love this so much,
so JavaScript is not Java.
So there's a really common misconception outside
of the programming world,
but people who think Java is just short for JavaScript
when really they are two completely different languages.
But back in the day when Netscape Navigator was huge,
which is a really long time ago,
it's just basically just a marketing ploy because Java was
like the hot new language and so the people
who made JavaScript are like, yeah, let's just like jump
on the Java bus and put that on the top of our language.
So Java and JavaScript really have nothing to do
with each other, just a bit of history of why we have Java
at the beginning of JavaScript,
because programmers drink coffee a lot I guess.
So last week we took a look at PHP which was also awesome
because it's PHP stands for PHP.
So this was a server side programming language, right.
So when you write a PHP file, your server is gonna find
that PHP file, execute it, and produce some output.
Then it's gonna send that output to the client
or basically the web browser,
the person who is accessing the site.
So when you access a site that's written in PHP on your laptop,
your laptop isn't actually running any PHP code.
Instead, some server on some boat data center somewhere is
actually running the code and sending it to your browser.
JavaScript on the other hand is actually running on your laptop.
So JavaScript is not going to be evaluated on this server,
but rather the server is going
to send you some JavaScript code.
And as you're viewing the page, the browser is gonna execute it
and do it whatever it is that JavaScript,
but the JavaScript is telling the browser to do it.
And so that's what we mean
when we say PHP is server side 'cause it's being executed
on the server.
JavaScript is client side, it's being executed
on our browser, make sense?
So this is not to say JavaScript cannot be executed
on the server, which it can then that's starting
to gain some ground in the tech world but we're just not going
to be doing that for the purposes of this course.
So the syntax for JavaScript, just like PHP, is very similar
to what we've seen so far.
We still have our if's or else's or for's, our while's or,
you know, all the other things we're used to.
What we don't have anymore is dollar sign in front
of our variables, woo.
And we also have strings built into the language,
so no longer dealing with pointers and mallocs.
But we do get strings just like what we had in PHP.
So again we can compare the two strings just the equals
operator, and we probably want to.
So also like in PHP, we don't need
to explicitly declare the types for our variables.
We don't need to say, "Index equals 5."
We just say, "X equals 5"
and because JavaScript is the best programming language ever,
it's gonna figure out that X is an integer.
Similarly, if our functions, we're just gonna say the word
"function" and JavaScript is awesome enough
to know what you mean by that.
So there are few different ways
that we can actually get JavaScript onto our page.
When we take look at CSS, we saw you can embed CSS.
You could link in your CSS.
We can do the same thing with JavaScript.
So with CSS, we have the style tag and inside
of the style tag that's where we could put all of our CSS.
So with JavaScript, we just have this script tag.
Inside of the script tag, we can put all of the JavaScript
that we want for our page.
Now if we don't wanna put it all in this one HTML file,
which in a lot of case we don't
because that's gonna get really unwieldy really fast.
We can put all of our JavaScript in one file.
If we just say, you know, something like file.js,
we can link in that JavaScript file by saying "script"
so that's just that same script tag.
And then the source attribute is going to point
to you wherever that file lives.
So just like in CSS, we send link href,
now we're saying script source.
Unfortunately, you can't just say script source
and then have the closing tags so you can--
that little shortcut we saw to avoid having that nscript,
you have to explicitly close that tag, have nothing
and then have a close script tag.
So it's kinda lame but that's the way it is.
So let's just take a look at some examples
of getting some JavaScript on our page.
So here's an example of HTML file.
So we all-- we've all seen this before,
just really basic skill and structure.
So you notice here I have a two script tags.
So the first of these is going to look
at some file called simple.js, it's going to live
in the same directory as this HTML file.
So simple.js just looks like this.
So this alert function is how we see those annoying pop-ups.
So you can just say pass this function some string
and the browser is gonna display a pop-up containing that string.
So here we also define a function, it's called add,
it's gonna add two variables A and B, just return their sum.
So that's all that simple JS does.
So now, inside of this other script tag,
we're just gonna declare two variables and now we're going
to use this function "add" that we declare it in simple.js.
So you notice, just like include dot-- including an .h file,
kind of copy-pasted the file into the current file.
It's a same thing with the script source.
Everything that we wrote inside of simple.js is now accessible
to us inside of this HTML file and inside
of any other java script file that we include after it.
So because we define this function "add" inside
of simple.js, we've pulled in simple.js already,
that's why we can access this function and use it.
So inside of simple.js, we just use this alert
to display message to the user
where now we're using this other function console.log.
And so this is basically a nicer form of alert
because you can pass this really anything and it's going
to output it in a really smart way,
but this is basically just going to write something
to your debug console.
So you don't have to keep clicking okay
on pop-ups every time you wanna try to figure something out.
So let's actually open this up.
So just like-- Oh, by the way,
so this is what our CS50 Shuttle will look like once--
if you haven't downloaded the code yet,
you can get really good at it if you look
at the bottom right corner and stuff like that.
Yeah, it's Mark.
So if you wanna play with the stuff implementation,
you could just go to shuttle.cs50.net
and you'll notice here
that we've implemented pretty much all of the extra features
on the PSETs, so you don't need to worry about things
like speed, time remaining, and points if you don't choose
to implement those features ultimately in your own version.
So back to JavaScript, so if I go to-- the same as before,
if I go up to 192.168 and tell the J [phonetic] Harvard
and then I just called this file simple.html.
So here we go.
So the first thing that executed was this pop-up.
Why? Well, I'd pulled in this simple.js first.
So as soon I as pulled in my JavaScript file,
it's immediately going to be executed.
So this alert didn't lie inside of some--
into main or something but because we've pulled
in this file, that line of code is being executed,
so that's why we've got immediately a pop-up before we
even see any content on the page, right,
this is still blank behind it.
So now that [inaudible] of the page just says simple.html,
so that output from the add function is going
to be located in the debug console.
So if you're using Chrome on a mac,
you can hit command option J. If not, you can install Firebug
and Firefox which should be pre-installed in the appliance,
you can acts-- look for the developer console.
Now, basically have this little thing,
we can evaluate JavaScript.
So when I say console.log and I added the numbers 5
and 10 that spit out 15.
So when I called console.log on anything, doesn't have
to be a string, I've called it on integer in this case,
it's gonna print here.
So it's really, really handy.
You can actually play
around with JavaScript inside of this console.
So if I wanna say something like var C equals 4, I can say,
what's the value of C plus 5, I can just do so
and I can basically evaluate JavaScript right here.
So I don't need to go into my file and edit it and save it
and reload the page if it's just something quick like, "Oh,
what's the syntax for doing this."
You can just try out things inside
of this developer console.
This will work on both Chrome and Firefox.
I personally recommend Chrome
but I don't think I can use CS50 to endorse that.
So, questions on basic JavaScript principles
or getting it into our page?
Alright, so let's move on.
So erasing JavaScript, we can create a number of ways.
So, one way to do so in the way that we've done
on the problem set is to use this array function.
You notice it takes one argument and it's going
to return an array of link 5 in this case.
So link whatever it is you pass in.
So now I can access this array, just like I would in any
of the programming language, I can-- well, any other,
but the ones you've seen so far, I can just say A bracket 0
and that's going to be the first element of my array.
So just like PHP, my arrays can have multiple types.
So here I've inserted an integer and then a string,
and that's totally okay.
So we also have a little bit of a short hand notation
for creating arrays, if I say something,
just var b equals open bracket close bracket,
I just created an array of size 0.
There's nothing inside of it yet.
If instead I want to create an array
and pre-initialized some element,
I can just say something like var C equals bracket 1, 2, 3, 4.
And so now I've created an array of size 4 where the indices 0
through 3 are the numbers 1 through 4.
>> So you notice in this middle line here,
I'm arbitrarily saying I want the 4th element of B--
or index 3 to be this value here.
So you'll notice that that I didn't actually give B an
explicit size but here I am trying
to access an element inside of it.
So the C program inside of you should say, "segfault."
But no JavaScript is the best program and language ever.
And once you accept that you can do things like this.
So what this will actually do is take this array, so okay,
it's now has a size of 0.
Well, this guy wants to access the 4th element, no problem,
now it has 4 elements.
The first 3 elements of this array are just undefined.
They're just null.
You know, who cares.
You haven't tried to access them yet.
But the 4th element of this array is now the value
we specified.
So really no segfault in JavaScript
because it's too smart for that.
Make sense?
I'm converting you slowly.
So just like in PHP we have associative arrays.
So these key value pairs, we have that kind
of awkward syntax for declaring them.
We had to say like, equal sign greater than, which is different
than hyphen greater than even though they're both arrows.
So we can do the same thing inside of JavaScript.
So whereas with in array, we have that shorthand notation
of saying, open bracket close bracket to create an object
or an associative array, we have this shorthand notation
of open brace close brace.
So, we could also use the function object,
with a capital O, and that would be the same thing
as this open brace close brace.
But now that I have an associative array--
well, I can say something like I wanna set this key equal
to some value where this key needs to be a string,
just like it was in PHP.
And if you want to have that shorthand initialization,
we don't need to type the word array in that weird arrow again,
we can just do something like this.
So I say var 'cause I'm creating new variable,
I'm calling this variable TF,
it's gonna be an associative array because I'm starting off
with these braces, now the first key, it has 2 keys.
The first key is called name and that's just a string.
And it also has a key called "coolness"
which is just an integer.
So this is a lot faster than typing array
in that awkward arrow.
Make sense?
So we also have-- Before that, so reiterate over an array,
we have very similar to PHP's for each,
we have the for in construction in JavaScript.
So we can say for some variable that's gonna be our iterator
inside of some array that I can do something with each element.
Now in PHP, when we said for each array as something,
that something is going
to be the actual value inside of the array.
In JavaScript, not so much, this "I" is going to be the index.
So when I run this for loop, I is gonna be 0, 1, 2 not 1, 2, 3.
So in order to actually access the ith element I need
to say array bracket I.
I can't just say I like we did in PHP.
Next, this actually makes a lot more sense, of course,
because if we could also use this for loop to iterate
over an associative array.
Now if we iterate over an associative array with this
for loop, this I is going to be 0, 1, 2, but if we iterate
over this TF, this I is going to be named coolness.
So we can access the values associated with those keys
in the same way, just TF bracket I.
Questions?
Yeah.
>> Sorry. Could you repeat how it iterates through?
>> Sure. So this I going to be--
to repeat how it iterates through, so this I is going
to be the actual indices inside of this array.
So it's basically saying for there I equal 0,
I is less than array.length I plus plus
which you can still say in JavaScript
because it's the best.
This is just a shorter way of expressing that.
So this I is going to basically be what we're used
to seeing this iterator variable as being.
This index inside of the array,
not the actual value at that index.
Other questions?
Yup.
>> How does that work for the associative one?
>> So how does this work with the associative array?
So same thing.
So if we're iterating over this TF, we're now--
this I is now going to become these 2 keys.
So first it's going to be the string name.
So if we say something like TF bracket I that's gonna be the
same as saying TF bracket in quotes name
which is gonna give us the value Tommy in this case.
Other questions?
Okay, so we actually have an even either shorter syntax
for iterating over--
for accessing the elements of an associative array.
So JavaScript actually says, well this associative arrays,
they're really just these objects.
So we first saw these objects inside of PSET 7,
we had a stock object which is basically like a C struct
and inside of those object, we have those various fields
like stock price and stock name.
So here, just like I get access the name--
the name element with TF quotes name, I can also just say TF dot
and then whatever it is that I want to access.
Yup?
>> So you just say TF dot name and you have the same thing?
>> Yes. So I could say, just TF dot name
and give the same thing.
So these 2 lines are just the 2 different ways
of accessing the keys in your associative array.
I personally think the second one is cooler.
Other questions?
Yup?
>> [Inaudible] but how do the hash thing work
with the associative array?
Where you had a hash [inaudible]?
>> Oh, so when I had a hash?
So basically, when I create an associative array,
that's basically the same as a hash table, remember.
So I just use the word hash
so we could remember how much fun we had in PSET 6.
But all we're doing is mapping some key that has to be a string
to some value which could be anything
and how JavaScript actually is doing that,
we don't really care, we can trust it because it's awesome.
Other questions?
Yup?
>> If you wanted to like-- if you add, you know, third key--
you want like-- have like TF dot like how [inaudible] something
and then could you just compare it when you [inaudible]?
>> Exactly, so could we just add in a third key?
We could. If I wanted to add an another key
that says how good looking I was in addition to how cool I was,
then I could just say TF dot good looking equals true
or something like that.
And so this is really, really powerful just
like we can have dynamically-sized arrays,
we could have the dynamically-sized
associative arrays.
We just say, well, take this key
and if this key doesn't exist yet, make it right now
and set it to the value that I want.
Other questions?
Okay, so let's just take an example--
let's just take a look at an example of this.
So if you open up array [inaudible] HTML this time
and I make sure I put all of this inside of the slides
so I'll make PDFs of the source just like PDF you get back
with your graded source code.
So in this case, we don't have any script embedded inside
of the HTML, we're just bringing
in a single JavaScript file called arrays.js.
So if we open that up-- so here we go.
So now we're declaring 3 associative arrays.
So you'll notice that all 3
of these arrays have a key called name
and in every case this name is just a string
and they also have a key for grade.
And so this grade is actually not just a value
but it's a function.
So if I say I want grade to be some function
and this function doesn't take any inputs,
all it does is return 5 because I'm the best TF ever
and I give it all 5s.
So now if we have another TF, again,
we have the same 2 keys name and grade
but this time we've defined grade a little bit differently.
So if we scroll over here, you'll notice
that Joseph is the worse TF ever
and just assigns completely random grades
to all of his students.
So if I say in JavaScript math.random, that's going
to return a random number between 0 and 1.
So if I multiply that by 6 I'd effectively have a random number
between 0 and 6.
And so this math.floor is just like [inaudible],
just says truncate all the decimal places
and convert this decimal to an integer.
And so now this is just going to return a random number between 0
and 6 every time it's run.
So now with each of these associative arrays,
I can create an array of associative arrays.
So here I have some array called TFs
and I'm using this shorthand syntax to create it,
so I say open bracket and then just a list of these 3 objects.
So now TFs has a list--
is a list of length 3 and that could iterate
over it now just with my for loops.
So I say for there I inside of TFs.
So for every TF, what I wanna do is I wanna print out their name
and then in PHP, we needed to use dots to concatenate strings,
and we all thought that was kind of dumb so JavaScript fix that
and decided to use plus because adding 2 strings is basically
the same as combining them.
So I can add these strings together,
so I'm gonna output the TF's name then just the colon
and then I'm going to output what their grade is.
Make sense?
Yup?
>> Okay, console.log that brings to the terminal index?
>> Yeah, so console.log is going to print
to the developer console
or whatever it is your browser decided to call it.
So if I'm in Chrome and I go up to the little wrench in the top,
I click that and I go down to tools
and that's gonna give me this menu
and I can see this JavaScript console.
So if I click that, that's gonna pull
up this thing here at the bottom.
And so I can do some other cool stuff like look
at the HTML inside of my page or look at all the things
that are being downloaded, but what we're concerned
about with console.log is this thing down here.
So that console.log printed out that 15 'cause it just printed
out the result of adding 5 and 10
and so there is the 15 from the console.log.
>> I have another question.
>> Oh sure.
>> Going back to the JavaScript file.
>> Yup.
>> So [inaudible] iterate and I know that each one is
like a different function, so it's not exactly [inaudible]
but it seems that like we would
like to have a kinda of type job things.
So it could be like Tommy just [inaudible] that's being
like an instantiation look like this object thing
that like you wanna be using [inaudible],
is there like that thing [inaudible]?
>> So you're kind of getting just the idea
of object-oriented programming, right.
What if we just created some definition that said, "Well,
if you're going to be a TF, then you need
to have a name and a grade."
So there is a way of doing that in JavaScript,
we're just not gonna get into that really,
just the shorthand way of doing that as well when I create them
since I'm a really good programmer,
I'm just gonna make sure they all have a name and a grade.
>> And if not, then you're just gonna get some error
that you can catch if that function doesn't exist inside
of this variable.
But we don't really need to get
in to object-oriented programming
for these purposes of this class.
To do that, we basically need to do this
in JavaScript essentially.
>> But when you say object-oriented,
you mean like we type that stuff that we were doing
on the other-- I mean it seem like we're defining structure
on the previous problem set as well?
>> Exactly.
So in the previous problem sets, so--
we just don't really get into the topic too much in CS50
but we certainly will in CS51 and other courses down the road.
But this idea of saying, "Well, there's gonna be some structure
and every instantiation of that structure needs
to have the same thing.
This is just a loser way of doing that.
We don't need to have some definition
of Tommy before we can create Tommy.
That's just a fun little property of JavaScript.
It's much more flexible in that sense.
Other questions?
Okay, so that is arrays and associative arrays.
So one more thing that we'll get right on to on this PSET likely,
scope in JavaScript is a little bit different
than other languages.
And of course at this point,
you'll find that I think it's better.
So inside of [inaudible] PHP, when we created loops
and conditions and functions,
all of these 3 things limited the scope of variables, right.
You can see I said for int I equal 0,
that I could not be accessible anywhere outside
of that for loop.
If we wanted it to be accessible outside of that
for loop then we have to declare it outside.
In JavaScript, not so much.
The only thing that can limit the scope
of a variable is a function.
So you'll notice that throughout my examples I've been using this
keyword var.
And so what this keyword var does if it's going to say,
"I want this variable to be local.
I want you to limit the scope of this variable
to my current function."
Now if I don't have this var keyword,
any variable I create is going to be by default global.
So if I just say inside of my JavaScript X equals 5
and X doesn't exist yet,
I've just created a global variable called X.
If instead I just want that variable to be local
to my current function, I would need to say var X equals 5.
Make sense?
Yup.
>> What if you declare var like before you start an option?
If there was like [inaudible].
>> So if I use var before I get into any functions?
So because I'm limited to the scope of my current function
and I'm not really in the function yet,
then I effectively just create a global variable.
So if I'm outside of any function,
and I say var A equals 5, or A equals 5,
that's gonna be the same thing.
Because if that don't exist within a function,
then you can't really be limited to the scope of any function.
Other questions?
Okay, so let's just look at a quick scope example here,
so you see what I mean.
So again, scope.html, is just going
to just include a single JavaScript file,
we're used to that now.
So now scope.js, so these first 2 lines do exactly that.
So we're creating 2 global variables here.
So the first is called global 1
and even though I've used the keyword var I don't exist inside
of function yet.
So this is the global variable
and the second case I have not used the var keyword,
so I'm also global variable.
So now inside of my function here,
I'm creating a local variable saying it's equal to 0,
and now I can access this global variable
without doing anything special.
And if this is a global variable,
if I wanna increment it I can and I can also read its value
in addition to changing it.
So I can just say console.log global 1.
So now I have some for loop and inside of this
for loop I'm creating a what would be local variable
in some other languages.
This A you might think only exists within this for loop
and then we're accessing this local variable again.
But if afterwards I can log both I and j, both of these are going
to be the actual values.
For A I'm gonna get 3, and for I I'm going to get 5
and the same thing with local, I'm also going to get 5.
And so now I'm just gonna actually call this function
and then afterwards, that's it.
So if I actually run this file--
[ Noise ]
>> So here we go.
So these last 2, so these both say 5,
the last 2 things I printed are 5 and if we go back,
the last 2 things I printed were both I and local.
Make sense?
So a little bit tricky and it's a little bit counterintuitive
since we're not really used to that yet.
But just remember that scope is gonna be limited
to the current function not necessarily the current loop.
Okay, so any last questions on JavaScript?
So again, we're gonna go over this much more in detail
in lectures and in sections but this is just kind
of the JavaScript primer that you'll need to complete all
of the elements of the PSET.
So now let's take a look at the distribution code.
And to the first glance there's a little-- there's a lot of it.
So first we have to file buildings and houses.
And so these 2 JavaScript files essentially just define arrays
that are containing objects that are on the map.
So we have houses which are destinations for passengers
and then we just have buildings which are
where passengers could be for you to pick them up.
So let's take a look at those first
because they're definitely the simplest.
So let's just close all these, so we have more room.
Alright, so I'm gonna open up inside of my public HTML,
I already ran, get clone, and got PSET 8,
and so now let's first take a look at buildings.
So here, we see their buildings, so we're using the var keyword
but again we're not inside of any function,
so this is effectively a global variable
and now we're using the shorthand notation.
So because I've used the open bracket,
that means that building is an array.
So now what is each element of this array?
Well it's an object or an associative array
because I'm using these curly braces.
So to start this curly brace, just says,
I'm starting a brand new associative array right here.
And so now here are our key value pairs.
In this case we're always map--
in the first case we have 3 keys mapping to strings,
and then we have 2 more keys that are mapping to decimals.
So again, not everything inside of your associative array needs
to have the same type.
And so now, we've just created some big long list of all
of the buildings inside Harvard square
and I really hope David didn't have to type all of these
out 'cause that's kinda sad.
So that's buildings and if we open up houses,
we have something really, really similar
and this is perhaps more useful.
So in this case, buildings was an array, right,
because the first thing was this square bracket, right.
If we go back up, we saw var buildings equal square bracket.
Houses on the other hand is not an array,
it's in an associative array.
Why? Because we see var houses equals not open bracket
but open brace.
And so this is effectively our hash table.
So that means that every [inaudible] on the left needs
to be some key inside of our hash table and now the value
of each of these elements of our hash table is another object
or another hash table.
So now this object or associative array,
whatever you wanna call it,
in this case they call have the same 2 elements.
We have a LAT for latitude and LNG for longitude.
So now you'll notice here that over in the left,
we've actually put quotes around all of keys, while over here
on the right, we don't.
So these quotes are actually optional
if your key is only one word, right.
And I could have said quote LAT quote LNG
and that would have been fine.
But the reason we need quotes in this case is because something
like winter house is 2 words.
And so we basically just run it to a syntax error
if we didn't have those quotes for that string.
So if you wanna type the quotes, when you're defining any key
in your array that's fine.
If you want to omit them, make sure you don't have any keys
that are multiple words or else you're gonna ran
into some problems.
Make sense?
Alright, so next is passengers.js.
So this is also pretty similar.
So let's open this up.
So now instead of buildings, we now have passengers which again,
we now know that this is an array because it starts off
with a square bracket and each element of the array is going
to be an associative array.
And so here we just have an array of all
of our staff members including people like Al Gore
or Bill Gates who clearly work for CS50.
And if they didn't, they wish they would.
So that's passengers.
So next is math 3D.js.
So let's open that up and this looks scary
so that's the end of that.
Next down the list is shuttle.j-- I'm not kidding.
I'm really not good at math.
So next if we open up shuttle.js,
you can just trust me that everything
in math 3D works very well.
So now we're getting into some more interesting things.
So here we just have some more global variables
and these are basically the starting state of the shuttle,
so where we are, and we happen to be
at university hall facing it.
And so we actually calculated it to that many decimal places
because you want to be really sure you're looking
at university hall.
So next, we have the number of seats inside of the shuttle,
you notice that this is some constant, right.
At no point in our game can we add a seat to the shuttle
or remove one or at no point can we buy a really cool luxury
shuttle with tables, that will be next year's version.
I love luxury.
So anyway, so now, we're just loading in some plug-ins
like the Google Earth plug in that we're using for this PSET,
so that's just gonna load all of that from Google.
And so now we're gonna jump into some functions
that you all need to be working with.
So the first of these is chart.
And so this function is going to be what's responsible
for drawing the seating chart on the right
of the shuttle interface.
So if we just go back to-- so J Harvard PSET 8 [inaudible].
>> Woo-ho!
So once this loads over here to the right,
we have our seating chart and this is drawn
by this function called chart.
So right now we don't have anywhere
in our shuttle 'cause you haven't picked anyone up yet.
So if I scroll through this list, everything is just empty.
And we have a list of 0 to 34
because we're computer scientists and 0 index things,
so next is drop off which is clearly I already done for you,
this is going to be what's responsible
for dropping passengers off at their locations.
Next is just some function,
if there is some error while we created Google Earth, well,
it just let the user know there is an error,
hopefully this never happens.
So this where it ends,
so basically whenever the user does something
that changes the position of the shuttle,
we need to constantly refresh what the screen looks like.
And so this just says, "Well,
we need to be constantly refreshing the position
of the shuttle."
And so we need to find this update function inside
of shuttle.js which we'll look at next.
So in it is the [inaudible]--
is kind of like our int main in this case.
This is what's going to be fired when the program first starts.
So once Google Earth is all loaded up and we can use it,
then we're going to fire this init CB, where the CB stands
for call back or some function that's going to be called
by something when it's done.
So Google Earth says, well once I'm done I could execute some
function that you give me.
And so in this case we're giving it init CB so that
when Google Earth is done, then Google Earth is going
to call this function
for us that's gonna set everything up first.
So here we're just creating a new shuttle,
putting everything down.
Now, we're calling this function populate.
So before populate, this function keystroke,
so this is very similar to getch or these game loops
that we saw in PSETs 4 and 5.
This is basically what's going to handle input.
So every time the user hit something on their keyboard,
this function keystroke is going to fire.
And so, we can get the key
that the user typed using this event dot key code.
And unfortunately these key codes aren't strictly mapped
to ASCII values because, you know, we can run out--
we run into things like the left and the right arrow
that aren't really defined by ASCII.
And so we have instead these numerical key codes.
And so we've commented what each of these key codes is
so that looking at 40 you don't have--
you're not completely lost as to what 40 is.
So with some features that require, you know,
implementing some additional feature, you might wanna look
into keystroke regarding how it is
that we handle input from the user.
So things like letters, you'll notice are indeed mapped
to their ASCII values 'cause we have an A of 65
and a lowercase a of 97, but we also have some additional ones.
So that's keystroke, although we don't really need to worry
about we're just kind of doing some things with Google Earth,
we're loading it up, you notice here we're passing this init
call back.
So we say, "Well, Goolge once you've created your instance
of an earth, I want you to fire this init CB.
And if you run into any error that I want you
to run this failure CB or this failure call back
that will just tell the user, yeah, something went wrong."
So next is pick up, and so this is the other main half
of the problem set you need to implement.
So once we drive through a passenger, we want to add them
to the shuttle if we can, and finally, populate.
So this is a function that randomly distributes all
of the staff members or all the passengers on the map.
And so we basically gonna say,
every staff member is gonna be assigned to a random building.
So we're saying, first we're gonna drop
down the houses [inaudible].
First you're gonna drop down the houses and then
for each passenger, we're gonna assign them to random building.
And so this is the same construction that we saw before
when Joseph was trying to grade PSETs.
We have mapped out random, it's gonna return a random
between 0 and 1, 0 and 1.
We can multiply that by the length of an array
which by we just have an array and we say dot length,
that's going to give us the number
of elements inside of the array.
So no longer do we have to pass around the length of an array
like we did in C. And so now we're just--
this is how we can access a random element inside
of buildings, making sure it never go over the bounds.
So after that, we're just doing some Google Earth API kind
of things, we're just creating both a picture on the 3D world
and then a little marker in the bottom right
to the map setting that all up.
And so now here is your first minor task, you know,
remembering where each passenger is so that you can pick them up.
And so finally, just some other necessary functions
for unloading everything from memory,
some things you don't really need to worry about.
So the last file in our [inaudible] code is going
to be service.js-- shuttle.js.
So let's open up shuttle.
And so while service implements things like driving around
and picking up passengers, shuttle is going to what the--
what represents the state of our shuttle at any given time.
And so here is just some variables inside of the shuttle
that we'll be using in order to handle things
like moving the camera around, but the function
that we really care about inside of shuttle is this distance.
And so there's a question
about how do we kind create this definition of classes.
Well, this is how we're doing so.
This is how to do so in JavaScript.
We can say that there exist some class called shuttle
and if there's going to exist some shuttle, then there needs
to be something called distance.
And here's where we're defining this distance method
of the shuttle.
And it looks, again, really complicated.
But what this does is it's going to calculate the distance
from the current position of the shuttle
because there can only be one shuttle at a time,
we're gonna calculate distance from out current point
to some arbitrary latitude and longitude.
And so this is going to return the distance
from your current point to that point that you give it.
So it's just gonna return a single number.
So feel free to parse through the rest of this file and most
of it is just things like moving the camera
and actually implementing how the shuttle is actually moving
around, pretty interesting if you wanna look at it
in your abundant free time.
Any questions on the distribution code?
Yup.
[ Inaudible Remark ]
>> So that shuttle dot prototype?
[ Inaudible Remark ]
>> Yeah, so this is JavaScript's interesting syntax
for creating objects.
So this just says that there is some-- this class called shuttle
and I can create multiple shuttles in my game,
but I really just want to have one shuttle right now.
So each of these shuttles in order for a shuttle to exist,
it needs to have this function update.
And so on any-- with any shuttle that I create,
I know that that shuttle has to have an update function.
Well before we created these objects for each TF,
now when we created those TF objects, we basically said,
"Well, you can have a name and a grade,
but I could very feasibly create a TF that doesn't have a name
and a grade function."
When I was creating them I just made sure
to give them each a name and a grade.
Wherein this case if we use this shuttle,
so what it is I'm creating,
this dot prototype is a really cool JavaScript thing
that you can Google on your free time 'cause that'd be another
hour to explain.
And then the last part is just what the function actually is.
So anytime I actually create a shuttle it has a function
called update.
So this is just the JavaScript syntax for doing--
for creating what we would have seen as just class stock in PHP,
this is just the JavaScript syntax.
Other questions on the district code?
Yes?
>> [Inaudible] you said there is something called [inaudible]
seats, does that in the [inaudible] code?
>> Sure. So we saw seats as a constant.
I wanna say in service.
Yeah, so this constant seats is the number of seats
in the shuttle and inside of shuttle, we have--
[ Noise ]
>> So inside of shuttle, we have an array of seats.
So the capital seats is the number
of seats inside of this array.
And inside of shuttle,
every shuttle we create has an array associated with it
and you'll notice here
that because we're creating some array here,
this array always has the same size.
And that size is equal to that capital seats,
'cause for each seat, we're just creating a blank seat.
This null just says there's nobody in that seat right now.
Other questions on the [inaudible]?
Okay, so let's jump in to what you actually need to do
for this PSET and you'll find that it's really not
that bad and quite fun.
So first we saw this function populate.
And so things like randomly distributing people
and putting people in buildings and assigning them to houses,
that's already done for us.
What we need to do is we need
to remember the location of each passenger.
Because as we're driving around if we don't remember
where each passenger is placed randomly, there's no way
of being able to pick them up.
Because once you pick them up, we need to determine if we're
in range of them, if they can actually get to the shuttle.
So what we need to do
with populate is somehow add each passenger that was created
on the board to an array where we keep track
of the passenger's positions.
So again, we saw how to do this with arrays,
JavaScript arrays are really cool.
And so we probably don't wanna just keep track of something
like the passenger's name 'cause that's not particularly helpful.
We need to keep track of their name and also where they are
on the map because that where they are in the map,
I mean the place marking marker that's going
to define the latitude and longitude
that they're placed at.
So you also need to remember where they're going,
basically as much information as you need,
needs to be remembered somehow inside of an array.
So what you probably wanna do is create some associative array
that defines things like name and house and add each
of these associative arrays to some other array you creat
that has-- we know it's gonna have size equal
to the number of total people.
So this is-- again, this is just a reminder
of the syntax for doing that.
>> If you want to create a new object
on the fly we can just say, "Well, O,
it's gonna be key value and they can also have, remember,
objects of objects because things like markers
and place mark are already objects but that's okay."
Because if I just say-- if I have some object O
and just putting it into an array,
it's not even associative array that's associated
with they key something.
So creating arrays of arrays of arrays of objects
or whatever is no problem.
So any questions on how we're going
to remember the location of each passenger?
So just inside of service.js at the bottom of populate,
we kind of already tell where it is you need to put all
of your code for this.
So if we scroll down to populate,
we have [inaudible] just to do.
Remember, each passenger's place mark and marker.
And so here is right where you want to put it inside
of some array or some way of remembering
where each passenger is.
Make sense?
Alright, so our next function that we need
to actually implement, it's a little bit more work
than populate is going to be pick up.
So the goal of this function is
to actually add people to the shuttle.
So as you're driving around, you're eventually going to come
into range of some person.
We've say, "Well, if you're at 15 meters away from this person,
then that's close enough for them to jump in the shuttle."
So when we add someone to the shuttle,
we need to do a few things.
We first need to add them to that seats array
so that they show up on the right-hand side
and we remember who's inside of our shuttle.
We also need to remove them from the map, right after we go pick
up David, we don't to be able to pick up David again.
We wanna remove them not only from this 3D world but also
from that little 2D representation
at the bottom right because both of those--
those 2 states should be the same at any time.
So here's how to do for this.
So as you're driving around and someone clicks that pick
up button, the first thing you wanna do is detect if we're
in range of any of the passengers.
After that, then we need to add them to the shuttle if we can
and then remove their spot from the 3D world
and remove their spot from the 2D world.
So as we saw, we have this handy function shuttle.distance that's
going to calculate this distance for us.
So we can just give it some arbitrary latitude and longitude
and it will tell us how far away we are
from that latitude and longitude.
So since we remember where each passenger is inside of populate,
we just need to check if we are near any passenger
or any possible passenger not who's already in the shuttle,
of course, but any possible passenger every time we click
pick up.
So the basic approach here is to say, okay, I have this long list
of passengers, I need to go through anyone.
And anyone that's inside-- that's--
I'm within 15 meters of, then I want add them to the shuttle.
But remember, we only have 35 seats.
So if your shuttle is already full and you drive to someone
to pick them up, you don't wanna be able
to add them to the shuttle.
So now how do we know where each passenger is?
Well, they all have an associated place mark
because remember we needed to remember that place mark thing.
So from the place mark,
if you look at that Google API documentation page
which you'll probably need to do to complete this PSET,
you can see that each of these objects has a bunch
of functions associated with it.
So in order from a place mark to determine
where the place mark is on the page,
I can just call this get geometry function.
And so this get geometry is gonna give me back an object
through an associative array where I can basically ask that,
well, what's the latitude and what's the longitude in order
to get back the numerical representations
of that position?
So I highly recommend checking out those links.
We listed throughout the spec of the PSET that link
to code dot Google.com or something that list
out all the functions associated with Google Map's API.
Combined with that and the functions that we've given you,
there's a very high probability that a function already exits
for what you're trying to do.
So if you're thinking to yourself, well,
this sounds really complicated
to write some helper function that's gonna take forever,
take a look at those links and make sure you're not trying
to do something that's already done for you.
So that's how we're going to detect if we're in a range.
So now we actually need to add them to the shuttle.
So remember that we can only add them
if our shuttle.seats has room.
And so we know that our shuttle.seats has room not
by its size because it's always going to be 35,
but if there are any empty spaces left.
So remember when we first initialize shuttle.seats,
we set every element to be null.
And so that's how we're representing an empty seat.
If it's null, that's means there's nobody there.
So once we detect who we're in range of, we can have some list
of TFs, we need to try to add each
of those TFs to the shuttle.
So to that we can basically through out seats
and if we find some null inside of our seats,
then we can put the TF there and then they're added and we need
to remove them from the world.
But if we don't find a null or a spot for that TF,
then we don't wanna add them and we don't want
to remove them from the world.
So just remember that just because you're in range,
you may be in range of multiple TFs at the same time,
so your pick up function shouldn't just add
that first one.
So if I click pick up and I'm by 5 TFs, I should get all 5.
I shouldn't have to click pick up 5 times.
So that's an important distinction.
So now we need to display each passenger.
So if we go back to this chart function, that looks so done
for us, it's unfortunately not
because if I can remember the alphabet,
we're actually just printing out.
If we picked up some person we're just saying, "To do."
So here we actually need to print out some information
like their name or maybe where they're going
or this can change based on what extra feature you're choosing
to implement.
But we need to replace this "to do" that's very innocuous
with the actual--
with information regarding who's sitting in that seat.
So any questions on getting people inside
of the shuttle yet?
Okay, so now once they're inside of the shuttle,
we need to change the world.
So we can't pick up the same person multiple times.
So this is given to in the PSET spec, how to deal with this.
But in order to remove a place mark from the map, we just need
to say, okay, so from the Earth, I wanna get all
of the place marks that are here.
And now given this current place mark which I know
because I remember that each place mark associated
with each passenger, I can just say remove child.
And that's going to remove the place mark from the 3D world.
So this is the function again defined by Google for you.
And these-- these 2 snippets are given in the spec for you.
So removing a marker is just as easily-- it's just as easy.
So if we have some marker, M, that we remembered
in our passenger's array and we've got back a marker,
we can remove the marker by just saying m.set map null.
We're saying that there is no more map associate with map--
with this marker or before the map associated
with marker was the one in the bottom right.
So if we say there is no more maker associated here,
then the marker is just not gonna show
up on the map anymore.
Questions about modifying the world
and for the PSET on general?
Question?
>> Your-- the distance, I don't have to recalculate it,
there was the distance function within shuttle?
>> Yes. So there is a function inside of shuttle that's going
to calculate the distance from your position of your shuttle
which is kept track for you automatically.
So we know where the shuttle is to some arbitrary point.
Whereas on the case of picking up, we wanna look,
are we close to Tommy?
Are we close to some other TF?
And all the TFs that we're close enough to,
then we wanna pick them up.
Make sense?
>> So like if the distance function the latitude
and longitude [inaudible] an array
and if [inaudible] their distance remain close
as opposed to--
>> Exactly.
So you're gonna give this function the latitude
and longitude of a point.
You're gonna get back the distance
as a single scaler to that point.
Other questions?
Scalers are mathy word.
I'm surprised I just said that.
So the other function we need to implement
for this PSET is going to be drop off.
So again, kinda self-explanatory,
pick up brought TFs into the shuttle.
When we drop off TFs-- when we drive to the house
that they're trying to get to,
we need to remove them from the shuttle.
And so this is a little bit easier
because their place marks are already gone, we don't need
to like add a marker to the house or anything.
All we need to do is take them out of the shuttle.
So again, every time someone clicks drop off, we need to see
if we're near any of the houses.
So there might be some corner case actually where you can be
like between [inaudible] and like close enough to the 2
of them, I don't know.
So do make sure that you handle that corner case
which may or may not exist.
But basically it's gonna be the same deal as pick up.
We need to say, look at all of the houses
and am I near one of them?
And you can get where the houses are based on this houses array
because each element of the houses array has a latitude
and a longitude and we can again calculate via shuttle.distance.
Are we close enough to this house in order
to drop off passengers going to that house?
So in order to remember--
or in order to know where passengers are going,
we do need to keep track of their destination,
which again is just going to be defined inside
of that array that we hand you.
So now, we need to actually drop passengers off.
So again, shuttle.distance will calculate distance.
Now to remove the passenger, you want to set that element
in the array to null because we're using nulls
to represent an empty seat.
So if you say passenger 6 he needs to get off here,
then you need to just go onto array or go in to shuttle.seats
where you're saying who is currently in your shuttle
and we can remove someone from the shuttle by saying okay,
well, that person is now null.
So while we could technically, and this is kind
of what we did last year,
you could have the seat array be dynamic and say that, well,
if you remove someone, then they're physical gone
from the array, and our array went from size 10 to 5
when we just dropped off 5 people.
>> We wouldn't really recommend doing that because functions
like chart are going to assume a fixed size of the array
and it's also a little bit harder to do that.
So for this piece I'm recommending you just say,
if person 5 needs to get off, just set seats 5 equal to null.
And so that's how we're going to remove them.
And so doing so will also create an empty seat.
So if you have a full shuttle and drop people off,
you should be able to drive
around to a new person and pick them up.
Any questions there?
Alright, so finally, just some extra features, here are a few
of them, you can do things like implement points for picking
up passengers, implement a timer, things like that.
And we also have the condition, you could make your own feature,
if you think something is really cool
and you wanna make your own feature, your addition
that we haven't listed just know your TF before you do
so to get approval to make sure it's not too simple
or too complicated.
If you wanna implement multiplayer shuttles like we had
at the fair that's probably a little too complicated for this.
But definitely if you think you could do something cool
which we recommend, think of something cool, you know,
just email your TF and get approval
and you can do that for this PSET.
So any questions on PSET 8?
Yup?
>> Actually going back to houses [inaudible] is do we assume
that there is already array of [inaudible] or--
>> Yes.
[ Inaudible Remark ]
>> So there already exists, some array of houses
and it's defined inside of houses.js.
So this is just capital house and remember
that this is an associative array
because this starts with a brace.
And so we can access the location of Adam's house
by saying houses bracket quotes Adam's house.
And that'll spit back an object
where you could say dot LAT or dot LNG.
Yup?
>> We're [inaudible] your directly wanna access
like latitude of a certain house,
so like houses.adam's house [inaudible]?
>> Right. So we can't-- So if we wanted
to just access this directly, so we can't say
in this case dot Adam's house only because this is 2 words.
So we need to say something like-- so we could say houses,
Adam's house.lat, right.
So this-- and once we say Adam's-- quotes--
houses quotes Adam's house, this is going
to give us back some object, so this effectively evaluates
to an associative array and now that we have
that associative array, we can say dot lat to get
at the latitude element of that array.
So I can also say if I didn't wanna say do
and be consistent I could also say-- not dot-- quotes LAT.
And so that would be the same thing.
Yup?
[ Inaudible Remark ]
>> Right. And so that's a good question.
So how is this different?
And so you notice that in the houses we started
with the curly brace but now we're starting
with the square bracket.
So if I wanted to get Alex, I would end up saying, pass--
I can't I-- passengers.
And so now this is going to be a number
because this is just a numerically indexed array 'cause
it starts with the square bracket.
And now I could say something like dot name
or I could say inside of quotes name.
Make sense?
So generally, when we're iterating through this,
if we have this inside of a for int then our--
or whatever variable we're using
to iterate is gonna wanna go there not inside
of the second one.
Other questions?
Yup?
>> And [inaudible] through the houses array, is there--
by the way we're [inaudible] particular distance
through the house, is there a more efficient way of doing it
than just looking with the for house [inaudible] houses loop
and then saying distance of this house to the bus?
>> So is there a more efficient way
of calculating a distance to a house?
So not really, because we don't really know immediately
where our shuttle is relative to every single house,
so we need to check, are we near Adam's, are we near [inaudible]?
I mean you could probably implement some heuristic that's
like, well, if you're latitude is less than this,
then you're not at the quad
because it's-- at the North Pole.
But we don't really need to do that.
Effectively, yeah [inaudible].
So effectively, we just need to go through each of these houses
and calculate the distance of it.
That wouldn't be-- that's too inefficient
because calculating distance is quick and there aren't
that many houses or passengers really.
Other questions?
Alright, well if not, then good luck on PSET 8.
These were the walkthroughs.
Thank you very much for allowing me to teach them
and I really hope you find them helpful.
And that's it for this semester.
[ Applause ]