all right hello world this is cs50 on
twitch my name is Colton Ogden and this
is the third code review we've done with
David and Brian Brian this is Brian's
second time being on our code review
yeah it was a good time last time we
covered a lot of different languages and
this time we'll be doing the Google form
and we picked out a few samples to look
at today David even dressed up just for
the secure I did a very formal code
reviews I'm taking this one very
seriously thanks to a hacker Becker for
following just before the stream we have
a lot of people in the chat I say we
just cut straight to the first demo that
we're gonna look at today which is
actually a really nice one so let me go
ahead and bring it over to clear strike
by Sam Martha gr yeah so what do we have
here calls them so when I was looking at
this it looked like a COI
version of a game that's very popular in
South Asia called Karrimor Khurram I'm
not entirely sure how it's pronounced
but it's very similar and actually have
it on Wikipedia there on the second tab
if you want to pull that over so there's
a picture of the board and folks might
be able to see it underneath the chat
with varying ease yeah sure should we
enhance yeah let's enhance a little too
much enhancement there we go
so it's it's very similar to and I
haven't played this myself or look too
deeply into it but it's a version of
pool essentially with what look like
checker pieces where there's a sort of a
cue piece that you get knock in at the
very end of the Queen piece so to speak
and the app that we'll be looking at is
sort of a COI
version of this there's kind of an
interesting implementation nice well
yeah if you've played this game in the
real world do feel free to chime in
especially to correct anything
assumptions we're making fortunately
we'll focus on the code itself and
indeed yet in response to one of the
questions that was just asked here by I
lost track I have the code so we have it
up there
yeah yeah can we make that a little
bigger oh that one's mine that one's
mine so yes this the kind of code review
that we've been doing in these streams
would be akin to what you might do with
a colleague or manager and
real-world that accompany often these
good reviews that would be done
asynchronously so by a github or some
similar web basically doing things in
person is not uncommon as well yeah why
should we dive in yeah it sounds good
let's take a look all right so the
repository that some are code and I'm
seeing a whole bunch of files here just
under ten or so files and folders how
would you grow and go about wrapping
your mind around what to do if you've
never seen a project before and you want
to start reviewing it to give someone
helpful feedback all right well the
first file that sort of catches my eye
is main dump I often main act as an
entry point for a program so it seems
like a reasonably place to start looking
ok trying to figure out is works alright
and how would you approach reading the
file for the very first time that's not
part of an assignment but indeed as a
whole project so first thing and
probably take a look at is it looks like
there are a couple of functions that are
defined here so I might just glance
through the file get a sense for the
functions we have a function called load
turns here a function called main right
now them I'm guessing it's probably
where the game is going to begin main
tends to be a common first function that
gets called in the program we can keep
scrolling down this file trying to
execute this is the code run and it
looks like and then it actually calls
them so this actually it does seem like
it's perhaps a little bit less
conventional to be putting a lot of
logic and they underscore underscore
name the equals main and then run
through a whole bunch of logic and then
call the main function it seems like a
lot of this information about
initializing the parser checking the
arguments loading the inputs based on
these comments I do like the commenting
it helps to make it clear as to what
things going what sections but I would
say that probably all of this could just
go inside of the main
or even go to separate functions inside
of the main function doesn't seem to me
there's much of a reason to separate the
main function functionality from indeed
and to be clear let me go ahead and
temporarily pretend to edit this file
even though we won't be able to save the
changes since it's not actually ours if
I go and scroll down here what Brian is
alluding to is a very common paradigm
that you actually see in a few of cs50
zone examples whereby you don't actually
put much code at all in this block let
me just temporarily delete that you
would instead just quite simply call the
main function so for those unfamiliar
like why is there this paradigm because
I daresay in an introductory course like
cs50 this is just attrocious syntax I
think when someone is problem does this
actually solve yeah so one thing that
distinguishes Python from a language
like C is that when you execute a C
program the main function is a function
that has some it's a special function
that when you exit the program the
compiler knows that the function is the
first and so this line down here is
supposed to say all right when you run
the function we actually want to run the
main function if the first thing that
happens in the file and the extra syntax
of a is underscore underscore name
equals underscore underscore main is to
account for different ways in which we
might use a file in Python so we could
just try and run a file by running
Python main dot Pi in this case where we
want to run the main function you could
imagine if there are variables or
functions defined in a file that we want
to use in some other bot
we don't want to actually run the main
function we probably just want to import
it for example yeah and for the
interruption looks like some people were
saying the sound is low just want to
confirm that that's indeed the case some
people are saying that it got fixed
Brian would you mind saying a few words
hey tested and then David case a few
things testing testing and then one two
three so let us know sound is going from
loud to low intermittent Lisa's
methodology yes still happening it looks
like thanks to Kaiser twitch yeah well
we have somebody is currently working on
it so apologies for the sound issue
hopefully we'll get that fixed and then
adamantine sings sound is good right now
voi thank you very much for the follow
here folks anybody who has any issues
with the sound definitely us know so we
can see if it's maybe localized or
whether it's still going or what the
issue might be perhaps so far so good
alright so just to be clear in most
cases what we could even do if you do
want to have a main function it's just
literally in the last line of your code
just call main itself thereby kicking
off the whole process of running this
file the additional presence of this
condition here that Brian is describing
really only solves a problem for more
sophisticated programs where you indeed
might want to import them if you're
making a library or a Python package or
module of your own but if it helps to
keep things in mind more simply for now
just do this at the end of the file but
I definitely concur with Brian's
assessment that probably shouldn't have
as much logic as was in here that's the
whole point of having main is move this
into the main function I don't know if
you if you brought this up already but
having that if name equals main great
for a test cases do you mention that
already no I don't think we can I mean
but test cases like having if you were
to have the test for a module within a
module so you can run it and test its
correctness you could have all of those
test cases be within main within that
module and then run them that way in the
file yeah and the function within if you
were to test this module and have a set
of test cases that for example I say oh
this came with a bunch of functions you
could import it in some as some library
or you want to test this module for
correctness on its own you could execute
this module by itself and within its
main function it would execute a set of
test case sure yeah yeah
make sense and I think I saw in the main
root directory the repository there is a
test directory so it looks like this
writer may have written some tests for
their code as well I'm guessing there's
probably a more pet like a idiomatic way
to do TDD with some other system that
doesn't usually happen so just a few
quibbles if I may in terms of the style
of this file so I see what we're using
single quotes up here which is perfectly
fine in Python it's slightly easier to
type because you don't have to hold the
shift key but then I'm seeing double
quotes everywhere else and I'm not
seeing a particularly compelling reason
to switch in that way down here we're
back to single quotes for some reason
down here we're a double quote so to me
this just is a bit sloppy it's an easy
thing to fix but it also just presents
yourself better especially if someone
it's gonna read your code or modify your
code you want to be diligent about
things like this even more nitpicky Lee
I'm saying that this comment here is not
capitalized this one is this one is not
so here - there's just sort of a
sloppiness that the risk of reading into
it too much just suggests hey if you're
not even getting the basics right like
that maybe the code itself isn't as
strong as it should be and I think you
want to be putting your best foot
forward here - oh this looks like this
just commented out and that's fine if
the project is still in development but
really in your master branch the main
branch of your repository everything
that's there should be there and this
should have just been deleted I think
from that branch and in terms of where
else to go
one of the very first lines here were
these imports up here let me go back to
the previous view of this screen so that
we have a sense of where we're gonna go
it looks like samarth who is
implementing this imported some of his
own files so Karen board Pi player dot
PI and so forth so that's a nice
modularization if it seemed of the code
it's not all just in one massive file
should we take a look at say the main
function itself sure all right so I'm
seeing here that main takes in a few
arguments which is okay but that's kind
of violating the spirit of main main
should really be taking command-line
arguments if anything but it doesn't
need to take that in Python because you
can get access to those by assist.org v
so I would keep this simple and more
pythonic and just to have a def main
open paren close paren and that's it I
do see that he's changed commenting
Styles here but this is probably a good
thing do you mind speaking to this
convention yeah these triple court
marks that you might have seen before
are what it's called a docstring in
Python and this is often conventional
for documenting the behavior of a
function or documenting the behavior of
a class like player or carom board R
which we might take a look at later and
so conventionally underneath main you'll
have triple quotation marks and then a
description of what it is if this
function does and often times you'll
also see this as an opportunity to talk
about what the types of the arguments
should be what the return type of the
function is if the function is returning
something and just helps to document the
behavior of the function and then a
whole bunch of tools that have the
ability to actually read that doc string
and use the doc string in order to
inform someone who's using the function
how it is that the function actually
works let me go ahead and go back to the
editable version just so we can make
some tweaks as we go the no tweaks
necessary they're kind of oddly python
does it's doc strings sort of underneath
the function signature whereas in a
language like Java it would be placed
above the function yeah I can see the
motivation because it means when you're
parsing the function the doc string is
actually part of the function and not
just randomly appendant above it but I
do it feels a little weird given the s
conventions - here I'd just be a little
neater like give me some white space
before your next comments so I can just
understand that this is relating to the
code below it and not just commented out
or something like that right I would
like a little more detail here you you
do say that this is initial coin details
for the carom board and frankly find you
more about the game itself this might go
without saying but y9y
one I would elaborate at least for the
reader just so that we're not
questioning the design decision down the
road here is pretty reasonable thing
initializing two players using the
constructor function here the player
such-and-such strictly speaking I'm not
sure you gain much by in declaring
player one and player two and less yeah
I'm not even seeing those variables used
elsewhere so I would honestly probably
just simplify this and let me go ahead
and grab this personally I would
probably do this passing in player one
name and player two name just so it's to
not add variables unnecessarily it's
just something else to think about it's
something to accidentally misuse and
because the line of code is still pretty
darn short I think this is pretty clean
but I think reasonable people could
disagree on the goal and always say
that's the pie
phonic way to do it yeah yeah I mean in
that case to you might not even want
these two names here separately although
those did come in I think as argument so
yeah that's to be expected up in yep in
mains actual signature someone asked and
this is separate but someone was asking
about sections for the web and games
course I don't know if Brian your course
has online sections that we made
available not for the EDX course no
there are certainly if you're looking
for additional support with any of the
online classes like the web class at the
games class if you log into the EDX page
on the right hand side there are a whole
bunch of cs50 communities that you can
join so there's a discord server there's
a slack there's Reddit and Stack
Exchange that you can go on in order to
ask questions and interact with other
students but there are no sections per
se for the EDX course and I see a little
earlier on whip streak 23 a store noted
that he's been using Python for two
years and never use name equals equals
underscore main and that's fine because
it really is a solution to a problem and
you don't need to solve that problem if
you've not yet encountered it as by
writing your own library code that might
warrant it as well if you use Python for
web like flask or jangle you encounter
it might still be true for Django flasks
recommended method is no longer to use a
main function you should actually be
running a program called flask to
initiate execution of the server but you
will see that in older versions of flask
and I think there is one other question
you when scrolling up just a little
better yeah
can we go back in the questions oh and
Babic knight asks why not a separate
test file so I think Colton's comment
earlier you could absolutely factor out
any tests to a separate file however if
I were writing a pretty small library
for instance cs50 zone library I might
just keep everything together because it
keeps things simple only when it becomes
unwieldy should you actually solve a
problem sure you're told exists and then
adamantine let's say while you're on the
topic is there anywhere I can find the
sample code that was shown in class
examples for the web programming course
that should be all be linked on the
curriculum page on EDX yeah if you go to
the courseware page everything should be
there in a set of blue links or red
links associated with each and every
lecture all right well let's take a
closer look at some of the code here
we're still in that main function and I
think it's pretty straightforward we
seem to be initializing the Karen board
here and yes very excitedly having
created it we're going to go ahead and
start playing here so you
on line 45 we're calling a method it
would seem call play inside of the board
and I like that kind of modular ization
there's this notion of playing the board
down here we're printing out the results
that to makes sense to encapsulate as
part of the board if only because one
the carom board is representing a real
world object the real world board and it
also allows you theoretically to even
have multiple boards in memory
simultaneously especially for testing
purposes or the like here I feel like
there's maybe an opportunity for
improvement do you know where my mind is
wandering with comparing these literal
strings yeah yeah I see at least two
possible ways that you could approach
maybe improving the design here so the
issue that I think we're both touching
on here is that we're comparing result
dot outcome to a string where the string
is 1 or draw and whenever you're dealing
with a situation where they're only like
a fixed number of possible outcomes for
the game it could be 1 or it could be
drawn comparing it to a string is not
necessarily the best way to go it
becomes easier to potentially make
mistakes if some wherever I'm setting
the result I accidentally have a typo
somewhere for instance and it's not 1 or
draw then you could run into unexpected
behavior that you're not expecting and
so sometimes even come up with ways of
trying to work around that problem so I
can imagine maybe you make outcome and
enum for instance where it can only be
one of a fixed number of possible values
and so you can guarantee that will
always be one or the other or even it
looks like the way they're doing this is
they care about result outcome and when
it's one they print out the player that
won the game so I might imagine maybe
just like having a variable called like
who the winner is and if the winner is
set to either the player who won it or
if there is no winner then it could be
set to none which is just a default
Python value representing the absence of
a value and I could imagine if result
dot winner is equal to none and that
tells you that the game is a draw
because there is no winner so you can
imagine a number of possible ways you
could go about trying to architect that
yeah and because python is loosely typed
too you can effectively achieve ternary
States if you were to use a variable it
called not outcome but called one you
could say that result you could check
whether result dot one equals equals
true or if it equals false or if it is
some other state it could be none which
gives you a third option as well but I
think it's in the spirit of what you're
saying
now you mentioned enum before and I
think we can do that in Python per se
there's a you can their classes that you
can extend fit I guess so that's
probably more complicated and in fact I
don't even think this needs to be
ternary now that I look at it I think it
can just be binary just true or false
well I think well I don't know enough
about the game but I imagine the game
could be one a draw or still in progress
which is why they're not might not be an
outcome yet but this is only happening
after they print game ended so I'm
assuming at this point in time thank you
sir yeah I don't know enough about the
game to its parent you sure and you know
a technique I just saw in a library I've
been using recently is actually to use
class constants even though they're not
technically constant can I go ahead and
open up a little scratch pad here sure
what you could do what's wrong page
there let me go back I don't do this and
windows there we go all right so let me
go into one of the other files like the
carom board which i think is gonna be in
its own file here and also thanks to
vana villain jofi 9d and I can't read
that and think use me but it looks like
Korean text thank you very much for the
follows wonderful and so I think what
you could do here in your class is do
something that's very common in Java and
in other languages but actually the Fair
declare our class level variables and
correct me from rolling on the syntax I
think we could do something like let's
say how could we do this we could have a
variable called one and set it equal to
any old value whether it's one or even
one for instance and then we could have
draw equals draw just a string
representation of it and then in my
other code correct me if I'm wrong I
could down here if I scroll down to
where we left off at the very bottom I
could say something like if result dot
outcome equals equals Karen board
dot one to actually check as though it
is a constant even though Python doesn't
give us those same constraints as
someone what if me it would be the class
name though not the object name right I
think both would work actually um so
it's actually probably more than
vegetable to use the class name but I
think you can still get away with both
yeah Karen board here dot one so it's a
little sloppy but at least in this way
you're not comparing against a
hard-coded string that maybe will change
for grammatical purposes or if you enter
Nash
lines the game and therefore you have
different languages speaking those
strings you don't want to necessarily
hard-coded strings I think some folks
might knows that they know this as being
a static variable or pythons
implementation thereof
yeah the closest you can something you
see may be a Java or C sharp indeed
what's the difference being cs50 on EDX
and cs50 course website our lectures
divided into more bite sizes or know the
same content is there on Harvard
colleges website in EDX it's just a
different user interface I mean how long
will the cs50 be on series be we might
offer it again next year
Brian most recently put this online but
that's picks up where 650 leaves off and
is a shorter version of what is Brian's
web programming class which is already
on web on EDX all right so we're next to
look I think if we look at the top of
the file perhaps there is this other
function def low turns but should we
take a look maybe at the class itself
before moving on to another project when
I was looking at this it looked like
Karen board was the largest module in
this project by far
lovely so let's say we have okay but the
good news is when I was reading this it
looked a very well commented oh that's
good okay so let let me go all the way
back up to the top and shortcuts don't
work yeah it's weird you have to use a
page up page up yeah and home there we
go yeah okay so actually here is
something similar it seems to what you
were describing earlier or I was
describing earlier of having sort of
class level constants in a file called
config dot PI inside of which is a
settings something-or-other it looks
like a config directory inside of which
is the setting of time less likely okay
nice all right
and then we seem to be importing a an
abstraction of a player implemented
probably as a class that I'm inferring
from it a capitalized P here all right
so here's the class name we have a
really big doc string that's nice I
think this does go in much more detail
than we've seen thus far as to how this
all works I'm seeing an init method now
those of you who are unfamiliar with
classes a class is just a construct in
Python and Java and C++ for
encapsulating related pieces of data as
well as pieces of functionality so if
you've only studied C as in cs50 you
might recall strux and C which allow you
to encapsulate or group together similar
pieces of data a class does that and
more
you can also have functions otherwise
known as methods built into it as well
and in Python it's a bit curious because
if you want to initialize a class or
specifically an object of that class the
class is like what would you call like a
blueprint or a mold out of which you can
make multiple copies of it one or more
carom boards you see this function in
Python quite commonly do you want to
speak to what this is this is being used
for yeah so this is what we would call
like a class constructor basically this
is a function that will run that will
create what we'll call an instance of a
carom board so this class is defining a
blueprint of what it means to create one
such board and it's gonna sign in again
and when we say in main dot pie you may
have recalled we use carom board in in
capital C capital B and then in
parentheses we passed in the coins and
the players that was implicitly calling
this init method to say let's create a
new board and the nice thing about this
object-oriented syntax is that you can
use this to create arbitrarily many
boards if you wanted to have three games
running simultaneously you could create
three carom boards each time invoking
this init method and that would create
three different boards that have their
own set of variables and of their own
state and own functionality and Brian
did an object-oriented programming
stream actually fairly recently so if
you're watching on cs50 our YouTube
definitely check that one out if you're
on Twitch I think the bots probably
still up right now all right so we see
here a few different checks here a lot
of good error checking I think this
looks a lot like code that I write where
the very top of my function I do a lot
of if else ifs I might iterate over a
whole bunch of variables just to make
their sure they're of the right type
looks like we're using some arthanari's
using value error which is a built-in
exception to Python which just connotes
you have done something wrong with some
value if you pass in a string to it that
is the exceptions message that the user
will see or the programmer will see it
which is nice I see we have some kind of
dictionary here of coin types that we
could see if we dived into that config
file most likely to see what we're
validating here you look you're looking
at sconce
yeah if coin types is actually a
dictionary I don't know whether
I'm assuming it is because we're calling
keys and I actually think the dock keys
it's probably not necessary here that if
you want to check if coin is a key
inside the dictionary you could just
omit the donkey's that's true because
keys is gonna return a list of the keys
in the dictionary which is just a
redundant operation if you can already
do it by way of the end operator that's
a good point
all right so we're checking some types
just to make sure that the user is
passed in the right variables it would
seem yeah it's worth all the money that
it's a little bit more this will work
you can use the type function in Python
to get the type of a particular variable
and like check of players is in fact a
list it's a little bit more pythonic and
more recommended in Python to use
actually a different function which
exactly the is instance method every
function and that's going to yeah syntax
like that will say if player's is an
instance of list which is effectively
doing a very similar thing it's more
recommended for a couple of reasons but
one is to deal with the possibility of
classes that are inheriting from other
classes so you could imagine for
instance if I had I defined a class
called book for example and I defined a
new class called hardcover book that is
a type of book like a specific type of
book and now I have a hardcover book and
I want to check to see if it is in fact
a book if I just checked if the type is
equal to book it's not going to match up
but if I check if it's an instance of a
book that'll get a the result the next
step so long story short it's usually
preferable to use these instance over
just checking if type is equal to
something and actually back up to the to
the line 36 here I'm guessing if they're
currently checking to see if coin is in
a you know a sort of collection we could
probably use a set here they're all
unique I would we have to look at coin
types and verify that but true but if
coin types I'm guessing is associating
keys with values they are over here to
be doing necessary that's fair that's
not and if I may I would push back on
this and we were just coincidentally
talking about this over email with some
of the staff because I was trying to
design something involving types just
this weekend and you know I actually
preferred this on further thought
because one it would be weird or
presumptuous to subclass the list class
absolutely that's a primitive type built
into the language you can use it as part
of your own class but to really be
tucked in as an instance variable I
think I'll just extend it into when I'm
especially for Maine code like this like
I don't want you to be able to subclass
something necessarily like that's not a
feature I want to provide I don't know
if that's gonna break my own code and so
I would at least in cases like this if I
know it should be a list I would argue
that it should be a list no matter what
but I do agree that the code would break
especially down here for instance if we
enhance player to have its own subtypes
then I'm gonna have to go back and do
this so I could be convinced that way
that's right here as well and Ellen one
asked why not use a try-catch block here
in reference to of the various raised
errors you could because the presumption
is I think later on that it will be
taken for granted that players is a list
that player is a player and just bad
things will happen if you try to treat
those as they in ways that they are not
this is a downside I think of Python in
any loosely typed language and languages
like Java and C and C++ you would
specify the types of these parameters as
the inputs to the function so the
compiler would actually statically be
able to tell you yes or no the type is
as you expect and you wouldn't have to
have all this annoying error checking
and this is a trade-off I actually think
this is an annoying feature but a lot of
languages like Python where you have to
or should do this kind of checking if
you really want to write defensive code
or an argument could be made don't do
any of this error checking and just
don't write incorrect code that uses
incorrect types I mean the Python is
kind of a mature language for mature
adults if you will where you should just
agree not to miss call things too I
think that's probably a little naive cuz
even I miss call some of my own
functions sometimes that's their defense
for head for not having like or not
having a idiom or paradigm for private
variables right you have it feel same
idea just don't don't do that it is
generally the advice so I would love to
see a comment or so here this looks like
we're just tucking away some default
state which is fine but it would be nice
to just define this in the constructor
array because of all the functions I'm
gonna care about the Constructors kind
of like a main entry point and giving
them over there and I think here I can
echo Brian's concerned earlier don't
just hard code some arbitrary string
instead treat it as some kind of
constant
you an approximation thereof we have a
quite a question from a belt P 2006
please please please hello guys nice to
see you could you help me with this
simple question how can I receive the
data in book as a dictionary not as a
simple array book ID gets input I don't
know maybe want to write it into a thing
or what not but so this I presume is
from 150 this looks like a part of a web
programming problem so if this is using
sequel alchemy which is the library via
which you can execute sequel queries on
a database DB execute probably returns
some kind of class that's specific to
sequel alchemy you can probably if
you're storing that in a variable called
book just cast or convert book to a
dictionary and I wanna I'm making this
up just off the top of my head be
installed on you to feel it freezing
well I'm just gonna arbitrarily add it
to Sam arts program I think you can
probably do something like this to
convert whatever that structure is to a
book that should mostly work yeah you
shouldn't necessarily need to do that
though if all you're trying to do is
access the properties of the book you
can probably do something like book
title and book author already to get at
the properties of the book and another
comment here about YouTube I'm glad
folks are able to tune in by Oh YouTube
it's also on Facebook though YouTube
probably tends to be the most robust
internationally and so by all means have
a couple windows open watch us there and
comment here yeah I think they have
dynamic encoding to lower resolutions
gotcha yes Twitter does not and realize
you can comment on YouTube and Facebook
it's just none of us are looking there
right now we have a twitch comments up
yeah so pull up twitch that TV
associated TV if you're watching on
Facebook and YouTube and comment in
there so we'll mention typescript I'm a
big fan of typescript so if you're
unfamiliar typescript is a typed version
of JavaScript and it just makes it
really easy to write JavaScript code
that is free of potential type errors
because it is a strongly typed version
of JavaScript so I heard good things
yeah I should take it out at some point
all right well let's let's move on
shortly I think to another project but
overall I think we're seeing a good
amount of commenting there's still some
room for improvement I think we see some
pretty clean code but some
inconsistencies with commenting
capitalization and with single quotes
versus double quotes and then some
actual design opportunities for
improvement things like the state
management
actually representing things and then
the main function as well
yeah the gamestate being started as a
string - I think it goes back to our
prior Brian's prior point about using an
enum or at least your point about using
sort of faux enums using static
variables I think we could have done
something like not yet began in all caps
and that would've probably been better
does I'm gonna string two nice cool as
an aside I'm just kind of thinking ahead
here this is kind of interesting because
I'm seeing a double negative so to speak
if it is not the case that input turns
equals equals none I think what you
could do is actually distill that a
little more Python eclis as just this
because that will return true if it is
anything other than none so long as we
don't need to distinguish between none
and zero that should work correct
assuming that's some kind of input turns
I don't know what data type that's gonna
be I don't either so it could just be
that it was optional so if it's anything
other than what is the default value so
actually it looks like it's supposed to
be a dict
yeah so that should work fine okay I'll
bring us over to the other screen when
we say a couple hellos as we get ready
for next one sorry about that by the way
we've seen 23 please look at my code
we'll get to you Nate don't worry I
don't know about today but we have you
on the list
defensive programming is an art to write
good Python code yeah it's a pain those
as bad ignite and Bev ignite says thank
you Brian and we'll keep that in mind
regarding typescript funny you mentioned
Babic night because I think we are next
up to tick-tock Oh which here we go
occasion so Babic night at UC is in the
chat today so everyone get ready to with
your feedback hopefully very positive as
to what we're about to say all right
let's do it
first thing I'm noticing actually though
I don't think this has a readme ah this
is a directory inside of the cs50 beyond
repository so maybe cs50 Beyond hasn't
read me on it as I can see it does okay
so thanks for the link back to us we
would have liked to see more descriptive
information about the project but that's
okay let me go back here so Brian
probably knows this best so I'm a little
this is not the guy to ask I think for
feedback so here we go
so actually can I comment on one thing
don't check into version control your
pie cache file folder so python as an
interpreted language typically can do
some optimizations underneath the hood
and one is to pre compile your code and
then save the outputted bytecode the
temporary version of your code for
efficiency this should not end up in
version control and so one way to avoid
this if we go back to the repo is in
this git ignore file it looks like PI
cache look the issue is the spelling of
get ignore oh wow I think that would
have taken me a little while to figure
out I think yes you must name your get
ignore file get ignore and not get
ignore ignore but this is the right line
here and in fact you don't strictly have
to do the star you can actually just
specify tic-tac-toe PI cache and I think
if you only do underscore underscore ply
cache underscore underscore slash
that'll get well that get PI caches
everywhere they can show yeah yeah if
you don't have the leading slash popular
you're getting roasted Kappa so I think
we're we're I think we're friends by now
actually I think we are on Facebook so
we're cool okay all right should we take
a look at tic-tac-toe yeah take a look
so do you want to remind folks what
tic-tac-toe is all about I mean for can
we draw on the screen do we know how to
draw we might have an app why don't we
switch over to here oh no I can do it
right here
oh yeah draw two yeah draw that cs50
that IO and then actually you should be
able just use this pen right yeah so why
don't we make this a little interactive
would you play it with me testing to
make sure yeah so we have a draw that
cs50x want to make sure we draw that
cs50 dot IO which you're welcome to use
to we use it in classes for drawing on
touchscreens and shall we for those
unfamiliar especially outside the US
what is tic-tac-toe yeah so tic-tac-toe
is a game whereby we're gonna have a
three by three grid that's basically
just a nine squares arranged from the
three by three grid there are two
players a player X and a player oh and
they alternate taking turns drawing
either an X or an O whichever one of
them in one of the nines
and the goal is to get three in a row
you can get three in a row in a vertical
line you can get three in a row in a
horizontal line or you can get three in
a row along a diagonal and so the goal
is to try and get three in a row and the
funny thing is with tic-tac-toe the game
is such that if you have two players
playing optimally let's call it
intelligently no one should ever win
this game so with that in mind watch me
lose now I think even though most people
start with the center I think the best
strategy is not to do that and you're
smiling which makes me think you're not
gonna tell me I'm gonna go over here I'm
gonna hope that that was for the best
okay I'm gonna play Oh in the middle
I'll go yeah here all right all right
and now again we don't want I don't want
to let Brian get three O's in a row and
he doesn't want to get me to let get
three X's in a row so now I'm gonna I'm
gonna go here which I'm really liking
that's gonna force his hand correct it
doesn't want to lose I have to play in
the upper left that's the only way to
block and now I'm gonna go yeah I didn't
do this right I have to go here if I
don't want to lose now cuz diagonal is
allowed now I'm running into the same
problem I have to play in the lower
middle otherwise he's gonna get three in
a row and now I have to go over here so
I don't immediately lose and it looks
like this game is probably gonna be a
tie because now I could choose either
one of these places but I no longer have
a you could pass I couldn't go ahead and
all my bears and then damn to tie we
both played optimally Kyser twitch
saying you started with the worst
possible move I don't think so
are you supposed to start with the
corner though how about I start with one
of the corners I think the first move I
always start with the center I know you
can you can avoid losing if you start
with the center it's the second move
where if the first person place in the
center and the second person plays on
the edge then you can lose you might not
have played often I might I might not
have played off the way it's Paul Ryan
let me win I think it's a table rice and
bagging or let me not lose yeah if
you're actually interested in through
the game theory of tic-tac-toe is an
example of what's called an MN
a game where you're playing on an m-by-n
board until someone gets K in a row in
the example of tic-tac-toe and then KNK
all happen to be three but if you vary
what MN and K are equal to you can get
different games that have different
strategies so if this is the thing of
interest or if you'd like to take all
the fun out for as much all right so
that's what tic-tac-toe is now let's go
ahead and take a look at that McKnight's
implementation thereof and maybe even
some of his cash buy code here alright
so where you want to where you want to
start all right so I happen to know that
tic-tac-toe is a flask based games with
cs50 beyond but even if I didn't there's
a file called application PI which seems
like a reasonable place to start not a
requirement but flask has used this file
in like their documentation is just the
default you might see server dot PI or
app dot PI other possibilities exist -
all right you kind of a function or a
comment block up top yeah and I'm seeing
this shebang up here this hash-bang
which allows us to run this code through
Python and if I scroll down to the
bottom yeah this came up before this is
actually the older way of doing this
with flask and I think it's not
recommended anymore
so first and foremost I would get rid of
the first line the shebang get rid of
this line because all of your
application PI should be run as a
command-line argument these days to a
program called flask this will still
work but there is some reason that I
think is documented as to why they now
recommend the other approach alright
let's go back up to the top here how
would we go about wrapping our minds
around this file alright well start by
looking at some of the things that are
imported we're importing a whole bunch
of things from flask itself and things
to help this web application run ok on
line 14 we're importing from flask
session it looks like we're gonna be
using sessions in this application
probably so that we can maintain the
state of the game board inside of the
application session and the session
technically needs to be stored somewhere
and so here we're importing a function
called make D temp for make a temporary
directory which is where we're going to
store that session information and then
there's some configuration to get that
session and this is actually problematic
in some context because if you run flask
in debugging mode and therefore it
restarts after every request I believe
you will get a different temporary
directory we've run into this problem
before I remember before yeah so I think
this is actually fine in production code
where the server is running for a long
time but if you're using classics
debugging mode where it's supposed to
restart itself after every request just
to give you a clean slate I believe you
will end up seeing your session files
end up in different folders on the file
system and therefore you might be losing
some of your states so just FYI
you can probably omit this and what we
have started to do for class purposes is
let flask use the default which is core
called flask underscore session then add
that to your get ignore file to make
sure you don't check it in unnecessarily
as well all right so here we have a
route in flask if unfamiliar this allows
you to specify hey flask call the
following function any time the user
visits this route and slashes the
default route presumably and here we see
an index function that's for some reason
takes an argument can you help me figure
this out yeah I'm a little bit uncertain
about why that's there I mean it
probably could be a variable but I
wonder if any where index is called
that's a different that's a different
I'm not sure we're use not sure either
so unless there's some way just not in
this file to get to index with a
different value of n which is it
possible no I know there could be a URL
for let's say your index doesn't change
but you could pass in a different value
for n you could although generally when
you do that in the app dot route slash
you would have another route that would
have n as a parameter if you can
generate greet well for that Oh very
true yeah so I think Babic night this is
just not necessary this argument you're
sort of giving yourself a local variable
or a constant of sorts even though
that's not really the right way to do it
so I'm probably defined that up above
somewhere or because as easy as using it
it looks like the default size of his
board is indeed three by three but that
should be defined probably as a constant
or a global variable somewhere else all
right yeah big file I'd say so now this
is really cool but this is also kind of
crazy for those folks who haven't seen
this technique what's going on here
yeah so this is a special feature of
five python known as list comprehension
which is just a fancy way of trying to
create a list and so the thing to focus
on is first the
trying to create a board with no way
we're gonna represent the board is a
list of three things where each thing
itself is going to be a row of the board
and so each row is also going to be a
list of three things
and so each individual row is generated
this way for underscoring range and
might look familiar from like for I in
range something that you may have seen
in creating a for loop we're just using
an underscore because we don't really
need a name for this variable we don't
care about keeping track of what number
it is we just want some loop to run some
number of times and here we're saying
basically n times of put none inside of
this list so we end up getting a list
that has none three times and then we
repeat that process three times as well
so the result is that we get three rows
in a list where each row is a list that
contains none three times
I don't remember are you able to do it
like do - hold on a second like time
like a times a list by three or by N and
have that work so normally you can't can
we open up a sandbox just a quick we've
done something for more on cs50 sin but
tune in tomorrow for our stream on that
so you'll run into an interesting
problem if you try and do that here but
in short normally you can and so if I
just go ahead and open up a Python
interpreter here and I define a list
called X which I set to be the number
one and I say like x five for example
what I get is that X is the number one
repeated five times this is awesome a
strategy that people doing the Mario
assignment and Python thing is by taking
a hashtag and maybe repeating it but and
you could imagine doing this for a list
- if I say x equals let's say none I'm
just not going to use a generator for
now say none none none times three it
looks like you get the right result
where X is not that it's not what I want
flat oh I want no
yeah oh it flattens it why is it that's
weird I'm not sure I'm not sure I've not
had a kid well let's do none for blinken
range 3 oh when you multiply a list it
might try to make it equals as well yeah
I don't know why it's flattening it it's
actually related - that's weird that's
yeah cuz I thought you could do it
definitely this way but I didn't
actually know in advance that it was
gonna flatten the list yeah the point I
was trying to make is that if you try
and say like Rho is none three times
oops none none and you have a board I
see a lot of people that try and say
like let's go ahead and add the road to
the board and add the road to the board
three times and now you have a board
that looks like it has none none none
none but this isn't quite gonna work
because if I try and edit one of the
cells and say set X to be in the first
cell and I look at the board now X shows
up a three time the ranch's the rows
yeah and so multiplying a list will
often do that where we'll take the list
and it will end up just giving you
references to the same list of brand new
lists and so that's really ever seen
this problem before but not it's not
problem cantons come up I think that's
how you cheat and just what X wins okay
all right yeah all right
so this would seem to be initializing
the board here here we could probably
comment just as we did with some Earth's
code where could maybe use some other
kind of symbol however I don't know
tic-tac-toe is so simple that it's X I
know only however you could imagine
accidentally doing the lowercase X and a
big X so there's still some risk of bugs
there so I probably would just factor
that out with a variable name instead
and you could call the variable X and
the other one oh just to keep your life
simple but I think that would be more
resilient against bugs all right so
let's see
as an aside I'm pretty sure that
strictly speaking you don't need to pass
in session board in session turn because
your template in Jinja is going to have
access to session as a global variable
itself that might save you a little bit
of
of complexity here even though this
makes it more explicit as to what
variables you should have access to
we're passing in n as well but again we
should probably factor that out to a
global constant as well all right so it
looks like there's some reset route
which has to do with resetting the game
maybe after you've lost or you just want
to start over
deleting the session board would seem to
delete that key from the session and
then this is just gonna redirect the
user back to the home page yeah but he
or she can start again this is kind of
cool for those less familiar with flask
routes what's this funky syntax and the
route going yeah so this is a way of
creating variables inside of the route
so for instance if you imagine a website
like Twitter for instance where you have
if you want to go to someone's Twitter
page and go to twitter.com slash cs50
for example it's not like Twitter if
we're Twitter we're using flask it's not
like they have a whole bunch of routes
where they have one app route for a
slash via 50 and one route for every
other Twitter user what you can do is
you can have variables in the route and
say if someone goes to in this example /
play / some integer / some other integer
that that's going to result in taking
you to this particular function where
those parameters inside the route get
passed in as variables into the play
function and so that can allow us to
generate a whole bunch of play routes
for all the different places on the
board where you could potentially move
and each one will call this function
with different arguments this way yeah
Oh Colin's off-camera okay no I think
I'm no I think we just the chat windows
a little big - yeah yeah oh do you want
me to decrease this alright so you know
this is a subtle bug but there is a bug
here it would seem suppose that a user
had in their autocomplete or their
history a URL like / play / something /
something it would seem possible to
induce execution of this function play
even before the session board exists
because the session board recall is
initialized in the index function so
long story short there's a subtle bug
here whereby if a user starts visiting
your website not via index but somehow
or other visits that play route as by
autocomplete or something you could
actually get some kind of server error a
key error most
because session is not going to have
this variable in there there's a few
ways to deal with this you could add
some error checking a line 42 to make
sure the board exists or you can use
something that I've started using in a
lot of Flast projects let me Google
flask API before first request I think
the function is called and in this
documentation here let me search for it
again before first request you can
actually implement a function in your
own code that allows you to specify hey
flask run the following code before any
of my other requests before any of my
other routes are handled thereby
ensuring as follows that this happens if
I go up into a text editor here and
let's do test stop I
I believe the syntax for this is this
def before first request you can do
something like if board not in session
you can go ahead and say session board
gets an empty dictionary and this then
ensures that no matter what route in
your program is visited there will be an
empty dictionary if nothing else at
session bracket board and is there a
reason that's before first requested not
just before request like shouldn't we
say before every request make sure so I
don't think that's necessary right
because so long once the server is
running oh before every request first
request yeah this might not be yep you
are right because this is not user
specific and you want to make sure that
every user has a session key for board
so before request ensures that no matter
who is visiting you're gonna check to
make sure that he or she has in fact a
board even if it's empty available to
them oh and Bhavik night has corrected
my mistake from earlier if you wanted to
generate the board that way you would
have said putting put none none on
inside of the list and then multiply it
by 3 that will give you the list of them
and this creates the problem where you
can set something equal to X and X wins
automatically because we've updated all
of the lists so in short even if you do
that correctly don't do that right
exactly
ok it's weird that it uses this recycles
the same one but I
that makes sense because the
comprehension parses it as the same
object duplicate that same value again
right exactly
you could probably well you could
probably use them what is it a copy or a
deep copy duplicate but yeah that makes
sense
all right so let's go back here looks
like we're doing some game state I see a
nice use of tuples here so this game
state function presumably is taking as
input a row and a column and then it's
returning to variables which is
something you can't really do easily and
see you can kind of sort of do it in
Python even though technically you're
returning one value that value just
happens to be a tupple which is a group
of one or two or more values in this
case separated by commas here we're
checking hopefully a boolean value a
true/false and then we're explaining to
the user whether or not they are the
winner or if it's a tie and then we're
rendering an actual template as such so
I would know a couple things here too
just trying to make sense of this winner
- X oh I'm not sure I understand this no
I think I see what they're getting it's
a little bit strange but it seems to me
that winner is going to be a number
where 0 represents a tie 1 represents X
winning and 2 represents a winning is my
guess and what they're doing here is
they're printing out the winner by
taking the string - x 0 and indexing
into it to get a particular character so
winner and then they index into - XO
with 1 and it prints out X as the winner
this is my guesses yeah I think I think
you're right yeah ok and the fact that I
had to think so hard about that it seems
like this is too clever right you would
seem that rather than return a value
like 0 1 2 you should probably just
return X or o or variables representing
them or maybe none to represent that
third state of like no there is no
winter just yet and I would also propose
that you have this string being
constructed here in your controller code
in your route or this string here being
constructed instead honestly in the
spirit of MVC Model View controller that
kind of logic probably belongs in the
template itself so in final HTML you're
checking the value of a variable passed
in whether
a winner variable or some other such
variable don't construct the string in
your controller construct it instead in
your view among the benefits here is you
keep a cleaner separation of your codes
logic and your aesthetics design you can
also internationalize or change the
language more easily in your templates
without touching any of your logic your
controller code so I would keep that in
mind and honestly you know clever though
this is I think this is too clever for
its own good
if epic night to confer brain was
correct yeah I'll be curious back again
if you'd like to chime in why you did it
that way cuz I'm not sure I would even
have thought to do it that way when you
could just return a dash and X or no
feel free to chime in here to push back
but some nice use of ternary stuff here
where you're actually setting a variable
equal to this or that based on some
condition it's a little different in C
and in Java where you use the question
mark in the colon but this is pythons
closest equivalent good use of
redirection here's the gamestate really
nice documentation there's that tupple
that we inferred from the calling
convention earlier so no complaints
there to be honest really good
commenting overall anything jump out at
you that's of concern if you take the
suggester that we originally suggested
which is move n this to a global
variable that in line 66 stops becoming
necessary you don't need to killing that
the grid recomputed and how come he's
doing this i thought you had to indent
everything in a line of its own in
python if it's just a single line as the
body of the estate minh you can put it
on the same line as he's done there very
nice and that is that good or bad do you
think it's in this case I would say it's
probably many of me a little bit clearer
to put something on the next line just
to make it easier to read I've seen it
all in the same line when there's like a
lot of very quick if-else if-else is
where it makes make sense to put
everything and put it under the same
line I don't think it's necessary here
though yeah but no strong feelings on my
parts although we're seeing it again and
again although now we're seeing a
counter example so Oh a counter example
wow that was unintentional thank you
very much I would probably put this one
at least on the same line as well for
the same reasons Yeah right
alright is one function presumably
returns
oh so that's interesting and I'm not
sure I'm loving this the
is called is one but it doesn't return a
boolean a true or false it returns a
tuple containing a boolean as well as
that ant which is probably that index 0
1 or 2 here feels like an opportunity to
name the function not is one but who won
or winner and allow it to pass back some
value such as we described earlier yeah
forget win data something that's more
verbose and something like this too I
mean this is just this is getting to I
think cryptic for its own good like
Thoth which is probably total I wouldn't
start saving characters now when you've
just had a whole paragraph of
explanation I don't know why it's
negative 1 initially or why we're
initializing it to the length
I think Babic night this is just
starting to get unnecessarily
complicated and it might be correct and
work but you're making our third party
reader a collaborator just think too
hard about what's going on for a
relatively simple goal - all right and
oh my goodness now this is just getting
so crazy it looks like we're doing
return false none if total mod and so if
that is an odd number it seems not even
if it's if it's what is on a multiple of
3 through n f3
oh yeah cuz n take on those several
values I don't really know what total is
doing its we're taking for ian's check I
don't know what check is check is a list
I think don't don't make your reader
think this hard especially for something
that is pretty straightforward you've
just trying to return X or 0 or no one
won the game or do we take a look at
maybe one other file Babic was saying I
wanted to use enum for that so only one
of the result I could output that's true
but again I would propose some kind of
ternary variable where you're either
returning X or o or neither namely none
or some such value akaash says how do we
get to know if and when our code will be
reviewed thanks
some folks have asked to be notified and
they sent them an email but let us know
if you want us to email you and we can
let you know in advance so we take a
look at one of the templates yeah it
looks like there was only yeah that's a
big game ducks like there are only three
and gamed up HTML yeah so it's extending
layout but front layout probably just
contains some of the default HTML for
the page so the interesting stuff is
probably inside of game dot HTML and it
looks like we're rendering the game's
board as a table which is a pretty
reasonable use of a table looks like
there's a link to actually play the game
which uses URL for if unfamiliar URL for
is a nice way to dynamically get the the
correct route for a particular function
that you want to call and it does it in
a way where you don't have to hard code
this because you could imagine very
easily doing something like this we're
down in your code you don't say URL for
but you instead say slash play oops
/ play / curly brace I slash curly brace
J so you could construct this URL
manually the downside of that is that if
you rename if you rename that route over
in your application PI and this breaks
and that's a little fragile I would say
but frankly we do this sometimes in cs50
at least in that first project like this
with you finance it's just so much more
understandable so I think that ignite I
think you've done a good job in the
right approach here we just tend not to
do this in class because it just feels
like too much too soon sometimes any
concerns really looks pretty good pretty
clean game yeah yeah let's take a quick
look at the layout and then maybe move
on to another project sure all right
let's go back layout dot HTML for those
unfamiliar in flask this web framework
it's a common paradigm to have a layout
on HTML which gives you the overall
structure for a page and then smaller
templates that inherit from it to fill
in other blanks not much here strictly
speaking in html5 which Babic night is
indeed using per this doctype you no
longer need to specify a type CSS is
gonna be inferred you also don't need to
close this tag you're welcome to it's a
remnant of what's called a XHTML or it's
also valid in HTML but no one really
does it anymore it's just not necessary
in here minor point you don't really
need separate lines there I would just
pull the end block onto the same line
but there's really no downside other
than extra few white spaces that you'll
see in your file
all right well really nicely done by Vic
now
nice use of cs50 bjaaland feel free to
tune into cs50 beyonds videos online if
you'd like to take a look at that as
well alright you want me to bring it we
want to say a few pillows and ketchup
and sure sure you'll see what else we
got going on keep it up pretty well with
the chat actually thankfully sure we
have yeah so um yeah if you want to this
was the next one I kind of put them in
sequence relative to like tips of the
languages we're gonna this one though
you want to do that one yeah cuz we keep
mentioning Java okay that one yeah all
right we're gonna take a look at a java
application this looks like this is from
a student actual name is on the other
thing if you want to okay let's let's
Krishna three so McCauley alright
Krishna alright so here we have a looks
like something related to a whoops
something related to a course on
information security to semester course
and we have a whole bunch of
implementations of its seem of ciphers
so this is great since this code should
of course be perfectly correct so please
rely on us for this should we start with
maybe something a little warm-up
exercise of arithmetic take a look at
arithmetic dot java all right let's
weigh in on your arithmetic oh my
goodness
I was hoping for addition and
subtraction alright so here we have a
class called arithmetic necessary in
Java cuz everything has to be a class
here I do think we can make some
comments on style like I'm not quite
sure why this is indented looks like
some tabs there oh now I'm seeing spaces
alright so without getting into the
weeds of tabs versus spaces do not use
both would be one takeaway and I'm
seeing that this is a tab because the
whole thing gets highlighted and github
here
other comments this is partly user
choice but I mean I find it less
readable when you're not using any white
spaces in between your operators however
this is perhaps personal preference here
Java hasn't really standardized these
details as much as say python has if
that sounds right
it looks like they're not being super
consistent between whether to keep
variable names uppercase or lowercase
imagine the convention in most languages
is kind of what's being done in line 19
which is lowercase variable names in the
function for sure but mod inverse and
mod both have uppercase a uppercase C
yeah though to be fair if the student
were given a formula say in a text book
or in the Bezier statement using capital
letters I might push back and say well
I'm just trying to be consistent except
so it looks like this is implementing
modular arithmetic a mod C which is yeah
which is effectively the remainder
operation though not a hundred percent
of the time but we're seeing especially
when you have negative values which the
student is accounting for here it would
seem they're ensuring that it becomes
positive so as to then just use the
built-in modulo operator I think there
are probably more efficient ways to do
this if a is a really big negative
number and C is a small number you're
gonna end up running this loop a lot of
times and probably be a little bit
smarter about that logic yeah because it
looks like you've just made what could
be probably a close to constant time
operation linear now writing the size of
the input mod inverse and it's nice that
we do have definitions here because
otherwise it would be less obvious what
the code is supposed to be doing I'm not
sure we should necessarily get into the
weeds since this is just the first of
many files of all of the correctness
here but maybe we can pull out some
salient characteristics stylistically in
design indentation seems to have taken a
turn here now that we're indenting by
one space and then two spaces so I would
be consistent there it's just starting
to get a little sloppy and honestly this
is starting to get really hard to read
without spaces I think exploding this a
little more certainly giving me some
spaces around the mod operator maybe not
here because then I can kind of think of
this as a single argument but again you
could argue this both ways so yeah I
think I'd like to definitely see more
spaces now this is interesting it looks
like X or here is taking as input actual
string representations or char
representations of bits which is okay
and maybe that was the problem statement
but what can we glean here this is
interesting in Java when something goes
wrong you can throw a particular type of
exception however I see this only
happening down here
if a equals equals 1 what is going oh I
see I think what's going on line 27 is
checking to make sure that both a and B
are either the character 0 or the
character 1 if so we return sure
otherwise we'd only ever hit line 33 if
either one where the other character
wasn't a 0 or 1 so if a is a 0 or 1 then
B has to be the character that's not
represented correctly otherwise a oh
that's kind of clever but you have to
think about it is there some other way
to express that more succinctly um I
guess not it's just sort of logically
correct yeah however if you wanted to
specify well you could just very easily
check if a does not equal 0 or 1 throw a
binary representation of a otherwise do
the same thing for B and same check I
mean frankly I would prefer that just
like tell me what you're doing as
opposed to doing it a little more
cleverly like this because we've already
spent you know 10 seconds talking about
it when we would have spent 0 I think if
it were just a little more authentic
all right greatest common denominator
GCD seems to be net next this is finding
the the largest value that is common to
both as a factor I like this a lot this
is using Euclid's algorithm for
calculating the greatest common
denominator which is a very nice
recursive algorithm for doing this it's
calling itself on a smaller problem each
time now should we be citing Euclid if
this is his work and not ours
I would actually recommend putting a
comment in here I think it is
non-obvious if you haven't seen this way
of calculating the greatest common
denominator before what exactly is going
on why are you switching the arguments
of a and B to be an a on line 41 so
explaining that in the comment is
probably helpful for someone reading the
cofunction for the first time
now does Euclid have a github repo maybe
it came from I don't think he has an
account
oh no okay all right is Prime this is an
interesting one and this is kind of a
challenge in many domains to determine
if something is prying efficiently how
are we doing this here looks like we're
quickly checking if it's zero or
negative checking if it's pretty easy if
it's the value 1 2 or 3 so we're kind of
special case that you can get a few of
these or 2 or 3 and then here we're
doing a bit of math
what do you think is the gist here the
common kind of explains that every prime
number other than two or three is of the
form 6-k plus 1 or 6k minus 1 and so
they're just going over all possible K
is it not sure interesting mixture like
11 would be 12 minus 1 yep and then like
13 to be 12 it might be a number theory
thing that is true yeah I'm haven't
heard of it myself no I don't think
that's true there's no known gaps
predictable gaps between the prime
numbers right because his prime was only
determined to be a polynomial well
they're not saying that every 6 K plus 1
or 6 K minus 1 is a prime number they're
saying that if it's a prime number then
it is of this form which means there
could be larger gaps but when you get to
a prime number that the form I don't
actually know if it's true but let me
just go something real quick Prime's is
empty there's a paper just some years
ago Prime's is in P let's say yeah so I
don't think that can be the case because
this would not be such a seminal work if
it determines in polynomial time if an
number is prime well this algorithm is
not gonna be this is gonna be a long
algorithm because it's it's gonna
iterate over all the possibilities and
calculate the mod for each one but given
a prime you could certainly figure out
minus 1 and then divide by 6 or add 100
you're right your eyes right I'd have to
think about it a little to verify the
prime and that's what the whole primes
are the MS whoops let me just look up
like prime + 6 k plus 1 who kind of
curious sweet hilarious if it was that
easy and no no no actually you wouldn't
be able to tell for sure because you can
represent a number a 6 k plus 1 but that
doesn't tell you it's prime yeah so I
see a number could still be yes but this
function though aspires to tell you if
something is prime and it's doing that
just by testing all the possible case oh
I see I see so it's not easy not
efficient but it will just iterate over
all the possibilities that's interesting
you know I don't know if I
ever learned this little he recited
either but it does in fact show up in
216,000 Google results a prime number
is every prime number of the form of the
form 6-k plus or minus 1 yeah so all
prime numbers have to be that's
interesting
that's fascinating for more on this
check out Cora calm I should have
countered this already any no all right
so we take a look at some actual code
alright so that's it for arithmetic why
don't we take a look at Caesar cipher
then maybe one other just so that we
don't get too far out of my comfort zone
with the implementations of these and
really quick question for David I have
seen an old course of his CS 164 where
lerigot was taught can I get into
laravel with just completing cs50 MIT
6.0 0.1 X and cs6 sorry that's a cs50
6.0 point to X I did cs50 when PHP was
the language taught in C yeah you don't
really need any of those other courses I
think back when we talked PHP learned
enough of the fundamentals that you
could then next dive into laravel we
didn't talk much about object oriented
programming in cs50 back then or now but
which laravel does rather assume but I
definitely think you are overqualified
to go off and learn a framework like
laravel it's a wonderfully accessible
PHP framework for making web programming
easier so a Caesar cipher for those
unfamiliar should we perhaps just do a
quick example here sure let's do an
example
alright so Caesar cipher so suppose that
you want to send a message secretly from
one person to another ideally you'd want
to encrypt it or scramble in some way
but you want to scramble it
deterministically in a way that the
recipient can reverse and that is
cryptography or encryption yep so the
way you might encrypt something using
the Seavers cipher caesar cipher it's a
cipher that works on alphabetic
characters and we'll give it give you is
a key some value generally
representative the letter K which is how
many characters to shift each of the
letters in what we're going to call the
plaintext by so if we wanted to encrypt
the word hello with a key of let's say
like K equals 2 then I'm gonna take each
letter and just shift it forward in the
alphabet by two letters
so each goes to I and then J II after
ecomes F and then G L comes m and an N
oh is P and then Q so assuming I know my
alphabet right
JG and NQ would be the encryption of the
word hello with a value of four the key
of two and then at least known as the
ciphertext the ciphertext exactly and
then I send this message JG @nq over
some channel to the person who I want to
receive the message and if they also
know the key K equals to what they would
do is they would do the reverse of what
I did I move forward in the alphabet by
two characters and so they'll go
backwards by two characters taking J
going backwards to Jake just kidding
nope that's my message to you oh so I
received this message JK and the key is
- I'm gonna go backwards in the alphabet
two letters before J is H did you plan
this in advance so that you got issues
on the bottom one screen oh I've just
dropped 50 below just go to H and after
- before K is I so I've been able to
decrypt the message going from the
ciphertext back to the plaintext by
going backwards by - you orchestrated
that it just kidding that wasn't but
that's actually one of the points - if
you don't know the key in advance you
might decrypt something to text you
think it is but unless you know the key
for sure like hey equals - it's only
with some probability that you've
decrypted it properly any questions that
have popped up here so why is hashing in
cryptography like there's a whole
conversation yeah there are some folks
yeah though I think the one question or
at least the last tie to that was the
duck saying most crypto algorithms don't
need real primes just Co primes
I think RSA didn't need real Prime's -
not sure
I think RSA does need real primes
in order to work right I could be wrong
about that there's an RSA module in
thirds we can take a look in
so the Caesar cipher is just that it's a
rotational cipher where you're
effectively rotating every character by
want 0 or more places so I see some
interesting features of Java here or
what is a stringbuilder I don't see this
what is a stringbuilder
I've never actually a string builder
just lets you I believe concatenate
strings just kind of over and over again
it's just a place to hold it and what do
you know Java has that now back in my
day we built strings manually this
around for a while 1.5 that's like why I
think that's job I know there's they
remember all right anyhow
so here we have the string builder class
of course bio which you can catenate
on additional characters pretty
efficiently so what are we doing here so
it looks like if the character is
uppercase we're going ahead and
subtracting off from it the number 65
here and I think you can pretty sure you
can do this in Java just as you can in C
I probably wouldn't hard code the value
65 there I would change that instead to
actually doing something like quote
unquote a for a capital a and if you
want to be an explicit cache just so you
know what's going on even though I don't
think this should be necessary in Java
you can explicitly cast the a to the
corresponding Unicode or asking number I
think I think chars are that you can use
them in the same way as C um this
actually seems like a bug because it's
not the case that if something is not
uppercase that it is lower case this
would seem to be mutating even
punctuation characters sure yeah and so
I'm not loving this this should really
be an else if is the lowercase charkie
so that you're not mutating punctuation
characters which you should not be
because otherwise you're rotating you're
rotating all of the characters instead
of just those according to Caesar it
would rotate the letters this isn't even
doing the rotation yet but this is just
calculating how much to do the rotation
by oh so there could be you're assuming
that charkie is going to be higher at
the upper case or lower case I guess
which you might want to check for as a
matter of error checking
I'm not sure I see that anywhere down
here because we're again just checking
for uppercase yes yeah there they
McAllister yeah so I think and that's
fine because if this were done for like
a homework assignment or for a textbook
it might have been prescribed that write
a function that takes as input an
alphabetical string right in which case
this is perhaps okay to assume all right
so let's go ahead he ordered that the
charkie at least is a numeric number or
at a managed medical number
stringbuilder lets you build a string
yeah that's what we all right so what
are we doing here it looks like yes
antics and comments as before this is
just a lot to unpack visually it just
seems like it's getting a little messy
and I have to no really look closely as
to what's being subtracted and added so
that can just be cleaned up a little bit
here's where we're using the
stringbuilder class of course which
allows you to append characters to it
although is there any upside to doing it
with string builder as opposed to just
appending to a string object I've seen
it used in the context of streams but I
don't think in the context of just this
where you could easily substitute it
with a concatenation of the plus I don't
think there's any rule to remember in
Java if you just concatenate on a
character to an existing string you
probably create a new string object in
memory which is really less efficient
yeah that's true a string builder would
probably be for very large bodies of
text more efficient because it probably
has a internal buffer that it's not
necessarily reallocated okay all right
so this is really just a nice vector
class that we're getting but specialized
for Strings yeah all right so very nice
looking ahead a little bit the thing
that I will comment on as a design
decision is they have encrypt and
decrypt as these two different functions
of which the vast majority these two
functions are identical the only thing
that's different about encrypting and
decrypting in the caesar cipher is these
lines on line 20 and line 23 where
you're actually moving the character
forward by certain number of characters
are moving it back so this seems like an
opportunity to potentially I distract a
little bit in order to combine the
common functionality into a single
function in order to minimize the
repeated code sure yeah because you can
imagine just having a generic helper
function that either
things in a positive direction or a
negative direction exactly okay I like
that as well all right should we take a
look at one more perhaps I heard RSI you
mentioned so Brian will take this one
since I did so RSA is actually one of
the earliest most popular examples of a
public key cryptography system it is
supports what's called public key
cryptography or public keys and private
keys which are asymmetric so if Brian
wants it to send me a message encrypted
he would use my public key and encrypts
his message with it I would then use my
corresponding private key to then
decrypt that message this is distinct
from Caesar where both of us use the
same K or the same key value here we
have a symmetric keys and what's going
to come full circle today we just talked
about this in class on campus this
morning in fact so RSA is also
noteworthy because you know what notice
how github right now is using HTTPS and
if I go ahead and pull up my developer
tools and go to my security tab and
click on view certificates let's go
ahead and Center this let's go ahead and
look at the details and wallah I can't
really zoom in very clearly here but you
might see some mention of RSA as well as
sha-256 which is the hash function that
I think was mentioned in a chat just a
moment ago our browsers today are doing
this because after all if you go to
github.com via HTTPS for secure
connection and encrypted connection you
probably don't know anyone a human at
github with whom you could prearranged a
key like the number two so your browser
has to be able to talk to with remote
server kit hubs without knowing in
advance anything about it
so public key crypto lets us do this my
browser will use github public key in
order to establish that secure
connection someone was asking and for
nju says I never seem to understand how
SSL Certificates at work I don't know if
there's a two minute distillation that
you yeah well maybe let's come back to
that once we've looked at this
particular algorithm for just a moment
here and the fundamental premise to know
with RSA is that the entire security the
system is built on the assumption that
if you take two really big prime numbers
multiply them together you of course get
an even bigger number and the assumption
in the mathematical world is that it's
really hard and really time-consuming to
figure out given that big product what
the original prime numbers actually were
you can absolutely do it it's just a for
loop
but it takes so long because these
numbers are so big a lot more time than
the bad guys the adversaries out there
presumably have time for or computer
computational probabilities so should we
just take a look at this and maybe draw
out some of the features of RSA and the
style even if we don't get into the guts
of the algorithm yeah sure so it seems
like the first function they're defining
here at generate keys which taken
arguments three variables P Q and E
conventionally P and Q and RSA refer to
those two big prime numbers that David
was referring to these two big numbers
that we're gonna have to choose two
prime numbers those two numbers are
effectively going to be the private key
the thing that we keep secret those
eventually are going to get multiplied
together and the multiplied result is
going to become part of the public key
the thing that we're going to distribute
to anyone who wants to send information
to us via RSA I'm thrilled that
everything I just said is borne out in
code here yeah we're multiplying it
together so I the what you'll notice on
line two is the function is documenting
what it is that it returns the public
key in RSA is this pair of numbers D and
N and is the product of the two prime
numbers and D is just some other
parameter I forget exactly how its
computed but I guess we'll see you in
just a moment I don't want to return the
private key to whoever's using this
right we don't want to return the
private key so there's like is prime
function I'm glad we took a look at that
now checking to make sure the P and Q
are actually prime numbers otherwise
this algorithm isn't gonna work I do
like how the library sort of referencing
its own modules to do more sophisticated
stuff yeah and actually this is an
interesting convention notice that is
prime we didn't draw attention to this
earlier what kind of function would you
infer from this syntax because
arithmetic is a class so this isn't an
object
static function yeah so you can have
these sort of helper functions that are
sort of grouped in a class even though
they're not really using the class for
class purposes per se so here's some use
of the greatest common denominator
function which we looked at briefly as
well here's a calculation of D according
to our essays algorithm and then lastly
we're just returning actually all three
values de and n so that comments up top
wasn't strictly thorough as we see here
and then the encrypt function seems to
take in as inputs three different inputs
here and then we're go ahead
and what are we doing here plaintext
length so we're initializing an array
that's at the U it's a tentacle size to
the plaintext which is interesting let's
see what's going I think performing math
on each individual character yeah
they're going one character at a time
through the plaintext and taking its
exponent multiplied by exponent raised
to the nth power where n is that
parameter from before the part of the
public key so they're using the public
key to generate these really big
characters in order to return the cipher
which might not actually be totally
secure this method of encryption it's
usually used on generally not because if
you do this then you could just take a
character encrypt it using the public
key and you could figure out what the
public agenda limit is on the entirety
aspect so this is probably not the most
this isn't likely not the most secure
way to actually encrypt using RSA it was
not alright say that was develop ID NSA
was Shah right and Ra was it okay so on
if that sounds right yeah our say is
three faculty from I think all of whom
were from MIT at the time where these
Ron Rivest was who was the are an artist
thing gotcha all right they did that a
lot and CS and we were just talking
about this earlier Betar a wk Brian
Kernighan the UNIX utility ya know
people name things after so we're gonna
see a Colton cipher someday
oh yes maybe all right little Rob 26
maybe RSA is pretty simple mathematics
you can do it in four lines of math
there's the duck though or or 41 lines
of Java and did you want to talk about
SSL Certificates oh oh yeah so easy to
put down in a nutshell when you visit
github.com or amazon.com or gmail.com
and those sites use HTTPS that means
they've been configured for SSL or a
protocol called TLS whereby they
generates the very first time the
software for the web browser the web
servers installed a public key and a
private key and they generate a
certificate for themselves which is
essentially the public key and some
other information they then ask a third
party company like Verisign or GoDaddy
or let's encrypt out there either for
some cost or these days for free to
digitally sign that SSL certificate
their public key essentially
testifying to the fact that yes this is
github coms public here yes this is
amazon.com public key or your own domain
name when Brian or my laptop visit
Amazon or github or whatever website
that their server presents to me that
certificate and with it its public key
my browser on my Mac or PC or phone uses
that public key to encrypt my first
message to them and from there can we
begin to establish a secure connection
and there's a few more steps in there
but the SSL certificate is important in
that it one involves that public/private
key pair and two its digitally signed by
someone else otherwise you get a scary
looking message on the browser saying
that the website you visited might not
be secure because this certificate is
invalid can you see honest give a
certificate through the developer tools
the actual key itself is that visible I
believe so
I'm sure we could find some tool via
which to do that but if I go to security
what we can see is this if I go back to
view certificate you can see some
details about it so this is the one for
github calm you can see who the
certificate authority was did you serve
being the company here you can see that
the certificate is good for another year
and a half or so and if I go to the
details you'll see a whole bunch of
information serial numbers not the same
thing as the public key in chrome it
seems so we can copy this to a file you
can actually use this manually and okay
there's a whole certificate export
wizard yes you can see the key it would
be problematic if you can see the
private key of course because if you're
writing like a CLI application that
needed to use absolutely no photography
or whatever yeah cool all right so we're
coming up on the end should we we have
still a few minutes should we pull up at
least one more project but just do a
quick look yeah what do we do that
anything to catch up on in the chat we
just make sure we didn't miss anything
so curve two five five one nine is the
better option the doctor was saying
better than niste cc
let's squeeze this in because if we have
a few minutes okay sure so we'll pull up
whip streaks other project and he's been
asking all right get excited we only
have a few minutes so we'll try to be as
constructive as we can real quick I
actually downloaded this one in advance
we can actually execute it and run it if
you wanted to look at it but it's in the
Downloads folder oh okay oh to look at
the site itself yeah so let me go ahead
and switch so that we can be 100% sure
it is this one yep this is sorry this is
the zip it's actually in the Downloads
folder go to the Downloads right here
yeah the yeah the folder yeah okay oh
they just have a weird type of autograph
or something you can right-click and go
to index Ont m and then right click open
with chrome cool all right let me go
ahead and switch us back to the computer
here okay okay interesting so we've just
opened up a file called NTM dot HTML
they offer some very useful tools for
ten kisses a day okay so we see you list
which is another file and you've links
let's take a look at another one here ah
you link seems to be using a nice tabbed
interface okay so this is some
interesting stuff here different colors
maybe some bootstrap or some other such
library so why don't we take a look at
links HTML as well as at NTM dot HTML
sure all right that first one's NTM dot
HTML and actually the calculator one if
you go back to the NTM I did like his
calculator one just go back one more mmm
and then my calc or you calc at the very
bottom this is kind of cool oh my
goodness nice this is things escalated
quickly here
all right twelve plus three equals
fifteen very nice alright so let's go
ahead and take a look here is NTM dot
HTML I'm seeing html5 as per the doctype
nice mention that this is in english
which helps browsers like Chrome auto
translate from one language to another
so that's good to have as well it'd be
nice to see some indentation honestly
now once we're this far in we should
start indenting things to spaces for
spaces something like that it's
interesting because I actually see this
a lot in encode all over the place the
sort of left a line and I don't like it
either I think it should definitely be
but I wonder if that's conventional in
certain domains to indeed have
everything left aligned I'm gonna say no
okay in all context this is less
readable yeah it's weird I just weird
that I see all the time if I'm like
really readable code - I forgot seen
something like big repos I have it I
don't see any reason to do this I don't
I don't either I'm just curious if why
it's been white people do it that way
for the actual style of content I would
say it looks like the entire page
remember before you literally rather
than styling each individual tag maybe
just saying body text-align:center might
be a cleaner way of just centering
everything and normally in cs50 we
preach not putting your CSS inside of a
style tag - instead put it into a file
but honestly this page is so relatively
short I'm perfectly comfortable with
there being so relatively little CSS in
the file itself indentation aside agreed
with Brian on the need for all of those
properties this this is horrible I never
never never do this and I used to do
this - back in the day when HTML was
even less feature full if you wanted
multiple line breaks you hit brbrbrbr
this is the opportunity for CSS and to
actually use a margin top or a padding
top to specify however much white space
that you want above it so this is really
my only qualm structurally don't do this
and you should have known this the
moment you started copying and pasting
BR again and again and again odds are
that was that was the beginning I think
he's only 10 he's only 10 we got to take
a look I think I see 10 BR - indeed so I
think it looks great overall except for
that one one detail and the
factorization you could do with the CSS
y'all get the calculator real fast with
estimating time all right let's go look
at the calculator count HTML all right
so this one's cool because it actually
has some JavaScript in it but in an
interesting way all right so let's
scroll down to the HTML and I often do
this if I do see a lot of CSS I don't
care about the aesthetics yet I care
about the structure so I'll just kind of
scroll through all that and honestly
we're kind of at the point now where
maybe that belongs in a separate file
however if this is just a set of HTML
examples frankly maybe they shouldn't be
standalone and just all in one file so
comment here as well I think we can
improve that but this is interesting so
do you want to kind of walk us through
what you're saying here yeah sure so it
looks like they
decided to represent the calculator as
an HTML table which makes sense that
we've got rows and columns here and if
we look we see the first row here is
going to be the place at the top of the
calculator where you're saying the
result and so here they have TD which
stands for table data like a data cell
where call span is equal to 4 this is a
way of making a table cell take up
multiple cells worth of space on the
table where we want the thing at the top
of the calculator to take up more space
than any of the individual buttons so in
this case we're making it take up that
whole space and that looks like just an
input field that's disabled because we
don't want the user to actually be able
to type numbers in you want them to
click the buttons instead it looks like
they have a whole bunch of buttons one
for each of the possible values and all
right they have some JavaScript in line
with the input field so when your yoga
so for each of these buttons when you
click on the button this on click event
listener is going to get triggered so
we're gonna run this javascript anytime
you click the plus button and it seems
what they're doing here is just adding
two calculator displayed value which I'm
assuming is this that this this input
field and it's just tacking on the plus
to that and I would make one note here
disabled is fine however I don't know
how that's gonna behave on all browsers
read-only as probably well you can
probably still edit it you can read it
in JavaScript I would probably change it
to read-only
I'd have to Google to understand this so
disabled means in the context of forms
that get submitted to a server it will
not even be submitted now that's
inapplicable here because we're keeping
everything client-side I would have to
read on the differences subtly between
read-only and disabled I just worry that
disabled might be too strong of a
property for some browsers just a
thought so I think we can clean this up
too I don't mind this for like a first
version of a calculator that we just
have the logic inside of the file itself
but honestly there's so much redundancy
here that among the ideas I have are
this let me go ahead and copy just my
number one here and going to cs50
sandbox and let me just paste that there
so we know so we have something to look
at what you could also do is instead a
version like this we could get rid of a
lot of this complexity and we could for
instance just say something like update
this and if you have a function now
elsewhere in your code in a script tag
down here you could imagine doing
something like this function update
inputs and what you could then do is
calculator let's see calculator is
display where was calculator defined
that's what I was trying to look for
before I didn't see it I wonder if it's
lower down
notice right there is the form so this
is an old-school way of accessing
properties inside of a inside of a form
so if I go into calculator display dot
value I can still do plus equals and
then I can do this and I'm trying to
remember how I think it's this dot value
will actually give me I'm sorry not this
input dot value will give me the value
of that variable I think I'm pretty sure
this would work I'd have to double check
as I'm doing this off the top of my head
but the upside of this update function
is now you don't have to hard code all
of the logic into the string you can do
something even more succinctly just by
updating and passing in this which is a
reference to that local input element or
frankly we could do this even more
abstractly we can factor that out and
elsewhere in my script tag could I do
something like this document query
selector and then I can select all of
the input elements if this is what I
want to do but this is probably too many
but I could do something like this query
selector input and then what do I want
to do on click you would probably have
to do query selector all I think of all
of them and can you oh then we have to
iterate over it as a loop yeah so you
could do it it would just mean query
selector all can we do this you each I
goes after input oh yeah sorry I'm gonna
head to myself and then it's for each
capital for each and then that gets
passed in what an input referencing
element elements itself so you would
then you do input for each fun function
taking the input input and then it's the
same as the contents of the function
from that way so let's close this and
now down here we can do something like
this however what I don't love about
this
is and I'm just gonna make a to-do to
myself ensure this only works for
certain inputs because I have some of
these inputs are special we had an equal
sign we had a clear button so what we
might want to do is actually at a class
or a data property to only those numbers
and frankly at that point what you can
do is this instead of using value which
strictly speaking should be used for the
value of an element to a form and
buttons typically they can have values
but it's not something you would
generally mutate you can actually do
something like this data value equals
one and data - anything is a way of
defining a custom HTML attribute on an
element so you could put data value only
on the numeric buttons for instance and
you can use other types of attributes
for like your special buttons as well
that makes sense
there's an interesting bug that I
noticed that this program - because all
of the behavior is such that you just
add plus equals something to the display
including the operators so for example
plus plus 20 you can get Plus as many
times as you want and then all that
equals does is just an eval right there
so if you try to eval anything with
multiple operators it just bricks so
there's something just to be mindful of
it's a kind of an easy yeah with some
operators the pluses would be okay I
think I tested on the bus isn't it broke
so oh really it doesn't interpret it as
a plus plus value a plus a positive oh
you can try it if you want but you have
to do like 10 pluses I think I want to
plus a plus a plus 2 and I think that
won't work yeah that might work oh
that's interesting so I guess you can't
use a prefix plus to represent
positivity
you can also receive console dot log and
see if that gives you because eval I'm
guessing is outputting maybe some issues
yeah that's interesting
oh yeah I wanted out let's take a look
at the inspector console invalid
left-hand side expression interesting so
generally speaking a vowel tends to be
dangerous I think we're okay here
because the there's no user input per se
that is freeform the input is only
coming from those buttons but generally
I think it's worth noting that eval
where you just say evaluate the
following code can be very dangerous if
some of that code
becoming from the user let's see should
we let's see we're just after 2:30
here's yen time let's make sure we
didn't miss anything spammy I was saying
I remember one old walkthrough where rob
bowden and another fellow explained RSA
which went over my head like those paper
planes they used to explain deep will
there be a part 4 well we'll see we're
gonna circulate the Google Form which we
can do I think right at the end of the
stream yeah you would like to contribute
to make our own code we definitely still
have quite a few projects left to look
at Adam was saying I'm pretty impressed
when I was 10 I was still just
developing the Linux kernel I think
that's a humble brag they're a little
low in there Sasha kaun hello um Divac
Knight asks can we use jQuery or Ajax
for this jQuery absolutely that would
make them some of the syntax a little
shorter Ajax doesn't really feel
applicable unless you want to involve a
server Ajax typically involves talking
to some endpoints which we don't really
have a need for here in fact I don't Lee
don't want the users input being a valid
on my server better to keep that in
their own browser every release how late
am I just about it late as you can be
I'm afraid it will post the final video
online and you can go back on YouTube or
Facebook and replay it even this live
stream in the meantime if anybody is
interested bitly slash cs50 twitch code
review submit that form make sure your
github repo make sure it's on github
somebody post a get a lab project which
required us to register so make sure
it's on github and make sure it's public
so that we have access to see it because
if we can't see it we can show it
unfortunately yeah and really nicely
done overall Webb Street 23 I would
propose that the opportunity with this
page and a few of the others is really
to make successive versions of this like
it's great to get the Calcutta HTML up
and working in this way go ahead and
create a Cal - HQ ml a calc 3 that sort
of advances the sophistication of each
of them that might have been too hard to
implement right out of the gate from the
beginning but once you get something
working and you can make a slight
improvement and a number to their
improvement you can get pretty far from
where you started
so I'd consider doing that for something
like this code and start to factor out a
lot of these redundancies
yeah it's always nice seeing all the
different varieties of codes bases and
projects all the students so feel free
to uh post your code on the Google forum
let us know what to look at we are well
qualified for many many languages and
cryptographic algorithms feel free to
reach out yeah nice to see someone so
many folks in the stream again today
yeah it was a good time it looks like
we're all caught up on the chat so
tomorrow what am have coming up tomorrow
cs50 zone David J Malan again for the
cs50 sandbox Oh what is the cs50 sandbox
of would you speak well we've seen it
quite a few times here so basically just
allows you to spin up a little workspace
you know in the web so you can just do
it you don't have to have a dedicated
developer machine if you want experiment
and you'll be talking much more about
this tomorrow indeed feel free in the
meantime to play around if you'd like to
get a taste of it if you go to sandbox
that cs50 dot IO
it requires a github account but you'll
probably already have one of those
you'll be logged in and then you can
simply specify what kind of sandbox to
create for instance you'll see that
there's support for bunches of different
languages here among them C and Python
in HTML and more and it's really just a
quick and dirty way to get a programming
environment up and running that is not
permanent it's more temporary the cs50
IDE keeps your files and folders and all
that around for as long as you have the
account whereas these sand boxes are
meant to be just quick and easy just as
we've been using it for these streams
and you just edit go is that right yes
but then we took it back so now it's
stopped Oh we'll be back as will be
Erlang in Prolog and Haskell as well no
closure no in fact we need to have no
closure right now either
that makes me sad yeah so we have the
sandbox tomorrow so tenant for that one
at 1:00 p.m. on tomorrow's Wednesday I'm
little screwed up because of the week
off set on Thursday I'll be doing
solitaire which we were gonna do last
week but unfortunately I was ill so
Thursday tune in for saw a solitary
stream love and Lua
so a game from scratch and it's actually
been like probably two or three weeks
since we've done one of those and then
on Friday
States face Emily Emily Hong is coming
in for her very first stream on web
scraping and I see in a suggestion from
Adam here for a data structure stream is
that on the horizon
um not one specifically but I'm going to
see if any folks might be amenable to
holding one that would be cool I
wouldn't
plus we have this nice fancy way of
actually drawing data structures on the
screen where we could draw see you some
linked lists and some tree structures
and some others are you are you
interested I'm not qualified to teach
that yeah all right well thanks so much
great to see everyone again yeah thanks
so much everybody we'll see you tomorrow
for the cs50 sandbox until then have a
great rest of your day and thanks to
David and Brian for today's code review
good to see everyone thanks everyone