All language subtitles for Harvard-CS50-Full-Computer-Science-University-Course_en

af Afrikaans
ak Akan
sq Albanian
am Amharic
hy Armenian
az Azerbaijani
eu Basque
be Belarusian
bem Bemba
bh Bihari
bs Bosnian
br Breton
bg Bulgarian
km Cambodian
ca Catalan
ceb Cebuano
chr Cherokee
ny Chichewa
zh-CN Chinese (Simplified)
zh-TW Chinese (Traditional)
co Corsican
hr Croatian
cs Czech
da Danish
nl Dutch
eo Esperanto
et Estonian
ee Ewe
fo Faroese
tl Filipino
fi Finnish
fy Frisian
gaa Ga
gl Galician
ka Georgian
de German
el Greek
gn Guarani
gu Gujarati
ht Haitian Creole
ha Hausa
haw Hawaiian
iw Hebrew
hi Hindi
hmn Hmong
hu Hungarian
is Icelandic
ig Igbo
ia Interlingua
ga Irish
it Italian
ja Japanese
jw Javanese
kn Kannada
kk Kazakh
rw Kinyarwanda
rn Kirundi
kg Kongo
ko Korean
kri Krio (Sierra Leone)
ku Kurdish
ckb Kurdish (Soranรฎ)
ky Kyrgyz
lo Laothian
la Latin
lv Latvian
ln Lingala
lt Lithuanian
loz Lozi
lg Luganda
ach Luo
lb Luxembourgish
mk Macedonian
mg Malagasy
ms Malay
ml Malayalam
mt Maltese
mi Maori
mr Marathi
mfe Mauritian Creole
mo Moldavian
mn Mongolian
my Myanmar (Burmese)
sr-ME Montenegrin
ne Nepali
pcm Nigerian Pidgin
nso Northern Sotho
no Norwegian
nn Norwegian (Nynorsk)
oc Occitan
or Oriya
om Oromo
ps Pashto
pl Polish
pt-BR Portuguese (Brazil)
pt Portuguese (Portugal) Download
pa Punjabi
qu Quechua
ro Romanian
rm Romansh
nyn Runyakitara
ru Russian
sm Samoan
gd Scots Gaelic
sr Serbian
sh Serbo-Croatian
st Sesotho
tn Setswana
crs Seychellois Creole
sn Shona
sd Sindhi
si Sinhalese
sk Slovak
sl Slovenian
so Somali
es Spanish
es-419 Spanish (Latin American) Download
su Sundanese
sw Swahili
sv Swedish
tg Tajik
ta Tamil
tt Tatar
te Telugu
th Thai
ti Tigrinya
to Tonga
lua Tshiluba
tum Tumbuka
tr Turkish
tk Turkmen
tw Twi
ug Uighur
uk Ukrainian
ur Urdu
uz Uzbek
cy Welsh
wo Wolof
xh Xhosa
yi Yiddish
yo Yoruba
zu Zulu

Original subtitles

If you want to learn about computer science and the art\n

CS50 is considered by many to be one of the\n

This is a Harvard University course\ntaught by Dr. David Malan

and we are proud to bring it to\n

Throughout a series of lectures, Dr. Malan will teach you \n

And make sure to check the description for a lot of\n

DAVID MALAN: All right, this is CS50,\n

to the intellectual\nenterprises of computer science

and the art of programming, back here\n

for the first time in quite a while.

And I took this class myself\nsome time ago, but almost didn't.

It was sophomore fall and I\nwas sitting in on the class.

And I was a little curious\nbut, eh, it didn't really

I was definitely a computer\nperson, but computer science

felt like something altogether.

And I only got up the\nnerve to take the class

ultimately, because the professor\nat the time, Brian Kernighan

allowed me to take the\nclass pass/fail, initially.

And that is what made\nall the difference.

I quickly found that\ncomputer science is not just

about programming and working\nin isolation on your computer.

It's really about problem\nsolving more generally.

And there was something\nabout homework, frankly

that was, like, actually fun for perhaps\n

And there was something\nabout this ability

that I discovered, along\nwith all of my classmates

to actually create something and bring\n

and sort of bring to bear something\n

but didn't really know how to harness,\n

and definitely challenging\nand frustrating.

Like, to this day,\nall these years later

you're going to run up against\n

in programming, that\njust drive you nuts.

And you feel like you've hit a wall.

But the trick really is\nto give it enough time

to take a step back, take\na break when you need to.

And there's nothing better, I daresay,\n

and pride, really,\nwhen you get something

to work, and in a class like\nthis, present, ultimately

at term's end, something like\nyour very own final project.

Now, this isn't to say that\nI took to it 100% perfectly.

In fact, just this past week, I looked\n

have from some 25 years\nago, and took a photo

of what was apparently the very first\n

and quickly received minus 2 points on.

But this is a program that we'll\n

does something quite simply like\n

And to be fair, I\ntechnically hadn't really

followed the directions, which is\n

But if you just look at this, especially\n

you might have heard\nabout programming language

but you've never typed\nsomething like this out

undoubtedly it's going to look cryptic.

But unlike human\nlanguages, frankly, which

were a lot more sophisticated, a\nlot more vocabulary, a lot more

grammatical rules, programming, once\n

it is and how it works and what these\n

you'll see, after a few\nmonths of a class like this

to start teaching\nyourself, subsequently

other languages, as they may\ncome, in the coming years as well.

So what ultimately matters\nin this particular course

is not so much where you end\nup relative to your classmates

but where you end up relative\nto yourself when you began.

And indeed, you'll begin today.

And the only experience that matters\n

And so, consider where you are today.

Consider, perhaps, just how\ncryptic something like that

And take comfort in knowing just\n

will be within your own grasp.

And if you're thinking that, OK, surely\n

to the right, behind me, knows more than\n

2/3 of CS50 students have never taken\n

you're in very good company\nthroughout this whole term.

So then, what is computer science?

I claim that it's problem solving.

And the upside of that is\nthat problem solving is

something we sort of do all the time.

But a computer science\nclass, learning to program

I think kind of cleans up your thoughts.

It helps you learn how to think more\n

Because, honestly, the\ncomputer is not going

to do what you want unless you are\n

And so, as such, there's\nthese fringe benefits

of just learning to think like a\n

And it doesn't take all\nthat much to start doing so.

This, for instance, is perhaps the\n

sure, but really problem\nsolving in general.

Problems are all about taking input,\n

You want to get the solution, a.k.a.

And so, something interesting\nhas got to be happening in here

in here, when you're trying to\nget from those inputs to outputs.

Now, in the world of\ncomputers specifically

we need to decide in advance how we\n

We all just need to decide, whether\n

else, that we're all going to speak\n

of our human languages as well.

And you may very well know that\ncomputers tend to speak only

Assembly, one, but binary,\ntwo, might be your go-to.

And binary, by implying two,\nmeans that the world of computers

has just two digits at\nits disposal, 0 and 1.

And indeed, we humans have many more\n

But a computer indeed\nonly has zeros and ones.

And yet, somehow they can do so much.

They can crunch numbers in\nExcel, send text messages

create images and artwork\nand movies and more.

And so, how do you get from something\n

to all of the stuff\nthat we're doing today

in our pockets and laptops and desktops?

Well, it turns out that\nwe can start quite simply.

If a computer were to want to do\n

Well, in our human world,\nwe might count doing this

like 1, 2, 3, 4, 5, using so-called\n

on your fingers where one finger\n

if I'm, for instance, taking attendance.

Now, we humans would typically\nactually count 1, 2, 3, 4, 5, 6.

And we'd go past just those five\ndigits and count much higher

But computers, somehow, only\nhave these zeros and ones.

So if a computer only somehow\nspeaks binary, zeros and ones

how does it even count\npast the number 1?

Well, here are 3 zeros, of course.

And if you translate this\nnumber in binary, 000

to a more familiar number in decimal,\n

If we were to represent, with\na computer, the number 1

it would actually be 001,\nwhich, not surprisingly

is exactly the same as we\nmight do in our human world

but we might not bother writing\n

But a computer, now, if it\nwants to count as high as two

And so it has to use a different\npattern of zeros and ones.

So this is not 10 with\na zero in front of it.

It's indeed zero one zero\nin the context of binary.

And if we want to count\nhigher now than two

we're going to have to tweak these\n

And then if we want 4\nor 5 or 6 or 7, we're

just kind of toggling these\nzeros and ones, a.k.a.

bits, for binary digits that represent,\n

different numbers that you\nand I, as humans, know

of course, as the so-called\ndecimal system, 0 through 9

dec implying 10, 10 digits,\nthose zeros through nine.

So why that particular pattern?

And why these particular zeros and ones?

Well, it turns out that\nrepresenting one thing or the other

is just really simple for a computer.

At the end of the day, they're\npowered by electricity.

And it's a really simple thing to\n

or don't store some electricity.

Like, that's as simple as\nthe world can get, on or off.

So, in fact, inside of a\ncomputer, a phone, anything

these days that's\nelectronic, pretty much

is some number of switches,\notherwise known as transistors.

You've got thousands, millions of them\n

And these are just tiny little switches\n

And by turning those things\non and off in patterns

a computer can count from 0 on up\n

And so these switches, really, you\n

Let me just borrow one of\nour little stage lights here.

And so, I could just think\nof this as representing

in my laptop, a transistor,\na switch, representing 0.

But if I allow some electricity\n

Well, how do I count higher than 1?

I, of course, need another light bulb.

So let me grab another one here.

And if I put it in that same kind of\n

That's sort of the old finger\ncounting way of unary, just 1, 2.

I want to actually take\ninto account the pattern

of these things being on and off.

So if this was one a moment ago, what I\n

and let the next one over be on, a.k.a.

And let me get us a\nthird bit, if you will.

Here is that same pattern now,\nstarting at the beginning with 3.

Here is 010, a.k.a., in our\nhuman world of decimal, 2.

And then we could, of course,\nkeep counting further.

This now would be 3 and dot dot dot.

If this other bulb now goes\non, and that switch is turned

and all three stay on--\nthis, again, was what number?

So it's just as simple,\nrelatively, as that, if you will.

But how is it that these\npatterns came to be?

Well, these patterns actually\nfollow something very familiar.

You and I don't really\nthink about it at this level

anymore because we've probably been\n

But if we consider something in\ndecimal, like the number 123

This looks like 123 in decimal.

It's really just three symbols,\n

with a couple of curves, that\nyou and I now instinctively

But if we do rewind a few years,\n

because you're assigning meaning\nto each of these columns.

The 3 is in the so-called ones place.

The 2 is in the so-called tens place.

And the 1 is in the\nso-called hundreds place.

And then the math ensues\nquickly in your head.

This is technically 100 times 1, plus\n

And there we get the sort of\nmathematical notion we know as 123.

Well, nicely enough, in binary,\nit's actually the same thing.

It's just these columns mean\na little something different.

If you use three digits in decimal,\nand you have the ones place

the tens place, and the hundreds place,\n

They're technically just powers of 10.

So 10 to the 0, 10 to\nthe 1, 10 to the 2.

Decimal system, "dec" meaning 10.

You have 8 and 10 digits, 0 through 9.

In the binary system, if you're\ngoing to use three digits

just change the bases if you're\nusing only zeros and ones.

So now it's powers of 2, 2 to the\n

And if you keep going, it's going\n

So, why did we get these\npatterns that we did?

Here's your 000 because it's 4 times\n

This is why we got the\ndecimal number 1 in binary.

This is why we got the number 2\nin binary, because it's 4 times

0, plus 2 times 1, plus 1 times 0, and\n

And, of course, if you wanted to\n

What does a computer need to\ndo to count even higher than 7?

Add another light bulb, another switch.

And, indeed, computers\nhave standardized just how

many zeros and ones,\nor bits or switches

they throw at these kinds of problems.

And, in fact, most computers would\n

And even if you're only counting\nas high as three or seven

you would still use eight and\nhave a whole bunch of zeros.

But that's OK, because the\ncomputers these days certainly

have so many more, thousands,\n

All right, so, with that said, if\n

or, frankly, as high\nas we want, that only

seems to make computers\nuseful for things like Excel

But computers, of course,\nlet you send text messages

write documents, and so much more.

So how would a computer represent\nsomething like a letter

like the letter A of the English\n

AUDIENCE: You can represent\nletters in numbers.

DAVID MALAN: OK, so we could\nrepresent letters using numbers.

What number should represent what?

AUDIENCE: Say if you were starting\n

you could say 1 is A, 2 is B, 3 is C.

Yeah, we just all have to agree\nsomehow that one number is

going to represent one letter.

So 1 is A, 2 is B, 3 is\nC, Z is 26, and so forth.

Maybe we can even take into\naccount uppercase and lowercase.

We just have to agree and sort of\n

And humans, indeed, did just that.

It turns out they started\na little higher up.

Capital A has been\nstandardized as the number 65.

And capital B has been\nstandardized as the number 66.

And you can kind of imagine\nhow it goes up from there.

And that's because whatever\nyou're representing

ultimately, can only be stored, at\n

And so, some humans in a room before,\n

or, really, this pattern of zeros\n

So if that pattern of zeros and\nones ever appears in a computer

it might be interpreted then as indeed\n

But I worry, just to be clear, we\n

It might seem, if I play\nthis naively, that, OK

how do I now actually do\nmath with the number 65?

If now Excel displays 65 is\nan A, let alone Bs and Cs.

So how might a computer\ndo as you've proposed

have this mapping from numbers to\n

It feels like we've given something up.

AUDIENCE: By having\na prefix for letters?

DAVID MALAN: By having a prefix?

AUDIENCE: You could have\nprefixes and suffixes.

DAVID MALAN: OK, so we could\nperhaps have some kind of prefix

like some pattern of zeros and ones--

I like this-- that\nindicates to the computer

here comes another pattern\nthat represents a letter.

Here comes another pattern that\nrepresents a number or a letter.

How might a computer\ndistinguish these two?

AUDIENCE: Have a\ndifferent file format, so

like, odd text or just\ncheck the graphic or--

DAVID MALAN: Indeed, and that's spot-on.

Nothing wrong with what you suggested,\n

The reason we have all of these\n

like JPEG and GIF and PNGs\nand Word documents, .docx

and Excel files and so forth, is\n

and decided, well, in the context\n

more specifically, in the\ncontext of this type of program

Excel versus Photoshop versus\nGoogle Docs or the like

we shall interpret any patterns of\n

for Excel, maybe letters in, like, a\n

or maybe even colors of the rainbow\n

And we'll see, when we\nourselves start programming

you the programmer\nwill ultimately provide

some hints to the computer that tells\n

So, similar in spirit to that, but\n

So this system here actually has a\n

Code for Information Interchange.

And indeed, it began here\nin the US, and that's

why it's actually a little\nbiased toward A's through Z's

and a bit of punctuation as well.

And that quickly became a problem.

But if we start simply now,\nin English, the mapping

itself is fairly straightforward.

So if A is 65, B it 66,\nand dot dot dot, suppose

that you received a text\nmessage, an email, from a friend

and underneath the hood,\nso to speak, if you kind of

looked inside the computer, what you\n

or this email happened to\nbe the numbers 72, 73, 33

or, really, the underlying\npattern of zeros and ones.

What might your friend have sent you\n

Well, apparently, according to this\n

It's not obvious from\nthis chart what the 33 is

but indeed, this\npattern represents "hi.

And anyone want to guess,\nor if you know, what 33 is?

AUDIENCE: Exclamation point.

DAVID MALAN: Exclamation point.

And this is, frankly, not the\nkind of thing most people know.

But it's easily accessible by a\n

When I said that we just need to\n

They wrote it down in\na book or in a chart.

And, for instance, here is our\n72 for H, here is our 73 for I

and here is our 33\nfor exclamation point.

And computers, Macs, PCs,\niPhones, Android devices

just know this mapping\nby heart, if you will.

They've been designed to\nunderstand those letters.

So here, I might have received "hi.

Technically, what I've received is\n

But it's important to note that when\n

in any format, be it\nemail or text or a file

they do tend to come\nin standard lengths

with a certain number of\nzeros and ones altogether.

And this happens to be 8 plus 8, plus 8.

So just to get the message\n"hi, exclamation point

you would have received at least,\nit would seem, some 24 bits.

But frankly, bits are so tiny,\nliterally and mathematically

that we don't tend to think or\n

You're probably more\nfamiliar with bytes.

B-Y-T-E-S is a byte,\nis a byte, is a byte.

And even those, frankly, aren't\n

How high can you count\nif you have eight bits?

Unless you want to go\nnegative, that's fine.

Long story short, if we actually got\n

and ones, and we figured out what\n

to in decimal, it would\nindeed be 255, or less

if you want to represent\nnegative numbers as well.

So this is useful because now we can\n

but, if the files are bigger,\nkilobytes is thousands of bytes

megabytes is millions of bytes,\ngigabytes is billions of bytes

terabytes are trillions\nof bytes, and so forth.

We have a vocabulary for these\n

The problem is that, if you're using\n

byte per character, and\noriginally, only seven, you

can only represent 255 characters.

And that's actually 256 total\ncharacters, including zero.

And that's fine if you're using\nliterally English, in this case

But there's many human\nlanguages in the world

that need many more symbols\nand, therefore, many more bits.

So, thankfully, the world\ndecided that we'll indeed

support not just the US\nEnglish keyboard, but all

of the accented characters that\n

And heck, if we use enough\nbits, zeros and ones

not only can we represent all\nhuman languages in written form

as well as some emotions\nalong the way, we

can capture the latter with\nthese things called emojis.

And indeed, these are very\nmuch in vogue these days.

You probably send and/or receive\n

These are just characters, like\nletters of an alphabet, patterns

of zeros and ones that you're receiving,\n

For instance, there\nare certain emojis that

are represented with\ncertain patterns of bits.

And when you receive them, your\n

And this newer standard\nis called Unicode.

So it's a superset of\nwhat we called ASCII.

And Unicode is just a mapping of many\n

or characters, more\ngenerally, that might

use eight bits for\nbackwards compatibility

with the old way of doing things with\n

And if you have 16\nbits, you can actually

represent more than\n65,000 possible letters.

And that's getting up there.

And heck, Unicode might even use 32\n

and punctuation symbols and emojis.

And that would give you up\nto 4 billion possibilities.

And, I daresay, one of the reasons we\n

I mean, we've got room for\nbillions more, literally.

So, in fact, just as a\nlittle bit of trivia

has anyone ever received this decimal\n

has anyone ever received this pattern\n

in a text or an email,\nperhaps this past year?

Well, if you actually look this up,\n

happens to represent\nface with medical mask.

And notice that if you've got\nan iPhone or an Android device

you might be seeing different things.

In fact, this is the Android\nversion of this, most recently.

This is the iOS version\nof it, most recently.

And there's bunches of other\ninterpretations by other companies

So Unicode, as a\nconsortium, if you will

has standardized the descriptions\nof what these things are.

But the companies themselves,\nmanufacturers out there

have generally interpreted\nit as you see fit.

And this can lead to some\nhuman miscommunications.

In fact, for like, literally,\n

I started being in the habit of\n

like this because I thought it was\n

I didn't realize this\nis the emoji for hug

because whatever device I was using\n

And that's because of their\ninterpretation of the data.

This has happened too when\nwhat was a gun became a water

pistol in some manufacturers' eyes.

And so it's an interesting dichotomy\n

want to represent and how we\n

Questions, then, on these\nrepresentations of formats

be it numbers or letters, or soon more.

AUDIENCE: Why is decimal\npopular for a computer

if binary is the basis for everything?

DAVID MALAN: Sorry,\nwhy is what so popular?

AUDIENCE: Why is the decimal popular\n

DAVID MALAN: Yeah, so we'll come\n

There are other ways\nto represent numbers.

And hexadecimal is yet a fourth that\n

through 9 plus A, B, C,\nD, E, F. And somehow

you can similarly count\neven higher with those.

We'll see in a few weeks\nwhy this is compelling.

But hexadecimal, long story\nshort, uses four bits per digit.

And so, four bits, if you have two\n

And it's just a very\nconvenient unit of measure.

And it's also human convention in\n

But we'll come back to that soon.

AUDIENCE: Do the lights on the\nstage supposedly say that--

DAVID MALAN: Do the lights on the\nstage supposedly say anything?

Well, if we had thought in advance\nto use maybe 64 light bulbs

that would seem to give us 8\ntotal bytes on stage, 8 times 8

Other questions on 0's and 1's?

It's a little bright in here.

Where everyone's pointing\nsomewhere specific.

AUDIENCE: I was just going\nto ask about the 255 bits

like with the maximum characters.

DAVID MALAN: Ah, sure, and we'll\n

in the coming days too,\nat a slower pace too

we have, with eight bits, two\npossible values for the first

and then two for the next, two\nfor the next, and so forth.

That's 2 to the eighth\npower total, which

means you can have 256 total\n

But as we'll see soon computer\nscientists, programmers

software often starts counting at 0 by\n

patterns, 00000000 to represent\n

you only have 255 other patterns left\n

All right, so what then might we\n

Well, we of course have things\nlike colors and programs

like Photoshop and pictures and photos.

Well let me ask the question again.

How might a computer, do you think,\n

Like what are our options if all we've\n

RGB indeed is this acronym that\nrepresents some amount of red

and some amount of green and\nblue and indeed computers

can represent colors by just doing that.

Remembering, for instance, this dot.

This yellow dot on the screen that\n

these days, well that's some amount\n

And if you sort of mix\nthose colors together

you can indeed get a very specific one.

And we'll see you in\njust a moment just that.

So indeed earlier on, humans\nonly used seven bits total.

And it was only once they decided,\n

got extended ASCII and\nthat was initially in part

a solution to the same problem of\n

in those patterns of zeros and ones\n

But even that wasn't enough and that's\n

So if we come back now to\nthis one particular color.

RGB was proposed as a scheme,\nbut how might this work?

Well, consider for instance this.

If we do indeed decide as a group to\n

with some mixture of some red,\nsome green, and some blue

we have to decide how to represent\n

Well, it turns out if all we have\n

For instance, suppose a computer we're\n

no longer in the context of\nan email or a text message

but now in the context of something\n

and creating graphical files,\nmaybe this first number

could be interpreted as representing\n

And that's exactly what happens.

You can think of the first digit as\n

And so ultimately when you combine that\n

that amount of blue, it turns out it's\n

And indeed, you can come up\nwith a numbers between 0 and 255

for each of those colors to mix any\n

And you can actually\nsee this in practice.

Even though our screens,\nadmittedly, are getting really good

on our phones and laptops such that you\n

You might have heard\nthe term pixel before.

Pixel's just a dot on\nthe screen and you've

got thousands, millions of them these\n

If I take even this\nemoji, which again happens

to be one company's interpretation\nof a face with medical mask

and zoom in a bit, maybe\nzoom in a bit more

you can actually start\nto see these pixels.

Things get pixelated\nbecause what you're seeing

is each of the individual dots\n

And apparently each of\nthese individual dots

are probably using 24 bits, eight bits\n

bits for blue, in some pattern.

This program or some other like\n

and it's white or yellow or\nblack or some brown in between.

So if you look sort of awkwardly, but\n

or maybe your TV, you can\nsee exactly this, too.

All right, well, what\nabout things that we also

watch every day on YouTube or the like?

How would a computer,\nknowing what we know now

represent something like a video?

How might you represent a video\nusing only zeros and ones?

AUDIENCE: As we can see here,\nthey represent images, right?

[INAUDIBLE] sounds of\nthe 0 and 1s as well.

To summarize, what video really\n

It's not just one image, it's\nnot just one letter or a number

it's presumably some kind of\nsequence because time is passing.

So with a whole bunch of images,\nmaybe 24 maybe 30 per second

if you fly them by the\nhuman's eyes, we can

interpret them using our eyes\nand brain that there is now

movement and therefore video.

Similarly with audio or music.

If we just came up with some convention\n

on a musical instrument, could we have\n

And this might be\nactually pretty familiar.

Let me pull up a quick video here,\n

You might remember from childhood.

So granted that particular\nvideo is an actual video

of a paper-based animation, but\n

is some sequence of these images,\nwhich themselves of course

are just zeros and ones because they're\n

Now something like musical notes like\n

might just naturally play\nthese on physical devices

but computers can certainly\nrepresent those sounds, too.

For instance, a popular\nformat for audio is

called MIDI and MIDI\nmight just represent

each note that you saw a moment ago\n

But more generally, you might\nthink about music as having notes

for instance, A through G, maybe\nsome flats and some sharps

you might have the duration like how\n

on a piano or some\nother device, and then

just the volume like how hard\ndoes a human in the real world

press down on that key and\ntherefore how loud is that sound?

It would seem that just remembering\n

we can then represent really all of\n

So that then is really\na laundry list of ways

that we can just represent information.

Again, computers or digital have\nall of these different formats

but at the end of the day and as\nfancy as those devices in years

are, it's just zeros and ones, tiny\n

if you will, represented in some\nway and it's up to the software

that you and I and others\nwrite to use those zeros

and ones in ways we want to get\nthe computers to do something

Questions, then, on this representation\n

is ultimately what problem solving\n

and producing new via\nsome process in between.

AUDIENCE: Yeah, so we talked about how\n

you to interpret information.

How does a file format like .mp4\n

DAVID MALAN: So a really good question.

There are many other\nfile formats out there.

You allude to MP4 for video\nand more generally the use

are these things called\ncodecs and containers.

It's not quite as simple when\nusing larger files, for instance

in more modern formats that a\n

If you stored that many images\nfor like a Hollywood movie

like 24 or 30 of them per second,\n

And if you've ever taken\nphotos on your phone

you might know how many megabytes or\n

So humans have developed over\nthe years a fancier software

that uses much more math to represent\n

just using somehow shorter\npatterns of zeros and ones

than are most simplistic\nrepresentation here.

And they use what might\nbe called compression.

If you've ever used a zip\nfile or something else

somehow your computer is\nusing fewer zeros and ones

to represent the same\namount of information

ideally without losing any information.

In the world of multimedia, which we'll\n

there are both lossy and\nlossless formats out there.

Lossless means you lose\nno information whatsoever.

But more commonly as you're alluding\n

where you're actually throwing\naway some amount of quality.

You're getting some amount\nof pixelation that might not

look perfect to the human, but heck\n

And in the world of multimedia,\n

and other MPEG containers\nthat can combine

different formats of video, different\n

but there, too, do\ndesigners have discretion.

Other questions, then, on\ninformation here as well?

AUDIENCE: So I know\ncomputers used to be very big

and taking up like a\nwhole room and stuff.

Is the reason they've gotten\nsmaller because we can store

this information piecemeal or what?

I mean, back in the day you might\n

tube, which is like some\nphysically large device that

might have only stored some 0 or 1.

Yes, it is the miniaturization\nof hardware these days

that has allowed us to store as many\n

And as we've built more\nfancy machines that

can sort of design this hardware\nat an even smaller scale

we're just packing more and\nmore into these devices.

But there, too, is a trade off.

For instance, you might know by\nusing your phone or your laptop

for quite a while, maybe on\nyour lap, starts to get warm.

So there are these literal\nphysical side effects

of this where now some\nof our devices run hot.

This is why like a data\ncenter in the real world

might need more air conditioning\nthan a typical place

because there are these\nphysical artifacts as well.

In fact, if you'd like to see one of\n

across the river here in now Allston\n

is the Harvard Mark 1 computer that\n

Well if we come back now\nto this first picture

being computer science or\nreally problem solving

I daresay we have more\nthan enough ways now

to represent information, input and\n

on something and thankfully all\nof those before us have given us

things like ASCII and Unicode.

Not to mention MP4s, word\ndocuments, and the like.

But what's inside of this proverbial\n

going in the outputs are coming?

Well that's where we get this\nterm you might have heard, too.

An algorithm, which is just step-by-step\n

incarnated in the world\nof computers by software.

When you write software\naka programs, you

are implementing one or more algorithms,\n

for solving some problem, and maybe\n

but at the end of the day,\nno matter the language

you use the computer is going\nto represent what you type

So what might be a\nrepresentative algorithm?

Nowadays you might use\nyour phone quite a bit

to make calls or send texts\nor emails and therefore you

have a whole bunch of\ncontacts in your address book.

Nowadays, of course,\nthis is very digital

but whether on iOS or\nAndroid or the like

you might have a whole\nbunch of names, first name

and/or last, as well as numbers\nand emails and the like.

You might be in the habit of like\n

all of those names to find\nthe person you want to call.

It's probably sorted alphabetically by\n

This is frankly quite the same as\n

when we just used a physical book.

In this physical book\nmight be a whole bunch

of names alphabetically\nsorted from left to right

corresponding to a\nwhole bunch of numbers.

So suppose that in this\nold Harvard phone book

we want to search for John Harvard.

We might of course start\nquite simply at the beginning

here, looking at one page at a\ntime, and this is an algorithm.

This is like literally step-by-step\nlooking for the solution

In that sense, if John\nHarvard's in the phone book

is this algorithm page-by-page\ncorrect, would you say?

Like if John Harvard's\nin the phone book

obviously I'm eventually going to get to\n

Is it well designed, would you say?

I mean this is going to take forever\n

depending how this thing's sorted.

All right, well let\nme go a little faster.

I'll start like two pages at a time.

2, 4, 6, 8, 10, 12, and so forth.

Sounds faster, is faster, is it correct?

DAVID MALAN: OK, why is it not correct?

AUDIENCE: So if you're\nstarting on page 1

you're only going odd number of pages,\n

If I start on an odd number of\npages and I'm going two at a time

I might miss pages in between.

And if I therefore conclude\nwhen I get to the back

of the book there was no John\n

This would be again one of these bugs.

But if I try a little harder,\nI feel like there's a solution.

We don't have to completely\nthrow out this algorithm.

I think we can probably go\nroughly twice as fast still.

But what should we do\ninstead to fix this?

So I think what many of us, most of us,\n

these days, we might go roughly\nto the middle of the phone book

just to kind of get us started.

And now I'm looking down, I'm looking\n

and it looks like I'm in the M section.

So just to be clear,\nwhat should I do next?

DAVID MALAN: OK, and\npresumably it is John Harvard

would be to the left of this.

So here's an opportunity to\nfiguratively and literally tear

this particular problem in half,\nthrow half of the problem away.

It's actually pretty easy\nif you just do it that way.

But I've now just decreased the\n

So if I started with 1,000 pages\nof phone numbers and names, now

And already we haven't\nfound John Harvard

but that's a big bite\nout of this problem.

I do think it's correct because if\n

he's definitely not\ngoing to be over there.

I think if I repeat this again\n

here I might have gone a little too far.

Now I'm in like the E section.

So let me tear the problem in half\n

and again repeat, dividing\nand dividing and conquering

until finally, presumably, I end\n

book on which John Harvard's\nname either is or is not

but because of the algorithm\nyou proposed, step by step

I know that he's not in\nanything I discarded.

So traumatic is that\nmight have been made out

to be, it's actually just harnessing\n

Indeed, this is what\nprogramming is all about, too.

It's not about learning\na completely new world

but really just how to harness intuition\n

have and take naturally\nbut learning how to express

them now more succinctly,\nmore precisely

using things called\nprogramming languages.

Why is an algorithm like that if I found\n

just doing the first\none or even the second

and maybe doubling back\nto check those even pages?

Well let's just look\nat little charts here.

Again, we don't have to get\ninto the nuances of numbers

but if we've got like a chart\nhere, xy plot, on the x-axis

here I claim as the size of the problem.

So measured in the numbers\nof pages in the phone book.

So the farther you go out here, the\n

And here we have time\nto solve on the y-axis.

So the higher you go\nup, the more time it's

going to be taking to solve\nthat particular problem.

So let's just arbitrarily say that\n

like n pages, might be\nrepresented graphically like this.

No matter the slope,\nit's a straight line

because there's presumably\na one to one relationship

between numbers of pages and number\n

If the phone company adds\nanother page next year

because some new people\nmove to town, that's

going to require one\nadditional page for me.

If, though, we use the second\nalgorithm, flawed though it was

unless we double back a little bit\n

that's too going to be a\nstraight line, but it's

going to be a different slope because\n

relationship because I'm\ngoing to pages at a time.

So if the phone company adds\nanother page or another two pages

that still only just one more step.

You can see the difference\nif I kind of draw this.

If this is the phone book in\nquestion, this number of pages

it might take this many\nseconds on the yellow line

to represent or to find\nsomeone like John Harvard.

But of course on the first\nalgorithm, the red line

it's literally going to\ntake twice as many steps.

And what do the n here mean?\nn is the go-to variable

for computer scientist or programmer\n

So if the number of pages\nin the phone book is n

the number of steps the second\nalgorithm would have taken

would be in the worst case n over 2.

Half as many because\nyou're going twice as fast.

But the third algorithm, actually\nif you recall your logarithms

looks a little something like this.

There's a fundamentally\ndifferent relationship

between the size of the problem and\n

that technically is\nlog-based, too, again

but it's really the\nshape that's different.

The implication there is that if,\n

two different towns here in\nMassachusetts, merge next year

and there's just one phone\nbook that's twice as big

no big deal for that\nthird and final algorithm.

You just tear the problem\none more time in half

taking one more byte,\nthat's it, not another 1,000

bytes just to get to the solution.

Put another way, you\ncan walk it way, way

way out here to a much bigger\nphone book and ultimately

that green line is barely\ngoing to have budged.

So this then is just a way of\nnow formalizing and thinking

about what the performance or\n

Before we now make one more\n

any questions then on this notion of\n

AUDIENCE: How many phone\nbooks have you got?

DAVID MALAN: (LAUGHING) A lot\nof phone books over the years

and if you or your parents have any\n

use them because they're hard to find.

AUDIENCE: You could get Harry\nPotter as a guest speaker.

DAVID MALAN: Sorry, say again.

AUDIENCE: You could get Harry\nPotter as a guest speaker.

DAVID MALAN: (LAUGHING) Oh, yeah.

Then we'd have a little\nsomething more to use here.

So now if we want to formalize\nfurther what it is we just did

we can go ahead and introduce this.

A form of code aka pseudocode.

Pseudocode is not a specific\nlanguage, it's not like something

we're about to start coding in, it's\n

in English or any human\nlanguage succinctly

correctly toward an end of getting\n

So for instance, here\nmight be how we could

formalize the code, the pseudocode\nfor that same algorithm.

Step one was pick up the\nphone book, as I did.

Step two might be open to\nthe middle of the phone book

as you proposed that we do first.

Step three was probably to\nlook down at the pages, I did.

And step four gets a\nlittle more interesting

because I had to quickly make a\n

If person is on page, then\nI should probably just

go ahead and call that person.

But that probably wasn't the\ncase at least for John Harvard

So there's this other\nquestion I should now

ask else if the person\nis earlier in the book

then I should tear the problem\nin half as I did but go left, so

to speak, and then not just open to the\n

but really just go back to\nstep three, repeat myself.

Because I can just repeat what I\n

But, if the person\nwas later in the book

as might have happened with a\n

then I should open to the middle\nof the right half of the book

again go back to line\nthree, but again, I'm

not going to get sucked doing\nsomething forever like this

because I keep shrinking\nthe size of the problem.

Lastly, the only\npossible scenario that's

left, if John Harvard is not on\n

and he's not to the right,\nwhat should our conclusion be?

DAVID MALAN: He's not there.

So we need to quit in some other form.

Now as an aside, it's kind of deliberate\n

at the end because this is what\n

whether you're new at\nit or professional

just not considering all possible\n

that might not happen that often,\n

in your own code,\npseudocode or otherwise

this is when and why\nprograms might crash

or you might say stupid little\n

or your computer might reboot.

It's doing something\nsort of unpredictable

if a human, maybe myself,\ndidn't anticipate this.

Like what does this program do if\n

if I had omitted lines 12 and 13?

Maybe it would behave\ndifferently on a Mac or PC

because it's sort of undefined behavior.

These are the kinds of omissions\nthat frankly you're invariably

going to make, bugs\nyou're going to introduce

mistakes you're going to make early\n

But you'll get better at\nthinking about those corner cases

and handling anything that can\n

your code will be all the better for it.

Now the problem ultimately\nwith learning how to program

especially if you've\nnever had experience

or even if you do but you\nlearned one language only

is that they all look a little\ncryptic at first glance.

But they do share certain commonalities.

In fact, we'll use this\npseudocode to define those first.

Highlighted in yellow\nhere are what henceforth

we're going to start calling functions.

Lots of different programming\nlanguages exist, but most of them

have what we might call\nfunctions, which are actions

or verbs that solve\nsome smaller problem.

That is to say, you might use\na whole bunch of functions

to solve a bigger problem\nbecause each function tends to do

something very specific or precise.

These then in English might be\n

code, to these things called functions.

Highlighted in yellow now are\nwhat we might call conditionals.

Conditionals are things\nthat you do conditionally

based on the answer to some question.

You can think of them kind\nof like forks in the road.

Do you go left or go right\nor some other direction

based on the answer to some question?

Well, what are those questions?

Highlighted now in yellow or what we\n

after a mathematician last name Bool,\n

Or, if you prefer, true or false answers\n

We just need to distinguish\none scenario from another.

The last thing manifests\nin this pseudocode

is what I might highlight\nnow and call loops.

Some kind of cycle, some kind of\n

again and again so that I don't\n

a 1,000-page phone book, I can get\n

of repeat myself inherently in order to\n

So this then is what we\nmight call pseudocode

and indeed there are\nother characteristics

of programs that we'll touch on before\n

values, variables, and more, but\n

including some we will very\ndeliberately use in this class

and that everyone in the real\nworld these days still uses

its programs tend to look like this.

This for instance, is a distillation\nof that very first program

I wrote in 1996 in CS50 itself just\n

In fact, this version here just tries\n

Which is, dare say, the most\ncanonical first thing that most

any programmer ever gets a\ncomputer to say just because

I mean, there's a hash symbol,\n

words like int, curly braces, quotes,\n

I mean there's more overhead\nand more syntax and clutter

than there is an actual idea.

Now that's not to say that you won't\n

because honestly there's not that many\n

have typically a much smaller vocabulary\n

but at first it might\nindeed look quite cryptic.

But you can perhaps infer I have no\n

but "Hello, world." is\npresumably quote unquote what

will be printed on the screen.

But what we'll do today,\nafter a short break

and set the stage for\nnext week is introduce

these exact same ideas in\njust a bit using Scratch

something that you\nyourselves might have used

when you're quite younger but\n

The upside of what we'll soon do using\n

language from our friends down the\n

start to drag and drop things that\n

together if it makes\nlogical sense to do so

but without the distraction\nof hashes, parentheses

curly braces, angle brackets,\nsemicolons, and things

that are quite beside the point.

But for now, let's go ahead\nand take a 10 minute break here

and when we resume, we\nwill start programming.

So this on the screen\nis a language called

C something that will dive\ninto next week and thankfully

this now on the screen is\nanother language called Python

that we'll also take a look at\nin a few weeks before long along

with other languages along the way.

Today though, and for this first\nweek, week zero, so to speak

we use Scratch because\nagain it will allow

us to explore some of those\nprogramming fundamentals

that will be in C and in Python and in\n

but in a way where we don't have to\n

So the world of Scratch looks like this.

It's a web-based or downloadable\nprogramming environment

that has this layout here\nby default. On the left here

we'll soon see is a palette of puzzle\n

represent all of those\nideas we just discussed.

And by dragging and\ndropping these puzzle pieces

or blocks over this big area\nand connecting them together

if it makes logical\nsense to do so, we'll

start programming in this environment.

The environment allows you to have\n

Multiple characters, things\nlike a cat or anything

else, and those sprites exist\nin this rectangular world

up here that you can full screen to\n

is Scratch, who can move up, down, left,\n

Within its Scratch's\nworld you can think of it

as perhaps a familiar\ncoordinate system with Xs and Ys

which is helpful only when it comes\n

Right now Scratch is at the default,\n

If you were to move the cat way\n

If you move the cat all the way\n

but y would now be negative 180.

And if you went left, x would become\n

or to the right x would be\n240 and y would stay zero.

So those numbers generally don't\n

move relatively in this\nworld up, down, left, right

but when it comes time\nto precisely position

some of these sprites\nor other imagery, it'll

be helpful just to have that mental\n

Well let's go ahead and make perhaps\n

I'm going to switch over to the\nsame programming environment

now for a tour of the left hand side.

So by default selected here are\nthe category in blue motion

which has a whole bunch of puzzle\n

And whereas Scratch as\na graphical language

categorizes things by the type\nof things that these pieces do

we'll see that throughout\nthis whole palette

we'll have functions and\nvariables and conditionals

and Boolean expressions and more\n

So for instance, moving 10 steps\nor turning one way or the other

would be functions categorized\nhere as things like motion.

Under looks in purple, you\nmight have speech bubbles

that you can create by\ndragging and dropping

these that might say "hello" or\n

Or you could switch costumes, change\n

You can play sounds like "meow" or\n

Then there's these things Scratch calls\n

is the first, when green flag clicked.

Because if we look over to the\nright of Scratch's world here

this rectangular region has\nthis green flag and red stop

sign up above, one of which is\nfor Play one of which is for Stop

and so that's going to allow us to\n

when that green flag\nis initially clicked.

But you can listen for other types of\n

or something else, when this sprite\n

Here you already see like a\nprogrammer's incarnation of things

you and I take for granted like\nevery day now on our phones.

Any time you tap an icon or drag your\n

These are what a programmer\nwould call events

things that happen and\nare often triggered by us

humans and things that a program\nbe it in Scratch or Python

or C or anything else can\nlisten for and respond to.

Indeed, that's why when you tap\nthe phone icon on your phone

the phone application\nstarts up because someone

wrote software that's listening for a\n

So Scratch has these same things, too.

Under Control in orange,\nyou can see that we

can wait for one second\nor repeat something

some number of times,\n10 by default, but we

can change anything in these\nwhite circles to anything else.

There's another puzzle\npiece here forever

which implies some kind of loop where\n

Even though it seems a\nlittle tight, there's

not much room to fit\nsomething there, Scratch

is going to have these\nthings grow and shrink

however we want to fill\nsimilarly shaped pieces.

Here are those conditionals.

If something is true or false,\nthen do this next thing.

And that's how we can put in\nthis little trapezoid-like shape.

Some form of Boolean expression, a\n

or one/zero answer and decide\nwhether to do something or not.

You can combine these things, too.

If something is true, do this,\nelse do this other thing.

And you can even tuck\none inside of the other

if you want to ask three\nor four or more questions.

Sensing, too, is going to be a thing.

You can ask questions aka Boolean\n

the mouse pointer, the\narrow on the screen?

So that you can start to\ninteract with these programs.

What is the distance between\na sprite and a mouse pointer?

You can do simple calculations\njust to figure out maybe

if the enemy is getting\nclose to the cat.

Under Operator some lower level\n

to pick random numbers,\nwhich for a game is great

because then you can kind\nof vary the difficulty

or what's happening in a game\nwithout the same game playing

Something and something must be true\n

Or we can even join two words together.

Says apple and banana by default,\n

whatever you want there to\ncombine multiple words into full

Then lastly down here, there's in\n

In math we've obviously\ngot x and y and whatnot.

In programming we'll\nhave the same ability

to store in these named symbols,\n

Numbers or letters or words or\ncolors or anything, ultimately.

But in programming you'll see that\n

use simple letters like x\nand y and z, but to actually

give variables full singular or plural\n

Then lastly, if this isn't\nenough color blocks for you

you can create your own blocks.

Indeed, this is going to be a\n

and with the first problem set whereby\n

pieces and you realize, oh, would have\n

have just been replaced by one\nhad MIT thought to give me that

one puzzle piece, you yourself\ncan make your own blocks

by connecting these all together,\ngiving them a name, and boom

a new puzzle piece will exist.

So let's do the simplest,\nmost canonical programs

here, starting up with\ncontrol, and I'm going

to click and drag and drop this\n

Then I'm going to grab one\nmore, for instance under Looks

and under Looks I'm going\nto go ahead and just say

something like initially not\njust Hello but the more canonical

Now you might guess that in\nthis programming environment

I can go over here now and\nclick the green flag and voila

So that's my first\nprogram and obviously much

more user friendly than typing out\n

saw on the screen that you,\ntoo, will type out next week.

But for now, we'll just focus on\n

So what it is that just happened?

This purple block here is\nSay, that's the function

and it seems to take some form of input\n

Well this actually fits\nthe paradigm that we looked

at earlier of just inputs and outputs.

So if I may, if you consider\nwhat this puzzle piece is doing

The input in this case is going\n

The algorithm is going to be implemented\n

and the output of that is going\nto be some kind of side effect

like the cat and the speech\nbubble are saying Hello, world.

So already even that\nsimple drag and drop

mimics exactly this relatively\nsimple mental model.

So let's take things further.

Let's go ahead now and make the\n

that it says something like\nHello, David, or Hello, Carter

or Hello to you specifically.

And for this, I'm going\nto go under Sensing.

And you might have to poke around\n

around, but I've done this a few times\n

Ask what's your name,\nbut that's in white

so we can change the\nquestion to anything

we want, and it's going to wait for\n

This function called Ask\nis a little different

from the Say block, which just had\n

The ask function is even more powerful\n

This function is going\nto hand you back what

they typed in in the form of\nwhat's called a return value, which

is stored ultimately and by\ndefault this thing called Answer.

This little blue oval here\ncalled Answer is again

one of these variables\nthat in math would

be called just x or y but in\n

So I'm going to go ahead and do this.

Let me go ahead and\ndrag and drop this block

and I want to ask the question\nbefore saying anything

but you'll notice that\nScratch is smart and it's

going to realize I want to\ninsert something in between

and it's just going to\nmove things up and down.

I'm going to let go and ask the\n

And now if I want to go ahead\nand say hello, David or Carter

let's just do Hello\ncomma, because I obviously

don't know when I'm writing the\nprogram who's going to use it.

So let me now grab another looks block\n

let me go back to Sensing and now\n

by this other puzzle piece, and\n

Notice it's the same shape, even\n

Things will grow or shrink as needed.

All right, so let's now zoom out.

Let me go and stop the old version\n

Let me hit the green\nflag and what's my name?

All right, maybe I just wasn't\npaying close enough attention.

Green flag, D-A-V-I-D, Enter.

What's the bug or\nmistake might you think?

AUDIENCE: Do you need to somehow add\n

DAVID MALAN: Yeah, we kind of want\n

And it's technically a bug because\n

It's just saying David\nafter I asked for my name.

I'd like it to say\nmaybe Hello then David

but it's just blowing past\nthe Hello and printing David.

But let's put our finger\non why this is happening.

You're right for the solution, but\n

AUDIENCE: So it says hello,\nbut it gets to that last step

so quickly you can't see it.

I mean, computers are\nreally darn fast these days.

It is saying Hello, all of us\nare just too slow in this room

to even see it because it's then saying\n

So there's a couple of solutions\nhere, and yours is spot on

but just to poke around,\nyou'll see the first example

of how many ways in programming be\n

else, that there are going\nto be to solve problems?

We'll teach you over the\ncourse of these weeks

sometimes some ways are\nbetter relatively than others

but rarely is there a\nbest way necessarily

because again reasonable\npeople will disagree.

And what we'll try to teach\nyou over the coming weeks

is how to kind of think\nthrough those nuances.

And it's not going to be\nobvious at first glance

but the more programs you\nwrite, the more feedback

you get, the more bugs\nthat you introduce

the more you'll get your footing with\n

So let me try this in a couple of ways.

Up here would be one\nsolution to the problem.

MIT anticipated this kind of issue,\n

and I could just use a\npuzzle piece that says

say the following for\ntwo seconds or one second

or whatever, then do the\nsame with the next word

and it might be kind\nof a bit of a pause

Hello, one second, two seconds, David,\n

it would look a little\nmore grammatically correct.

But I can do it a little more\nelegantly, as you've proposed.

Let me go ahead and throw\naway one of these blocks

and you can just drag and let\ngo and it'll delete itself.

Let me go down to Operators because\n

So even if you're not sure what goes\n

Let me go ahead and\nsay hello comma space.

Now it could just say by\ndefault Hello, banana

but let me go back to\nSensing, Drag answer

and that's going to drag and drop there.

So now notice we're sort of stacking\n

so that the output of one becomes the\n

Let me go ahead and zoom\nout, hit Stop, and hit Play.

All right, what's your name?

Now it's presumably\nas we first intended.

So consider that even with\nthis additional example

it still fits the same mental model,\n

Here's that new function\nAsk something and wait.

And notice that in this case too\n

henceforth as an argument\nor a parameter, programming

speak for just an input in\nthe context of a function.

If we use our drawing as before\nto represent this thing here

we'll see that the input now is going\n

The algorithm is going to be implemented\n

the function called Ask, and the\noutput of that thing this time

is not going to be the\ncat saying anything yet

but rather it's going\nto be the actual answer.

So instead of the visual side effect\n

now nothing visible is happening yet.

Thanks to this function it's sort of\n

with whatever I typed in written on it\n

Now what did I then do with that value?

Well consider that with\nthe subsequent function

we had this Say block,\ntoo, combined with a join.

So we have this variable\ncalled Answer, we're joining it

with that first argument, Hello.

So already we see that\nsome functions like Join

can take not one but two arguments,\nor inputs, and that's fine.

The output of Join is presumably going\n

or whatever the human typed in.

That output notice is essentially\n

Say, just because we've\nkind of stacked things

or nested them on top of one another.

But methodically, it's\nreally the same idea.

The input now are two things,\nHello comma and the return value

from the previous Ask function.

The function now is going to be Join,\n

But that Hello, David\noutput is now going

to become the input to another function,\n

and that's then going to have the side\n

So again as sort of sophisticated\n

are going to get, they really do\n

of inputs and outputs and you just have\n

and to know what kinds of puzzle\n

But you can ultimately really\nkind of spice these things up.

Let me go back to my\nprogram here that just is

using the speech bubble at the moment.

Scratch's inside has some pretty\n

I click the Extensions button\nin the bottom left corner.

And let me go ahead and choose\nthe Text to Speech extension.

This is using a Cloud service, so\n

it can actually talk to the\nCloud or a third party service

and this one is going to give me a\n

the ability to speak\nsomething from my speakers

instead of just saying it textually.

So let me go ahead and drag this.

Now notice I don't have to interlock\n

and I want to move some things around.

I just want to use this as\nlike a canvas temporarily.

Let me go ahead and\nsteal the Join from here

put it there, let me throw away\nthe Say block by just moving it

left and letting go, and\nnow let me join this in

so I've now changed my program\nto be a little more interesting.

So now let me stop the old version.

DAVID MALAN: (LAUGHING)\nOK, minus 2 for real.

All right, so what I accidentally\n

for instructional purposes,\nwas the actual answer

that came back from the ask block.

So now if I play this again,\nlet's click the green icon.

OK, so we have these functions then\n

Well what about those conditionals\n

How can we bring these programs\nto life so it's not just

clicking a button and voila,\nsomething's happening?

Let's go ahead and make this\nnow even more interactive.

Let me go ahead and throw\naway most of these pieces

and let me just spice things up\n

I'm going to go to Play\nSound Meow until done.

OK, it's a little loud, but it\ndid exactly do what it said.

It's kind of an underwhelming\nprogram eventually

since you'd like to think that the\n

I have to keep hitting the button.

Well this seems like an opportunity\n

So all right, well if I\nwanted to meow, meow, meow

let me just grab a few of these, or you\n

and you can Copy Paste\neven in code here.

All right, so now like\nit's not really emoting

happiness in quite the same way.

Let me go to Control, wait\none second in between

which might be a little less worrisome.

OK, so if my goal was to make\nthe cat meow three times

I dare say this code or\nalgorithm is correct.

But let's now critique its design.

AUDIENCE: You could use the forever\n

DAVID MALAN: Yeah, so yeah, agreed.

I could use forever or repeat,\nbut let me push a little harder.

Like this works, I'm kind of done with\n

AUDIENCE: There's too much repetition.

DAVID MALAN: Yeah, there's\ntoo much repetition, right?

If I wanted to change the\nsound that the cat is making

to a different variant of meow or\n

I could change it from the\ndropdown here apparently

but then I'd have to change it here\n

and God, if this were even longer\nthat just gets tedious quickly

and you're probably\nincreasing the probability

that you're going to\nscrew up and you're going

to miss one of the dropdowns or\n

Or, if you wanted to change the\n

you've got to change it in\ntwo, maybe even more places.

Again, you're just\ncreating risk for yourself

and potential bugs in the program.

So I do like the repeat or the forever\n

And indeed, what I\nalluded to being possible

copy pasting earlier, doesn't\nmean it's a good thing.

And in code, generally\nspeaking, when you

start to copy and paste puzzle\npieces or text next week

you're probably not doing\nsomething quite well.

So let me go ahead and throw away most\n

keeping just two of the\nblocks that I care about.

Let me grab the Repeat block for now,\n

block, it's going to grow to fit\nit, let me reconnect all this

and change the 10 just\nto a 3, and now, Play.

It's still correct, but\nnow I've set the stage

to let the cat meow, for instance,\n

40 times by changing one thing, or\n

and just walk away and it\nwill meow forever instead.

If that's your goal,\nthat would be better.

A better design but still correct.

Now that I have a\nprogram that's designed

to have a cat meow, wow like why?

I mean, MIT invented\nScratch, Scratch as a cat

why is there no puzzle\npiece called Meow?

This feels like a missed opportunity.

Now to be fair, they gave\nus all the building blocks

with which we could implement that\n

and really computer science\nis to leverage what we're

going to now start calling Abstraction.

We have step-by-step instructions\nhere, the Repeat, the Play

and the Wait that collectively\nimplements this idea

that we humans would call meowing.

Wouldn't it be nice to abstract\naway those several puzzle

pieces into just one that literally\n

Well here's where we\ncan make our own blocks.

Let me go over here to Scratch\nunder the pink block category

here and let me click Make a Block.

Here I see a slightly\ndifferent interface

where I can choose a name for it\nand I'm going to call it Meow.

Now I'm just going to\nclean this up a bit here.

Let me drag and drop Play\nSound and Wait over here.

I'm just going to drag this\nway down here, way down

here because now that I'm\ndone implementing Meow

I'm going to literally abstract\nit away, sort of out of sight

out of mind, because now notice at\n

So at this point, I'd argue it doesn't\n

Frankly, I don't know how Ask\nor Say was implemented by MIT.

They abstracted those\nthings away for us.

Now I have a brand new puzzle\npiece that just says what it is.

And this is now still correct,\nbut arguably better design.

Because it's just more\nreadable to me, to you

it's more maintainable\nwhen you look at your code

a year from now for the first time\n

back at the very first\nprogram you wrote.

The function itself has semantics,\n

If you really care about\nhow Meow is implemented

you could scroll down and start\nto tinker with the underlying

implementation details, but otherwise\n

Now I feel like there's an\neven additional opportunity

here for abstraction and to factor\n

It's kind of lame that I\nhave this Repeat block that

lets me call the Meow function,\n

Wouldn't it be nice if I could\njust call them Meow function

aka use the Meow function, and pass\n

piece how many times I want it to meow?

Well let me go ahead and\nzoom out and scroll down.

Let me right click or Control click on\n

or I could just start from scratch,\n

Now here, rather than just give this\n

I'm going to go ahead and\ntype in, for instance, n

for number of times to\nmeow, and just to make

this even more user friendly\nand self descriptive

I'm going to add a label,\nwhich has no functional impact

it's just an aesthetic,\nand I'm just going

to say Times, just to make\nit read more like English

in this case that tells me\nwhat the puzzle piece does.

And now I need to refine\nthis a little bit.

Let me go ahead and grab\nunder Control a repeat block

let me move the Play, Sound,\nand Wait, into the repeat block.

I don't want 10 and I\nalso don't want 3 here.

What I want now is this n that is\n

is creating for me that represents\n

Notice that snaps right in place.

Let me connect this and now voila, I\n

It takes input that affects\nits behavior accordingly.

Now I'm going to scroll back up,\n

I just care that Meow exists.

Now I can tighten up my code, so\nto speak, use even fewer lines

to do the same thing by\nthrowing away the Repeat block

reconnecting this new puzzle piece here\n

now we're really programming, right?

We've not made any forward\nprogress functionally.

The thing just mouse three times.

As you program more and\nmore, these are the kinds

of instincts still start\nto acquire so that one

you can start to take a big assignment,\n

for homework even, that feels kind of\n

But if you start to identify what are\n

Then you can start making progress.

I do this to this day where if I have to\n

it's so easy to drag my feet and ugh,\n

until I just start writing\ndown like a to do list

and I start to modularize the\nprogram and say, all right, well

what do I want this thing to do?

I've got to have it say\nsomething on the screen.

All right, I need to have it\nsay something on the screen

Like literally a mental or written\n

if you will, in English on a\npiece of paper or text file

and then you can decide,\nOK, the first thing I

need to do for homework to\nsolve this real world problem

I need to use a bunch\nof other code, too

but I need to create a\nMeow function and boom

now you have a piece of the problem\n

book there, but in this case, we'll\n

All right, so what more can we do?

Let's add a few more\npieces to the puzzle here.

Let's actually interact\nwith the cat now.

Let me go ahead and now when the\n

and ask a question using an event here.

Let me go ahead and\nsay, let's see, I want

to do something like implement\nthe notion of petting the cat.

So if the cursor is touching the\n

it'd be cute if the cat meows\nlike you're petting a cat.

So I'm going to ask the question,\n

if let's see I think I need Sensing.

So if touching mouse\npointer, this is way too big

but again the shape is\nfine, so there goes.

And then if it's touching\nthe mouse pointer

that is if the cat to whom\nthis script or this program

any time I attach puzzle\npieces MIT calls them a script

or like a program, if you will, let\n

and say play sound meow until done.

All right, so here it is to be clear.

When the green flag is\nclicked, ask the question

if the cat is touching the mouse\npointer then place sound meow.

I'm worried it's not Scratch's\nfault. Feels like mine.

Yeah, in back, who just turned.

DAVID MALAN: Yeah, the problem is\n

Scratch asks the question, is the\n

And obviously it's not because the\n

It's fine if I move the cursor\ndown there, but too late.

The program already asked the question.

The answer was no or false or zero,\n

So what might be the solution here be?

I could move my cursor\nquickly, but that feels

like never going to work out right.

Could you use the forever loop?

So I could indeed use this Forever\n

to just constantly listen to me, well\n

or at least forever as\nlong as the program is

running until I explicitly hit Stop.

Let me go to Control, let\nme grab the Forever block

let me move the If inside of this\nForever block, reconnect this

go back up here, click the green\n

but let me try moving my cursor now.

So now the cat is actually\nresponding and it's

going to keep doing\nthis again and again.

So now we have this idea of taking these\n

pieces, assembling them into\nsomething more complicated.

I could definitely put a name to this.

I could create a custom\nblock, but for now

let's just consider what kind\nof more interactivity we can do.

Let me go ahead and do this.

By again grabbing a,\nwhen green flag clicked

let me go ahead and\nclick the video sensing

and I'm going to rotate the\nlaptop because otherwise we're

going to get a little inception thing\n

So I'm going to go reveal to\nyou what's inside the lectern

Now that we have a non video\nbackdrop, I'm going to say this.

Instead of the green flag\nclicked, actually, I'm

going to say when the video motion\n

measurement of motion, I'm going to go\n

And then I'm going to\nget out of the way.

We'll put them on top of there.

So my hand is moving faster\nthan 50 something or other

whatever the unit of measure is.

DAVID MALAN: (LAUGHING) Thank you.

So now we have an even\nmore interactive version.

But I think if I sort of slowly.

It's completely creepy, but I'm\n

Until finally my hand\nmoves as fast as that.

And so here actually is\nan opportunity to show you

something a former student did.

Let me go ahead and zoom out\nof this in just a moment.

(LAUGHING) If someone\nwould be comfortable

coming up not only masked but\nalso on camera on the internet

I thought we'd play one of your former\n

Would anyone like to volunteer\nhere and be up on stage?

Let me get it set up for you here.

All right, let me go ahead\nand full screen this here.

So this is whack-a-mole by one\nof your firmer predecessors.

It's going to use the camera focusing\n

to position inside of this rectangle.

Have you ever played the\nwhack-a-mole game at an arcade?

So for those who haven't,\nthese little moles pop up

and with a very fuzzy\nhammer you sort of hit down.

You though, if you\ndon't mind, you're going

to use your head to do this virtually.

So let's line up your head with\n

And now hit the moles with your head.

All right, a round of\napplause for Sahar.

So beyond having a\nlittle bit of fun here

the goal was to\ndemonstrate that by using

some fairly simple, primitive,\nsome basic building blocks

but assembling them in a fun\nway with some music, maybe

some new costumes or artwork, you\n

But at the end of the day, the\n

were ones like the ones I just\n

because there were\nclearly lots of moles.

So the student probably created a few\n

but at least four different moles.

They had like some kind of graphic\n

There were some kind of\ntimer, maybe a variable

that every second was counting down.

So you can imagine taking what looks\n

at first glance, and\nperhaps overwhelming

to solve yourself, but just think about\n

And pluck off one piece of the\npuzzle, so to speak, at a time.

So indeed if we rewind a little bit.

Let me go ahead here\nand introduce a program

that I myself made\nback in graduate school

when Scratch was first\nbeing developed by MIT.

Let me go ahead and open\nhere, give me just one second

something that I called back\nin the day Oscar Time that

looks a little something like this.

If I fullscreen it and hit Play.

[MUSIC - SESAME STREET, "I LOVE TRASH"]

OSCAR THE GROUCH:\n(SINGING) Oh, I love trash.

DAVID MALAN: So you'll notice\na piece of trash is falling.

I can click on it and drag and as I get\n

OSCAR THE GROUCH: (SINGING)\nAnything ragged or--

DAVID MALAN: It wants\nto go in, it seems.

OSCAR THE GROUCH: (SINGING) Yes, I--

OSCAR THE GROUCH: (SINGING) If you\n

DAVID MALAN: I'll do\nthe same, two points.

OSCAR THE GROUCH: (SINGING) I have here\n

DAVID MALAN: There's a\nsneaker falling from the sky

so another sprite of some sort.

OSCAR THE GROUCH: (SINGING)\nThe laces are torn.

DAVID MALAN: I can also\nget just a little lazy

and just let them fall into the\ntrash themself if I want to.

So you can see it doesn't have\nto do with my mouse cursor

it has to do apparently\nwith the distance here.

Let's listen a little further.

I think some additional trash\nis about to make its appearance.

Presumably there's some kind of variable\n

OSCAR THE GROUCH: (SINGING) I love--

DAVID MALAN: OK, let's see\nwhat the last chorus here is.

OSCAR THE GROUCH:\n(SINGING) Rotten stuff.

I have here some newspaper, crusty and

DAVID MALAN: OK, and thus he continues.

And the song actually\ngoes on and on and on

and I do not have fond memories\nof implementing this and hearing

this song for like 10\nstraight hours, but it's

a good example to just consider\nhow was this program composed?

How did I go about implementing\nit the first time around?

And let me go ahead and\nopen up some programs now

that I wrote in advance\njust so that we could

see how these things are assembled.

Honestly, the first thing\nI probably did was probably

to do something a little like this.

Here is just a version\nof the program where

I set out to solve\njust one problem first

of planting a lamp post in the program.

I kind of had a vision of what I wanted.

You know, it evolved\nover time, certainly

but I knew I wanted\ntrash to fall, I wanted

a cute little Oscar\nthe Grouch to pop out

of the trashcan, and some other\nstuff, but wow that's a lot

I'm going to start easy, download\na picture of a lamp post

and then drag and drop it into the\n

It doesn't functionally do anything.

I mean, literally that's the\ncode that I wrote to do this.

All I did was use like\nthe Backdrops feature

and drag and drop and\nmove things around

but it got me to version\none of my program.

Then what might version two be?

Well I considered what\npiece of functionality

frankly might be the easiest to\n

That seems like a pretty\ncore piece of functionality.

It just needs to sit\nthere most of the time.

So the next thing I\nprobably did was to open up

for instance, the trash can version\n

So this time I'll show\nyou what's inside here.

There is some code, but not much.

Notice at bottom right I change the\n

instead, but it's the same\nprinciple that I can control.

And then over here I added this code.

When the green flag is\nclicked, switch the costume

to something I arbitrarily\ncalled Oscar 1.

So I found a couple\nof different pictures

of a trash can, one that looks\n

and eventually one that\nhas Oscar coming out

and I just gave them different names.

So I said Switch to Oscar 1, which\nis the closed one by default

then forever do the following:\nif touching the mouse pointer

then switch the costume to\nOscar 2, else switch to Oscar 1.

That is to say, I just wanted to\n

and closing, even if it's not\nexactly what I wanted ultimately

I just wanted to make\nsome forward progress.

So here, when I run this program by\n

Nothing yet, but if I get\ncloser to the trash can

it indeed pops open because\nit's forever listening

for whether the sprite,\nthe trash can in this case

is touching the mouse pointer.

That was version 2, if you will.

If I went in now and added the lamp\n

now we're starting to make progress.

Now it would look a little\nsomething more like the program

I intended ultimately to create.

What piece did I probably\nbite off after that?

Well, I think what I did\nis I probably decided

let me implement one of the pieces of\n

Let's just get one piece of\ntrash working correctly first.

So let me go ahead and open this one.

And again, all of these examples will\n

so you can see all of\nthese examples, too.

It's not terribly long, I\njust implement it in advance

so we could flip\nthrough kind of quickly.

On the right hand side, I turned\nmy sprite into a piece of trash

this time instead of a cat,\ninstead of a trash can

and I also created, with Carter's help,\n

It's literally just a black line\nbecause I just wanted initially

to have some notion of a\nfloor so I could detect

if the trash is touching the floor.

Now without seeing the code yet,\njust hearing that description

why might I have wanted the second\n

with the trash intending\nto fall from the sky?

What might I have been thinking?

Like what problem might\nI be trying to solve?

AUDIENCE: You don't want the\nfirst sprite to go through it.

DAVID MALAN: Yeah, you don't want\n

go through, and then boom,\nyou completely lose it.

That would not be a very useful thing.

Or it would seem to maybe eat up more\n

if the trash is just endlessly\nfalling and I can't grab it.

It might be a little traumatic\nif you tried to get it

and you can't pull it back out\nand you can't fix the program.

So I just wanted the thing to stop.

So how might I have implemented this?

Let's look at the code at left.

Here I have a bit of randomness,\nlike I proposed earlier exists.

There's this blue\nfunction called Go To x

y that lets me move a\nsprite to any position

up, down, left, right, I picked a random\n

negative 240 to positive 240, and then\n

This just makes the\ngame more interesting.

It's kind of lame pretty quickly if the\n

Here's this a little bit of randomness,\n

So now if I click the green flag,\nyou'll see that it just falls

nothing interesting is\ngoing to happen, but it

does stop when it touches the black\n

I'm forever asking the question if\n

is to the floor is greater\nthan zero, that's fine.

Change the y location by negative 3.

So move it down 3 pixels, down 3\n

is not greater than zero, it is zero\n

it should just stop moving altogether.

There's other ways we could\nhave implemented this

but this felt like a nice,\nclean way that logically, just

OK, now I got some trash falling, I\n

I have a lamp post, now I'm a\ngood three steps into the program.

If we consider one or two\nfinal pieces, something

like the dragging of the trash, let me\n

Dragging the trash requires\na different type of question.

I only need one sprite, no\nfloor here because I just

want the human to move it up,\ndown, left, right and the human's

not going to physically be able\nto move it outside of the world.

If we zoom in on this code, the way\n

We're using that And conjunction\n

the green flag is clicked, we're\n

these questions, plural,\nif the mouse is down

and the trash is touching the\nmouse pointer, that's equivalent

logically to clicking on the trash.

Go ahead and move the\ntrash to the mouse pointer.

So again it takes this\nvery familiar idea

that you and I take for granted\n

Well Mac OS or Windows are\nprobably asking a question.

For every icon, is the mouse down\n

If so, go to the location\nof the mouse forever

while the mouse button is clicked down.

So how does this work in reality now?

Let me go ahead and click on the Play.

Nothing happens at first, but if\n

So I now need to kind of combine\n

but I bet I could just start\nto use just one single program.

Right now I'm using separate\nones to show different ideas

but now that's another\nbite out of the problem.

If we do one last one,\nsomething like the scorekeeping

is interesting, because recall that\n

into the can, Oscar popped out\nand told us the current score.

So let me go ahead and find\nthis one, Oscar variables

and let me zoom in on this one.

This one is longer because we\ncombined all of these elements.

So this is the kind of thing that\n

I have no idea how I would\nhave implemented this

from nothing, from scratch literally.

But again, if you take your\nvision and componenitize it

into these smaller,\nbite-sized problems, you

could take these baby\nsteps, so to speak, and then

solve everything collectively.

So what's new here is this bottom one.

Forever do the following:\nif the trash is touching

Oscar, the other sprite that\nwe've now added to the program

This is an orange and\nindeed if we poke around

we'll see that orange is a variable,\n

changing it means to add 1 or\nif it's negative subtract 1.

Then go ahead and have the\ntrash go to pick random.

Well, let me show you what it's doing\n

All right, it's falling, I'm clicking\n

All right, let me do it once more.

Why do I have this function at the\n

Like what problem is this solving here?

AUDIENCE: Just the same\ntrack teleported to the top

after you put it in the trash can.

Even though the human perceives\n

from the sky, it's\nactually the same piece

of trash, just kind of being\nmagically moved back to the top

There, too, you have this\nidea of reusable code.

If you were constantly copying\nand pasting your pieces of trash

and creating 20 pieces of trash, 30\n

want the game to have that many\n

Reuse the code that you wrote,\nreuse the sprites that you wrote

and that would give you not just\n

Well let's take a look at one\nfinal set of building blocks

that we can compose\nultimately into something

particularly interactive as follows.

Let me go ahead and\nzoom out here and let

me propose that we implement something\n

So I want to implement\nsome maze-based game that

looks at first glance like this.

It's not a very fun game yet,\nbut here's a little Harvard

shield, a couple of black lines, this\n

but notice you can't\nquite see my hand here

but I'm using my arrow keys to go down,\n

but if I keep going right, right,\nright, right, right, right

right it's not going anywhere.

And left, left, left, left, left, left,\n

So before we look at the code,\nhow might this be working?

What kinds of scripts,\ncollections of puzzle pieces

might collectively\nhelp us implement this?

There's probably some question being\n

and it happens to be a couple\nof sprites, each of which

is just literally a vertical black line\n

Is the distance to it\nzero or close to zero?

And if so, we just ignore the left\n

But otherwise, if we're\nnot touching a wall

what are we probably doing\ninstead forever here?

How is the movement working presumably?

DAVID MALAN: Sorry, say a little louder.

AUDIENCE: Presumably it's continually\n

and then moving when you do.

It's continually, forever listening for\n

and if the up arrow is\npressed, we're probably

changing the y by a positive value.

If the down arrow is pressed,\nwe're going down by y

and left and right accordingly.

So let's actually take a quick look.

If I zoom out here and take a look\n

there's a lot going on at\nfirst glance, but let's see.

First of all, let me drag\nsome stuff out of the way

because it's kind of\noverwhelming at first glance

especially if you, for instance, were\n

0 just to get inspiration,\nmost projects out there

are going to look\noverwhelming at first glance

until you start to wrap your\nmind around what's going on.

But in this case, we've\nimplemented some abstractions

from the get go to explain to\n

This is that program with the two black\n

It initially puts the shield\nin the middle, 0,0, then

forever listens for keyboard,\nas I think you were describing

and it feels for the walls, as\nI think you were describing.

These are custom blocks we created\n

those implementation details\nbecause honestly that's

all I need to know right now.

But, as aspiring programmers,\nif we're curious now

let's scroll down to the\nactual implementation

This is the one on the left\nand it is a little long

but it's a lot of similar structure.

We're doing the following, if the up\n

If the down arrow is pressed,\nthen change y by negative 1.

Right arrow, left arrow, and that's it.

So it just assembles all\nof those ideas, combines it

into one new block just because\nit's kind of overwhelming

let's just implement it\nonce and tuck it away.

And if we scroll now over to\nthe Feel for Walls function

this now is asking the\nquestion as hypothesized

if I'm touching the left wall, change my\n

If I'm touching the right\nwall, then move x by negative 1

to move a little bit away from it.

So it kind of bounces off the wall.

Just in case it slightly went over, we\n

All right, then a couple of\nmore pieces here to introduce.

What if we want to actually add\n

Well, let me go ahead to maybe this one\n

might, for instance, be designed to\n

This is like a maze and you're trying to\n

Uh oh, Yale is in the way and it\n

Well, let me ask someone else.

This is an idea you have,\nthis as an idea you see.

Let's reverse engineer in\nyour head how it works.

AUDIENCE: If the Yale symbol is\n

DAVID MALAN: Yeah, so\nif the Yale symbol is

touching the left wall or the right\n

And indeed we'll see there's a\npuzzle piece that can do exactly

that technically off\nthe edge, as we'll see

but there's another way we can do this.

The way we ourselves\ncan implement exactly

that idea bounce is just\nwith a little bit of logic.

So here's what this version\nof the program is doing.

It's moving Yale by default to 0,0\n

pointing it direction 90 degrees, which\n

and then it's forever doing\nthis: if touching the left wall

or touching the right wall,\nhere's our translation of bounce.

We're just turning 180 degrees.

And the nice thing\nabout that is we don't

have to worry if we're going from\n

180 degrees is going to\nwork on both of the walls.

After we do that, we just move\none step, one pixel, at a time

but we're doing it forever so\nsomething is happening continually

and the Yale icon is\nbouncing back and forth.

Well one final piece\nhere, what if now we

want another adversary, a more advanced\n

to go and follow us wherever\nwe are such that this time

we want the other sprite to\nnot just bounce back and forth

but literally follow us\nno matter where we go.

How might this be\nimplemented on the screen?

I bet it's another forever\nblock, but what's inside?

AUDIENCE: So forever get the\n

and move one step towards it.

DAVID MALAN: Yeah, forever point at\n

This is just going to go on forever if I\n

Notice it's sort of twitching\nback and forth because it goes one

pixel then one pixel then one pixel.

It's sort of in a frantic state here.

We haven't finished the game yet, but if\n

It didn't take much to\nimplement this simple idea.

Go to a random position just\nto make it kind of fair

initially, then forever\npoint towards Harvard

which is what we called the Harvard\ncrest sprite, move one step.

Suppose we now wanted to\nmake a more advanced level.

What's a minor change I could\nlogically make to this code just

to make MIT even better at this?

AUDIENCE: Change the\nnumber of steps to two.

DAVID MALAN: All right, change\nthe number of steps to two.

So now they got twice as fast.

Let me go ahead and just\nget this out of the way.

Oops, let me make it a fair fight.

All right, I unfortunately am\nstill moving one pixel at a time

so this isn't going to end well.

And if we're really aggressive and\n

Jesus, OK, so that's how you might\n

So it's not an accident that we\nchose these particular examples

here involving these particular\nschools because we have one more

demonstration we thought\nwe'd introduce today

if we could get one other\nvolunteer to come up and play

what was called by one of your\npredecessors Ivy's Hardest Game.

Let's see, you in the middle.

DAVID MALAN: Come a\nlittle closer, actually.

All right, round of applause\nhere if we could, too.

OK, sorry, what was your name?

So here we have on this other\nscreen Ivy's Hardest Game

written by a former CS50 student.

I think you'll see that it\ncombines these same principles.

The maze is clearly a\nlittle more advanced.

The goal at hand is to initially move\n

the way on the right so that you\ncatch up to him in this case

but you'll see that\nthere's different levels

and different levels of sophistication.

So if you're up for it, you can use just\n

You'll be controlling the\nHarvard sprite and if we

could raise the volume just a little\n

Here we go, clicking the green flag.

[MUSIC - MC HAMMER, "U CAN\'T TOUCH\nTHIS"]

MC HAMMER: (SINGING) Can't touch this.

MC HAMMER: (SINGING) so hard.

Makes me want to say, oh my Lord.

MC HAMMER: (SINGING) Feels\ngood when you know you're down.

MC HAMMER: (SINGING)\nYou can't touch this.

MC HAMMER: (SINGING) Can't touch this.

You let me bust the funky lyrics.

You got it like that and\nyou know you want to dance.

So move out of your seat and get\na fly girl and catch this beat.

Pump a little bit and let them know\n

Cold on a mission, so fall on back.

Let them know that you're too--

MC HAMMER: (SINGING) Can't touch this.

Why you standing there, man?

Give me a song or rhythm, making\n

You talking the Hammer when\nyou're talking about a show.

Singers are sweating so them\na wipe or a tame to learn.

DAVID MALAN: Second to last level.

MC HAMMER: (SINGING) That chart's legit.

Either work hard or\nyou might as well quit.

MC HAMMER: (SINGING)\nYou can't touch this.

DAVID MALAN: You're almost there.

MC HAMMER: (SINGING) Break it down.

MC HAMMER: (SINGING) Stop, Hammer time.

Go with the flow," it is said.

If you can't groove to this,\nthen you're probably dead.

So wave your hands in the\nair, bust a few moves

run your fingers through your hair.

Dance to this and you're\ngoing to get thinner.

Just for a minute let's all do the bump.

All right, that's it for CS50.

And this is week 1, the one in which\n

is something we technically said\n

played with this graphical language\n

But today, as promised,\nwe transition to something

a little more traditional,\na little more text-based

not puzzle piece- or\nblock-based, known as C.

It's been around for decades.

But it's a language that underlies so\n

among them something called\nPython that we'll also

come to in a few weeks' time.

Indeed, at the end of\nthe semester, the goal

is for you to feel that\nyou've not learned Scratch

you've not learned C, or\neven Python, for that matter

but fundamentally that you've\nlearned how to program.

Unfortunately, when you\nlearn how to program

with a more traditional language like\n

Last week I described all of the\n

that you see in this, like the\n

parentheses, curly braces,\nbackslash n, and more.

Well, today we're not going to reveal\n

But by next week, will this no\n

to you, a language that, presumably,\n

But to do that, we'll explore some\n

So recall that, via Scratch-- and\npresumably via problem set 1--

we took a look at things called\n

And related to functions\nwere arguments like inputs.

And related to some functions\nwere returned values like outputs.

Then we talked a bit about conditionals,\n

Boolean expressions, which are\n

questions, loops, which let you do\n

like in math, that let you\nstore values temporarily

and then even other topics still.

So if you were comfortable on the\n

realize that all of these topics\nare going to remain with us.

So really, today is just about acquiring\n

you translate those ideas into,\n

a new syntax, frankly,\nthat's actually more

simple in some ways than\nyour own human language

be it English or something else, because\n

There's actually far less\nsyntax that you might

have in, say, a typical human language.

But you need to be with these computer\n

so that you're most,\nultimately, correct

and ultimately will see to your code\n

So if you think about the last time\n

knowing what you were doing\nor encountered something new--

might not have been that long ago,\n

first time, or Old Campus or the like,\n

you didn't really need to know how\n

You didn't need to\nknow who everyone was

where everything was, how Harvard or\n

You sort of got by day to day by just\n

And anything you didn't\nreally understand

you sort of turned a blind\neye to until it's important.

And that's, indeed, what\nwe're going to do today.

And really, for the next\nseveral weeks, we'll

focus on details that\nare initially important

and try to wave our hands, so to speak,\n

we'll get to, might be interesting.

But for now, they might be distractions.

And by distractions, I really\nmean some of that syntax

So by the end of today-- and\n

your first foray, presumably,\ninto this language called C--

you'll have written some code.

And you'll be asking yourself--\nwe'll be asking yourselves--

Well, first and foremost, per\nlast week, be it in Scratch

or phone book form, code ultimately\n

You want the problem\nto be solved correctly.

So that one sort of goes without saying.

And along the way this term, we'll\n

so you don't have to just sit there\n

checking the output, trying\nanother input, checking the output.

There's a lot of automation\ntools in the real world--

and in this class and\nothers like it-- that

will help facilitate you answering\n

correct, according to our\nspecifications or the like.

But then something that's\ngoing to take more time

and you're probably not going to feel\n

the first weeks, is just how\nwell designed your code is.

It's one thing to speak\nEnglish or write English

but it's another thing-- or\nany language, for that matter.

But it's another thing to\nspeak it or write it well.

And we spend all these years in middle\n

writing papers and other documents,\n

as to how well formulated your\n

your paper was, and the like.

And there's that same\nidea in programming.

It doesn't matter necessarily that\n

If your code is a complete visual\nmess, or if it's crazy long

it's going to be really\nhard for someone else

to wrap their mind around what your code\n

And honestly, you-- the\nnext morning, the next year

the next time you look at\nthat code-- might have no idea

what you yourself were even thinking.

But you will if you focus,\ntoo, on designing good code

getting your algorithms efficient,\n

and even making sure your\ncode looks pretty, which

we'd describe as a matter of style.

So in the written human world, having\n

capitalization and the like-- the\nsort of way you write an essay

but not necessarily\nsend a text message--

relates to style, for instance.

And so good style in\ncode is going to have

a few of these characteristics that are\n

But you just have to start to get in the\n

So these three axes, so to speak,\n

are really the overarching\ngoals when writing code that

ultimately is going to look like this.

So this program we\nconjectured last week does

what if you run it on a Mac or\nPC or somewhere else, presumably?

DAVID J. MALAN: It just\nprints, Hello, world.

And honestly, that's kind\nof atrocious that you

need to hit your keyboard keys this\n

to get a program to say, Hello, world.

So a spoiler-- in a\nfew weeks' time when we

introduce other, more modern\nlanguages, like Python

you can distill this same logic\ninto literally one line of code.

And so we're getting there, ultimately.

But it's helpful to understand\nwhat it is that's going on here

because even though this\nis a pretty cryptic syntax

there's nothing after this week and,\n

be able to understand even about\nsomething that right now looks

a little something like this.

Well, I've given us sort\nof the answer to a problem.

How do you print, Hello,\nworld, on the screen?

So what do I do with this code?

Well, we're in the habit of typically\n

And yeah, I could open up Word or\n

and just literally transcribe\nthat character for character

save it, and boom, I've got a program.

But the problem, per last week, is\n

what other language, so to speak?

DAVID J. MALAN: Yeah, so\nbinary, zeros and ones.

And so this, obviously,\nis not zeros and ones.

So it doesn't matter if I put it in\n

The computer is not going to\nunderstand it until I somehow

translate it to zeros and ones.

And honestly, none of those\ntools that I rattled off

are really appropriate for programming.

Well, they come with features\nlike bold facing and italics

and sort of fluffy, aesthetic stuff\n

you're trying to do with your code.

And they don't have\nthe ability, it would

seem, to convert that code\nultimately to zeros and ones.

But tools that do have\nthis capability might

be called Integrated Development\nEnvironments, or IDEs

or, more simply, text editors.

A text editor is a tool that a\nprogrammer uses perhaps every day

And it's a simple program-- here,\n

called Visual Studio Code, or VS Code.

And at the top here, you\nsee that I've actually

created in advance before class a very\n

Well, .c indicates by convention that\n

It's not .docx, which would mean in\n

This is .c, which means in this file is\n

C. This number 1 here is just an\n

me keep track of how long\nor short this program is.

And the cursor is just\nblinking there, waiting

for me to start typing some code.

Well, let me go ahead and type\nout exactly the same code.

For me, it comes pretty\ncomfortably from memory.

So I'm going to go ahead and include\n

I'm going to magically type int\n

we'll come back to that later--

one of these curly braces and then a\n

Then I'm going to hit Tab\nto indent a few spaces.

And then I'm going to type not print,\n

close quote, close\nparenthesis, semicolon.

And I dare say this was essentially\n

I wrote it to say, "Hi, CS50.

Now it just says the more canonical,\n

And all I need to now do is\nmaybe hit Command-S or Control-S

And voila, I am a programmer.

The catch though, is,\nOK, how do I run this?

Like, on your Mac or PC,\nhow do you run a program?

Well, usually double-click an icon.

On your phone, you tap an icon.

In this environment that we're using\n

say most programmers-- use, you don't\n

That's very user friendly,\nbut it's not very necessary.

Especially when you get more\ncomfortable with programming

you're going to want to type commands\n

And you're going to\nwant to automate things

which is a lot easier if it's all\n

to mouse and muscular movements.

And so here I have my program.

It lives in this file called "hello.c.

I need to now convert it,\nthough, to zeros and ones.

Well, how do I go about doing this,\n

or source code, as it's\nconventionally called--

to this, these zeros and ones that\n

The zeros and ones from last\nweek can be used not only

to represent numbers and letters,\n

It can also represent instructions to a\n

or delete a file, or save a file.

All the sort of basics\nof a computer somehow

can be represented by other\npatterns of zeros and ones.

And just like last week,\nit depends on the context

in which these numbers are stored.

Sometimes they're interpreted as\nnumbers, like in a spreadsheet.

Sometimes they're interpreted as colors.

Sometimes they're interpreted as\n

to do very low-level operations,\n

So fortunately, last week's definition\n

is a nice mental model for\nexactly the goal at hand.

I have some input, AKA source code.

I want to output ultimately\nmachine code, those zeros and ones.

I certainly don't want to do\nthis kind of process by hand.

So hopefully there's an algorithm\n

And those of you who do\nhave some prior experience

this program might be called a?

So a few of you have,\nindeed, programmed before.

Not all languages use compilers.

C, in fact, is a language\nthat does use a compiler.

And so I just need to find myself--

on my computer somewhere,\npresumably-- a so-called compiler

a program whose purpose in life is\n

And source code written textually\n

The machine code is the\ncorresponding zeros and ones.

So let me go back to the same\nprogramming environment called

Visual Studio Code or VS Code.

This is typically a program you\n

can download onto their own Mac or\n

computer you own writing some code.

A downside, though, of that\napproach is that all of us

have slightly different\nversions of Macs or PCs.

We have slightly different\nversions of operating systems.

They may or may not be up to date.

It's just a technical support nightmare\n

especially for an introductory\n

be on the same page so we can\nget you up and running quickly.

And so I'm actually using a cloud-based\n

that you only need a browser to access.

And then you can be on any\ncomputer, today or tomorrow.

By the end of the semester, we're\n

so to speak, as best we can and\nget you onto your own Mac or PC

so that after this class, especially if\n

you feel like you can continue\n

But for now, wonderfully, the\nbrowser version of VS Code

should pretty much be identical\n

version of the same would be.

And you'll see in problem\nset 1 how to access this

and how to get going yourself\nwith your first programs.

But I haven't mentioned this\nbottom part of the screen

this bottom part of the screen.

And this is an area where we have\n

So this is sort of old-school technology\n

to interact with a computer, wherever\n

or even, in this case, in the cloud.

So on the top-hand\nportion of this screen

is my text editor, like tabbed\n

I can just create files and write code.

The bottom of the screen here,\nmy so-called terminal window

gives me the ability to\nrun commands on a server

that currently I have\nexclusive access to.

So because I logged into VS\nCode with my account online

I have my own sort of virtual\n

otherwise known as, in\nthis context, a container.

This has its own operating system\nfor me, its own hard drive

if you will, where I can save\nand create files of my own

separate from yours and vice versa.

And it's at this very\nsimple prompt, which

is conventionally-- but not always--\n

has nothing to do with currency.

It just means, type your commands here.

This is where I'm going to\nbe able to type commands

like compile my source\ncode into machine code.

So it's a Command Line Interface, or\n

that you might not have ever used\n

Odds are almost all of us in this room\n

but we're all going to start using an\n

is in a family of operating systems\n

line interface, but are used not\n

websites and developing\napplications and the like.

And it's, indeed, a familiar and very\n

So how do I go about making this\nfile, hello.c, into a program?

There's no icon to double-click,\nbut there is a command.

I can type, make hello, at this dollar\n

and nothing appears to happen.

And as we'll see in\nprogramming, almost always

if you don't see anything go wrong,\n

So this is going to\nbe a rarity at first

but this is a good thing that\nit just seems to do nothing.

But now there is in the\nfolder in my accounts

in this on the cloud\na file called "hello.

And it's a bit of a weird command,\n

. just means go into my current folder.

/hello means run the program called\n

So ./hello, and then Enter, and voila,\n

I'm going to go ahead and open\nup the sidebar of this program

and you'll see in problem\nset 1 how to do this.

And this might look a little different\n

Even the color scheme I'm using might\n

because it supports a\nnice colorful theme.

So you can have different colors\nand brightnesses depending

on your mood or the time of day.

What I've opened here, though, is\n

and this is just all of the\nfiles in my cloud account.

And there's not many right now.

One is the file called\nhello.c, and it's highlighted

because I've got it open right there.

And the other is a file called\n"hello," which is brand new

and was created when I ran that command.

And what's now worth noting is that\n

Like on the left-hand side, you have\n

But on the bottom here, again, you\n

These are just different ways\nto interact with computers

and you'll get comfortable with both.

And honestly, you're certainly familiar\n

so it's the command line one\nwith which we'll spend some time.

Now suppose that I just\nwanted to do something

more than compile this program.

Suppose I wanted to go\nahead and remove it.

Like, uh-uh, no, I made a mistake.

I want to say, "Hello,\nCS50," not "Hello, world.

I could just hover up here, like in\n

and I could poke around, and\nthere, delete permanently.

So most of us might have\nthat instinct on a Mac or PC.

You right-click or Control-click,\nand you poke around.

But in a command line interface,\nlet me do this instead.

The command for removing\nor deleting a file

in the world of Linux, this\nother operating system

is just a type rm for remove,\nand then "hello," Enter.

It's a somewhat cryptic confirmation\n

I'm going to go ahead\nand type Y for Yes.

And now when I hit\nEnter, watch what happens

at top left in the Explorer, the\nGUI, the graphical interface.

Not terribly exciting,\nbut this just means

this is a graphical version\nof what we're seeing here.

And in fact, if you want to\nnever use the GUI again--

I'll go ahead and close it\nwith a keyboard shortcut here--

you can forever just type\nls for list and hit Enter.

And you will see in the\ncommand line interface

all of the files in your current folder.

So anything you can do\nwith a mouse, you can

do with this command line interface.

And indeed, we'll see many more\nthings that you can do as well.

But the inventors of this, this\n

Like, the command is rm for remove.

Because it's just faster to type.

So before we forge ahead with making\n

just "Hello, world,"\nlet me pause here to see

if there's questions on\nsource code or machine

code or compiler or this\ncommand line interface.

DAVID J. MALAN: Really good\nquestion, and let me recap.

If I were to make\nchanges to the program

run it, and then maybe make other\nchanges and try to rerun it

would those changes be reflected,\n

I already removed the old version.

So let me go ahead and point\nout that if I do ./hello now

I'm going to see some kind of error\n

No such file or directory, so\nit's not terribly user friendly

but it's saying what the problem is.

Let me go ahead and remake\nit by typing make hello.

Now if I type ls, I'll see not one\n

is even green with a little asterisk\n

It's sort of the textual\nversion of something

you could double-click\nin our human world.

So now, of course, if I run hello, we're\n

But now suppose I change it to\n

Let me go ahead and save the file with\n

let me run ./hello again, and voila.

So let me ask someone else\nto answer that question.

Why did it not say, "Hello, CS50.

DAVID J. MALAN: Yeah, so\nI didn't compile it again.

So sort of newbie mistake, you're going\n

But now let me go ahead\nand remake hello, enter.

It's going to seemingly\nmake the same program.

But this time when I run\nit, it\'s, "Hello, CS50.

Any other questions on some\nof these building blocks?

And we'll come back to all the\ncrazy syntax I typed before long.

But for now, we're focusing\non just the output.

DAVID J. MALAN: When\nI keep running make

it creates a new version\nof the machine code.

So it keeps changing the hello program\n

There's no make file, per se.

DAVID J. MALAN: Good question, no.

If I open up that directory, you'll\n

And it doesn't matter how\nmany times I run make hello--

three, four, five-- it just\nkeeps overwriting the original.

So it's kind of like just saving in\n

But there's an additional step today.

We have to then convert my words to\n

DAVID J. MALAN: Oh, what\nhappens if I run hello.c?

So let me go ahead and do ./hello.c,\n

This is where the error\nmessages mean something

to the people who designed the operating\n

It's not that you don't\nhave access to the file.

It means that it's not executable.

This is not something you\nhave permission to run

but you do have permission to read\n

DAVID J. MALAN: Oh,\nreally good question.

So if I have named my file, hello\n

dot C, of the things that\nMake does is it automatically

we'll discuss this a bit more next week.

Make itself-- is kind of the\nfirst of white lies today--

It's a program that knows how to find\n

and automatically create the program.

If I use, as we'll discuss next\n

I have to type a much longer sequence\n

what do I want the name\nof my program to be.

Make is a nice program,\nespecially in week 1

because it just automates\nall of that for us.

And so here, we have now a\nprogram that very simply prints

So let's not put this\ninto the context of where

we left off last time in the context\n

So we discuss the last time, of\ncourse, functions and arguments.

Functions, again, are those actions and\n

And the arguments were the\ninputs to those functions

generally in those little white\novals that, in Scratch, you

could type words or numbers into.

We'll see, in all of the languages\nwe're going to see this term

And let's just start to translate\n

So for instance, let's put\nthis same program in C

This is what Hello, World looked like\n

This week, of course,\nit looks like print.

And then the parentheses,\nnotice, are kind of

deliberately designed in the world of\n

Even though this is a\nwhite oval, you kind of get

that it's kind of evoking that\nsame idea with the parentheses.

Technically the function\nin C, it's not called say.

The F stands for formatted, but we'll\n

But printf is the closest\nanalogous function

for say in the world of\nC. Notice if, though, you

want to print something like\nHello, World or Hello CS50 in C

you don't just write the\nwords as we did last week.

You also had an add what,\nif you notice already

what's missing from this version.

Yeah, so the double quotes\non the left and the right.

So, that's necessary in C whenever\nyou have a string of words.

And I'm using that word deliberately.

Whenever you have multiple words\n

And you have to put it in double\nquotes, not single quotes.

You have to put it in double quotes.

There's one other stupid thing\nthat we need to have in my C code

in order to get this function to do\n

So just like in our human\nworld, you eventually

got into the habit of using, at\n

Semicolon is generally what\nyou use to finish your thought

in the world of programming with C.

All right, so we have\nthat function in place.

Now, what does this really fit\n

Well, functions take arguments.

And it turns out functions can\nhave different types of outputs.

And we've actually seen\nboth already last week.

One type of output from a function\n

And it generally refers\nto something visual

like something appearing on the screen\n

It's sort of a side effect of\nthe function doing its thing.

And indeed, last week we saw this in\n

like Hello, World as\ninput to the say function.

And we saw on the screen Hello,\n

You can't actually do anything\nwith that visual output

other than consume it,\nvisually, with your human eyes.

But sometimes, recall last week, we\n

actually returned me some value.

Remember the ask, what's your name.

It handed me back whatever\nanswer the human typed in.

It didn't just arbitrarily\ndisplay it on the screen.

The cat didn't necessarily\nsay it on the screen.

It was stored, instead, in that special\n

Because some functions have not\nside effects but return values.

They hand you back an output\nthat you can use and reuse

unlike the side effect, which,\nagain displays and that's it.

You can't sort of catch\nit and hold on to it.

So, in the context of last\nweek, we had the ask block.

And that had this special\nanswer return value.

In C, we're going to\nsee in just a moment

we could translate this as follows.

The closest match I can\npropose for the ask block

is a function that we're going\nto start calling get string.

String is, again, a word, a\nset of words, like a phrase

or a sentence in programming.

It, too, is a function insofar as\n

this isn't always true--\nbut very often when

you have a word in C followed by an open\n

it's most likely the name of a function.

And we're going to see that\nthere's some exceptions to that.

But for now this indeed\nlooks like a function

because it matches that pattern.

If I want to ask the question,\nwhat's your name, question mark--

and I'm even going to deliberately\n

the cursor a little bit over so that\n

So that's just the nitpicky aesthetic.

This is perhaps the closest analog\nto just asking that question.

But because the ask\nblock returns a value

the analog here forget string is\nthat it, too, returns a value.

It doesn't just print the human's input.

It hands it back to you in the form\n

that I can then use and reuse.

Now ideally it would be as\nsimple as this literally

saying answer on the left equals.

And this is where\nthings start to diverge

from math and sort of our human world.

This equal sign, henceforth,\nis not the equal sign.

It is the assignment operator.

To assign a value means to\nstore a value in some variable.

And you read these things,\nweirdly, right to left.

So here is a function called get string.

I claim that it's going\nto return to you whatever

the human types in as their name.

It's going to get stored\nover here on the left because

of this so-called assignment\n

But it doesn't mean\nequality in this context.

But it does so by copying the value on\n

Unfortunately, we're not\nquite done yet with C.

And this is where, again, it\ngets a little annoying at first

where Scratch just let us express\n

In C when you have a\nvariable you don't just

give it a name like you did in Scratch.

You also have to tell the computer\nin advance what type of value

String is one such type of value.

Int, for integer, is\ngoing to be another.

And there's even more than that\nwe'll see today and beyond.

And this is partly an answer to the\n

last week, which was how does a computer\n

Like is this a letter, a number,\na color, a piece of video.

And I just claimed last week that\n

But within those\nprograms, it often depends

on what the human programmer\nsaid the type of the value is.

If this specifies that\nthe string, which means

interpret the following\nzeros and ones that

are stored in my program as\nwords or letters, more generally.

If it's an int for integer, it would\n

treat the following zeros and\nones in my program as a number

So here's where this\nweek, unlike with Scratch

which is kind of figures out what you\n

you have to be this pedantic\nand tell it what you mean.

There's still one stupid thing\nmissing from my code here.

DAVID J. MALAN: And we still\nneed the stupid semicolon.

And I'm sort of impugning it here.

Because honestly, these are\nthe kinds of stupid mistakes

you're going to make today,\ntomorrow, this weekend, next week

a few weeks from now, until you\n

as well as you do English or\nwhatever your spoken language is.

Suppose I mix apples and\noranges, so to speak

and I try to put a string in\nan int or an int in a string

the compiler is going to complain.

So when I run that make\ncommand as I did earlier

it's not going to be nice and blissfully\n

It's going to yell at me\nwith honestly a very cryptic

looking error message until we get\n

Ah, what happened to the backslash n.

So, we'll come back to that\nin just a moment, if we may.

Because I have deliberately omitted\n

And we'll see the different\nbehavior in a sec.

These are the kinds of\nthings that just matter.

And it's going to take time to recognize\n

Everything I've typed here except,\n

And the W is capitalized\njust because it's English.

Everything else is lowercase.

And this kind of varies by\nlanguage and also context.

So, in many languages the convention\n

Other languages might use\nsome capitals, as well.

But we'll talk about that before long.

But this is the kind\nof thing that matters

and is hard to see at first, especially\n

different when it's on your tiny\nlaptop screen from a capital S.

But you'll start to\ndevelop these instincts.

All right, so besides\nthis particular block

let's go ahead and consider how we can\n

So let me switch back to VS Code here.

This was the program I had earlier.

And let me go ahead and\nundo my CS50 change.

Rerun Make on Hello with the original\n

Enter, nothing bad\nseems to have happened.

So dot slash Hello, enter Hello, World.

Now, if you're curious,\nthis is a good instinct

to start to acquire what\nhappens if I get rid of this.

Well, I'm probably not going\nto break things too badly.

Let me go ahead now and do Make Hello.

So it's not a really bad mistake.

So let me go ahead and\nrun dot slash Hello.

Yeah, what do you see that's different?

Yeah, the dollar sign, my so-called\n

Well, we can presumably\ninfer now that the backslash

n is some fancy notation for\nsaying create a new line

move the cursor, so to\nspeak, to the next line.

Notice that the cursor will move to\n

If I keep hitting it,\nit just automatically

by nature of hitting enter, does it.

But it'd be kind of stupid if when\n

simple as it is, if\nthe next command is now

weirdly spaced in the middle of\n

It's really just an aesthetic argument.

And notice that it's not acceptable or\n

Let me go ahead and save that,\nthough, and see what happens.

Let me go ahead now and\nrun Make Hello enter.

This is like, what, 10 lines of\nerrors for a one line program.

And this is where, again, you'll start\n

These kinds of tools, like\nthe compiler tool we're using

were not designed necessarily\nwith user friendliness in mind.

That's changed over the\ndecades, but certainly early

on it's really just meant to be\n

Missing terminating\nclose quote character

long story short, when\nyou have a string in C

your double quotes just have to\n

Now, there's the slight white lie.

But the best way around it is to\n

To escape something means generally\nto put a backslash, and then

a special symbol like n for new line.

And this is just the agreed upon way\n

OK you don't just hit your enter key.

You instead put backslash n\nand that tells the computer

to move the cursor to the new line.

But once you know it, that's it.

It's just another word\nin our vocabulary.

So now let me transition to making\n

Instead of just saying\nHello, world, let me

change it like last week\nto say Hello, David

or whoever is interacting\nwith the program.

So I'm going to do string\nanswer gets, get string

quote unquote, what's your name.

I'm not going to bother\nwith a new line here.

This is now just a judgment call.

I deliberately want the human to\n

Well last week recall we used say.

And then we use the\nother block called join.

So the idea here is the same.

But the syntax this week is\ngoing to be a little different.

It's going to be printf, which\nprints something on the screen.

I'm going to go ahead\nand say Hello comma.

And let me just go with this initially\n

Let me go ahead and recompile my code.

Whoops, damn doesn't work still.

And look at all these errors.

There's more errors than code I wrote.

Well, this is actually\nsomething, a mistake you'll see

somewhat often, at least initially.

And let's start to glean\nwhat's going on here.

So here, if I look at the very first\n

so even though it jumped\ndown the screen pretty fast

I wrote Make Hello at\nthe dollar sign, prompt.

And then here's the first error.

technically character 5, but generally\n

there's an error, use of\nundeclared identifier string.

And this is not an\nobvious solution at first.

But you'll start to recognize\nthese patterns in error messages.

It turns out that if I want to use\n

I have to include another library\nup here, another line of code

rather, called CS50\ndot H. We'll come back

to what this means in just a moment.

But if I now retroactively say,\n

Before I added that new line,\nwhat is standard I/O doing?

Well, if you think\nback to Scratch, there

were a few examples with the camera and\n

Remember I had to poke around\nin the extensions button.

And then I had to load it into Scratch.

It didn't come natively with Scratch.

Some functions come with the language.

But for the most part, if you want to\n

like printf, you have to load\nthat extension, so to speak

that more traditionally\nis called a library.

So there is a standard I/O\nlibrary, STD I/O, standard I/O

where I/O just means input and output.

Which means, just like\nin MIT's World, there

was an extension for doing text\n

In C, there's an extension, a.k.a.

a library, for doing\nstandard input and output.

And so if you want to use any functions\n

like text from a keyboard, you\nhave to include standard I/O dot

H. And then can you use printf.

Get string, it turns out, is a\n

And as we'll see over\nthe coming weeks, it just

makes it way easier to\nget input from a user.

C is very good with printf at\nprinting output on the screen.

C makes it really annoying and\n

to just get input from the user.

So we wrote a function\ncalled get_string

but the only way you can use\nthat is to load the extension

a.k.a. load the library called CS50.

And we'll come back in time, like,\n

But for now, standard\nI/O is a library that

gives you access to printf and\ninput- and output-related stuff.

CS50 is a second library\nthat provides you

with access to functions\nthat don't come with C

that include something like get_string.

So with that said, we've\nnow kind of teased apart

at a high level what lines\n2 and now 1 are doing.

Let me go ahead and rerun make hello.

So all those crazy error messages\nwere resolved by just one fix

so key takeaway is not to get\noverwhelmed by the sheer number

Let me now do ./hello and if I type\n

Yeah, hello answer, because the\n

And it turns out that if\nyou just write "hello

answer" all in the double quotes,\nyou\'re really just passing

English as the input\nto the printf function

you're not actually\npassing in the variable.

And unfortunately in\nC, it's not quite as

easy to plug things in to\nother things that you've typed.

Remember in Scratch, there\nwas not just the Save block

but the Join block,\nwhich was kind of pretty

you can combine apples and oranges--

Then we changed it to hello and then\n

In C, the syntax is going\nto be a little different.

You tell the computer inside of your\n

a placeholder there, a so-called\n

put a string here eventually.

Then outside of your quotes, you\n

in whatever variable you want the\n

So %s is a format code which\nserves as a placeholder.

And now the printf function\nwas designed by humans years

ago to figure out how to\ndo the apple and banana

thing of joining two words together.

It's not nearly as user-friendly\nas it is in Scratch

but it's a very common paradigm.

So let me try and rerun\nthis now. make hello.

If I type Enter now, now it's hello.

And the printf, here's the F in printf.

It formats its input for you by using\n

strings, represented again by %s.

So a quick question then, if I focus\n

and even zoom in here, how many\n

A moment ago, I'll admit that it was\n

How many inputs might you\ninfer printf is taking now?

And it's implied by this comma here,\n

quote, unquote, "hello, %s"\nfrom the second one, answer.

And then just as a quick safety\ncheck here, why is it not 3?

Because there's obviously\ntwo commas here.

Why is it not actually\n3 arguments or inputs?

The comma to the left is actually\npart of my English grammar

And, again, here's where\nprogramming can just be confusing

early on because we're using the\n

different things, it just\ndepends on the context.

And so now is actually\na good time to point out

all of the somewhat pretty colors that\n

even though I wasn't going to a format\n

I certainly wasn't changing\nthings to red or blue or whatnot--

that's because a text editor like\n

This is a feature of so many different\n

If your text editor understands the\n

it highlights in different colors the\n

So, for instance, string and\nanswer here are in black

but get_string a function is in\nthis sort of nasty brown-yellow

here right now, but that's just\nhow it displays on the screen.

The string, though, here in red\nis kind of jumping out at me

and that's marginally useful.

That's kind of nice, because\nit's jumping out at me.

And so it's just using different colors\n

pop so you can focus on\nhow these ideas interrelate

and, honestly, when you\nmight make a mistake.

For instance, let me accidentally\nleave off this quote here.

And now all of a sudden,\nnotice if I delete the quote

the colors start to get a little awry.

But if I go back there and put it\n

What's another feature\nof this text editor?

Notice when my cursor is next\nto this parenthesis, which

demarcates the end of the\ninputs to the function

notice that highlighted in green\n

It's just a visually useful\nthing, especially when

you start writing more and\nmore code, just to make

sure your parentheses are lining up.

And that's true for these curly braces\n

We'll come back to those in a moment.

If I put my cursor there, you can\n

So it's nothing in your code\nfundamentally, it's just the editor

trying to help you, the human, program.

And you can even see it,\nthough it's a little subtle--

see these four dots here\nand these four dots here?

I configured VS Code to\nindent by four spaces, which

Any time I hit the Tab key, this\ntoo can help you make sure--

once we have more interesting\nand longer programs--

that everything lines\nup nice and neatly.

All right, any questions\nthen on printf or more?

AUDIENCE: [? Would ?]\nthe printf [INAUDIBLE]??

DAVID J. MALAN: Short\nanswer, yes. printf

can handle more than one\ntype of variable or value.

We're going to see %i is another\nfor plugging in an integer.

You can have multiple i's, multiple\n

We'll come back to that\nin just a little bit.

printf can take many more\narguments than just these two.

This is just meant to be representative.

Can you declare variables\nwithin the printf?

The only variable I'm\nusing right now is answer

and it's got to be done outside\n

Good question, we'll see\nmore of that before long.

DAVID J. MALAN: How do we\ndownload the CS50 library?

So we will show you in problems\nset 1 exactly how to do that.

It's automatically done for you in\n

If, ultimately, you program on your own\n

on, it's also installable online.

But if you want to ask that\nvia online or afterward

we can point you in the right direction.

DAVID J. MALAN: String is the type\n

the data type of the variable.

int is another keyword I alluded\n

int, for integer, is going to be\n

AUDIENCE: OK. [? Thank you. ?]

DAVID J. MALAN: Oh, good question.

Could I go ahead and just\nplug in this function

kind of like we did in Scratch,\n

and just do this, which\nrecall, is reminiscent of what

I did in Scratch by plopping\nblock on top of block on block?

Can I put string in front of get_string?

You only put the word string\nin front of a variable

And even though I'm apparently\nanswering the wrong question

let me go ahead and zoom out,\nsave this, do make hello again.

If I run ./hello, type in David, voila.

And so, actually, let's go down\n

Clearly, it's still correct--

at least, based on my limited testing.

Is this better designed\nor worse designed?

Let's open that question\nlike we did last week.

Yeah, I kind of agree with that.

Reasonable people could\ndisagree, but I do

agree that this seems harder to\n

but wait a minute. get_string\nis going to get used first

and then it's going to\ngive me back a value.

So, yeah, it just feels like it\nwas nicer to read top to bottom

And so this is useful if I only want\n

If I want to use it later in a\nlonger program, I'm out of luck

and so I haven't saved it in a variable.

So I think, long story short, we\ncould debate this all day long.

But in this case, eh, if you can\nmake a reasonable argument one

way or the other, that's a\npretty solid ground to stand on.

But, invariably,\nreasonable people are going

to disagree, whether first-time\n

So let's frame this one last example\n

of taking inputs and outputs.

The functions we've\nbeen talking about all

take inputs, otherwise now known as\n

That's just the fancy word\nfor an input to a function.

And some functions have either\nside effects, like we saw--

printing something, saying\nsomething on the screen

sort of visually or audibly--

or they return a value, which is a\n

If we look then at what we did last\n

the input was what's your\nname, the function was ask

and the return value was answer.

And now let's take a look at this block,\n

version of what we just did with the %s.

Last week we said save, then\njoin, then hello and answer.

But the interesting takeaway there\n

It was the fact that in Scratch\n2, the output of one function

like the green join, could become\nthe input to another function

The syntax in C is\nadmittedly pretty different

but the idea is essentially the same.

Here, though, we have\nhello, a placeholder

but we have to, in this\nworld of C, tell printf

what we want to plug in\nfor that placeholder.

But that's the way to do it.

When we get to Python and other\nlanguages later in the term

there's actually easier ways to do this.

But this is a very common\nparadigm, particularly when

you want to format\nyour data in some way.

All right, let's then take a\nstep back to where we began

which was with that whole\nprogram, which had the include

and it had int main(void) and\nall of this other cryptic syntax.

This Scratch piece last week\nwas kind of like the go-to

whenever you want to have a\nmain part of your program.

It's not the only way to\nstart a Scratch program.

You could listen for clicks or other\n

But this was probably the most popular\n

In C, the closest analog is\nto literally write this out.

So just like last week, if you were\n

when green flag clicked,\nas a C programmer

the first thing you would do is\nafter creating an empty file

like I did with hello.c,\nyou'd probably type int

main(void) open curly\nbrace, closed curly brace

and then you can put all of your\n

So just like Scratch had\nthis sort of magnetic nature

to it where the puzzle pieces would snap\n

tends to use these curly braces, one\n

And anything inside of\nthose braces, so to speak

is part of this puzzle piece, a.k.a.

We went down this rabbit hole moment ago\n

even though I didn't\ncall them by this name.

But, indeed, when we have a whole\n

Just have the one green flag\nclicked and then say hello, world.

After all, it's meant to be very\nuser-friendly and graphical.

In C, though, you technically can't just\n

Because, again, you need to tell\n

code that someone else wrote-- so that\n

You have to load the\nCS50 library whenever

you want to use get_string or\nother functions, like get_int

Otherwise, the compiler won't\nknow what get_string is.

You just have to do it this way.

The specific file name\nI'm mentioning here

stdio.h, cs50.h, is what C programmers\n

We'll see eventually what's\ninside of those files.

But long story short, it's like a menu\n

So in cs50.h, there's a menu\nmentioning get_string, get_int

And in stdio.h, there's a menu of\n

And that menu is what\nprepares the compiler

to know how to implement\nthose same functions.

All right, let me pause here.

A library provides all of the\nfunctionality we're talking about.

A header file is the very specific\n

And we'll discuss this more next week.

For now, they're essentially\nthe same, but we'll discuss

nuances between the two next week.

Yeah, the library would be standard\nI/O. The library would CS50.

The corresponding header\nfile is stdio.h, cs50.h.

incredibly common in the world of\n

but in C, there's technically no\n

We have sort of conjured it up\nto simplify the first few weeks.

That's a training wheel that we'll\n

take away, and we'll see why we've\n

Because C otherwise makes things\n

which then gets besides\nthe point for us.

Early on, you will have to use whatever\n

That will include CS50's functions.

Long story short, you referred, I\n

called scanf, we won't\ntalk about for a few weeks.

Long story short, in C, it's pretty easy\n

The catch is that it's really\neasy to do it dangerously.

And C, because it's an older,\nlower-level language, so to speak

that gives you pretty much ultimate\n

It's very easy to make mistakes.

And, indeed, that's too\nwhy we use the library

so your code won't crash unintendedly.

All right, so with this in\nmind, we have this now mapping

between the Scratch\nversion and the other.

Let me just give you a quick tour of\n

types that students will start seeing as\n

In the world of Linux, here\nis a non-exhaustive list

of commands with which you'll get\n

by playing with problem sets.

We've only seen two of these so\nfar, ls for list, rm for others.

But I mention them now\njust so that it doesn't

feel too foreign when you see them\n

cp is going to stand for copy.

mkdir is going to stand\nfor make directory. mv is

going to stand for move or rename.

rmdir is going to be remove directory,\n

and let me show you this\nlast one here first

only because it's something\nyou'll use so commonly.

If I go back to my code here on\n

and re-open the little GUI on the\n

revealing that I've got two\nfiles, hello and hello.c

so nothing has changed since there.

Suppose now that it's\na few weeks into class

and I want to start\norganizing the code I'm

writing so that I have a folder\nfor this week or next week

or maybe a folder for\nproblem set 1, problem set 2.

In the GUI, I can go up\nhere and do what most of you

would do instinctively on a Mac or PC.

You look for like a\nfolder icon, you click it

and then you name a\nfolder like PSet1, Enter.

Voila, you've got a folder called PSet1.

I can confirm as much with my command\n

How can I list what's in my folder?

and it's green with an\nasterisk because that's

my executable, my runnable program--

hello.c, which is my source\ncode, and now PSet1 with a slash

at the end, which just implies\nthat it's indeed a folder.

All right, I didn't really\nwant to do it that way.

I'd like to do it more advanced.

So let me go ahead and right-click\non PSet1, delete permanently.

I get a scary irreversible\nerror message.

But there's nothing\nin it, so that's fine.

Now I've deleted it using the GUI.

But now let me go ahead and start doing\n

And if you're wondering how\nthings keep disappearing

if you hit Control-L in your terminal\n

it will delete everything you previously\n

In practice, you don't need\nto be doing this often.

I'm doing it just to keep our\nfocus on my latest commands.

If I do-- what was the command\nto make a new directory?

DAVID J. MALAN: Yeah, so\nmkdir, make directory.

And notice at left, there's my PSet1.

If I want to get a little\noverzealous, plan for next week

Suppose now I want to open those\n

I could double-click on\nit like this, and you'd

see this little arrow is moving.

It's not doing anything because there's\n

But suppose again I want to get more\n

Notice if I type ls now, I\nsee all four same things.

Let me change directories\nwith cd space PSet1 Enter.

And now notice two things\nwill have happened.

One, my prompt has changed\nslightly to remind me where I am

just to keep me sane so that I don't\n

So here is just a visual reminder\n

If I type ls now, what should\nI see after hitting Enter?

Nothing, because I've only\ncreated empty folders so far.

If I wanted to create a folder called\n

called Mario this week, I can do that.

Now if I type ls, there is Mario.

Now if I do cd Mario,\nnotice my prompt's going

to change to be a little more precise.

And notice what's happening at top left.

Nothing now, because these\nfolders are collapsed.

But if I click the little\ntriangle, there I see Mario.

Nothing's going on in there\nbecause there's no files yet.

But suppose now I want to\ncreate a file called mario.c.

I could go up here, I could click the\n

Or I can just type code mario.c.

That creates a new tab for me.

I'm not going to write any code in here\n

And now at top left, you'll\nsee that mario.c appears.

So at some point, you can\neventually just close the Explorer.

Because, again, it's not providing\nyou with any new information.

It's maybe more\nuser-friendly, but there's

nothing you can't do at the command\n

All right, but now I'm kind of stuck.

How do I get out of this folder?

In my Mac or PC world,\nI'd probably click

the Back button or something like that\n

In the terminal window,\nI can do cd dot dot.

Dot dot is a nickname, if you\nwill, for the parent directory.

That is, the previous directory.

So if I hit Enter now, notice I'm\n

a.k.a. directory, and\nnow I'm back in PSet1.

Or, if I want to be fancy, let me\n

If I type ls, there's\nmario.c, just to orient us.

If I want to do multiple things\nat a time, I could do cd../..

which goes to my parent to my\ngrandparent all in one breath.

And voila, now I'm back in my\ndefault folder, if you will.

And one last little trick of the\n

was a moment ago, and you're\njust tired of all the navigation

if you just type cd and\nhit Enter, it'll whisk you

away back to your default\nfolder, and you don't have

to worry about getting there manually.

Recall a bit ago, though, that I\n

If dot refers to my parent,\nperhaps infer here syntactically

what does a single dot mean instead?

It means this directory,\nyour current directory.

It just makes super\nexplicit to the computer

that I want the program called\nhello that's installed here

not in some random other folder\non my hard drive, so to speak.

I want the one that's\nright here instead.

All right, so besides\nthese commands, there's

going to be others that\nwe encounter over time.

Those are kind of the basics.

That allows you to wean yourself off\n

and start using more comfortably,\nwith practice and time

a command line interface instead.

Well, what about those other\ntypes, now back in the world of C?

Those commands were not C. Those are\n

interface, like in Linux, which,\n

It's an alternative\nto Mac OS and Windows.

Back in the world of C now, we've\nseen strings, which are words.

I mentioned int or integer,\nbut there's others as well.

In the world of C, we've\nseen string, we will see int.

If you want a bigger integer, there's\n

If you want a single character,\nthere's something called a char.

If you want a Boolean value,\ntrue or false, there is a bool.

And if you want a floating-point value--

a fancy way of saying a real number,\n

that is what C and other\nlanguages call a float.

And if you want even more numbers\nafter the decimal point that

is more precision, you can\nuse something called a double.

That is to say, here is, again,\nan example in programming

where it's up to you now to provide\n

that it will rely on to know what\n

Is it a sound, an image,\na color, or the like?

These are the types of data types\n

What are the functions that come in\n

We talked about standard I/O, and\n

In the CS50 library, you can\nsee that it follows a pattern.

The C50 library exists largely\nfor the first few weeks

of the class to make our lives easier\n

So if you want to get a string,\n

If you want to get an integer from\n

When you want to get any of those\n

And they're indeed all\nlowercase by convention.

If we have the ability now to\nstore different types of data

and we have functions with which\nto get different types of data

how might you go about printing\ndifferent types of data?

Well, we've seen %s for string,\n%i for integer, %c for char

%f for a float or a double, those\n

and then %li for a long integer.

So here's the first\nexample of inconsistencies.

In an ideal world, that would\njust be %l and we'd move on.

It's %li instead in this case.

That's printf and some\nof its format codes.

no pun intended-- there is\na whole bunch of operators.

And, indeed, computers, one\nof the first things they did

was a lot of math and calculations, so\n

Computers, and in turn, C, really\ngood at addition, subtraction

multiplication, division,\nand even the percent sign

which is the remainder operator.

There's a special symbol\nin C and other languages

just for getting the remainder, when\n

There are other features in the world\n

And there's also what is of\n

makes it easier over time\nto write fewer characters

but express your thoughts the same.

So just as a single example\nof this, as a single example

consider this use of\na variable last week.

Here in Scratch is how you might\n

In C, it's going to be similar.

If you want the variable\nto be called counter

you literally write the word counter,\n

You then use the assignment\noperator, a.k.a. the equals sign

and you assign it whatever its initial\n

So, again, the 0 is going to get copied\n

because of that single equal sign.

But this isn't sufficient\nin C. What else

is missing on the right-hand\nside, instinctively now?

Even if you've never\nprogrammed in this before.

DAVID J. MALAN: A semicolon at the end.

And one other thing, I\nthink, is probably missing.

DAVID J. MALAN: A data type.

So if we can keep going\nback and forth here

what data type seems appropriate\nintuitively for counter?

So, indeed, we need to\ntell the computer when

creating a variable what\ntype of data we want

and we need to finish our\nthought with the semicolon.

So there might be a counterpart there.

What about in Scratch if we wanted\n

We had this very user-friendly\npuzzle piece last time

that was change counter\nby 1, or add 1 to counter.

In C, here's where things get\na little more interesting.

And pretty commonly done, you might\n

And this is where, again, it's\n

Otherwise, this makes no sense.

counter cannot equal\ncounter plus 1, right?

That just doesn't work if we're\ntalking about integers here.

That's because the equal\nsign is assignment.

So it can certainly be the\ncase that you calculate

counter plus 1, whatever that is,\n

from right to left to be that new value.

This, as we'll see,\nis a very common thing

to do in programming just to kind of\n

You can write this more succinctly.

This code here is what we'll\ncall syntactic sugar, sort

of a fancy way of saying the same thing\n

This also adds 1, or whatever\nnumber you type over here

to the variable on the left.

And there's one other form of syntactic\n

and it's even more terse than this.

That too will increment counter by 1\n

Or if you change it to minus\nminus, subtracting 1 from it.

You can't do that with\n2 and 3 and 4, but you

can do it by default with just plus plus\n

DAVID J. MALAN: Ah, so when you are\n

has been created, as we did with\nthe code that looked like this

you no longer need to remind the\ncomputer what the data type is.

Thankfully, the computer is\nat least as smart as that.

It will remember the type of\nthe data that you intended.

Other questions or comments on this?

All right, that's quite a lot.

Why don't we go ahead and\nhere take a 10-minute break?

And we'll be back, we'll\nstart writing some code.

We've just looked at some\nof the basics of compiling

even if it doesn't\nquite feel that basic.

But now, let's actually\nstart focusing really

on writing more and more code,\nmore and more interesting

code, kind of like we dove\ninto Scratch last week.

So here I have these code open.

I'm going to focus more on my\n

Many different ways I can create new\n

So, again, within this\nenvironment of VS Code

I can literally write the code\n

and it just creates a new\nfile for me automatically.

Or I could do that in the GUI.

I'm going to go ahead and create\nthis file called calculator.c

and I'm going to go ahead and\ninclude some familiar things.

So I'm just going to go ahead and\n

I'm going to go ahead from\nmemory and do the int void main--

more on that next week, why it's\n

And now let me just implement\na very simple calculator.

We saw some mathematical\noperators, like plus and the like.

So let me go ahead and\nfirst give myself a variable

called x, sort of like grade\nschool math or algebra.

Let me go ahead then and\nget an int, which is new

but I mentioned this exists.

And then let me just ask the user\nfor whatever their x value is.

The thing in the quotes is\njust the English, or the string

that I'm printing on the screen.\nso I could say anything I want.

I'm just going to say x colon\nto prompt the user accordingly.

Now I'm going to go ahead and\nget another variable called y.

And now, I'm going to\nprompt the user for y.

And I'm just very nitpickly\nusing a space just

to move the cursor so it doesn't\nlook too messy on the screen.

And then lastly, let me go ahead and\n

In an ideal world, I would just\nsay something like printf x + y.

But that is not valid in C. The\n

has to be a string in double quotes.

So if I want to print out\nthe value of an integer

I need to put something in quotes\n

if I want to move the cursor as well.

So, again, we only glimpsed\nit briefly, but what

do I replace these question marks with\n

DAVID J. MALAN: Yeah, so %i.

Just like %s was string, %i is integer.

And now if I want to add x and y, for\n

doesn't do much of anything other\n

And, again, it looks definitely\ncryptic at first glance.

It would be if programming\nweren't this cryptic.

Other languages will\nclean this up for us.

But, again, if you focus on the\n

which is a format string with\nEnglish or whatever language

then it takes potentially more\narguments after the comma

All right, let me go ahead\nnow and make calculator

which, again, compiles\nmy source code in C

pictured above, and converts\nit into corresponding machine

Let's do 1 plus 1 and Enter.

Now I have the makings of a calculator.

Now let's start to tinker\nwith this a little bit.

What if I instead had done this?

int z = x + y and then plug-in z here.

If I rerun make calculator, Enter,\n

still equals 2, and let me claim that\n

which of these versions\nis better designed?

If both seem to be correct at very\n

or is the previous one without the z?

OK, so this one is arguably better\n

variable called z that I\ncannot only print but, heck

if my program is longer,\nI can use it elsewhere.

Debatable, like before, because\nit depends on my intent.

And, honestly, I think\na pretty good argument

can be made for the first version.

Because if I have no\nintention of-- as you note--

using that variable\nagain, you know what?

Maybe I might as well do\nthis, just because it's

one less thing to think about.

It's one less line of code\nto have to understand.

So here, again, it does\ndepend on your intention.

But this field is pretty reasonable.

And I think, as someone\nnoted earlier, when

I did the same thing with get_string,\n

s line because get_string and the\nwhat's your name inside of it

it was just so much longer.

But x + y, eh, it's not that hard\nto wrap our mind around what's

going on inside of the printf argument.

So, again, these are the kinds\nof thoughts that hopefully you'll

acquire the instinct for\non not necessarily reaching

the same answer as someone\nelse, but, again, the thought

process is what matters here.

All right, so how might I enhance\nthis program a little bit?

Let's just talk about\nstyle for just a moment.

So x and y, at least in this case,\n

Because that's the go-to\nvariable names in math

when you're adding two things together.

So x and y seem pretty reasonable.

I could have done something like,\nwell, maybe my first variable

should be called first\nnumber and my next variable

should be called second number.

And then down here, I\nwould have to change this

to first number plus second number.

Like, eh, this isn't really\nadding anything semantically

But that would be one other\n

So if you have very simple\nideas that are conventionally

expressed with common variable names\n

What if I want to annotate this program\n

Well, I can add in C\nwhat are called comments.

With a slash slash, two forward slashes,\n

And then down here, I could\ndo something like prompt user

for y, just to remind\nmyself what I'm doing there.

And down here, perform addition.

Now, in this case, I'm not\nsure these commands are really

Because in the time it took me to write\n

I could have just read\nthe three lines of code.

But as our programs\nget more sophisticated

and you start to learn more syntax--

that, honestly, you might forget\nthe next day, the next week

the next month-- might be useful\n

reminds you of what your\ncode is doing or maybe even

With these early programs,\nnot really necessary

doesn't really add all that\nmuch to our comprehension

but it is a mechanism\nyou have in place that

can help you actually remind\nyourself or remind someone

else what it is that's going on.

Well, let me go ahead and rerun\n

And here, too, you might\nthink I'm typing crazy fast--

So it turns out that\nLinux, the operating system

we're using here in the cloud--

but, actually, Windows and Mac\nOS nowadays support this too--

So if you only have one\nprogram that starts with C-A-L

you don't have to finish writing\n

and the computer will\nfinish your thought for you.

The other thing you can do is\nif you hit Up and keep going up

you'll scroll through your\nentire history of commands.

So there too, I've been\nsaving some keystrokes

by hitting Up quickly rather than\n

So, again, just another\nlittle convenience

to make programming and interacting with\n

All right, let me go ahead and just make\n

The comments have no functional impact.

These green things are\njust notes to self.

Let me run calculator with\nmaybe-- how about this?

Instead of 1 plus 1,\nhow about 1 billion--

whoops, let's do that again.

1 million, 1 billion, and another 1\n

All right, so that seems correct.

Let's run this program one more time.

How about 2 billion\nplus another 2 billion?

So, apparently, it's not so correct.

And, clearly, running 1 plus 1 was\n

What might have gone wrong?

What might have gone wrong?

The computer probably ran\nout of space with bits.

So it turns out with these data types--\n

and also float and char and those\n

and, most importantly, finite\nnumber of bits to represent them.

Newer computers use more bits, older\n

It's not necessarily standardized\nfor all of these data types.

But in this case, in this environment,\n

So with 32 bits, you\ncan count pretty high.

This is 64 light bulbs on the\nstage and could count even higher.

An int is only using half of these, or\n

Now, if you think back to last week,\n

And if you have 8 bits, 8 zeros and\n

just a good number to\ngenerally remember as trivia.

8 bits gives you 256\npermutations of zeros and ones.

32 gives you roughly how\nmany, if anyone knows?

So it's roughly 4 billion, 2 to the 32.

If you don't know that, it's fine.

Most programmers, though, eventually\n

2 billion plus 2 billion\nis exactly 4 billion.

And that actually should\nfit in a 32-bit integer.

The catch is that my Mac,\nyour PC, and the like

also like to support negative numbers.

And if you want to support both positive\n

means with 32-bit integers,\nyou can count as high

as roughly 2 billion positive\nor 2 billion negative

That's still 4 billion, give or\ntake, but it's only half as many

in one direction or the other.

So how could I go about implementing\na correct calculator here?

Yeah, so not just li,\nwhich was for long integer.

I have to make one more change,\n

So let me go back up here and change\n

And then let me change y as well.

And then let me change the format code\n

Let me recompile the calculator--

That's should obviously be the same.

Now let's do 2 billion\nand another 2 billion

and cross our fingers this time.

Now we're counting as high as 4 billion.

And we can go way higher than\n4 billion, but we're only

kicking the can down the street a bit.

Even though we're now using--

64 bits, which is as long as this\n

It might be a really big\nvalue, but it's still finite.

And we'll come back at the\nend of today to these kinds

Because arguably now, my calculator\n

billions of possible inputs but not all.

And that's problematic\nif you actually want

to use my calculator for any\npossible inputs, not just

ones that are roughly less than,\n

All right, any questions then on that?

But it's really just a\nprecursor for all the problems

that we're going to have to\neventually deal with later on.

DAVID J. MALAN: A good question.

If we were still using z, we would\n

Otherwise, we'd be ignoring\n32 of the bits that

had been added together via the longs.

All right, so how about we spice things\n

how about something\nwith some conditions?

Let's start to ask\nsome actual questions.

So a moment ago, recall that we had\n

Now let's look back at\nsomething in Scratch that

looked a little something like\nthis, a bunch of puzzle pieces

asking questions by way\nof these conditionals

and then these Boolean expressions\n

In C, this actually maps pretty cleanly.

It's much cleaner from left to right\n

Here, we have just code\nthat looks like this.

If, a space, two parentheses\nand then x less than y

and then we have something like\nprintf there in the middle.

So here, it's actually\nkind of a nice mapping.

Notice that, just as the\nyellow puzzle piece in Scratch

is kind of hugging the\npurple puzzle piece

that's effectively the role that\nthese curly braces are playing.

They're sort of encapsulating\nall of the code on the inside.

The parentheses represent\nthe Boolean expression

that needs to be asked and answered to\n

And here's an exception to\nwhat I alluded to earlier.

Usually, when you see a word and\nthen a parenthesis, something

and then closed parenthesis, I\n

And I'm still feeling pretty\ngood about that claim.

And the word if is not a function.

It's just a programming construct.

It's a feature of the C language\n

for different purposes\nfor a Boolean expression.

How about something like this?

Last week, if you wanted to\nhave a two-way fork in the road

go this way or that way,\nyou can have if and else.

In C, that would look a\nlittle something like this.

And if we add in the printf's,\nit now looks quite like the same

but it adds, of course, the word else\n

As an aside, in C, It's not strictly\n

if you have only one line\nof code indented underneath.

For best practice, though, do so anyway,\n

and ultimately anyone\nelse reading your code

that you intend for just that one\n

How about this from last week?

Here was a three-way fork in the road.

If x is less than y, else if x is\n

Now, here's where you have some\ndisparities between Scratch

and C. Scratch uses an equals sign\n

C uses a single equals sign\nfor assignment from right

to left, minor difference\nbetween the two worlds.

In C, we could implement the same\n

just this additional else if.

And if we add in the printf's, it\n

This is correct both in the\nScratch world and in the C world.

But could someone make a claim that\n

We need the else, at least,\nbut we don't need the last if.

Because, at least in the\nworld of comparing integers

it's either going to be less\nthan, greater than, or equal to.

So you can save a few\nseconds, if you will

of your program running-- a blink of\n

and then inferring what\nthe answer to the third

must be just by nature of\nyour own human logic here.

Now, why is that a good thing?

If, for instance, x and y\nhappen to equal each other--

I type in 1 and 1 for both values,\n

in the case of this version,\nyou're sort of stupidly

asking three questions, all of\nwhich are going to get asked

even though the answer is no, no, yes.

That seems to be unnecessary because\n

get rid of the unnecessary if and\n

else print that x is equal to y--

now if x indeed equals y because\n

now you're only going to ask two\n

and then you're going to get\nyour same correct result.

So, again, a minor detail,\nbut, again, the kinds of things

you should be thinking\nabout, not only as

you write your code to\nbe correct but also write

it to be well-designed as well.

All right, so why don't we\ngo ahead and translate this

into the context of an\nactual program here?

I'll create a blank window here.

And let's do something with points,\n

Let me go ahead and\nrun code of points.c.

That's just going to\ngive me a new text file.

And then up here, I'm going to\ndo my usual, include cs50.h.

So a lot of boilerplate, so to\nspeak, in these early programs.

Let's ask the user, how\nmany points did they

lose on their most recent CS50 PSet?

So sort of evoke my photograph of\n

where I lost a couple of points myself.

Then I'll ask a question in English\n

And then once I have this answer,\n

So if points is less than 2--

borrowing the syntax that we\nsaw on the screen a moment ago--

let's go ahead and print\nout something explanatory

like you lost fewer points\nthan me, backslash n.

else if points greater than 2--

which is, again how many I lost--

I'm going to go ahead and print out you\n

else if-- wait a minute, else seems\n

I'm just going to go ahead\nand print out something

like you lost the same number\nof points as me, backslash n.

So, really, just a straightforward\n

but to a concrete scenario here.

So let me go ahead and save this.

Let me go ahead and\nrun make points, Enter.

And then, how many points did you lose?

All right, you lost\nfewer points than me.

So, again, we have the ability to\n

from last week in reality, which is\n

There's something subtle here, though,\n

that someone might call a magic number.

This is programming speak\nfor something I've done here.

There's a bit of redundancy unrelated\n

But is there something I typed twice\n

Exactly, I've hard-coded, so to speak,\n

in two locations, in this case--

that did not come from the user.

So, apparently, once I\ncompile this, this is it.

You're always comparing\nyourself to me in like, 1996

which for better or for worse,\nis all the program can do.

But this is an example too of\na magic number in the sense

like, wait, where did that 2 come\n

It feels like we are setting the\n

of screwing up down the road.

Because the longer this code gets,\n

am I going to keep typing the number 2?

But, honestly, eventually,\nyou're going to screw up

and you're going to miss one of the\n

because maybe I did worse the\nnext year, or 1, I did better.

And you don't want these\nnumbers to get out of sync.

So what would be a logical\nimprovement to this design

rather than hard-coding the\nsame number sort of magically

Yeah, why don't I make a\nvariable that I can use in there?

So, for instance, I\ncould create a variable

like this, another integer called mine.

And I'm just going to\ninitialize it to 2.

And then I'm going to change\nmentions of 2 to this.

And mine is a pretty reasonable\nname for a variable insofar

as it refers to exactly\nwhose points are in question.

There's a risk here,\nthough, minor though it is.

I could accidentally\nchange mine at some point.

Maybe I forget what mine represents,\n

So there\'s a way to tell the\ncomputer "don\'t trust me

because I\'m going to\nscrew up eventually

by making a variable constant too.

So a constant in a\nprogramming language--

this did not exist in Scratch--

is just an additional hint to the\n

you to program more defensively.

If you don't trust\nyourself necessarily to not

screw up later, or\nhonestly, in practice

if you know that number should\nnever change, make it constant

and never think about it again.

This tells the compiler to make sure\n

And another convention in C and other\n

it's often common to just\ncapitalize the variable.

Kind of like you're\nyelling, but it really just

visually makes it stand out.

So it's kind of like\na nice rule of thumb

that helps you realize, oh,\nthat must be a constant.

Capitalization alone does\nnot make it constant.

But the capitalization\nis just a visual reminder

that this is somewhere,\nsomehow a constant.

So just a minor refinement,\nbut, again, we're

sort of getting better at\nprogramming just by instilling

Questions, then, on conditionals\nin C or these constants?

AUDIENCE: Why do you not use\n

DAVID J. MALAN: Yeah, why do you\n

This is the way the\nlanguage was designed.

Generally speaking, when you're\n

there's no semicolons involved.

For now, assume that semicolons usually\n

That's not 100% reliable of a heuristic,\n

Left hand was not talking to the right\n

All right, so let's do something else.

If I have the ability to ask\nsomething conditionally--

is this thing true or\nis this other thing--

could I write a very simple program\n

tells me if a number the\nhuman types is even or odd?

Well, let me just get the\nframework for that in place.

Let me go ahead and\nwrite code of a parity--

is a fancy way of saying even or odd.

And let me go ahead and include cs50.h,\n

again, more on those down the road.

But, for now, I'm going to go ahead\n

by calling get_int and asking\nthem for whatever n is.

And then now I'm going to\nintroduce some pseudocode.

So here's the first\nexample of a program

honestly, that I'm not\nreally sure how to proceed.

So let me just resort to some\npseudocode using comments.

Eventually, I'll get rid of\nthis and write actual code.

But if n is even, then print--

actually, let me just print that.

Let me just go ahead and say\nprintf, quote unquote, "even"

because I know how to use printf.

else-- all right, I\nknow how to printf odd

so let me just say printf,\nquote unquote, "odd".

So here, I've sort of taken a bite\n

And let me go ahead and put\nin my little placeholders.

I want to do some kind of conditions.

So if, question marks now, let me go\n

I'm getting closer to solving this.

But I still have this\nquestion mark here.

How, using syntax we've seen, might\n

There's this little operator I\n

operator, that will let\nyou do exactly that.

If you divide any number by\n2, that mathematical heuristic

is going to tell you if it's even\n

And that's nice because the alternative\n

like if n == 0 or if n\nequals 2 or n equals 4--

your code would be infinitely long if\n

But if I do n divided by 2\nand look at the remainder--

it's a little cryptic, but\nthis will indeed do the trick.

So the percent sign is\nthe remainder operator.

It does numerator divided by denominator\n

but, rather, the remainder of that.

So if you divide anything by 2,\n

And if, indeed, 2 divides\ninto n evenly, giving you 0

then you're going to print even.

But there is something odd-- pun\n

What is another new piece of syntax,\n

And I even caught myself\nverbally saying it a moment ago

just because it's so ingrained.

DAVID J. MALAN: Yeah, if\nsomething's equivalent to the other.

So now this is the equality operator.

It's not assignment from right to left.

And this one too is an\nexample of, literally

humans not really planning\nahead, perhaps, left hand

not talking to right hand\nin that someone decided

let's use the equals\nsign for assignment.

And then some number of minutes or\n

how do we now compare for equality?

And if you think this is a little weird,\n

there's a third version where\nyou use three equal signs.

So, again, it's humans that\ndesign these languages.

So if you're ever frustrated by them,\n

it might just not have\nbeen the best design.

But we just kind of have\nto live with it ever since.

So let me go ahead and zoom out here.

Let me go ahead and make parity here.

So make parity-- and, again, parity\n

./parity, type in a number like 2.

3, that's indeed odd, and so forth.

If we continue testing, presumably,\n

Let me go ahead now and let me start\n

because, admittedly, it's getting\n

all of that boilerplate at the top.

Let me create a program\ncalled agree.c that's

reminiscent of any of\nthose forms you have

to agree to online with a checkbox\n

So let me throw away all the\nguts of this main program

and now ask something like this.

Let me go ahead and prompt\nuser to agree to something.

I'm going to go ahead and say, how\n

whatever the question might be--\n

for yes or no, respectively.

So if it's only a single\ncharacter, actually, I

can actually get by with just get_char.

Not used it before,\nbut it was on our menu

of functions from the CS50 library.

And if I want to get\nthe user's response

the return value should be\na char also on the left.

So now we've seen strings,\nints, and now chars

if we only care about a single letter.

And now let's go ahead,\ncheck whether user agreed.

So how about if c == "y", then let me\n

print out agreed or some\nsuch sentence like that.

else if they did not type\nc-- or you know what?

Let's be explicit here,\njust so they can't

type z or b or some random letter.

else if c=="n" n for no, then let me\n

And I'm just going to ignore\nthe user if they don't cooperate

and they type z or b or\nsomething that's not y or n.

All right, let me go ahead now and\n

Let's go with the default.\nOK, so that seems to work.

No, I don't agree this time.

How about my caps lock key is on or\n

So, obviously, a bug, at least if I want\n

which is kind of reasonable.

So what would be the possible\nsolutions here, do you think?

How do I solve this and tolerate\nboth capital and lowercase?

Maybe what's the simplest,\nmost naive implementation?

DAVID J. MALAN: Yeah, so why\ndon't I just ask two questions?

Or you know what, even more simplistic\n

if you will, let me just copy\nand paste some of this code.

Change this to an else-- whoops,\nnot in caps-- else if "Y".

And then I bet I could\ndo the same thing with n.

But here too, just like\nwith Scratch, as soon

as you start to find\nyourself copying and pasting

you're probably doing something wrong.

And what you said verbally,\nif I may, was actually better.

Because you're implying that I could\n

The catch is, you can't use the word OR\n

So you can express one\nquestion or another.

You only need one of the\nanswers to be yes or true

and you use two vertical bars.

By contrast, just so\nyou've seen it, if you

wanted to check if something is equal\n

you could use two ampersands.

This logically would make\nno sense here, though.

Certainly, what the human typed can't\n

So in this case, we do want OR.

But that allows me to\ntighten my code up.

I don't have to start copying\nand pasting whole branches.

I can now ask two questions at once.

Questions, then, on this variation?

Can you convert the\ninput to all lowercase?

We don't have the capability yet.

It turns out that's going to require--

to be easy, another library,\nthough we could do it

ourselves knowing a little bit about\n

But, yes, that would be an alternative,\n

DAVID J. MALAN: Good question.

Unfortunately, you have to be explicit\n

even though that's kind of\nhow you might think about it.

You have to ask a complete question\n

Let me ask a question now too.

I deliberately used single quotes\n

Previously, we used double quotes\n

Correct, string is double quotes for\n

And single quotes for single characters.

Because my data type is different.

I chose the simple route of\njust using a single char.

In fact, this program\nwon't work with Y-E-S

or N-O. That's not supported at the\n

I had to use single quotes\nbecause that's how C does it.

If you're dealing with\nsingle characters

a.k.a. chars, use single quotes.

even if it's one single\ncharacter in a string

as though you're starting to write\n

that would be double quotes.

And we'll see why this\nis before long too.

But, again, just things to keep\nin mind whenever writing code

in this particular language.

So, short answer, if I'm understanding\n

And this would be even more incorrect.

But if you don't mind, let me\nkick the can a couple of weeks

on this as to why this doesn't work.

The most pleasant way to do this would\n

But even this is a slippery\nslope, because what

if the user does something weird,\n

You can imagine this\ngetting messy quickly.

I like your idea earlier\nabout just forcing everything

to lowercase just to standardize things.

Unfortunately, you cannot compare\nstrings for equality like this

for, again, reasons will\ncome to before long.

So for today, we're keeping it\n

not nearly as user-friendly to\nonly tolerate individual letters.

And there's a question over here.

On the US English keyboard\nit's shift and then

the backslash key above Return,\nbut depending on your keyboard

All right, so let's\nactually now look back

at something we did a\nlittle bit of last week.

Let me go ahead and open\na file called meow.c

because, recall, that's what\nwe had Scratch do initially.

Let me include not the\nC50 library this time

but just stdio.h because I\nonly want printf for this demo.

Let me go ahead now and\njust print out meow.

And then if I want the cat to meow\n

The program is written--\ncorrect, I claim.

But, again, this was the\nbeginning of our conversation

last week of not being\nparticularly well-designed.

And if someone wants to maybe\npoint out the now obvious

why is this not\nwell-designed, necessarily?

Yeah, it's just repetition, right?

Again, I literally\nresorted to copy-paste.

That should be the signal\nthat you're probably

doing something wrong or, at best,\n

So the solution, as you\nmight glean from last week

is probably going to be one\nof those things called loops.

So let's just take a look at some\nof the syntax for loops in C.

But, again, no new ideas,\nit's just some new syntax

that'll take some getting used to.

In Scratch, if you wanted to meow\n

there's not a forever keyword in C, so\n

But this is the best we can do.

It turns out there is a\nkeyword called while in C.

And that kind of has\nthe right semantics

because it's like while I do\nsomething again and again

But just like an if condition\nor an else if condition

those took a Boolean\nexpression in parentheses

a while loop also takes a Boolean\nexpression in parentheses.

Now, if I want to do something\n

say while 2 is greater than\n1, while 3 is greater than 2

or just something completely arbitrary.

But that should rub you the wrong\n

Why 3-- if you want true, just say true.

So it turns out in C, there are\n

that are literally true\nand false, respectively.

I could also put the number 1 for\n

but most people would just\nsay true to be explicit.

So it's a little hackish, if\nyou will, but very conventional.

There's no forever keyword in C. If\n

I'm going to just use\nsomething like printf here.

So, again, not perfect\ntranslation from one

to the other, but absolutely\npossible in C. What about this?

This is a little more common\nif you want to do something

a finite number of times, like repeat 3.

There's a few different ways we can\n

And here's where C-- like a\nlot of text-based languages

you kind of have to whip out that\n

blocks and think about,\nall right, how can I

build a little machine in software that\n

Well, let me give myself a variable\n

Let me create a loop whose Boolean\n

the idea being here, why don't\nI just kind of count 1, 2, 3?

So how do I implement\nthis physicality in code?

I give myself a variable,\nset it to 0, 0 fingers up.

Now, I ask the question,\nis counter less than 3?

If so, go ahead and print out meow.

And just intuitively, even if\n

before Scratch, what\nmore do I need to do?

I've left room here for\none more line of logic.

We have to increase counter.

So I need code like I showed earlier,\n

And so here's where\nprogramming sometimes

becomes a bit more like plumbing.

You can't just say what you\nmean, like you couldn't Scratch.

You have to build a little\nsort of software machine

that initializes a value, does\n

And so it's kind of like\nthis software-based machine

but together, that's just using\nsome familiar building blocks.

Just like in Scratch, you\nmight have used loops a bunch

of times, pretty common in C.

So can we tighten this code up?

This is correct, but here are\nsome conventions that are popular.

If you're going to count, just say i.

A convention in\nprogramming-- with, at least

languages like C-- is just use i\n

is to count from like, 0 on up.

It's just more verbose\nthan you need to be.

You don't need more semantics than that.

All right, what else can I do here?

There's another opportunity\nto tighten up this code.

Yeah, that syntactic sugar\nthat does nothing new

but it does it more succinctly.

I can change this to either the\n

Now, this is pretty canonical.

This is how most people\nwould implement something

three times using a loop in C--

using a while loop, that is.

Turns out that it's so common\nin C and other languages

to do something finitely many times,\n

In this model, to be\nclear, the logic, though

is that we start by initializing the\n

We then ask the question,\nis i less than 0?

If so, everything that's\nindented inside the curly braces

gets executed-- namely,\nmeow then the update.

Then the computer is going to\nhave to recheck the condition

to make sure that i hasn't gotten\n

But if not, it then does this\nagain and it does this again.

And then it repeats, constantly\nchecking the condition

and executing what's in the\nblock, checking the condition

and executing what's in the block.

After three times of that, the condition\n

It just proceeds to whatever's\n

It jumps to the next blocks down below.

All right, what's another\nway, though, to do this?

Well, I've deliberately\nbeen counting from 0--

and that's a programming\nconvention, right?

We started last week with all\nthe light bulbs off, which was 0.

So it's pretty reasonable to\nstart counting at 0's, just

Like, no fingers are up, this is 0--

But if you prefer, you could\nstart counting at i equals 1.

But then you don't want to\ndo it while i is less than 3

you want to do i is\nless than or equal to 3.

On most keyboards, there's no symbol for\n

or equal to, so in C, you\nuse two characters, less than

and then an equals sign\nwith no spaces in between.

That just means less than or equal to.

We could change it to set i to 2\n

We could make this be a 10\nand less than or equal to 12.

But, again, just stick with the basics.

Start at 0 and count on up\nwould be the convention.

Or if you prefer to count\ndown, that's fine too.

Set i to 3 and then do this so\nlong as i is greater than 0

but you have to decrement\ninstead of increment.

So, again, we could\ndo this all day long.

There's literally an infinite number\n

And that's why I keep\nemphasizing convention.

Call the variable i for\nsomething like this

initialize it to 0 for something like\n

unless you really prefer to count down.

Again, just certain human conventions.

All right, how about\nanother way to do this?

This is what's called a for\nloop in C, also very common.

It's not quite as straightforward\n

to bottom in exactly the same way.

This kind of has a lot more\nlogic tucked into its first line.

But it does exactly the same thing.

notice that inside the\nparentheses, next to the word for

there's two semicolons-- which\nis another weird use of syntax.

They're not at the end\nof the line, now they're

in the middle of the parentheses.

But that's what the\nhumans chose years ago.

The first thing before the semicolons\n

The next thing is the condition\nthat's going to constantly get

checked every cycle through this loop.

And the last thing is going to be\n

in this case is going to be count up.

So, again, if I rewind\nwe initialize i to 0.

We then ask the question,\nis i less than 3?

If so, execute what's\ninside of the loop.

Then the computer does this, it does\n

And then it's not going\nto blindly meow again.

It's going to check again the\ncondition, is i less than 3?

Then it's going to meow if so.

Then it might go ahead and increment\n

So, again, this does not read quite\n

You kind of read it left to\nright and then jump around.

But, again, the initialization,\nthe constant Boolean expression

being checked, and the\nupdate after each time

does the exact same thing as what we saw\n

I think most people would\nprobably eventually use

a for loop once comfortable, but just\n

All right, any questions, then, on\n

DAVID J. MALAN: A for\nloop and while loop

can both be used to do\nexactly the same thing.

There are subtle differences\nwith issues of scope

which we'll discuss before\nlong, where when you

create a variable in a for loop--

notice that it was, again, inside\nof those parentheses, which

technically means it's only going to\n

By contrast, with the while loop,\nI declared my variable outside

That variable is going to continue\n

So that's one of the\nminor differences there.

But you'll see some others over time.

All right, so we claim then\nthat it's better in some form

So let's actually jump back to the code.

Let me go ahead and now re-implement\n

So how about for int i\n= 0, i less than 3, i++.

Then inside my curly braces, let me go\n

with a newline and a semicolon.

So I did it pretty quickly just because\n

But if I now make meow, no errors there.

Well, let's do now what\nwe did last week, which

was to begin to make our own\ncustom functions, if you will

by using our own in C. So here's\n

but we'll explain over time what\n

If I want to create a\nfunction called meow--

because the authors of C did not create\n

I need to give it a name, like meow.

I need to specify if\nit takes any inputs.

For now, I'm going to say no.

And I'm going to explicitly say no\n

It's also necessary when\nimplementing a function in C--

which was not necessary in Scratch--

to specify what its return type is.

But for now, I'm just going to say\n

and that's what the void\nin parentheses means--

and it does not return\nanything like ask did

or like get_string or get_int does.

meow's purpose in life is just to\n

by printing something on the screen.

So what is meow going to do?

I'm going to have it\nquite simply say printf

quote unquote, "meow", backslash n.

And now, just like in\nScratch, I can now just call

a brand new function called meow.

And here's where too, if you\nreally don't like the curly braces

technically speaking, you can\nget rid of them when there's

only one line of code inside your loop.

But, again, stylistically,\nI would encourage

you to preserve them to make\nsuper clear to yourself and others

Let me go ahead and save\nthis and do make meow.

DAVID J. MALAN: Yeah, so\n0 does not belong there.

All right, it's still working OK.

But recall what I did in Scratch,\n

And just to make a point, let me\njust highlight this and move it

Because, again, now that meow\nexists, it's an abstraction.

I just know a meow function exists.

I want to be able to use it.

My main function is the same.

Let me go ahead and make meow again.

And now, just by moving that function,\n

And let's look at the first.

Again, the rule of thumb\nhere-- it's a little small

but it says meow.c in bold-- which is\n

5 is the line number,\nand 20 is the character.

So line number is enough alone.

Oh, this is what happens\nwhen I scrolled up too far.

This is the error we're\nnow looking at, line 7.

I was looking at the old error message\n

All right, apparently, C does not\n

Implicit declaration of\nfunction meow is invalid in C99.

Declaration of function means\nyour creation of a function.

Like, I'm declaring that meow\nexists, but I haven't apparently

And then C99 is the version\nof C from the year 1999

which we generally use here, it's\n

Can you infer from the mere fact\n

of the file-- which was fine\nin Scratch but now is bad--

DAVID J. MALAN: Yeah, C is\njust kind of old school.

It reads your code top to bottom.

And if it does not know what meow\n

it just freaks out and prints\nout these error messages.

So the solution is, quite simply, don't\n

But you can imagine this getting a\n

because main is, by name, the\nmain part of your program.

And, honestly, it would just\nbe nice if main were always

Because if you want to\nunderstand what a file is doing

it makes sense to just\nread it top to bottom.

Well, there is a solution to this.

You can put functions in different\n

as you-- and this is perhaps the\n

so long as you leave a little\nbreadcrumb for the compiler

at the very top of your\nfile that literally

repeats the return value,\nthe name, and the arguments

to that function, semicolon.

This is, so to speak,\ndeclaring your function--

and the real fancy way\nis this is a prototype.

It's like, what is this\nthing going to look like?

But the semicolon means I'm not\ngoing to deal with this yet.

I'm going to actually\ndefine the function

or implement it down below here.

This is kind of a stupid detail.

More recent languages\nget rid of this need

you can put your functions in any order.

But, again, if you just\nthink about the basics

of programming languages\nlike this one here--

it must just be reading\nyour code top to bottom.

So annoying, yes, but\nexplained, yes too.

So let me go ahead and make meow one\n

And let me make one final enhancement\nto this meow program here.

Let me go ahead now and\nsay something like this.

Let me go ahead and say,\nall right, wouldn't it

be nice if my meow function could do\n

So suppose I want to do this.

This meow function at the moment\nis going to meow three times.

But suppose I want to meow\nn times, where n is just

some number provided by the user.

Well, just like in Scratch,\ncustom functions can take inputs

I just presently am saying void.

But if I change this to int n,\nthereby telling the compiler

hey, meow still doesn't\nreturn something

but it does take something as input.

It takes an integer,\nand I want to call it n.

So this is another way\nof declaring a variable

but a way of declaring a\nvariable that gets handed into

So now if I tighten up main here, now\n

just like in Scratch, which is this.

If I now look at this\ncode-- let me Zoom in here--

now my main program is really\nwell-written in the sense

that it just says what it\ndoes, meow three times.

This works, though, because I\n

an integer called n, and then using\n

You might have caught my one mistake.

I also have to remind myself up\nhere to make that change too.

Again, this is one of the only\nredundancies or copy-paste

But there, I have now a better version.

So let me go ahead and rerun\nthis, make meow, ./meow.

So, again, no change\nin correctness but now

again, we're sort of\nmodularizing our code.

And, heck, what you could do now-- and\n

those header files we talked\nabout early, those libraries

this is the kind of modularization\nwe're talking about.

We, the staff, wrote a function called\n

we put it in a file called CS50, and we\n

these things called prototypes--

So that when you all, as aspiring\nprogrammers, include cs50.h

you are sort of secretly telling the\n

what the menu of available functions is.

Because in CS50 is lines like\nthese-- obviously, not for meow

but for get_string,\nget_int, and so forth.

And stdio.h is the same lines\nof code for things like printf.

So that's all that's going on there.

It's just a way of telling the computer\n

All right, any questions,\nthen, on these here?

So if you don't mind, I\nwant to continue to wave

my hand at that detail for today.

Indeed, int main void is a little weird,\n

We have no mechanism\nfor providing input yet.

And what does it mean for\nmain to return anything?

Like, who is it returning to?

For another day, if we may.

They're going to come into\nplay but that, for now

today is just something you\nshould take at face value

as necessary copy-paste\nto begin programs.

So meow is a function that takes an\n

but it didn't actually have a\nreturn value, hence the void.

But what if we actually want\nto create our own function that

not only takes 0 or\nmore inputs as arguments

but also returns some value, maybe an\n

Well, it turns out, in C,\nwe can do that as well.

Let me go ahead and create a\nnew file here called discount.

And let's implement a\nquick program via which

we can discount some regular\nprice by some percentage

as though there's a sale\ngoing on in a store.

Let me go ahead and include our usual\n

Let me give myself int\nmain void as before.

And inside of main, let's go\nahead and do something simple.

Let's give ourselves a\nfloat called regular

representing the regular\nprice of something in a store.

Let's go ahead and get a float\nfrom the user asking them

Then, next, let's go ahead and declare\n

called sale, ultimately\nrepresenting the sale price

after some percentage discount off.

And let's go ahead and simply\ncalculate whatever regular is.

And, say, 15% off is a\npretty good discount.

So let's go ahead and discount\nregular, whatever it is, by 15%

which is equivalent, of course, to\n

Of course, if we're taking off 15%,\n

Now, let's go ahead and\nprint out the results here.

Let me go ahead and say\nprintf sale price, colon--

let me go ahead and %f,\nbut, more specifically

%.2f because, at least in US currency\n

And then let me go ahead and\nplug in the value of sale.

All right, let's go down here\nand do make discount, Enter.

So far, so good-- ./discount.

And the regular price is maybe $100.

So the sale price should be $85.

So our arithmetic seems\nto be correct here.

But let's fast-forward now in time.

Suppose that we find\nourselves discounting

a lot of prices in an\napplication, maybe a website

like Amazon where they're offering\n

And it'd be nice to have\na reusable function that

just does this arithmetic for\nus, simple though it may be.

So let's go ahead and\nmodify discount this time

to give ourselves our own\nfunction called discount

for instance, that takes an input--

like the regular price\nthat you want to discount--

and then it also returns a value.

It doesn't just print it out.

It returns a value, namely, a float\n

So let me go down\nbelow main and go ahead

and define a function that's\ngoing to return a float

because we're dealing\nwith dollar amount still.

The function is going\nto be called discount.

And it's going to take one input, like\n

In here, I'm going to do\nsomething very simple.

I'm going to say float sale equals\n

And then I'm going to go\nahead and return sale.

Now, for that matter, I can\nactually tighten this up a bit.

If I'm only declaring a variable\nto store a value that I'm then

returning with this keyword return, I\n

So I can delete the second line.

And I can actually just go ahead\nand get rid of that variable

altogether and immediately\nreturn whatever the arithmetic

result is of taking the price input,\n

So very simple function that\nsimply does the discounting for me.

As always, let me go\nahead and copy-paste--

the only time it's OK to copy-paste--\n

the top of the file, so that\nwhen compiling this code

main has already seen\nthe word discount before.

And now let me go into the code here.

And instead of doing\nthe math myself in main

let me presume that we\nhave some function already

in our toolkit called discount that\n

And then down here, my code\ndoesn't need to change.

I'm still going to print out\nsale the variable in which I'm

storing that result. But\nnotice what I've done here.

I've sort of abstracted\nthe way the notion

of taking a discount by creating my\n

price, or anything else as input.

It does a little bit of math,\nsimple though it is here

and then it returns a value.

But notice that discount\nis not printing that value.

It's literally using\nthis other keyword called

return so that I can hand back that\n

back a value, just like get_int\n

for you-- so that I up here on\nline 9 can go ahead and store

that value in a variable if I want\n

Let me go ahead now and recompile\nthis code with make discount.

Let me go ahead and do ./discount.

Sale price is going to be $85 as well.

Now, it turns out that functions don't\n

They can actually take 2 or 3 or more.

So, in fact, suppose we wanted to now\n

and take in as input to the discount\n

that I want to discount but\nalso the percentage off

thereby allowing us to support not just\n

Well, let me go up here and declare\n

And let me ask the user\nfor how many percentage

points they want to take off.

So I'm going to say percent_off\ninside of the prompt here

get that int called percent_off.

And now in addition to\npassing in regular as an input

to the discount function, I'm\nalso going to pass in percent_off.

But I need to tell the computer\n

and the way I do this\nis just with a comma

down here in the\nfunction's own definition.

Here is going to be a percentage\nargument, a second argument

And I'm now going to use that\n

I don't want to just do percentage\n

that's going to increase\nthe size of the total price.

I actually need to do a little bit\n

a percentage off, like the number\n15 for 15 percentage points

I need to do 100 minus that\nmany percentage points

thereby giving me 100 minus 15--

And then I need to divide\nthat by 100 in order now

to give myself 0.85 times\nthe price that was passed in.

But if I go ahead now and save this,\n

I notice that I've\nactually got an error here.

Well, I need to change\nthat prototype too.

And, again, this is admittedly\nan annoying aspect of C

that you have to maintain\nconsistency here.

I'm just going to go up\nhere, change this to int

percentage-- spelling incorrectly.

And now let me retry\ncompilation, make discount

crossing my fingers this time.

Worked OK. ./discount, and voila, $100.

And percent off, say, 15 points.

Now, it's worth noting\nthat I've deliberately

returned the results of my\nmath from this function.

I haven't just done the math on the\n

In fact, if we take a look\nat this second version

where discount is now taking a price\n

notice that I'm not doing\nsomething like this.

I'm not just saying price\nequals price times 100

minus percentage divided\nby 100 and leaving at that.

The problem there is that\nthis variable price is going

to be scoped to that discount function.

And we'll encounter this again\n

just refers to where in which a\n

So it turns out if I change price\n

function, that's not going\nto have a lasting effect.

If I actually want to\nget the result back

to the function that used the\ndiscount function, namely, main

I actually do need to take this\napproach of actually returning

the value explicitly so that ultimately\n

Well, let's go ahead and\nmaybe how about let's just

use these primitives in\njust a few different ways.

How about a little game of\nyesteryear, Super Mario Brothers?

And in the original Super Mario\n

so you have these\nside-scrolling worlds that

look like this where there's some coins\n

So let's just use this as a\nvisual to consider how in C could

I start to make\nsomething semi-graphical.

Like, not actual colors or fanciness,\n

just something like printing\nout some question marks.

Well, if I go back over here,\nlet me create that actual file

Let me go ahead and include\nstdio.h, int main void, again

which we'll continue to\ncopy-paste for today.

And then let me just go ahead and\n

All right, this is what we\nmight call ASCII art, which

just means graphics but really just\n

And if I make mario and do ./mario,\n

as this, but it's the beginning\nof this kind of map for a game.

Well, if I wanted to now print\nout of those things dynamically

let me go back to my code here.

And instead of printing\nout for all at once

I could do something like four int i\n

And then inside here, I could just\n

Let me save that, make mario.

And, at the risk of\ndisappointing, so close

but I made a mistake,\njust a stupid aesthetic.

The prompt is not on the new line.

DAVID J. MALAN: Yeah, I need an\n

OK, no, because that's going\nto put it after everyone

and it's going to make this thing\n

So, logically, just like in Scratch, put\n

And just print out, for instance,\nonly, quote unquote, new line.

And now if I do make\nmario again, ./mario, OK.

But a little better\ndesigned in that now I'm

not repeating myself multiple times,\n

But let's do one other\nthing here with mario.

Let me go ahead and ask the user how\n

The catch here is that there's another\n

and it's called a do\nwhile loop, generally.

A do while loop is\nsimilar to a while loop

but it checks the condition\nlast instead of first.

Recall earlier on the\nslide, we had while

open parenthesis, closed parenthesis.

And I kept claiming that we check\n

it was, 3 in advance again and again.

A do while loop just inverts the\nlogic so that you can actually

At the top of this program,\nI'm going to go ahead now

and give myself a variable\nn like this of type integer.

And then I'm going to do, literally,\n

n equals get_int-- and I'm going\nto ask the user for the width

like the number of\ndollar signs to print.

And I'm going to do this\nwhile n is less than, say, 1.

So this is a little cryptic,\nbut the salient differences

are the Boolean expression is now\n

Well, the difference\nhere if I make mario is--

I need to add cs50.h, because\nI'm now using get_int.

If I now compile this version\nof Mario and do ./mario

a do while loop is helpful when you want\n

and then check some condition or some\n

in this case, the user cooperated.

It would make no sense if\nthe user typed in, say, 0

because there's no work to be done.

It'd be really weird if\nthey said negative 100

because that makes no sense logically.

So with this simple construct\nhere, I am doing the following

The implication is that as soon\n

I'm going to break out of\nthis loop, and I've got myself

a variable called n containing,\nessentially, a positive value, 1

And I can now use this, for\ninstance, here, change the 4 to an n

so now my program is completely dynamic.

Let me go ahead and do\nmake mario, ./mario again.

And the difference here with the\n

involves getting user input,\nwell, there's no question to ask.

The user hasn't given you anything yet.

So you have to do something first,\n

if the human has, for instance,\ncooperated, in this case.

All right, well why don't\nwe escalate to something

more like this in the same game,\n

and this is like a two-dimensional\nwall that's popping up here?

It looks like a 3 by 3, for\n

And it's like, made of bricks, so\n

Well, it turns out that we can nest--

that is, combine-- some of\nthese same ideas as follows.

Let me go ahead now and\nchange back to this code.

And I'm going to keep the\ndo while loop from before.

And I'm going to ask,\nthough, this question

what's the size of this square?

I'm going to assume it's n by\nn, so 3 by 3, 4 by 4, whatever.

So I'm just going to ask for the\nsize of this square of bricks.

Well, I'm going to go ahead,\nfor instance, and print out--

how about for int i =\n0, i less than n, i++.

Let me just keep it simple\nand print out something

like this, just a single\nhash symbol that is a brick

All right, let's make mario.

OK, that's close to being it.

All right, but I need it to be wider.

So the solution last time\nwas to get rid of the newline

and then maybe put the\nnewline here, after the loop.

All right, so let's do make mario,\n

All right, so I kind of need to\ncombine these two ideas somehow.

So how might we solve this problem?

I want to print rows and\ncolumns, not row or column.

AUDIENCE: Add another\nloop in the for loop.

Add another loop in the for loop, right?

If you use one loop conceptually\n

to bottom, and then\nwithin each row, you then

sort of typewriter style--\nold school typewriter--

do like, character, character,\n

I think we could do exactly\nwhat we want to achieve here.

Let me get rid of this line and\nget rid of this line for now.

And let me just give myself\nanother loop on the inside.

And since I'm already using i,\nanother reasonable convention

here would be to say something like j.

So j also gets 0, j is less than n, j++.

And now, what's going to happen?

Let me go ahead and print out just\n

And let me save and let me run this.

Let me see how close we are.

OK, three, that's clearly wrong, but\n

What's the one fix I need now to\n

down to the next row when appropriate?

Yeah, I need one of these backslash n's.

And let me add some comments now to\n

For each row, for each column,\nhow about print a brick--

just to kind of explain the logic?

And so I add that because\nnow move to next row

I could do something like\nthis with a backslash n.

So here is where the comments,\nreally, my pseudocode

actually kind of illuminates\nthe situation a bit.

Let me go ahead and recompile\n

It's not a perfect square,\njust because these hash symbols

are a little taller than they are wide,\n

Now I've done something that's quite\n

All right, so let me pause here\n

Again, the code's getting\na little more complicated

but we're just building more\n

with familiar puzzle\npieces-- some variables

some loops, some conditionals.

It's all the same as before.

Can you multiply strings in C?

But ask that same question again in\n

and the answer will be yes.

In C, you must specify\nthe return type, the name

of the function, and the\ninputs, or arguments

to the function in that order.

And if none of them are applicable,\nyou write the word void.

So same question as earlier, let\nme kick that can a week or so

and we'll come back to\nthat and we'll see why.

But for now, just take on faith\n

Because main is a little\nspecial, similar to the

It too was a little special as well.

If you want to get out of a\nloop early, you could do this.

So let me answer this question this way.

An alternative to a do while loop\n

so do the following forever--

let me go ahead and get an inch from\n

that is, a positive integer--

then go ahead and use a\nnew keyword called break.

This is identical to what we just did.

It's like a couple extra\nlines, a lot of them are blank.

And so it's just an alternative.

But a do while does the same\nthing but a little tighter--

if that's in answer to your question.

All right, so let's now introduce,\n

that I've kind of been\nbrushing under the rug

though we did see a little bit\nof evidence of this earlier

when we tried to add 2\nbillion and 2 billion

and it overflowed the number\nof bits in an int, so to speak.

Let me go ahead and code up a\nprogram called calculator again.

But I'm going to go ahead now\nand change this to floats.

So I'm going to change x to a float,\n

And a float, again, is just\na floating point value

which is a fancy way of saying a real\n

And down here, I'm going to\ngo ahead and use %f for float.

And I'm going to go ahead\nnow and do one more thing.

Instead of addition, I want to do\n

And I'm going to give myself\nanother third float called z

as we did at the beginning of today.

And I'm going to print out z\ninstead of x and y explicitly.

So I'm going to go ahead now and\n

And let's do something like, oh, 2/3.

So that's what you would rather expect.

All right, so 0.1, and a bunch of zeros.

That too is what you\nwould rather expect.

But now let me get a little curious.

It turns out that in C, you can\n

By default, you get 6 or so digits.

Suppose that you want\nto get exactly 2 digits.

You can more succinctly say 0.2\n

This is the kind of thing that's\n

and you find that, OK,\nformat code for floats

uses 0.2 to do two decimal points.

So let me do make calculator\nagain, ./calculator.

So it handles the display of\nsignificant digits for us here.

And now let me go ahead\nand do 1/10 and 0.10.

Well, maybe I really want\na lot of precision, right?

I've got a really powerful computer.

Let me see 50 numbers\nafter the decimal point.

That's a lot of significant digits.

Let me remake the\ncalculator-- whoops, typo.

Let me remake the calculator,\n./mario calculator.

Pretty sure it's supposed to be\n

All right, well, maybe\nthat's just a bug.

OK, that's really getting funky.

It seems that my program cannot\nonly not do addition very well--

we eventually hit\nproblems in the billions--

we can't even do very\nprecise numbers here.

In a nutshell, the computer's\napproximating the answer

using that many numbers\nafter the decimal point.

But the problem\nfundamentally is actually

very similar to that integer\noverflow from before.

And I'm using that now as a term of art.

Integers can overflow if you're trying\n

You sort of change them all to ones, and\n

Same thing here, but in the\ndifferent context of floats--

if you only have 32\nbits-- or, heck, if we

change to double and only have 64\n

And, yet, pretty sure there's an\n

In the world, which is to say a computer\n

represent all possible\nnumbers in the world.

Because, again, there's\nnot an infinite number

of permutations of 32 or 64 bits.

It might be a lot, in the billions\n

And so, indeed, this is the\ncomputer's closest approximation

to what's actually going on there.

And so this is an example of what\n

Floating-point imprecision refers to the\n

to represent all possible\nreal numbers 100%

precisely, at least by default\nin languages like C. Thankfully

in the world of scientific\ncomputing and so forth

there are solutions to this problem\n

But the problem fundamentally\nis still going to be there.

So there's a reason I\nchanged x and y to floats.

Let's see what would\nhappen if we rewound a bit.

And instead of using floats for x and y,\n

And let's go far back\nand use get_int as well

thereby giving us integers x and y.

Let's still leave z as a float,\nbecause at the end of the day

we want to be able to handle\nfractions or floating-point values.

But let's go ahead now and\nprint out this value of z

having changed x and y now to ints.

make calculator, ./calculator, and\n

And it's not 0.666, and it's\nnot even rounding oddly.

It's just all zeros this time.

Well, it turns out that C, when\n

is always going to give you\nback an integer, an int.

The problem is that floating-point\nvalues don't fit in ints.

Only the integral part to the\nleft of the decimal point does.

Everything at and beyond the decimal\n

known as a feature in\nC called truncation.

When dividing an integer by an\ninteger, you get back an integer.

But if you're trying to then store\n

result in that integer, C is just\ngoing to throw away everything

at and beyond the decimal point,\nleaving us with this case

in just the 0 from what should\nhave been 0.666666 and so forth.

So let's see one more example, in fact.

Let me go back to my terminal here.

Let me do ./calculator again.

This time, It should be\n1.33333 and so forth.

But let's see, 4 divided by 3, both as\n

but there too the\nanswer should be 1.333.

But the floating-point part is\ngetting truncated or thrown away

Well, certainly, we could just use\n

But if, by nature of your program,\n

or maybe even longs, for which\nthe same problem would occur--

what we can actually do\nis called type conversion.

And we can explicitly tell\nthe computer that we actually

want to treat this int as though\nit's a floating-point value.

And we can do that for both x and y.

So let me go back to my code here, and\n

I can convert y to a float by\n

by literally writing the type\nfloat inside of parentheses

And if I really want to be explicit,\n

But, strictly speaking, it suffices\n

Let me go ahead now and do make\ncalculator again, ./calculator

and let's try 2 divided by 3.

And now, we're back to an\nanswer that's closer to correct.

But, indeed, we're still having\nsome rounding issues there.

Let's run it one more\ntime for 4 divided by 3.

There too we're closer to\nthe right answer, at least.

But we still have that\nfloating-point imprecision

but that's going to be another\nproblem altogether to solve.

And here in a little\nmore detail is that issue

of integer overflow, which\nis in the context of ints.

Suppose that we think back to\nlast week when we had three bits

and we counted from 0 to\n7, 0, 1, 2, 3, 4, 5, 6, 7.

I think I asked the question,\nhow would we count to 8?

Someone proposed, well,\nwe need a fourth bit.

That's fine if you have a\nfourth bit, if you have access

to another light bulb or transistor.

If you don't, though, the next number\n

But if you don't have space for\nor hardware for that fourth bit

you might as well just be\nrepresenting the number 0.

So in the world of integers, if\nyou're only using three bits

those three bits eventually\noverflow when you count past 7.

Because what should be 8 can't fit, so\n

And as arcane as this\nproblem might seem

we humans have done\nthis a couple of times.

You might recall\nknowing about or reading

about the Y2K problem,\nwhere a lot of people

thought the world was going to end.

Because on January 1st of\n2000, a lot of computers

presumably, were going to update their\n

The problem is, though, for\ndecades, for efficiency, we humans

were honestly in the habit of\nnot storing years as four digits.

Because that's just a lot of space\n

So a lot of computer systems,\nespecially early on when

hardware was very expensive\nand memory was very tight

just stored the last\ntwo digits of any year.

The problem, of course, on January 1st\n

But if you don't have room for\nanother digit it's just 00.

And if your code assumes a prefix of\n

1999 back to the year 1900.

Thankfully, long story short, a\n

in a lot of old languages and\nmostly warded off this problem

The next time the world might end\n

Now, that might feel\nlike a long time away

but so did the year 2000, at one point.

Why might clocks again break in\n

So this refers to some\nnumber of seconds.

So it turns out that the way\n

is they count the total number\nof seconds since the epoch, which

is defined as January 1, 1970.

It was just a good year\nto start counting at

when computers really\ncame onto the scene.

Unfortunately, most computers used 32\n

since January 1, 1970, the\nimplication of which is we

can only count up to\nroughly 2 billion seconds.

2 billion seconds is going to\nhappen in 2038, at which 30 11's

are going to roll over as follows.

That number 2 billion,\nwhich is the max--

because if you're representing\npositive and negative numbers

recall that you can only count\nas high as positive 2 billion

This is roughly the number\n2 billion in binary.

It's all ones with one\nzero way over here.

If I count one second past that\n2 billion number, give or take--

that means, all right,\nI add 1, I carry the 1--

it's just like 9's\nbecoming 0's in decimal.

If I keep this sort of simple\n

carrying the 1, carrying the 1, 1 second\n

I have this number in\nthe computer's memory.

So there's still 1 bit that's\na 1 all the way to the left.

Unfortunately, that bit\noften represents negativity

whereby if that first bit is negative,\n

somehow represents a negative number.

There's a fancier representation.

But a very big, positive\nnumber very suddenly

becomes a very big, negative number.

And that number is roughly\nnegative 2 billion.

That means computers\nin 2038 on that date

are going to accidentally\nthink that it's

been negative 2 billion seconds since\n

computers potentially think it's 1901.

So what is the solution to\nthe 2038 problem, perhaps?

Y2K was because we were\nusing two digits for years.

And, thankfully, we're getting a\n

and computers now are\nincreasingly using 64 bits.

And all of us will be long\ngone by the time we run out

of that number of seconds, so\nit's someone else's problem

But that's really the\nfundamental solution.

If you're running up against\nsomething finite, well

just kick the can further and\njust give yourself more bits.

And, frankly, because hardware\nis so much cheaper these days

computers are so much faster,\nit's not as big of a deal

as it might have been decades ago.

But that's indeed the solution.

But this arises in very common contexts.

In fact, let me go ahead and write a\n

You might think that just converting\n

might be simple, but let\nme go ahead and do this.

In pennies.c, I'm going to\ngo ahead and include cs50.h.

And I'm going to include stdio.h,\n

And now down here, I'm going to do this.

I'm going to get a float\ncalled amount, and I'm

going to ask the user for some amount\n

and I'm going to store that\nin a variable called amount.

Then I'm going to simply convert that\n

And then I'm going to go ahead and print\n

because that's just an\ninteger in pennies--

backslash n, quote\nunquote, comma, pennies.

All right, so if I didn't make any\n

And suppose I have, say, $0.99, so 0.99.

There's that imprecision issue.

And this isn't even\nthat big of an amount.

Now, not a big deal if the cashier gives\n

but you can imagine this adding up.

You can imagine this being worrisome\nfor financial implications

for financial transactions, for\n

My program can't even handle this.

Well, there are some solutions here.

And it looks like what's\nreally happening--

if I print it out using the %f with a\n

presumably, the computer is struggling\n

It's probably storing 4 dollars\nand 19.9999-something cents.

So it's close, but it's not quite there.

So I could at least solve this\nby rounding up, for instance.

And it turns out there is\na round function out there.

And it turns out that it's in a\nlibrary called the math library.

And you would know this by looking\n

And if I now make pennies again and\n

So at least in this context, it\nseems like a solvable problem.

But it's certainly something I\n

Unfortunately, even professional,\n

have not been particularly\nattentive to these kinds of details.

And in a class like this, the goal\n

but to really teach you what's going\n

so that you have a bottom-up\nunderstanding of how data

is represented, how computers\nare manipulating it

so that you are not on the failing\n

And so that we as a society are not\n

And this happens,\nunfortunately, all of the time.

This is a Boeing airplane\nthat a few years ago needed

to be rebooted after every 248 days.

Because this Boeing airplane software\n

tenths of a second to keep\ntrack of something or other

related to its electrical power.

And, unfortunately, after 248 days of\n

which in the airline\nindustry is apparently not

uncommon to make every dollar count,\n

the 32-bit number would\nroll over and the power

would shut off on the airplane\nas a side effect because of sort

of undefined behavior in that case.

The temporary solution by Boeing at\n

sort of operating system style,\n

And that was indeed the fix until they\n

And the more hardware we carry\n

use these kinds of devices,\nthe more of these problems

we're going to run into down the road.

DAVID MALAN: This is\nCS50 and this is week 2.

Now that you have some programming\nexperience under your belts

in this more arcane language called c.

Among our goals today is to help\n

been doing these past several days.

Wrestling with your first programs in\n

up understanding of what\nsome of these commands do.

And, ultimately, what more\nwe can do with this language.

So this recall was the very\nfirst program you wrote

I wrote in this language\ncalled C, much more textual

certainly, than the Scratch equivalent.

But at the end of the day,\ncomputers, your Mac, your PC

VS Code doesn't understand\nthis actual code.

What's the format into which we need\n

DAVID MALAN: So binary,\notherwise known as machine code.

The 0s and 1s that your computer\nactually does understand.

So somehow we need to\nget to this format.

And up until now, we've been\nusing this command called make

which is aptly named, because\nit lets you make programs.

And the invocation of that\nhas been pretty simple.

Make hello looks in your current\n

hello.c, implicitly, and then it\n

which itself is executable,\nwhich just means runnable

so that you can then do ./hello.

But it turns out that make is\nactually not a compiler itself.

It does help you make programs.

But make is this utility that comes on\n

to actually compile code by\nusing an actual compiler

the program that converts source code\n

or whatever cloud environment\nyou might be using.

In fact, what make is\ndoing for us, is actually

running a command automatically\nknown as clang, for C language.

And, so here, for instance, in VS\n

this time in the context\nof a text editor

and I could compile\nthis with make hello.

Let me go ahead and use the\ncompiler itself manually.

And we'll see in a moment why we've\n

I'm going to run clang instead.

And then I'm going to run hello.c.

So it's a little different\nhow the compiler's used.

It needs to know, explicitly,\nwhat the file is called.

I'll go ahead and run\nclang, hello.c, Enter.

Nothing seems to happen, which,\n

Because no errors have popped up.

And if I do ls for list, you'll see\n

But there is a curiously-named\nfile called a.out.

This is a historical convention,\nstands for assembler output.

And this is, just, the default\nfile name for a program

that you might compile yourself,\nmanually, using clang itself.

Let me go ahead now and\npoint out that that's

kind of a stupid name for a program.

Even though it works,\n./a.out would work.

But if you actually want to\ncustomize the name of your program

we could just resort to make,\nor we could do explicitly

It turns out, some\nprograms, among them make

support what are called\ncommand line arguments

and more on those later today.

But these are literally words or\n

after the name of a program that just\n

And it turns out, if you read\nthe documentation for clang

you can actually pass a -o, for\n

lets you specify,\nexplicitly what do you want

your outputted program to be called?

And then you go ahead and type the\n

want to compile, from\nsource code to machine code.

Again, nothing seems to happen,\nand I type ls and voila.

Now we still have the old a.out,\nbecause I didn't delete it yet.

So ./hello, voila, runs\nhello, world again.

And let me go ahead\nand remove this file.

I could, of course, resort to using\n

Which, I am in the habit of closing,\n

But I could go ahead and right-click\nor control-click on a.out

if I want to get rid of it.

Or again, let me focus on\nthe command line interface.

We didn't really use it much,\nbut what command removes a file?

DAVID MALAN: So rm for\nremove. rm, a.out, Enter.

Remove regular file,\na.out, y for yes, enter.

And now, if I do ls\nagain, voila, it's gone.

All right, so, let's\nnow enhance this program

to do the second version we ever did,\n

so that we have access to functions\n

Let me do string, name, gets,\nget string, what's your name

And now, let me go ahead and say hello\n

So this was version 2 of\nour program last time

that very easily compiled with make\n

If I want to compile this\nthing myself with clang, using

that same lesson learned,\nall right, let's do it.

clang-o, hello, just so I get a better\n

And a new error pops up that some of\n

So it's a bit arcane here, and there's\n

with temp for temporary there.

But somehow, my issue's in\nmain, as we can see here.

It somehow relates to hello.c.

Even though we might not have seen\n

but there's an undefined\nreference to get string.

As though get string doesn't exist.

Now, your first instinct might be, well\n

That's the very first\nline of my program.

But it turns out, make is doing\n

Just putting cs50.h, or any header\nfile at the top of your code

for that matter, just teaches the\n

It, sort of, asks the compiler\nto-- it asks the compiler

to trust that I will, eventually,\n

like get string, and cs50.h,\nand stdio.h, printf, therein.

But this error here, some kind of\n

that there's a separate\nprocess for actually

finding the 0s and 1s that\ncs50 compiled long ago for you.

That authors of this operating\n

We need to, somehow,\ntell the compiler that we

need to link in code\nthat someone else wrote

the actual machine code that someone\n

So to do that, you'd have to\ntype -lcs50, for instance

So additionally, telling clang\n

a file called hello, and you want\n

you also want to quote-unquote\nlink in a bunch of 0s and 1s

that collectively implement\nget string and printf.

So now, if I hit enter,\nthis time it compiled OK.

And now if I run ./hello, it works\n

But honestly, this is just going to\n

Notice, already, just\nto compile my code

I have to run clang-o,\nhello, hello.c, lcs50

and you're going to have\nto type more things, too.

If you wanted to use the math library,\n

you would also have\nto do -lm, typically

to specify give me the math\nbits that someone else compiled.

And the commands just\nget longer and longer.

So moving forward, we won't have\n

but clang is, indeed, the compiler.

That is the program that converts\n

But we'll continue to use make because\n

And the commands are\nonly going to get more

cryptic the more sophisticated and\n

And make, again, is just a tool\nthat makes all that happen.

Let me pause there to see if\n

take a look further under the hood.

AUDIENCE: Can you explain again what\n

DAVID MALAN: Sure, let me\ncome back to that in a moment.

We'll come back to that,\nvisually, in just a moment.

But it means to link in the\n0s and 1s that collectively

implement get string and printf.

But we'll see that, visually, in a sec.

DAVID MALAN: Really good question.

How come I didn't have\nto link in standard I/O?

Because I used printf in version 1.

Standard I/O is just, literally,\nso standard that it's built in

It did not come with the\nlanguage C or the compiler.

And other libraries, even though\n

they might not be enabled by default,\n

So you're not loading more 0s\nand 1s into the computer's memory

So standard I/O is special, if you will.

DAVID MALAN: Oh, what does the -o mean?

So -o is shorthand for\nthe English word output

and so -o is telling clang to\nplease output a file called hello

because the next thing I\nwrote after the command line

recall was clang -o hello, then\n

And this is where these commands\ndo get and stay fairly arcane.

It's just through muscle\nmemory and practice

that you'll start to remember, oh\n

what are the command line arguments\nyou can provide to programs?

But we've seen this before.

Technically, when you run make\n

hello is the command line argument.

It's an input to the\nmake function, albeit

typed at the prompt, that tells\nmake what you want to make.

Even when I used rm a moment\nago, and did rm of a.out

the command line argument\nthere was called a.out

and it's telling rm what to delete.

It is entirely dependent on the programs\n

whether you use dash this\nor dash that, but we'll

see over time, which ones\nactually matter in practice.

So to come back to the first question\n

let's consider the code more closely.

So here is that first\nversion of the code

again, with stdio.h and only\nprintf, so no cs50 stuff yet.

Until we add it back in\nand had the second version

where we actually get the human's name.

When you run this command,\nthere's a few things

that are happening\nunderneath the hood, and we

won't dwell on these\nkinds of details, indeed

we'll abstract it away by using make.

But it's worth understanding\nfrom the get-go

how much automation is going on, so\n

You have this bottom-up\nunderstanding of what's going on.

So when we say you've been\ncompiling your code with make

that's a bit of an oversimplification.

Technically, every time\nyou compile your code

you're having the computer do\nfour distinct things for you.

And this is not four distinct things\n

every time you run your\nprogram, what's happening

but it helps to break it\ndown into building blocks

as to how we're getting from source\n

It turns out, that when you compile,\n

speaking, you're doing four things\n

Preprocessing it, compiling it,\nassembling it, and linking it.

Just humans decided, let's just\n

But for a moment, let's\nconsider what these steps are.

So preprocessing refers to this.

If we look at our source code,\n

and therefore get string, notice that\n

And they're kind of special\nversus all the other code

we've written, because they start\n

And that's sort of a\nspecial syntax that means

that these are, technically,\ncalled preprocessor directives.

Fancy way of saying they're handled\n

In fact, if we focus on\ncs50.h, recall from last week

that I provided a hint as to what's\n

What was the one salient thing that\n

why we were including\nit in the first place?

DAVID MALAN: So get\nstring, specifically

the prototype for get string.

We haven't made many of\nour own functions yet

but recall that any time\nwe've made our own functions

and we've written them\nbelow main in a file

we've also had to, somewhat\nstupidly, copy paste

the prototype of the function\nat the top of the file

just to teach the compiler that\n

it does down there, but it will exist.

So again, that's what these\nprototypes are doing for us.

So therefore, in my\ncode, If I want to use

a function like get string,\nor printf, for that matter

they're not implemented\nclearly in the same file

they're implemented elsewhere.

So I need to tell the compiler\nto trust me that they're

implemented somewhere else.

And so technically,\ninside of cs50.h, which

is installed somewhere in the\ncloud's hard drive, so to speak

that you all are accessing via VS Code,\n

A prototype for the get string function\n

get string, it takes one input,\nor argument, called prompt

and that type of that\nprompt is a string.

Get string, not surprisingly, has a\n

So literally, that line and a\nbunch of others, are in cs50.h.

So rather than you all having\nto copy paste the prototype

you can just trust that\ncs50 figured out what it is.

You can include cs50.h\nand the compiler is going

to go find that prototype for you.

Same thing in standard\nI/O. Someone else-- what

must clearly be in stdio.h,\namong other stuff, that

motivates our including stdio.h, too?

DAVID MALAN: Printf, the\nprototype for printf

and I'll just change it here\nin yellow, to be the same.

And it turns out, the format--

the prototype for printf\nis, actually, pretty fancy

because, as you might have noticed,\n

something to print, 2, if you want\n

So the dot dot dot just\nrepresents exactly that.

It's not quite as simple a prototype\n

So what does it mean to\npreprocess your code?

The very first thing the\ncompiler, clang, in this case

is doing for you when it reads your\n

notices, oh, here is hash include,\n

And it, essentially, finds those files\n

and does the equivalent of copying\n

into your code at the very top.

Thereby teaching the compiler\nthat gets string and printf

will eventually exist somewhere.

So that's the preprocessing\nstep, whereby, again, it's

just doing a find-and-replace of\n

It's plugging in the files\nthere so that you, essentially

get all the prototypes\nyou need automatically.

What does it mean, then,\nto compile the results?

Because at this point\nin the story, your code

now looks like this in\nthe computer's memory.

It doesn't change your\nfile, it's doing all

of this in the computer's\nmemory, or RAM, for you.

But it, essentially, looks like this.

Well the next step is what's,\ntechnically, really compiling.

Even though again, we use\ncompile as an umbrella term.

Compiling code in C\nmeans to take code that

now looks like this in\nthe computer's memory

and turn it into something\nthat looks like this.

But it was just a few\ndecades ago that, if you

were taking a class like\nCS50 in its earlier form

we wouldn't be using C it didn't exist\n

something called assembly language.

And there's different types of,\n

But this is about as low level as\n

understands, be it a\nMac, or PC, or a phone

before you start getting\ninto actual 0s and 1s.

And most of this is cryptic.

I couldn't tell you what this is doing\n

and rewound mentally, years\nago, from having studied it

but let's highlight a\nfew key words in yellow.

Notice that this assembly language\n

for you automatically,\nstill has mention of main

and it has mention of get string,\nand it has mention of printf.

So there's some relationship to\nthe C code we saw a moment ago.

And then if I highlight\nthese other things

these are what are called\ncomputer instructions.

At the end of the day,\nyour Mac, your PC

your phone actually only\nunderstands very basic instructions

like addition, subtraction, division,\n

load from memory, print something to\n

And that's what you're seeing here.

These assembly instructions\nare what the computer actually

feeds into the brains of the computer,\n

And it's that Intel CPU,\nor whatever you have

that understands this instruction, and\n

And collectively, long\nstory short, all they do

is print hello, world on\nthe screen, but in a way

that the machine understands how to do.

Are there any questions on\nwhat we mean by preprocessing?

Which finds and replaces the hash\n

and compiling, which technically\ntakes your source code

once preprocessed, and converts it to\n

AUDIENCE: [INAUDIBLE] each CPU has--

Each type of CPU has\nits own instruction set.

And as a teaser, this is why,\nat least back in the day, when

we used to install software from\n

this is why you can't take a program\n

and run it on a Mac, or vice-versa.

Because the commands, the instructions\n

Now Microsoft, or any company, could\n

like C or another, and they can\n

It's twice as much work and sometimes\n

but that's why these steps\nare somewhat distinct.

You can now use the same code and\n

Thankfully, this part is fairly\n

To assemble code, which is step\nthree of four, that is just

happening for you every time\nyou run make or, in turn, clang

this assembly language, which the\n

for you from your source code,\nis turned into 0s and 1s.

So that's the step that, last\nweek, I simplified and said

when you compile your code, you convert\n

Technically, that happens\nwhen you assemble your code.

But no one in normal\nconversations says that, they just

say compile for all of these terms.

Even in this simple program\nof getting the user's name

and then plugging it into printf, I'm\n

My own, which is in hello.c.

Some of CS50s, which is\nin hello.c, sorry-- which

is in cs50.c, which is not\na file I've mentioned, yet

but it stands to reason, that if\n

turns out, the actual\nimplementation of get string

and other things are in cs50.c.

And there's a third file\nsomewhere on the hard drive

that's involved in compiling\neven this simple program.

hello.c, cs50.c, and by that\nlogic, what might the other be?

And that's a bit of a white lie,\n

that there's actually multiple files\n

and we'll take the simplification.

So when I have this code,\nand I compile my code

I get those 0s and 1s that end up taking\n

into 0s and 1s that are combined with\n

Here might be the 0s and 1s for my code,\n

Here might be the 0s and 1s for what\n

Here might be the 0s and 1s that someone\n

The last and final step\nis that linking command

that links all of these\n0s and 1s together

essentially stitches them together\n

or called a.out, whatever you name it.

That last step is what combines all of\n

And my God, now we're\nreally in the weeds.

Who wants to even think about\nrunning code at this level?

When you're running make,\nthere's some very concrete steps

that are happening that humans\nhave developed over the years

over the decades, that breakdown\n

to 0s and 1s, or machine code,\ninto these very specific steps.

But henceforth, you can\ncall all of this compiling.

AUDIENCE: Can you explain\nagain what a.out signifies?

a.out is just the conventional,\n

that you compile directly\nwith a compiler, like clang.

It's a meaningless name, though.

It stands for assembler output, and\n

from this assembling process.

It's a lame name for a\ncomputer program, and we

can override it by outputting\nsomething like hello, instead.

DAVID MALAN: To recap, there are\n

cs50.h, stdio.h, technically, they're\n

even though you, strictly\nspeaking, don't need most of them

but they are there, just in\ncase you might want them.

And finally, any other questions?

DAVID MALAN: Does it matter what order\n

Sometimes with libraries,\nyes, it matters

what order they are linked in together.

But for our purposes, it's\nreally not going to matter.

It's going to-- make is going to take\n

So with that said, henceforth,\ncompiling, technically

But we'll focus on it as a higher\nlevel concept, an abstraction

So another process that we'll\nnow begin to focus on all the

more this week because, invariably,\n

ran up against some challenges.

You probably created your very first\n

and so let's focus for a moment on\n

As you spend more time\nthis semester, in the years

to come If you continue to program,\n

going to write bug\nfree code, ultimately.

Though your programs are going to get\n

and we're all going to start to\n

And to this day, I write\nbuggy code all the time.

And I'm always horrified\nwhen I do it up here.

But hopefully, that\nwon't happen too often.

But when it does, it's a process,\nnow, of debugging, trying

to find the mistakes in your program.

You don't have to stare at your code,\n

There are actual tools\nthat real world programmers

use to help debug their\ncode and find these faults.

So what are some of the techniques\nand tools that folks use?

Well as an aside, if you've ever--

a bug in a program is a mistake,\n

If you've ever heard this tale,\nsome 50 plus years ago, in 1947.

This is an entry in a log book written\n

as-- named Grace Hopper,\nwho happened to be the one

to record the very first discovery of a\n

This was like a moth\nthat had flown into

at the time, a very sophisticated system\n

very large, refrigerator-sized\ntype systems

in which an actual bug caused an issue.

The etymology of bug though,\npredates this particular instance

but here you have, as any computer\n

of a first physical bug in a computer.

How, though, do you go\nabout removing such a thing?

Well, let's consider a very\nsimple scenario from last time

for instance, when we were trying to\n

like this column of 3 bricks.

Let's consider how I might go about\n

Let me switch back over to VS\nCode here, and I'm going to run--

And I'm not going to\ntrust myself, so I'm

going to call it\nbuggy.c from the get-go

knowing that I'm going\nto mess something up.

But I'm going to go ahead\nand include stdio.h.

And I'm going to define main, as usual.

So hopefully, no mistakes just yet.

And now, I want to print those\n3 bricks on the screen using

So how about 4 int i get 0, i less\n

Now, inside of my\ncurly braces, I'm going

to go ahead and print out a hash\n

All right, saving the file, doing\n

So there's no syntactical errors,\n

But some of you have probably\nseen the logical error already

because when I run this\nprogram I don't get

this picture, which was 3 bricks\n

Now, this might be jumping out\nat you, why it's happening

but I've kept the program\nsimple just so that we

don't have to find an actual bug, we can\n

What might be the first strategy\nfor finding a bug like this

rather than staring at your code,\n

Well, let's actually try to diagnose\n

And the simplest way to do\nthis now, and years from now

is, honestly, going to be to\nuse a function like printf.

Printf is a wonderfully\nuseful function, not

for formatting-- printing\nformatted strings and all that, for

just looking inside\nthe values of variables

that you might be curious\nabout to see what's going on.

I see that there's 4 coming\nout, but I intended 3.

So clearly, something's\nwrong with my i variables.

So let me be a little more pedantic.

Let me go inside of this\nloop and, temporarily

say something explicit, like, i is--

&i /n, and then just\nplug in the value of i.

This is not the program I want to\n

writing, because now I'm going\nto say make buggy, ./buggy.

And if I look, now,\nat the output, I have

some helpful diagnostic information.\n

and I get a hash, 2 and I\nget a hash, 3 and I get hash.

I'm clearly going too many\nsteps because, maybe, I

forgot that computers are,\nessentially, counting from 0

and now, oh, it's less than or equal to.

Again, trivial example,\nbut just by using printf

you can see inside of\nthe computer's memory

by just printing stuff out like this.

And now, once you've figured it out, oh,\n

or I should start\ncounting from 1, there's

any number of ways I could fix this.

But the most conventional is\nprobably just to say less than 3.

Now, I can delete my temporary print\n

All right, and to this day, I do this.

Whether it's making a command line\n

or mobile application,\nIt's very common to use

printf, or some equivalent\nin any language

just to poke around and see what's\ninside the computer's memory.

Thankfully, there's more\nsophisticated tools than this.

Let me go ahead and\nreintroduce the bug here.

And let me reopen my\nsidebar at left here.

Let me now recompile the code\nto make sure it's current.

And I'm going to run a\ncommand called debug50.

Which is a command that's\nrepresentative of a type of program

And this debugger is\nactually built into VS Code.

And all debug50 is doing for us is\n

VS Code's built-in debugger.

So this isn't even a\nCS50-specific tool, we've

just given you a debug50\ncommand to make it easier

to start it up from the get-go.

And the way you run this debugger\n

the name of the program\nthat you want to debug.

So you don't mention your c-file.

You mention your already-compiled code.

And what this debugger is going\n

walk through my code step-by-step.

Because every program we've written\n

even if I'm not done thinking\nthrough each step at a time.

With a debugger, I can\nactually click on a line number

and say pause execution\nhere, and the debugger

will let me walk through my code one\n

one minute at a time,\nat my own human pace.

Which is super compelling when\nthe programs get more complicated

and they might, otherwise,\nfly by on the screen.

So I'm going to click\nto the left of line 5.

And notice that these\nlittle red dots appear.

And if I click on one it\nstays, and gets even redder.

And I'm going to run debug50 on ./buggy.

And in just a moment, you'll see that a\n

It's doing some\nconfiguration of the screen.

Let me zoom out a little bit here so\n

And sometimes, you'll see in VS\n

which looks very cryptic, just go back\n

Because at the terminal window is where\n

And let's now take a\nlook at what's going on.

If I zoom in on my\nbuggy.c code here, you'll

notice that we have the same program\n

Not a coincidence, that's the line\n

The little red dot means break\nhere, pause execution here.

And the yellow line has\nnot yet been executed.

But if I, now, at the top of my\n

There's one for this,\nwhich, if I hover over it

says Step Over, there's another\nthat's going to say Step Into

there's a third that says Step Out.

I'm just going to use the\nfirst of these, Step Over.

And I'm going to do this, and\n

moved from line 5 to line\n7 because now it's ready

but hasn't yet printed out that hash.

But the most powerful thing here,\nnotice, is that top left here.

It's a little cryptic, because\nthere's a bunch of things

going on that will make more\nsense over time, but at the top

there's a section called variables.

Below that, something\ncalled locals, which means

local to my current function, main.

And notice, there's my variable\n

So now, once I click Step Over\nagain, watch what happens.

We go from line 7 back to line 5.

But look in the terminal window,\none of the hashes has printed.

But now, it's printed at my own pace.

I can think through this step-by-step.

Notice that i has not changed, yet.

It's still 0 because the yellow\n

But the moment I click Step Over,\nit's going to execute line 5.

Now, notice at top left, i has become\n

because now, highlighted is line 7.

So if I click Step Over\nagain, we'll see the hash.

If I repeat this process at my\nown human, comfortable pace

I can see my variables changing, I\n

and I can just think about\nshould that have just happened.

I can pause and give\nthought to what's actually

going on without trying to race the\n

I'm going to go ahead and\nstop here because we already

know what this particular problem\nis, and that brings me back

to my default terminal window.

But this debugger, let me\ndisable the breakpoint now

so it doesn't keep\nbreaking, this debugger

will be your friend\nmoving forward in order

to step through your code step-by-step,\n

where something has gone wrong.

Printf is great, but it gets annoying if\n

print this, print this, print this,\n

The debugger lets you do the\nequivalent, but automatically.

Questions on this debugger, which you'll\n

AUDIENCE: You were using\na Step Over feature.

What do the other\nfeatures in the debugger--

DAVID MALAN: Really good question.

We'll see this before long, but those\n

step into and step out of, actually\n

if I had any more than main.

So if main called a\nfunction called something

and something called a function\n

stepping over the entire execution of\n

and walk through its\nlines of code one by one.

So any time you have\na problem set you're

working on that has multiple functions,\n

if you want, or you can set it inside\n

to focus your attention only on that.

And we'll see examples\nof that over time.

And what's the sort of, elephant\nin the room, so to speak

is actually a duck in this case.

Why is there this duck and\nall of these ducks here?

Well, it turns out, a third, genuinely\n

is talking through problems, talking\n

Now, in the absence of having\na family member, or a friend

or a roommate who actually wants to\n

generally, programmers turn to a\n

if something animate is not available.

The idea behind rubber duck\ndebugging, so to speak

is that simply by looking at your code\n

I'm starting a 4 loop and\nI'm initializing i to 0.

OK, then, I'm printing out a hash.

Just by talking through your\ncode, step-by-step, invariably

finds you having the proverbial\n

because you realize, wait a minute\nI just said something stupid

or I just said something wrong.

And this is really just a proxy for any\n

But in the absence of any\nof those people in the room

you're welcome to take,\non your way out today.

One of these little, rubber ducks and\n

you want to talk through one\nof your problems in CS50

or maybe life more generally.

But having it there on\nyour desk is just a way

to help you hear illogic\nin what you think

might, otherwise, be logical code.

So printf, debugging, rubber-duck\n

you'll see over time, to\nget to the source of code

that you will write that has mistakes.

Which is going to happen,\nbut it will empower you

all the more to solve those mistakes.

All right, any questions on debugging,\n

DAVID MALAN: What's the difference\n

At the moment, the only one that's\n

is Step Over, because it means\nstep over each line of code.

If, though, I had other functions\n

maybe lower down in the file, I\n

and walk through them one at a time.

So we'll come back to this\nwith an actual example

but step into will allow\nme to do exactly that.

In fact, this is a perfect segue to\n

Let me go ahead and open\nup another file here.

And, actually, we'll\nuse the same, buggy.

And we're going to write one\nother thing that's buggy, as well.

Let me go up here and\ninclude, as before, cs50.h.

So all of this, I think,\nis correct, so far.

And let's do this, let's\ngive myself an int called i

and let's ask the user\nfor a negative integer.

This is not a function that\nexists, technically, yet.

But I'm going to assume, for the\n

Then, I'm just going to print\nout, with %i and a new line

whatever the human typed in.

So at this point in the story,\nmy program, I think, is correct.

Except for the fact that\nget negative int is not

a function in the CS50\nlibrary or anywhere else.

I'm going to need to invent it myself.

So suppose, in this case, that I declare\n

It's return type, so to speak, should\n

I want to hand the user back\nin integer, and it's going

to take no input to keep it simple.

So I'm just going to say void there.

No inputs, no special\nprompts, nothing like that.

Let me, now, give myself\nsome curly braces.

And let me do something familiar,\nperhaps, from problem set 1.

Let me give myself a variable,\n

Assign n the value of get int, asking\n

And I want to do this while\nn is less than 0, because I

want to get a negative from the user.

And recall, from having\nused this block in the past

I can now return n as the\nvery last step to hand back

whatever the user has typed in, so\n

Now, I've deliberately\nmade a mistake here

and it's a subtle,\nsilly, mathematical one

but let me compile this program after\n

so I don't make that mistake again.

Let me do make buggy, Enter.

I'll give it a negative\ninteger, like negative 50.

So it's, clearly, working backwards,\n

So how could I go about debugging this?

Well, I could do what I've done before?

I could use my printf technique and\n

new line, comma n, just to print\nit out, let me recompile buggy

let me rerun buggy, let\nme type in negative 50.

So that didn't really\nhelp me at this point

because that's the same as before.

So let me do this, debug50, ./buggy.

Oh, but I've made a mistake.

So I didn't set my breakpoint, yet.

So let me do this, and I'll\nset a breakpoint this time.

I could set it here, on line 8.

Let's do it in main, as before.

That fancy user interface\nis going to pop up.

It's going to highlight the line\nthat I set the breakpoint on.

Notice that, on the left\nhand side of the screen

i is defaulting, at the moment to 0,\n

But let me, now, Step Over this\n

and you'll see that I'm being prompted.

So let's type in my negative 50, Enter.

Notice now that I'm\nstuck in that function.

So clearly, the issue seems to be\n

So, OK, let me stop this execution.

My problem doesn't seem to be in\n

Let me set my same breakpoint at line 8.

Let me rerun debug50 one more time.

But this time, instead of just stepping\n

So notice line 8 is, again,\nhighlighted in yellow.

In the past I've been\nclicking Step Over.

When I click Step Into,\nboom, now, the debugger

jumps into that specific function.

Now, I can step through these\nlines of code, again and again.

I can see what the value of\nn is as I'm typing it in.

I can think through my logic, and voila.

Hopefully, once I've solved the issue,\n

So Step Over just goes over\nthe line, but executes it

Step Into lets you go into\nother functions you've written.

So let's go ahead and do this.

We've got a bunch of\npossible approaches that we

can take to solving some\nproblems let's go ahead

and pace ourselves today, though.

Let's take a five-minute break, here.

And when we come back, we'll take\n

Up until now, both, by way of week 1\n

we've just translated from Scratch into\n

like loops and conditionals,\nBoolean expressions, variables.

So sort of, more of the same.

But there are features in C that\n

like data types, the types of variables\n

but that, in fact, does\nexist in other languages.

In fact, a few that\nwe'll see before long.

So to summarize the types we saw last\n

We had ints, and floats, and\nlongs, and doubles, and chars

there's also Booles and also string,\n

But today, let's actually start to\n

and actually what your Mac and PC\n

as an int versus a char, versus\na string, versus something else.

And see if we can't put more tools\n

so we can start quickly writing\n

So it turns out, that on\nmost systems nowadays

though this can vary by\nactual computer, this

is how large each of the\ndata types, typically

is in C. When you store a Boolean value,\n

That's a little excessive,\nbecause, strictly speaking

you only need 1 bit,\nwhich is 1/8 of this size.

But for simplicity,\ncomputers use a whole byte

to represent a Boole, true or false.

A char, we saw last week,\nis only 1 byte, or 8 bits.

And this is why ASCII, which uses 1\n

on, was confined to only 256\nmaximally possible characters.

Notice that an int is\n4 bytes, or 32 bits.

A float is also 4 bytes or 32 bits.

But the things that we call long,\n

A double is 64 bits of precision\nfor floating point values.

And a string, for today, we're\n

We'll come back to that,\nlater today and next week

as to how much space a string\ntakes up, but, suffice it to say

it's going to take up a\nvariable amount of space

depending on whether the\nstring is short or long.

But we'll see exactly what\nthat means, before long.

So here's a photograph of\na typical piece of memory

inside of your Mac, or PC, or phone.

Odds are, it might be a little\nsmaller in some devices.

This is known as RAM,\nor random access memory.

Each of these little black\nchips on this circuit

board, the green thing,\nthese little black chips

are where 0s and 1s are actually stored.

Each of those stores\nsome number of bytes.

Maybe megabytes, maybe\neven gigabytes, nowadays.

So let's focus on one of those chips,\n

Let's consider the fact that, even\n

how this kind of thing is made, if\n

for the sake of discussion,\nit stands to reason that

if this thing is storing 1\nbillion bytes, 1 gigabyte

then we can number them, arbitrarily.

Maybe this will be byte\n0, 1, 2, 3, 4, 5, 6, 7, 8.

Then, maybe, way down here in the bottom\n

We can just number these things,\nas might be our convention.

Let's draw that graphically.

Not with a billion squares,\nbut fewer than those.

And let's zoom in further,\nand consider that.

At this point in the\nstory, let's abstract

away all the hardware,\nand all the little wires

and just think of memory as taking\n

as taking up some number of bytes.

So, for instance, if you were to store\n

was 1 byte, it might be stored\nat this top left-hand location

of this black chip of memory.

If you were to store something like\n

it might use four of those bytes,\n

back-to-back-to-back, in this case.

If you were to store a long or a double,\n

So I'm filling in these\nsquares to represent

how much memory and given variable\n

1, or 4, or 8, in this case, here.

Well, from here, let's abstract\naway from all of the hardware

and really focus on\nmemory as being a grid.

Or, really, like a canvas that\nwe can paint any types of data

At the end of the day, all of this\n

But it's up to you and I to build\nabstractions on top of that.

Things like actual numbers,\ncolors, images, movies, and beyond.

But we'll start\nlower-level, here, first.

Suppose I had a program\nthat needs three integers.

A simple program whose purpose\nin life is to average your three

scores on an exam, or some such thing.

Suppose that your three scores were\n

Let's write a program that does\nthis kind of averaging for us.

Let me go back to VS Code, here.

Let me open up a file called scores.c.

Let me implement this as follows.

Let me include stdio.h at the\ntop, int main(void) as before.

Then, inside of main, let me\ndeclare score 1, which is 72.

Then, a third score, called\nscore 3, which is going to be 33.

Now, I'm going to use printf to print\n

and I can do this in\na few different ways.

But I'm going to print out %f, and\n

plus score 3, divided by 3,\nclose parentheses semicolon.

Some relatively simple arithmetic to\n

if I'm curious what my average grade\n

Let me, now, do make scores.

All right, so I've somehow\nmade an error already.

But this one is, actually, germane\nto a problem we, hopefully

won't encounter too frequently.

So underlined to score 1, plus\n

Format specifies type double, but\n

Because the arithmetic\nseems to check out.

AUDIENCE: So the computer is doing the\n

just gives out a value at the\nend because, well [INAUDIBLE]

And we'll come back to\nthis in more detail

but, indeed, what's happening here\n

obviously, because I\ndefine them right up here.

And I'm dividing by another\nint, 3, but the catch

is, recall that C when it performs math,\n

But integers are not\nfloating point value.

So if you actually want to get a\nprecise, average for your score

without throwing away the remainder,\n

it turns out, we're going to have to--

[LAUGHTER] we're going to have to\n

And there's a few ways to\ndo this but the easiest way

for now, I'm going to go\nahead and do this up here

I'm going to change the\ndivide by 3 to divide by 3.0.

Because it turns out, long story short,\n

participating in an\narithmetic expression

like this is something\nlike a float, the rest

will be treated as promoted to\na floating point value as well.

So let me, now, recompile this\ncode with make scores, Enter.

This time it worked OK, because\nI'm treating a float as a float.

All right, my average is\n59.33333 and so forth.

So the math, presumably, checks out.

Floating point imprecision\nper last week aside.

But let's consider the\ndesign of this program.

What is, kind of, bad about it, or if\n

are we going to regret the\ndesign of this program?

What might not be ideal here?

DAVID MALAN: Yeah, so in this case,\n

So, if I'm hearing you\ncorrectly, this program

is only ever going to tell\nme this specific average.

I'm not even using\nsomething like, get int

or get float to get three different\nscores, so that's not good.

And suppose that we wait\nlater in the semester

I think other problems could arise.

AUDIENCE: Just thinking\nalso somewhat of an issue

that you can't reuse that number.

DAVID MALAN: I can't\nreuse the number because I

haven't stored the average in some\n

a big deal, but certainly, if\nI wanted to reuse it elsewhere

Let's fast-forward again, a\nlittle later in the semester

I don't just have three\ntest scores or exam scores

AUDIENCE: Yeah, if you\never want to have to take

the average of any number of\nscores other than 3, [INAUDIBLE]

DAVID MALAN: Yeah, I've sort\nof, capped this program at 3.

And honestly, this is, kind\nof, bordering on copy paste.

Even though the variables, yes, have\n

Imagine doing this for a\nwhole grade book for a class.

Having to score 4, 5, 6, 11 10, 12,\n

You can imagine just\nhow ugly the code starts

to get if you're just defining variable\n

So it turns out, there are\nbetter ways, in languages like C

if you want to have multiple\nvalues stored in memory that

happened to be of the same data type.

Let's take a look back\nat this memory, here

to see what these things\nmight look like in memory.

Here's that grid of memory.

Each of these recall represents a byte.

To be clear, if I store\nscore 1 in memory first

how many bytes will it take up?

So I might draw a score 1 as\nfilling up this part of the memory.

It's up to the computer as to whether it\n

I'm just keeping the pictures clean\n

If I, then, declare another\nvariable, called score 2

it might end up over there,\nalso taking up 4 bytes.

And then score 3 might end up here.

So that's just representing what's going\n

But technically speaking, to\nbe clear, per week 0, what's

really being stored in the computer's\n

32 total, in this case,\nbecause 32 bits is 4 bytes.

But again, it gets boring\nquickly to think in and look

So we'll, generally, abstract\nthis away as just using

decimal numbers, in this case, instead.

But there might be a better way to\n

but maybe four, maybe,\nfive, maybe 10, maybe, more

by declaring one variable to store\n

or more individual variables.

The way to do this is by way\nof something known as an array.

An array is another type of data that\n

of the same type back-to-back-to-back.

That is, to say, contiguously.

So an array can let you create\n

or even more than\nthat, but describe them

all using the same variable\nname, the same one name.

So for instance, if, for one\n

but I don't want to messily declare\n

This is today's first\nnew piece of syntax

the square brackets\nthat we're now seeing.

This line of code, here, is\nsimilar to int score 1 semicolon

or int score 1 equals 72 semicolon.

This line of code is declaring for\n

And that array is going\nto store three integers.

Because the type of that\narray is an int, here.

The square brackets tell the\ncomputer how many ints you want.

And the name is, of course, scores.

Which, in English, I've\ndeliberately pluralized

so that I can describe this array\n

So if I want to now assign values\n

I can say, scores bracket 0 equals\n

and scores bracket 2 equals 33.

The only thing weird\nthere is, admittedly

the square brackets which are still new.

But we're also, notice,\n0 indexing things.

To zero index means to\nstart counting at 0.

When we've talked about\nthat before, our four loops

have, generally, been zero indexed.

Arrays in C are zero indexed.

And you do not have choice over that.

You can't start counting at 1\nin arrays because you prefer to

you'd be sacrificing\none of the elements.

You have to start in\narrays counting from 0.

So out of context, this\ndoesn't solve a problem

but it, definitely, is\ngoing to once we have more

than, even, three scores here.

In fact, let me change\nthis program a little bit.

And delete these three lines, here.

And replace it with a\nscores variable that's

ready to store three total integers.

And then, initialize them as\nfollows, scores bracket 0 is 72

as before, scores bracket 1 is\ngoing to be 73, scores bracket 2

Notice, I do not need to say\nint before any of these lines

because that's been\ntaken care of, already

for me on line 5, where I already\n

Now, down here, this code needs\n

three variables, score 1, 2, and 3.

I have 1 variable, but\nthat I can index into.

I'm going to, here, then, do scores\n

plus scores bracket 2, which is\n

giving me back those three integers.

But notice, I'm using the same\nvariable name, every time.

And again, I'm using this new square\n

index into the array to get at the first\n

and then, to do it again down here.

Now, this program, still not really\n

I still can only store three\nscores, but we'll come back

to something like that before long.

But for now, we're just introducing\n

whereby, I can now store multiple\nvalues in the same variable.

Well, let's enhance this a bit more.

Instead of hard coding these scores,\n

let's use get int to ask\nthe user for a score.

Let's, then, use get int to\nask the user for another score.

Let's use get int to ask\nthe user for a third score

storing them in those\nrespective locations.

And, now, if I go ahead and save\n

Now these errors should be\ngetting a little familiar.

Let me give folks a moment.

That was not intentional, so still\n

Now, I'm going to go back to the bottom\n

We're back in business, ./scores.

Now, the program is getting\na little more interesting.

So maybe, this year was better and I got\n

So now, it's a little more dynamic.

It's a little more interesting.

But it's still capping the number\n

But now, I've introduced another,\n

There's this expression in programming,\n

[SNIFFS AIR] something\nsmells a little off.

And there's something off here in\n

Does anyone see an opportunity to\n

if my goal, still, is to get three\n

without it smelling [SNIFF] kind of bad?

AUDIENCE: [INAUDIBLE] use a 4 loop?

That way you don't have to copy\nand paste all of those scores.

DAVID MALAN: Yeah, exactly.

Those lines of code\nare almost identical.

And honestly, the only thing\nthat's changing is the number

and it's just incrementing by 1.

We have all of the building\nblocks to do this better.

So let me go ahead and improve this.

So for int i get 0, i\nless than 3, i plus plus.

Then, inside of this 4 loop,\nI can distill all three

of those lines into\nsomething more generic

like scores bracket i equals get\n

once, via get int, for a score.

So this is where arrays\nstart to get pretty powerful.

You don't have to hard\ncode, that is, literally

type in all of these magic\nnumbers like 0, 1, and 2.

You can start to do\nit, programmatically

So now, I've tightened things up.

I'm now, dynamically, getting\nthree different scores

but putting them in three\ndifferent locations.

And so this program, ultimately, is\n

Make scores, ./scores, and 100, 99,\n

But it's a little better designed, too.

If I really want to\nnitpick, there's something

that still smells, a little bit, here.

The fact that I have indeed, this\n

has to be the same as this number here.

Otherwise, who knows\nwhat's going to go wrong.

So what might be a\nsolution, per last week

to cleaning that code up further, too?

AUDIENCE: [INAUDIBLE]\nthe user's discretion

how many input scores [INAUDIBLE].

DAVID MALAN: OK, so we could leave\n

And so we could, actually,\ndo something like this.

Let me take this a few steps ahead.

Let me say something like, int n gets\n

then I could actually change this\n

and, indeed, make the\nwhole program dynamic?

Ask the human how many tests\nhave there been this semester?

Then, you can type in\neach of those scores

because the loop is going\nto iterate that many times.

And then you'll get the average\nof one test, two test, three--

well, lost another-- or however\nmany scores that were actually

specified by the user Yeah, question?

AUDIENCE: How many bits or\nbytes get used in an array?

DAVID MALAN: How many\nbytes are used in an array?

AUDIENCE: [INAUDIBLE] point of\ndoing this is to save [INAUDIBLE]

DAVID MALAN: So the purpose of\nan array is not to save space.

It's to eliminate having\nmultiple variable names

because that gets very messy quickly.

If you have score 1, score 2,\nscore 3, dot, dot, dot, score 99

that's, like, 99 different\nvariables, potentially

that you could collapse into one\nvariable that has 99 locations.

At different indices, or indexes.

As someone would say,\nthe index for an array

is whatever is in the square brackets.

DAVID MALAN: So it's a good question.

So if you-- I'm using\nints for everything--

and honestly, we don't\nreally need ints for scores

because I'm not likely to get a\n

And so you could use\ndifferent data types.

And that list we had on the screen,\nearlier, is not all of them.

There's a data type called short,\nwhich is shorter than an int

you could, technically, use char, in\n

Generally speaking, in\nthe year 2021, these

tend to be over optima--\noverly optimized decisions.

Everyone just uses\nints, even though no one

is going to get a test score that's 2\n

Years ago, memory was expensive.

And every one of your\ninstincts would have been

spot on because memory is so tight.

But, nowadays, we don't\nworry as much about it.

AUDIENCE: I have a question\nabout the error [INAUDIBLE]..

Could it-- when you're doing a\nhash problem on the problem set--

DAVID MALAN: So what is the\ndifference between dividing two ints

and not getting an error, as\nyou might have encountered

in a program like cash,\nversus dividing two ints

and getting an error\nlike I did a moment ago?

The problem with the scenario I created\n

And I was telling printf to use a %f,\n

of dividing integers by another integer.

So it was printf that was yelling at me.

I'm guessing in the scenario you're\n

printf was not involved in\nthat particular line of code.

So that's the difference, there.

So we, now, have this\nability to create an array.

And an array can store multiple values.

What, then, might we do that's more\n

Well, let's take this one step further.

As opposed to just storing 72, 73, 33 or\n

because again, an array gives you one\n

or indices therein,\nbracket 0, bracket 1

bracket 2 on up, if it\nwere even bigger than that.

Let's, now, start to consider something\n

Chars, being 1 byte each,\nso they're even smaller

they take up much less space.

And, indeed, if I wanted\nto say a message like

hi I could use three variables.

If I wanted a program to print,\nhi, H-I exclamation point

I could, of course, store those in\n

And let's, for the sake of discussion,\n

Let me create a new\nprogram, now, in VS Code.

This time, I'm going to call it hi.c.

And I'm not going to bother\nwith the CS50 library.

I just need the standard\nI/O one, for now.

And then, inside of main, I'm going\n

And this is already, hopefully,\nstriking you as a bad idea.

But we'll go down this\nroad, temporarily

with c1, and c2, and, finally, c3.

Storing each character in\nthe phrase I want to print

and I'm going to print this\nin a different way than usual.

And we've, generally, dealt with\n

But %c, %c, %c, will let me print out\n

So, kind of, a stupid way\nof printing out a string.

So we already have a solution\nto this problem last week.

But let's poke around at what's\n

But we, again, could\nhave done this last week

with a string and just one\nvariable, or even, 0, at that.

But let's start converting\nthese characters

to their apparent numeric equivalents\n

Let me modify these %c's,\njust to be fun, to be %i's.

And let me add some spaces so there\n

Let me, now, recompile\nhi, and let me rerun it.

Just to guess, what should\nI see on the screen now?

AUDIENCE: The ASCII values?

DAVID MALAN: The ASCII values.

And it's intentional that\nI keep using the same word

hi, because it should be, hopefully,\n

Which, is to say, that c knows about\n

and can do this conversion\nfor us automatically.

And it seems to be doing it\nimplicitly for us, so to speak.

Notice that c1, c2 and\nc3 are, obviously, chars

but printf is able to tolerate\nprinting them as integers.

If I really want it to be pedantic,\n

known as typecasting,\nwhere I can actually

convert one data type to another,\n

And we saw in week 0,\nchars, or characters

are just numbers, like 72, 73, and 33.

So I can use this parenthetical\n

[LAUGHTER] three chars to\nthree integers, instead.

So that's what I meant\nto type the first time.

So parenthesis, int,\nclose parenthesis says

take whatever variable comes after this,\n

The effect is going to be no different,\n

then running ./hi still works the same,\n

And we can do this all day long,\nchars to ints, floats to ints

Sometimes, it's equivalent.

Other times, you're going\nto lose information.

Taking a float to an\nint, just intuitively

is going to throw away everything\nafter the decimal point

because an int has no decimal point.

But, for now, I'm going to\nrewind to the version of this

that just did implicit-type\nconversion, or implicit casting

just to demonstrate that we can, indeed,\n

Let me go ahead and do\nthis, now, the week 1 way.

Let's just do printf, quote-unquote--

Actually, let's do this, string\ns equals quote-unquote hi

and then let's do a simple printf\n

So now I've rewound to last\nweek, where we began this story

but you'll notice that, if we\nkeep playing around with this--

Oh, and let me introduce the C50 library\n

Let me go ahead and\nrecompile, rerun this

we seem to be coding in circles, here.

Like, I've just done the same\nthing multiple, different ways.

But there's clearly\nan equivalence, then

between sequences of chars and strings.

And if you do it the\nreal pedantic way, you

have three different variables, c1, c2,\n

or you can just treat them all together\n

But it turns out that\nstrings are actually

implemented by the computer\nin a pretty now familiar way.

What might a string actually be\nas of this point in the story?

Where are we going with this?

Let me try to look further back.

AUDIENCE: Can a string like\nthis be an array of chars?

DAVID MALAN: Yeah, a string\nmight be, and indeed is, just

So last week we took for\ngranted that strings exist.

Technically, strings exist,\nbut they're implemented

as arrays of characters,\nwhich actually opens up

some interesting possibilities for us.

Because, let me see, let\nme see if I can do this.

Let me try to print out,\nnow, three integers again.

But if string s is but an array, as you\n

s bracket 1, and s bracket 2.

So maybe I can start poking\naround inside of strings

even though we didn't\ndo this last week, so I

can get at those individual values.

So make hi, ./hi and,\nvoila, there we go again.

It's the same 72, 73, 33, but\nnow, I'm sort of, hopefully

like, wrapping my mind around\nthe fact that, all right

a string is just an array of\ncharacters, and arrays, you

can index into them using this\nnew square bracket notation.

So I can get at any one of\nthese individual characters

and, heck, convert it to an\ninteger like we did in week 0.

Let me get a little curious now.

What else might be in\nthe computer's memory?

Well, let's-- I'll go back to the\n

Here might be how we\noriginally implemented hi

with three variables, c1, c2, c3.

Of course, that map to these\ndecimal digits or equivalent

But what was this\nlooking like in memory?

Literally, when you create a\nstring in memory, like this

string s equals quote-unquote hi,\nlet's consider what's going on

underneath the hood, so to speak.

Well, as an abstraction, a string,\n

it would seem, 3 bytes, right?

I've gotten rid of the\nbars, there, because if you

think of a string as a type, I'm just\n

But technically, a string, we've\njust revealed, is an array

So technically, if the\nstring is called s

s bracket 0 will give\nyou the first character

s bracket 1, the second,\nand s bracket 3, the third.

But let me ask this question now,\n

is the only thing in\nyour computer memory

and the ability, like a canvas to draw\n

or whatever on it, but\nthat's it, like this

is what your Mac, and PC, and\nphone ultimately reduced to.

Suppose that I'm running a piece\n

and now I write down\nbye exclamation point.

Well, where might that go in memory?

B-Y-E. And then the next thing I type\n

My memory just might get\nfilled up, over time

with things that you or\nsomeone else are typing.

But then how does the computer know if,\n

is right after H-I exclamation point\n

All we have are bytes, or 0s and 1s.

So if you were designing\nthis, how would you

implement some kind of\ndelimiter between the two?

Or figure out what the\nlength of a string is?

DAVID MALAN: OK, so the right\nanswer is use a nul character

and for those who don't\nknow, what does that mean?

DAVID MALAN: Yeah, so\nit's a special character.

Let me describe it as\na sentinel character.

Humans decided some\ntime ago that you know

what, if we want to delineate\nwhere one string ends

and where the next one begins,\nwe just need some special symbol.

And the symbol they'll use is\ngenerally written as backslash 0.

This is just shorthand notation\nfor literally eight 0 bits.

And the nickname for eight\n0 bits, in this context

And we can actually see this as follows.

If you look at the\ncorresponding decimal digits

like you could do by doing out\nthe math or doing the conversion

like we've done in code, you would\n

but then 1 extra byte that's sort of\n

And now I've just written\nit as the decimal number 0.

The implication of this is\nthat the computer is apparently

using, not 3 bytes to store\na word like hi, but 4 bytes.

Whatever the length of the string is,\n

that demarcates the end of the string.

So we might draw it like this instead.

And this character is, again,\npronounced nul, or written N-U-L.

If humans, at the end of the day,\n

they just needed to\ndecide, all right, well

how do we distinguish\none string from another?

It's a lot easier with\nchars, individually, it's

a lot easier with ints, it's\neven easier With floats, why?

Because, per that chart earlier,\n

Every int is always 4 bytes.

Every long is always 8 bytes.

Well, hi is 1, 2, 3 with\nan exclamation point.

Bye is 1, 2, 3, 4 with\nan exclamation point.

David is D-A-V-I-D, five\nwithout an exclamation point.

And so a string can be\nany number of bytes long

so you somehow need to\ndraw a line in the sand

to separate in memory\none string from another.

So what's the implication of this?

Well, let me go back to code, here.

This is a bit dangerous, but I'm going\n

So let me go ahead and\nrecompile, make hi.

Now let me go ahead and\nrerun make hi, ./hi, Enter.

So you can actually see in the\ncomputer, unbeknownst to you

previously, that there's indeed\nsomething else going on there.

And if I were to make one\nother variant of this program--

let's get rid of just this\none word and let's have two.

So let me give myself\nanother string called t

for instance, just this common\n

Let me, then print out with %s.

And let me also print out with %s,\n

Let me recompile this program,\nand obviously the out--

ugh-- this is what happens\nwhen I go too fast.

All right, third mistake\ntoday, close quote.

Now we have a program that's\nprinting both hi and bye

only so that we can consider what's\n

If s is storing hi and\napparently one bonus byte that

demarcates the end of that\nstring, bye is apparently

going to fit into the\nlocation directly after.

And it's wrapping around, but that's\n

But bye, B-Y-E exclamation\npoint is taking up

1, 2, 3, 4, plus a fifth byte, as well.

All right, any questions on this\n

And we'll contextualize\nthis, before long

so that this isn't just\nlike, OK, who really cares?

This is going to be the source\nof actually implementing things.

In fact for problem set 2, like\ncryptography, and encryption

and scrambling actual human messages.

AUDIENCE: So normally if\nyou were to not use string

you would just make a character\nrange that would declare

how many characters there are so\n

DAVID MALAN: A good\nquestion, too and let

me summarize as, if we were\ninstead to use chars all the time

we would indeed have to know in advance\n

string that you're storing, how, then,\n

because when you CS50 wrote\nthe get string function

we obviously don't know\nhow long the words are

going to be that you all are typing in.

It turns out, two weeks from\nnow we'll see that get string

uses a technique known as\ndynamic memory allocation.

And it's going to grow or shrink\n

AUDIENCE: Why are we using a nul value?

DAVID MALAN: Good question.

Why are we using a nul value,\nisn't it wasting a byte?

But I claim there's really no other way\n

from the start of another, unless we\n

All we have, at the end of the day,\n

Therefore, all we can do is spin\nthose bits in some creative way

So we're minimally going to spend\n1 byte to solve this problem.

AUDIENCE: How does our memory device\n

the /n if we don't have\nit stored as a char?

how does the computer know to move\n

So /n, even though it\nlooks like two characters

it's actually stored as just 1\nbyte in the computer's memory.

There's a mapping between\nit and an actual number.

And you can see that, for instance,\n

AUDIENCE: So with that being\nstored would be the [INAUDIBLE]..

If I had put a /n in my code here,\n

and here, that would actually shift\n

need to make room for a /n\nhere and another one over here.

So it would take two\nmore bytes, exactly.

AUDIENCE: So if hi exclamation\n

too as 72, 73, 33, if we are to\n

and convert them into binary how\n

DAVID MALAN: And what's\nthe last thing you said?

DAVID MALAN: It's context sensitive.

So if, at the end of the day, all\n

like 72, 73, 33, recall\nthat it's up to the program

to decide, based on context,\nhow to interpret them.

And I simplified this story in week 0\n

as RGB colors, and iMessage\nor a text messaging program

interprets them as letters, and\n

How those programs do it is by way\n

And in fact, later this\nsemester, we'll see

a data type via which you can represent\n

and red value, a green\nvalue, and a blue value.

So we'll see other data types as well.

AUDIENCE: It seems easy enough to just\n

so why do we have integers\nand long integers?

Why can't we make everything\nvariable in its data size?

DAVID MALAN: Really\ninteresting question.

Why could we not just make all\ndata types variable in size?

And some languages, some\nlibraries do exactly this.

C is an older language, and\nbecause memory was expensive

The reality was you\ngain benefits from just

standardizing the size of these things.

You also get performance\nincreases in the sense

that if you know every int is\n4 bytes, you can very quickly

and we'll see this next week,\njump from integer to another

to another in memory just by adding\n

You can very quickly poke around.

Whereas, if you had variable\nlength numbers, you would have to

kind of, follow, follow, follow,\nlooking for the end of it.

Follow, follow-- you would have to\n

So that's a topic we'll come back to.

But it was generally for efficiency.

AUDIENCE: Why not store the\nnul character [INAUDIBLE]

DAVID MALAN: Good question\nwhy not store the--

why not store the nul\ncharacter at the beginning?

You could-- let's see, why\nnot store it at the beginning?

You could absolutely--\nwell, could you do this?

If you were to do that\nat the beginning--

No, because I finally thought\nof a problem with this.

If you store it at\nthe beginning instead

we'll see in just a moment how\nyou can actually write code

to figure out where\nthe end of a string is

and the problem there\nis wouldn't necessarily

know if you eventually hit a\n0 at the end of the string

because it's the number 0 in the\n

or if it's the context of some\nother data type, altogether.

So the fact that we've standardized--

the fact that we've standardized\nstrings as ending with nul

means that we can reliably distinguish\n

And that's actually a\nperfect segue way, now

to actually using this\nprimitive to building up

our own code that manipulates\nthese things that are lower level.

Let me create a new file called length.

And let's use this basic idea to\n

is after it's been stored in a variable.

Let me include both the CS50\nheader and the standard I/O header

give myself int main(void) again\n

Let me prompt the user for\na string s and I'll ask them

for a string like their name, here.

And then let me name it more\nverbosely name this time.

Now let me go ahead and do this.

Let me iterate over every\ncharacter in this string

in order to figure out\nwhat its length is.

So initially, I'm going\nto go ahead and say this

int length equals 0, because\nI don't know what it is yet.

So we're going to start at 0.

And then while the following is true--

while-- let me-- do I want to do this?

Let me change this to i,\njust for clarity, let me do

this, while name bracket i does not\n

So I typed it on the slide is N-U-L,\n

you actually use its numeric equivalent,\n

While name bracket i does not equal the\n

and increment i to i plus plus.

And then down here I'm going\nto print out the value of i

to see what we actually get,\nprinting out the value of i.

All right, so what's\ngoing to happen here?

./length and let me type in something\n

Let me try bye,\nexclamation point, Enter.

Let me try my own name, David, Enter.

So what's actually going on here?

Well, it seems that\nby way of this 4 loop

we are specifying a\nlocal variable called

i initialized to 0, because we're\n

I'm then asking the\nquestion, does location 0

that is i in the name string,\nwhich we now know is an array

Because if it doesn't, that means it's\n

Then, let's come back around to line\n

So does name bracket 1 not equal /0?

Well, if it doesn't, and it won't\nif it's an i, or a y, or an a

based on what I typed in, we're\ngoing to increment i once more.

Fast-forward to the end of the story,\n

technically, one space\npast the end of the string

name bracket i will equal /0.

So I don't increment i anymore, I\n

So what we seem to have here with some\n

is a program that figures out the length\n

Let's practice our abstraction\nand decompose this into

maybe, a helper function here.

Let me grab all of this\ncode here, and assume

for the sake of discussion for a moment,\n

And the length of the string\nis name that I want to get

and then I'll go ahead and print\nout, just as before with %i

So now I'm abstracting away\nthis notion of figuring out

That's an opportunity for to\nme to create my own function.

If I want to create a\nfunction called string length

I'll claim that I want to\ntake a string as input

and what should I have this\nfunction return as its return type?

What should get string\npresumably return?

Float really wouldn't\nmake sense because we're

measuring things that are integers.

In this case, the length of something.

So indeed, let's have it return an int.

I can use the same\ncode as before, so I'm

going to paste what I\ncut earlier in the file.

The only thing I have to change\nis the name of the variable.

Because now this function,\nI decided arbitrarily

that I'm going to call it\ns, just to be more generic.

So I'm going to look at s\nbracket i at each location.

And I don't want to print it at the\n

What's the line of code I should\ninclude here if I actually

want to hand back the total length?

DAVID MALAN: Return i, in this case.

So I'm going return i, not print it.

Because now, my main function can\n

and print it on the next line itself.

I just need a prototype, so that's\n

I'm going to rerun make length.

Hopefully I didn't screw up.

I didn't. ./length,\nI'll type in hi-- oops--

I'll type in bye again, and so forth.

So now we have a function that\n

Well, it turns out we didn't\nactually need this all along.

It turns out that we can get rid of my\n

I can definitely delete the\nwhole implementation down here.

Because it turns out, in\na file called string.h

which is a new header file today, we\n

called, more succinctly,\nstrlen, S-T-R-L-E-N. Which

This is a function that comes with C,\n

and it does what we just\nimplemented manually.

So here's an example of, admittedly, a\n

And how do what kinds\nof functions exist?

Well, let me pop out of my\nbrowser here to a website that

is a CS50's incarnation of\nwhat are called manual pages.

It turns out that in a lot\nof systems, Macs, and Unix

and Linux systems, including\nthe Visual Studio Code

instance that we have\nin the cloud, there

are publicly accessible\nmanual pages for functions.

They tend to be written very\nexpertly, in a way that's

So we have here at\nmanual.cs50.io is CS50's version

of manual pages that have this\nless-comfortable mode that

give you a, sort of, cheat\nsheet of very frequently used

helpful functions in C. And\nwe've translated the expert

notation to things that a\nbeginner can understand.

So, for instance, let me go ahead and\n

You'll see that there's documentation\n

but more interestingly\ndown here, there's

a whole bunch of\nstring-related functions

that we haven't even seen most of, yet.

But there's indeed one\nhere called strlen

calculate the length of a string.

And so if I go to strlen here, I'll\n

And the way a manual\npage typically works

whether in CS50's format\nor any other, system

is you see, typically, a\nsynopsis of what header

files you need to use the function.

So you would copy paste\nthese couple of lines here.

You see what the prototype\nis of the function so

that you know what its inputs are,\n

Then down below you might see a\ndescription, which in this case

This function calculates\nthe length of s.

Then you see what the\nreturn value is, if any

and you might even see an example, like\n

So these manual pages\nwhich are again, accessible

here, and we'll link to these in\n

are pretty much the place to\nstart when you want to figure out

has a wheel been invented already?

Is there a function that might help\n

so that I don't have to really\nget into the weeds of doing all

of those lower-level steps as I've had.

Sometimes the answer is going to be\n

But again the point of our\nhaving just done this together

is to reveal that even the\nfunctions you start taking for

granted, they all reduce to some\nof these basic building blocks.

At the end of the day, this is\n

We're just learning,\nnow, how to harness those

and how to manipulate them ourselves.

AUDIENCE: We did just see\n[INAUDIBLE] Is that so common

that we would have to\nspecify it, or is it not?

DAVID MALAN: Good question.

Is it so common that you would\nhave to specify it or not?

You do need to include its\nheader files because that's

where all of those prototypes are.

You don't need to worry about\nlinking it in with -l anything.

And in fact, moving\nforward, you do not ever

need to worry about linking in\n

We, the staff, have configured make to\n

We want you to understand\nthat it is doing it

but we'll take care of\nall of the -l's for you.

But the onus is on you for the\nprototypes and the header files.

Other questions on these\nrepresentations or techniques?

AUDIENCE: [INAUDIBLE] exclamation mark.

How does it actually define\nthe spaces [INAUDIBLE]??

DAVID MALAN: A good question.

If you were to have a string with actual\n

what would the computer actually do?

Well for this. let me\ngo to asciichart.com.

Which is just a random website that's\n

This is, in fact, what we had\na screenshot of the other day.

And if you look here, it's a little\n

If a computer were to store a space, it\n

32, or technically, the pattern of 0s\n

All of the US English keys that\nyou might type on a keyboard

can be represented with a\nnumber, and using Unicode can

you express even things like\nemojis and other languages.

AUDIENCE: Are only strings\nfollowed by nul number

or let's say we had a series of\nnumbers, would each one of them

DAVID MALAN: Good question.

Only strings are accompanied\nby nuls at the end

because every other data type\nwe've talked about thus far

is of well defined finite length.

1 byte for char, 4 bytes\nfor ints and so forth.

If we think back to last week, we did\n

Integer overflow, because 4 bytes, heck,\n

We also talked about\nfloating point imprecision.

Thankfully in the world of scientific\n

there are libraries you can\nuse that draw inspiration

from this idea of a\nstring, and they might

use 9 bytes for an integer\nvalue or maybe 20 bytes

that you can count really high.

But they will then start to\nmanage that memory for you

and what they're really probably doing\n

and somehow remembering how\nlong the sequence of bytes is.

That's how these higher-level\nlibraries work, too.

All right, this has been a lot.

Let's take one more break here.

We'll do a seven-minute break here.

And when we come back, we'll\nflesh out a few more details.

So we just saw strlen as an\nexample of a function that

comes in the string library.

Let's start to take more of these\n

So we're not relying only on the\n

Let me switch over to VS Code.

And create a file called, say string.h.

to apply this lesson\nlearned, as follows.

Let me include cs50.h,\nstdio.h, and this new thing

string.h as well, at the top.

I'm going to do the usual\nint main(void) here.

And then in this program suppose,\nfor the sake of discussion

that I didn't know about\n%s for printf or, heck

maybe early on there\nwas no %s format code.

And so there was no easy\nway to print strings.

Well, at least if we know that\n

we could use %c as a\nworkaround, a solution to that

So let me ask myself for a\nstring s by using get string here

and I'll ask the user for some input.

And then, let me print out say, output\n

Now, the simplest way to do this, of\n

printf %s, and plug in\nthe s, and we're done.

But again, for the sake of\ndiscussion, I forgot about

or someone didn't implement %s,\nso how else could we do this?

Well, in pseudo code, or in English\n

this problem, printing out the string\n

How might we go about solving this?

Just in English, high-level?

What would your pseudo code look like?

AUDIENCE: You could\njust print each letter.

DAVID MALAN: OK, so\njust print each letter.

And maybe, more precisely,\nsome kind of loop.

Like, let's iterate over\nall of the characters in s

Well, for int i, get 0 is kind of the\n

OK, how long do I want to iterate?

Well, it's going to\ndepend on what I type in

but that's why we have strlen now.

So iterate up to the length of\ns, and then increment i with plus

And then let's just print\nout %c with no new line

because I want everything\non the same line

whatever the character\nis at s bracket i.

And then at the very\nend, I'll give myself

that new line, just to move the\ncursor down to the next line

so the dollar sign is\nnot in a weird place.

All right, so let's see if I\ndidn't screw up any of the code

make string, Enter, so far so good,\n

Let me do it once more with\nbye, Enter, and that works, too.

Notice I very deliberately\nand quickly gave myself

two spaces here and one space\nhere just because I, literally

wanted these things to line up properly,\n

But that was just a\ndeliberate formatting detail.

Which is a claim I've made before,\nbut it's not well-designed.

It is well-designed in that I'm using\n

like, I've not reinvented\na wheel, there's no line 15

or below, I didn't implement\nstring length myself.

So I'm at least practicing\nwhat I've preached.

But there's still an\nimperfection, a suboptimality.

This one's really subtle though.

And you have to think\nabout how loops work.

What am I doing that's\nnot super efficient?

AUDIENCE: [INAUDIBLE]\nover and over again.

DAVID MALAN: Yeah, this\nis a little subtle.

But if you think back to the\nbasic definition of a 4 loop

and recall when I highlighted\nthings last week, what happens?

Well, the first thing\nis that i gets set to 0.

Then we check the condition.

How do we check the condition?

We call strlen on s,\nwe get back an answer

like 3 if it's a H-I exclamation point\n

and then we print out the character.

Then we increment i from 0 to 1.

How do I recheck the condition?

Get back the same answer, 3.

So we print out another character. i\n

Well, what's the string like the best?

So I keep asking the same\nquestion sort of stupidly

because the string is, presumably,\nnever changing in length.

And indeed, every time\nI check that condition

that function is going to get called.

And every time, the answer\nfor hi is going to be 3.

So it's a marginal suboptimality,\nbut I could do better, right?

Don't ask multiple times questions\n

So how could I remember the answer to\n

How could I remember the\nanswer to this question?

AUDIENCE: Store it in a variable.

DAVID MALAN: So store\nit in a variable, right?

That's been our answer most any time\n

Well, I could do something like this,\n

Then I can just change\nthis function call.

Let me fix my spelling here.

Let me fix this to be comparing\n

Because now strlen is only\ncalled once on line 9.

And I'm reusing the value\nof that variable, a.k.a.

length, again, and again, and again.

Turns out that 4 loops let you\n

so we can do this a little\nmore elegantly all in one line.

And this is just some\nsyntactic improvement.

I could actually do something\nlike this, n equals strlen of s

and then I could just say n\nhere or I could call it length.

But heck, while I'm being succinct\n

So now it's just a marginal\nchange but I've now

declared two variables\ninside of my loop, i and n.

i is set to 0. n extends\nto the string length of s.

But now, hereafter, all of my condition\n

i less than n, and n is never changing.

All right, so a marginal\nimprovement there.

Now that I've used this\nnew function, let's

use some other functions\nthat might be of interest.

Let me write a quick program here\n

changes to uppercase some\nstring that the user types in.

So let me code a file\ncalled uppercase.c.

Up here I'll use my new friends,\n

So standard I/O, and string.h So\njust as before int main(void).

And then inside of main, what\nI'm going to do this time

is let's ask the user for a string\n

And then let me print\nout something like after.

So that it-- just so I can see what\n

And then after this, let me\ndo the following, for int, i

equals 0, oh, let's\npractice that same lesson

so n equals the string length of\n

So really, nothing\nnew, fundamentally yet.

How do I now convert characters from\n

In other words, if I type\nin hi, H-I in lowercase

I want my program, now, to uppercase\n

Well how can I go about doing this?

Well you might recall\nthat there is this--

you might recall that\nthere is this ASCII chart.

So let's just consult this\nreal quick on asciichart.com.

We've looked at this last week\nnotice that a-- capital A is 65

capital B is 66, capital\nC is 67, and heck, here's

lowercase a, lowercase b,\nlowercase c, and that's 97, 98, 99.

And if I actually do some\nmath, there's a distance of 32.

So if I want to go from\nuppercase to lowercase

I can do 65 plus 32 will give me\n97 and that actually works out

across the board for everything else.

66 plus 32 gets me to 98 or lowercase b.

Or conversely, if you have a\nlowercase a, and its value is 97

subtract 32 and boom, you have capital\n

But now that we know that\nstrings are just arrays

and we know that characters,\nwhich are in those arrays

are just binary\nrepresentations of numbers

I think we can manipulate a\nfew of these things as follows.

Let me go back to my\nprogram here, and first

ask the question, if the current\n

is lowercase, let's\nforce it to uppercase.

So how am I going to do that?

If the character at s bracket i,\n

is greater than or equal to\nlowercase a, and s bracket

i is less than or equal to\nlowercase z, kind of a weird Boolean

expression but it's completely\nlegitimate, because in this array

s is a whole bunch of characters\nthat the humans typed in

because that's what a string is,\n

be a little nonsensical\nbecause when have you ever

compared numbers to letters?

But we know from week 0 lowercase a\n

And so that would allow us to answer\n

All right, so let me\nanswer that question.

If it is, what do I want to print out?

I don't want to print\nout the letter itself

I want to print out the\nletter minus 32, right?

Because if it happens to be a\nlowercase a, 97, 97 minus 32

gives me 65, which is\nuppercase A, and I know that

just from having stared\nat that chart in the past.

Else if the character is not\nbetween little a and big A

I'm just going to\nprint out the character

itself by printing s bracket i.

And at the very end of this, I'm\n

to move the cursor to the next line.

So again, it's a little wordy.

But this loop here, which I\nborrowed from our code previously

just iterates over the string, a.k.a.

array, character-by-character,\nthrough its length.

This line 11 here is\njust asking the question

if that current character,\nthe i-th character of s

is greater than or equal\nto little a and less

than or equal to little z, that\nis between 97 and 132, then

we're going to go ahead and\nforce it to uppercase instead.

All right, and let me zoom\nout here for just a second.

And sorry, I misspoke 122, which\nis what you might have said.

Let me go ahead now and\ncompile and run this program.

So make uppercase, ./uppercase, and\n

And there's the capitalized\nversion, thereof.

Let me do it again, with\nmy own name in lowercase

and now it's capitalized as well.

Well, what could we do to improve this?

Let's stop reinventing wheels.

Let's go to the manual pages.

So let me go here and search for\nsomething like, I don't know

I did some auto complete\nhere, our little search box

is saying that, OK there's\nan is-lower function

check whether a character is lowercase.

Well let me check, is lower, now I see\n

that's the header file\nI need to include.

This is the prototype for is-lower,\n

I feel like is-lower should\nreturn true or false.

So let's scroll down to the\ndescription and return value.

It returns, oh this is interesting.

And this is a convention in C. This\n

if C is a lowercase letter and 0\nif C is not a lowercase letter.

So like 1, negative 1, something that's\n

and 0 if it is not a lowercase letter.

So how can we use this building block?

Let me go back to my code here.

Let me add this file, include ctype.h.

And down here, let me get rid of\nthis cryptic expression, which

was kind of painful to come up with,\n

That should actually work but why?

Well is-lower, again, returns a non-zero\n

That means it could return 1.

It could return negative 1.

It could return 50 or negative 50.

It's actually not\nprecisely defined, why?

This was a common convention to\nuse 0 to represent false and use

any other value to represent true.

And so it turns out, that\ninside of Boolean expressions

if you put a value like a function\n

that's going to be equivalent to false.

It's like the answer\nbeing no, it is not lower.

But you can also, in\nparentheses, put the name

of the function and its arguments,\n

Because we could do something like\n

Because that's the definition,\nif it returns a non-zero value

But a more succinct way to do that\n

If it's is lower, then print\nout the character minus 32.

So this would be the common\nway of using one of these

is- functions to check if\nthe answer is true or false.

DAVID MALAN: OK, well we might be done.

It would be incorrect to check for\n

You want to check for the opposite of 0.

Or more succinctly, like I did by\n

Let me see what happens here.

So this is great, but some of you\n

A moment ago when we were on\nthe manual pages searching

for things related to lowercase,\nwhat might be another building

Based on what's on the screen here?

There's a function that would literally\n

so I don't have to get into the\nweeds of negative 32, plus 32.

I don't have to consult that chart.

Someone has solved this\nproblem for me in the past.

And let's see if I can\nactually get back to it.

Let me go ahead, now, and use this.

So instead of doing\ns bracket i minus 32

let's use a function that someone else\n

And now it's going to\ndo the solution for me.

So if I rerun make uppercase, and then\n

now it's working as expected.

And honestly, if I read the\ndocumentation for to-upper

by going back to its man page,\nor manual page, what you'll see

is that it says if it's lowercase,\n

If it's not lowercase, it's already\nuppercase, it's punctuation

it will just return\nthe original character.

Which means, thanks to this\nfunction, I can actually

tighten this up significantly,\nget rid of all of my conditional

there, and just print out\nthe to-upper return value

and leave it to whoever wrote\nthat function to figure out

if something's uppercase or lowercase.

All right, questions on\nthese kinds of tricks?

Again, it all reduces to\nweek 0 basics, but we're just

building these abstractions on top.

AUDIENCE: I'm wondering\nif there's any way just

to import all packages under\na certain subdomain instead

of having to do multiple\n[INAUDIBLE] statements

kind of like a star [INAUDIBLE]

There is no easy way in C\nto say, give me everything.

That was for, historically,\nperformance reasons.

They want you to be explicit\nas to what you want to include.

In other languages like\nPython, Java, one of which

we'll see later this term, you\ncan say, give me everything.

But that, actually, tends to be best\n

execution or compilation of your code.

AUDIENCE: Does to-upper\naccommodate for special characters?

Does to-upper accommodate special\ncharacters like punctuation?

If I read the documentation\nmore pedantically

It will properly hand me\nback an exclamation point

So if I do make uppercase here,\nand let me do ./upper, sorry--

./uppercase, hi with an exclamation\n

pass it through unchanged Yeah?

AUDIENCE: Do we access to a\nfunction that would do all of that

but just to the screen\nrather than to [INAUDIBLE]

DAVID MALAN: Really good question, too.

No, we do not have access to a function\n

with CS50's library that will just\n

In C, that's actually\neasier said than done.

So stay tuned for another language\n

All right, so what does\nthis leave us with?

There's just a-- let's\ncome full circle now

to where we began today where we\n

Recall that we talked about rm\ntaking command line argument.

The file you want to delete,\nwe talked about clang

taking command line\narguments, that again

modify the behavior of the program.

How is it that maybe you and I\ncan start to write programs that

actually take command line arguments?

Well here is where I\ncan finally explain why

we've been typing int\nmain(void) for the past week

and just asking that you take on faith\n

Well, by default in C, at least\n

there's only two official\nways to write main functions.

You might see other formats\nonline, but they're generally

not consistent with the\ncurrent specification.

This, again, was sort of a\nboilerplate for the simplest

function we might write last\nweek, and recall that we've

been doing this the whole time.

(Void) What that (void) means, for all\n

and you have written thus far,\nis that none of our programs

that we've written take\ncommand line arguments.

That's what the void there means.

It turns out that main is the way you\n

in fact, take command\nline arguments, that

is words after the command\nin your terminal window.

If you want to actually not\nuse get int or get string

you want the human to be able to\n

And just run-- print\nhello, David on the screen.

You can use command line arguments,\nwords after the program name

So we're going to change this in a\n

but something that's now a bit\nmore familiar syntactically.

If you change that (void) in main\n

int, argc, comma, string, argv,\nopen bracket, close bracket

you are now giving yourself\naccess to writing programs

that take command line arguments.

Argc, which stands for\nargument count is going

to be an integer that stores how many\n

The C automatically gives that to you.

String argv stands for\nargument vector, that's

going to be an array of all of the words\n

So with today's building\nblock of an array

we have the ability now to let\nthe humans type as many words

or as few words, as\nthey want at the prompt.

C is going to automatically put\nthem in an array called argv

and it's going to tell us how many\n

The int, as the return type here,\n

Let's use this definition\nto make, maybe

just a couple of simple programs.

But in problem set 2\nwill we actually use

this to control the\nbehavior of your own code.

Let me code up a file called\nargv.0 just to keep it aptly named.

Let me go ahead and include--

That is not the right name of a\nprogram, let's start that over.

Let's go ahead and code up argv.c.

include cs50.h, include\nstdio.h, int, main, not void

let's actually say int, argc, string,\n

No numbers in between because\nyou don't know, in advance

how many words the human's\ngoing to type at their prompt.

Now let's go ahead and do this.

Let's write a very simple program that\n

whoever the name is that gets typed.

But not using get string, let's\ninstead have the human just

type their name at the prompt, just like\n

so it's just one and\ndone when you hit Enter.

Let me go ahead then and do this,\nprintf, quote-unquote, hello

comma, and instead of world\ntoday, I want to print out

whatever the human typed in.

So let's go ahead and do\nthis, argv, bracket 0 for now.

But I don't think this is quite\nwhat I want because, of course

that's going to literally print\nout argv, bracket, 0, bracket.

I need a placeholder, so let me\n

So if argv is an array, but\nit's an array of strings

then argv bracket 0 is\nitself a single string.

And so it can be plugged\ninto that %s placeholder.

Let me go ahead and save my program.

And compile argv, so far, so good.

Let me now type in my name\nafter the name of the program.

I'm literally typing an extra word,\n

OK, it's apparently a little\nbuggy in a couple of ways.

I forgot my /n but\nthat's not a huge deal.

But apparently, inside of\nargv is literally everything

that humans typed in including\nthe name of the program.

So logically, how do I print out hello,\n

the actual name of the program?

AUDIENCE: Change the index to 1.

So presumably index to 1, if that's\n

So let's do make argv\nagain, ./argv, Enter.

So this is another form of nul.

But this is user error, now, on my part.

I didn't do exactly what I said I would.

AUDIENCE: You forgot the parameter.

DAVID MALAN: Yeah, I\nforgot the parameter.

I should probably deal\nwith that, somehow

so that people aren't\nbreaking my program

and printing out random\nthings, like nul.

But if I do say argv, David,\nnow you see hello, David.

I can get a little curious,\nlike what's at location 2?

Well we can see, make argv,\nbracket, ./argv, David, Enter.

All right, so just nothing is there.

But it turns out, in a couple of weeks,\n

and see if we can't crash\nprograms deliberately

because nothing is\nstopping me from saying

oh what's at location 2\nmillion, for instance?

We could really start to get curious.

But for now, we'll do the right thing.

But let's now make sure the human has\n

So let's say this, if argc equals\n

and one more word after that, go\nahead and trust that in argv 1

as you proposed, is the person's name.

Else, let's go ahead and default\n

like, well, if we don't get a name\n

So now we're programming defensively.

This time the human, even if they\n

or they give us too many names,\n

because I now have some\nerror handling here.

Because, again, argc is argument\n

Let me make the same mistake as before.

I don't get this weird nul behavior.

I get something well-defined.

I could do David Malan, but\nthat's not currently supported.

I would need to alter my logic to\n

So what's the point of this?

At the moment, it's\njust a simple exercise

to actually give myself a way of taking\n

Because, consider, it's\njust more convenient in

this new, command-line-interface world.

If you had to use get string\nevery time you compile your code

it'd be kind of annoying, right?

You type make, then you might get a\n

Then you type in hello, or cash, or\n

it just really slows the process.

But in this\ncommand-line-interface world

if you support command line arguments,\n

Like, scrolling up and down in\n

You can just type commands more quickly\n

And you don't have to keep\nprompting the user, more

pedantically, for more and more info.

So any questions then on\ncommand line arguments?

Which, finally, reveals why\nwe had (void) initially

but what more we can now put in main.

That's how you take\ncommand line arguments.

AUDIENCE: If you were to put--

if you were to use argv, and you\n

would it still give you, like, a string?

Would that still be considered string?

Or would you consider [INAUDIBLE]?

If you were to type at\nthe command line something

like, not a word, but\nsomething like the number 42

that would actually be\ntreated as a string.

Because again, context matters.

So if your program is\ncurrently manipulating memory

as though its characters or strings,\n

are, they will be interpreted\nas ASCII text, or Unicode text.

If we therefore go to the chart here,\n

then how do you distinguish numbers\n

Well, notice 65 is a, 97 is a,\nbut also 49 is 1, and 50 is 2.

So the designers of ASCII,\nand then later Unicode

realized well wait a minute,\nif we want to support programs

that let you type things\nthat look like numbers

even though they're not\ntechnically ints or floats

we need a way in ASCII and\nUnicode to represent even numbers.

And it's a little silly that we have\n

But again, if you're in the\nworld of letters and characters

you've got to come up with\na mapping for everything.

And notice here, here's the dot.

Even if you were to represent 1.23\n

even the dot now is going to be\n

So again, context here matters.

All right, one final example\nto tease apart what this int is

and what it's been\ndoing here for so long.

So I'm going to add one\nbit of logic to a new file

that I'm going to call exit.c.

We're going to introduce something that\n

It turns out this is not\na feature we've used yet

but it's just useful to know about.

Especially when automating\ntests of your own code.

When it comes to figuring out if\na program succeeded or failed.

It turns out that main has one\n

An ability to signal to the user\n

And that's by way of\nmain's return value.

So I'm going modify this\nprogram as follows, like this.

Suppose I want to write\na similar program that

requires that the user\ntype a word at the prompt.

So that argc has to be 2\nfor whatever design purpose.

If argc does not equal 2, I want to\n

I want to insist that the user\noperate the program correctly.

So I might give them an error message\n

But now I want to quit\nout of the program.

The right way, quote-unquote, to do\n

Now it's a little weird\nbecause no one called main yet

right, main just gets\ncalled automatically

but the convention is\nanytime something goes

wrong in a program you should\nreturn a non-zero value from main.

We don't need to get into the weeds of\n

But if you return 1, that is a clue to\n

device that's something went wrong.

If everything works fine, like, let's go\n

before, quote-unquote argv bracket 1.

So this is just a version of\nthe program without an else.

So this is the same\nas doing, essentially

an else here like I did earlier.

I want to signal to the\ncomputer that all is well.

But strictly speaking, if\nI'm already returning here

I don't technically need, if\nI really want to be nit picky

I don't technically need the\nelse because the only way

I'm going to get to line 11\nis if I didn't already return.

The only new thing here logically,\n

I'm returning a value from main.

That's something I\ncould always have done

because main has always been defined by\n

By default, main automatically,\n

If you've never once use the\nreturn keyword, which you probably

haven't in main, it just\nautomatically returns 0

and the system assumes\nthat all went well.

But now that we're starting\nto get a little more

sophisticated with our\ncode, and you know

the programmer, something went\n

You can exit out of them by returning\n

And this is fortuitous\nthat it's an int, right?

Unfortunately, in programming, there are\n

And int gives you 4\nbillion possible codes

that you can use, a.k.a. exit\nstatuses, to signify errors.

So if you've ever on your Mac\nor PC gotten some weird pop up

that an error happened, sometimes,\n

Maybe it's positive,\nmaybe it's negative.

It might say error code 123, or\n

What you're generally seeing, are\n

values from main in a program\nthat someone at Microsoft

or Apple, or somewhere else\nwrote, something went wrong

they are unnecessarily showing you,\n

If only, so that when you call\n

you can tell them what exit\nstatus you encountered

what error code you encounter.

All right, any questions\non exit statuses

which is the last of our new\nbuilding blocks, for now?

AUDIENCE: [INAUDIBLE] You know how\n

if you want to make [INAUDIBLE]

The question is can you\ndo things again and again

at the command line like you\ncould with get string and get int.

Which, by default,\nrecall are automatically

designed to keep prompting\nthe user in their own loop

until they give you an int, or a\n

You're going to get an\nerror message but then

you're going to be\nreturned to your prompt.

And it's up to you to type\nit correctly the next time.

AUDIENCE: [INAUDIBLE]\nautomatically for you.

DAVID MALAN: If you\ndo not return a value

explicitly main will\nautomatically return 0 for you

that is the way C simply works\nso it's not strictly necessary.

But now that we're starting\nto return values explicitly

if something goes wrong,\nit would be good practice

to also start returning a value\n

So let's now get out of\nthe weeds and contextualize

this for some actual problems that\n

by way of problems set 2 and beyond.

So here for instance, is a\nproblem that you might think back

to when you were a kid the\n

the grade level in which\nsome book is written.

If you're a young student, you\nmight read at first-grade level

or third-grade level in the US.

Or, if you're in college\npresumably, you're

reading at a university-level of text.

But what does it mean\nfor text, like in a book

or in an essay, or something\nlike that to correspond

to some kind of grade level?

Well, here's a quote-- a\ntitle of a childhood book.

One Fish, Two Fish, Red Fish, Blue Fish.

What might the grade level be for\n

Maybe, when you were a kid or if\n

these things, what might the\ngrade level of this thing be?

DAVID MALAN: Before grade\n1 is, in fact, correct.

So that's for really young kids?

These are pretty simple phrases, right?

I mean there's not even\nverbs in these sentences

they're just nouns and adjectives,\nand very short sentences.

And so that might be a\nheuristic we could use.

When analyzing text, well if\nthe words are kind of short

the sentences are kind of\nshort, everything's very simple

that's probably a very\nyoung, or early, grade level.

And so by one formulation, it might\n

Mr and Mrs. Dursley, of\nnumber 4, Privet Drive

were proud to say that they were\n

They were the last\npeople you would expect

to be involved in anything\nstrange or mysterious

because they just didn't\nhold with such nonsense.

All right, what grade\nlevel is this book?

DAVID MALAN: OK, I heard third.

DAVID MALAN: Seventh, fifth.

But grade 7, according to\none particular measure.

And whether or not we can debate exactly\n

and maybe you're feeling ahead\nof your time, or behind now.

But here, we have a snippet of text.

What makes this text assume an older\n

a higher grade level, would you think?

DAVID MALAN: Yeah, it's longer,\ndifferent types of words

there's commas now in\nphrases, and so forth.

So there's just some kind\nof sophistication to this.

So it turns out for the\nupcoming problem set

among the things you'll do is\ntake, as input, texts like this

Considering , well, how\nmany words are in the text?

How many sentences are in the text?

How many letters are in the text?

And use those according to a\n

exactly, the grade level of some\n

Well what else are we going\nto do in the coming days?

Well I've alluded to this notion\nof cryptography in the past.

This notion of scrambling\ninformation in such a way

that you can hide the\ncontents of a message

from someone who might\notherwise intercept it, right?

The earliest form of this might\nalso be when you're younger

and you're in class, and you're passing\n

from yourself to someone else.

You don't want to necessarily\nwrite a note in English

or some other written,\nlanguage you might want

to scramble it somehow, or encrypt it.

Maybe you change the As\nto a B, and the Bs to a C.

So that if the teacher snaps\nit up and intercepts it

they can't actually\nunderstand what it is you've

written because it's encrypted.

So long as your friend,\nthe recipient of this note

knows how you manipulated it.

How you added or subtracted\nletters to each other

they can decrypt it, which\nis to reverse that process.

So formally, in the world of\ncryptography and computer science

this is another problem to solve.

Your input, though, when you have a\n

is what's generally known as plain text.

There's some algorithm that's\ngoing to then encipher, or encrypt

that information, into what's\ncalled ciphertext, which

is the scrambled version that\ntheoretically can get safely

intercepted and your message\nhas not been spoiled

unless that intercept\nactually knows what algorithm

you used inside of this process.

So that would be generally\nknown as a cipher.

The ciphers typically take,\nthough, not one input, but two.

If, for instance, your cipher\nis as simple as A becomes B

B becomes C, C becomes D,\ndot dot dot, Z becomes A

you're essentially adding one to\nevery letter and encrypting it.

Now that would be,\nwhat we call, the key.

You and the recipient both have to\n

in advance, what number you're\ngoing to use that day to rotate

or change all of these letters by.

Because when you add 1, they\nupon receiving your ciphertext

have to subtract 1 to\nget back the answer.

For instance, if the input,\nplaintext, is hi, as before

and the key is 1, the ciphertext using\n

otherwise known as the Caesar cipher,\n

So it's similar, but it's at\nleast scrambled at first glance.

And unless the teacher\nreally cares to figure out

what algorithm are they using today,\n

it's probably sufficiently\nsecure for your purposes.

How do you reverse the process?

Well, your friend gets this\nand reverses it by negative 1.

So I becomes H, J becomes I,\nand things like punctuation

remain untouched at\nleast in this scheme.

So let's consider one\nfinal example here.

If the input to the algorithm\nis Uijtxbtdt50, and the key

Such that now B should become A, and C\n

So we're going in the other direction.

Well if we spread all the letters\n

and we start subtracting one letter,\n

T becomes S, X becomes W, A, was, D, T--

DAVID J. MALAN: This is CS50, and\nthis is already week three.

And even as we've gotten much more\n

and some of the C stuff\nthat we've been doing

is all the more cryptic looking,\n

like, everything we've been doing\n

So keep that in mind,\nparticularly as things

seem like they're getting more\n

It's just a process of learning\na new language that ultimately

lets us express this process.

And of course, last week we really\n

inputs and outputs are represented.

And this thing here, a photograph\nthereof, is called what?

DAVID J. MALAN: RAM, I heard--

Random Access Memory or just\ngenerally known as memory.

And recall that we looked at\none of these little black chips

that contains all of the bytes--

all of the bits, ultimately.

It's just kind of a grid,\nsort of an artist grid, that

allows us to think about every\none of these memory locations

as just having a number or\nan address, so to speak.

Like, this might be byte\nnumber 0 and then 1 and then 2

and then, maybe way down here\nagain, something like 2 billion

if you have 2 gigabytes of memory.

And so as we did that, we started to\n

to create kind of our own information,\n

just the basics like ints\nand floats and so forth.

But we also talked about strings.

And what is a string as you now know it?

How would you describe in\nlayperson's terms a string?

DAVID J. MALAN: An array of characters.

And an array, meanwhile--\nlet's go there.

How might someone else define an\n

AUDIENCE: Kind of like\nan indexed set of things.

DAVID J. MALAN: An indexed\nset of things-- not bad.

And I think a key characteristic to\n

does actually pertain to memory.

Byte after byte after byte\nis what constitutes an array.

And we'll see in a couple of\nweeks time that there's actually

more interesting ways to use this same\n

things that are sort of two directional\n

But for now, all we've talked about\n

from left to right, top to bottom,\n

So today, we'll consider still an array.

But we won't focus so\nmuch on representation

of strings or other data types.

We'll actually now focus on\nthe other part of that process

of inputs becoming outputs,\nnamely the thing in the middle--

But we have to keep in mind, even though\n

thus far, certainly on the board\n

have the luxury of\njust kind of eyeballing

the whole thing with a bird's eye view\n

If I asked you where a\nparticular number is

like zero, odds are your eyes\nwould go right to where it is

and boom, problem solved\nin sort of one step.

But the catch is, with a computer\n

the human, can [INAUDIBLE] see\n

It's better to think of your\n

or more specifically an\narray of memory like this

as really being a set of closed\n

And only by opening\neach of those doors can

the computer actually\nsee what's in there

which is to say that the\ncomputer, unlike you, doesn't

have this bird's eye view of all\n

It has to much more\nmethodically look here

maybe look here, maybe look here, and\n

Now fortunately, we already have some\n

Boolean expressions, and the like--

where you could imagine\nwriting some code

that very methodically goes from left\n

more sophisticated that actually\n

And just remember that the\nconventions we've had since last week

now is that these arrays are\nzero indexed, so to speak.

To be zero indexed just means that the\n

So this is location 0, 1, 2, 3, 4, 5, 6.

And notice even though there\nare seven total doors here

the right-most one,\nof course, is called 6

just because we've\nstarted counting at 0.

So in the general case, if you\nhad n doors or n bytes of memory

0 would always be at the left, and n\n

That's sort of a generalization of just\n

All right, so let's revisit the problem\n

with in week zero, which was\nthis notion of searching.

And what does it mean\nto search for something?

Well, to find information-- and\nthis, of course, is omnipresent.

Anytime you take out your phone, you're\n

Any time you pull up a browser,\n

So search is kind of one of the\n

So let's consider how the Googles, the\n

are implementing something as\nseemingly familiar as this.

So here might be the problem statement.

We want some input to\nbecome some output.

What's that input going to be?

Maybe it's a bunch of closed doors\n

to get back an answer, true or false.

Is something we're\nlooking for there or not?

You can imagine taking this one\nstep further and trying to find

where is the thing you're looking for.

But for now, let's just take\none bite out of the problem.

Can we tell ourselves, true or\nfalse, is some number behind one

of these doors or lockers in memory?

But before we go there and start\n

Let's consider how we might\nlay the foundation of, like

comparing whether one algorithm\nis better than another.

We talked about\ncorrectness, and it sort of

goes without saying that any code you\n

Otherwise, what's the point if it\n

But we also talked about design.

And in your own words, what do we\n

designed at this stage than another?

How do you think about\nthis notion of design now?

AUDIENCE: Easier to understand\nor easier to institute.

DAVID J. MALAN: OK, so easier to understand.

DAVID J. MALAN: Efficiency, and what do\n

It doesn't use up too much\nmemory, and it isn't redundant.

So you can think about\ndesign along a few

of these axes-- sort of\nthe quality of the code

but also the quality of the performance.

And as our programs get bigger and\n

those kinds of things are\nreally going to matter.

And in the real world,\nif you start writing code

not just by yourself but with\nsomeone else, getting the design

right is just going to make it easier\n

write code, with just\nhigher probability.

So let's consider how we might focus\n

the efficiency, of an algorithm.

And the way we might talk about the\n

or how slow they are, is in\nterms of their running time.

That is to say, when they're\n

And we might measure this in\nseconds or milliseconds or minutes

or just some number of\nsteps in the general case

because presumably fewer steps, to\n

So how might we think\nabout running times?

Well, there's one general\nnotation we should define today.

So computer scientists tend to describe\n

or a piece of code, for that matter, in\n

This is literally a\ncapitalized O, a big O.

And this generally means that the\nrunning time of some algorithm

is on the order of such and such,\n

is just going to be a very\nsimple mathematical formula.

It's kind of a way of waving\nyour hands mathematically

to convey the idea of just how fast\n

without getting into\nthe weeds of like, it

took this many milliseconds or\n

So you might recall then from week\n

At the time, we just use this to\n

Recall that this red straight\nline was the first algorithm

The yellow line that's still\n

That line represented what\nalternative algorithm?

What is that second algorithm?

AUDIENCE: Like, two pages at a time.

DAVID J. MALAN: Two pages at a time, which\n

potentially double back a page if maybe\n

So it had a potential bug\nbut arguably solvable.

This last algorithm, though, was\n

strategy where I sort of unnecessarily\n

and then in half and\nthen in half, which

as dramatic as that was unnecessarily,\n

bites out of the\nproblem-- like 500 pages

the first time, another 250, another\n

And so we described its\nrunning time as this picture

there, though I didn't use that\n

But indeed, time to solve\nmight be measured just

abstractly in some unit of measure--

seconds, milliseconds, minutes, pages--

So let's now slap some numbers on this.

If we had n pages in that\nphone book, n just representing

a generic number, the\nfirst algorithm here

we might describe as taking n steps.

Second algorithm we might describe\n

maybe give or take one if we\nhave to double back but generally

And then this thing, if you\nremember your logarithms

was sort of a fundamentally\ndifferent formula--

log base 2 of n or just\nlog of n for short.

So this is of a fundamentally\ndifferent formula.

But what's noteworthy is that\nthese first two algorithms

even though, yes, the second\nalgorithm was hands down faster--

I mean, literally twice as fast--

when you start to zoom out and if\n

these first two start to look\nawfully similar to one another.

And if we keep zooming out\nand zooming out and zooming

out as n gets really large--

that is, the x-axis gets really long--

these first two algorithms start\nto become essentially the same.

And so this is where computer\nscientists use big O notation.

Instead of saying specifically,\nthis algorithm takes any steps.

And this one n divided by 2, a\ncomputer scientist would say

eh, each of those algorithms\ntakes on the order of n steps

or on the order of n over 2.

On the order of n over 2\nis pretty much the same

when n gets really large as being\n

So yes, in practice, it's obviously\n

But in the big picture, when n\nbecomes a million, a billion

the numbers are already\nso darn big at that point

that these are as, the\nshapes of these curves imply

pretty much functionally equivalent.

But this one still\nlooks better and better

as n gets large because it's\nrising so much less quickly.

And so here, a computer\nscientist would say

that that third algorithm was on the\n

And they don't have to\nbother with the base

because it's a smaller mathematical\n

a constant, multiplicative factor.

So in short, what are\nthe takeaways here?

This is just a new\nvocabulary that we'll start

to use when we just want to describe\n

To make this more real, if\nany of you have implemented

a for loop at this point in any of your\n

where maybe in was the height\nof your pyramid or maybe n

was something else that you wanted\nto do n times, you wrote code

or you implemented an algorithm\n

So this is just a way now\nto retroactively start

describing with somewhat\nmathematical notation what we've

been doing in practice for a while now.

So here's a list of commonly seen\n

This is not a thorough list\nbecause you could come up

with an infinite number of\nmathematical formulas, certainly.

But the common ones we'll discuss\n

probably reduce to this list here.

And if you were to study\nmore computer science theory

this list would get longer and longer.

But for now, these are sort of the\n

All right, two other pieces\nof vocabulary, if you will

before we start to use this stuff--

so this, a big omega,\ncapital omega symbol

is used now to describe a lower bound\n

So to be clear, big O is\non the order of-- that

is, an upper bound-- on how\nmany steps an algorithm might

take, on the order of so many steps.

If you want to talk, though,\nfrom the other perspective, well

how few steps my algorithm take?

Maybe in the so-called\nbest case, it'd be nice

if we had a notation to\njust describe what a lower

bound is because some\nalgorithms might be super fast

in these so-called best cases.

So the symbology is almost the\nsame, but we replace the big O

So to be clear, big O describes\nan upper bound and omega

And we'll see examples\nof this before long.

And then lastly, last one here, big\n

when you have a case where both\n

running time is the\nsame as the lower bound.

You can then describe it in one breath\n

instead of saying it's in big O\nand in omega of something else.

All right, so out of context, sort\n

but all they refer to is upper\nbounds, lower bounds, or when

they happen to be one in the same.

And we'll now introduce over time\n

apply these to concrete problems.

But first, let me pause to\nsee if there's any questions.

DAVID J. MALAN: Smaller n\nfunctions move faster.

So yes, if you have something\nlike n, that takes only steps.

If you have a formula like n\n

that take more steps\nand therefore be slower.

So the larger the\nmathematical expression

the slower your algorithm is because the\n

AUDIENCE: So you want your\nn function to be small?

DAVID J. MALAN: You want your n function,\n

And in fact, the Holy\nGrail, so to speak

would be this last one here either\n

when an algorithm is on\nthe order of a single step.

That means it literally takes constant\n

100 steps, but a fixed,\nconstant number of steps.

That's the best because even\nas the phone book gets bigger

even as the data set you're\nsearching gets larger and larger

if something only takes a finite\nnumber of steps constantly

then it doesn't matter how big\nthe data set actually gets.

Questions as well on these notations--\n

This is actually very helpful.

I'm seeing pointing this way?

DAVID J. MALAN: What is the input\nto each of these functions?

It is an expression of how\nmany steps an algorithm takes.

So in fact, let me go\nahead and make this

more concrete with an actual\nexample here if we could.

So on stage here, we have\nseven lockers which represent

if you will, an array of memory.

And this array of\nmemory is maybe storing

seven integers, seven integers that\n

And if we want to search\nfor these values, how might

Well, for this, why don't\nwe make things interesting?

Would a volunteer like to come on up?

Have to be masked and on the\ninternet if you are comfortable.

Both of-- oh, there's someone putting\n

And in just a moment,\nour brave volunteer

is going to help me find a\nspecific number in the data set

that we have here on the screen.

So come on down, and I'll get things\n

DAVID J. MALAN: [? Nomira. ?] Nice to meet.

So here we have for Nomira seven\nlockers or an array of memory.

And behind each of\nthese doors is a number.

And the goal, quite simply,\nis, given this array of memory

as input, to return, true or false, is\n

So suppose I care about the number 0.

What would be the simplest,\nmost correct algorithm you could

apply in order to find us the number 0?

OK, try opening the first one.

All right, and maybe just step\naside so the audience can see.

I think you have not found 0 yet.

Let's move on to your next choice.

DAVID J. MALAN: Oh, go ahead, second door.

Let's just move from left to\nright, sort of searching our way.

All right, also not working\nout so well yet, but that's OK.

If you want to go on to the\nnext, we're still looking for 0.

All right, it's not so good yet.

No, that's a-- all\nright, very well done.

All right, so I kind of set you\nup for a fairly slow algorithm

but let me just ask you\nto describe what is it

you did by following\nthe steps I gave you.

AUDIENCE: I just went one\nby one to each character.

DAVID J. MALAN: You went one\nby one to each character

if you want to talk into here.

So you went one by\none by each character.

And would you say that algorithm\nleft or right is correct?

AUDIENCE: Or, yes, in the scenario.

DAVID J. MALAN: OK, yes in this scenario.

What's going through your mind?

AUDIENCE: Because it's not the\nmost efficient way to do it.

So we see a contrast here\nbetween correctness and design.

I mean, I do think it was correct\n

But it took some number of steps.

So in fact, this would be an algorithm.

It has a name, called linear search.

And, [? Nomira, ?] as you\ndid, you kind of walked along

a line going from left to right.

If you had gone from right\nto left, would the algorithm

have been fundamentally better?

DAVID J. MALAN: OK, and why?

AUDIENCE: Because the zero is\nhere in the first scenario.

But if it was like, the zero is in\n

DAVID J. MALAN: Yeah, and so here is\n

becomes a little less obvious.

You would absolutely have\ngiven yourself a better result

if you would just happened\nto start from the right

or if I had pointed you\nto start over there.

But the catch is if I asked her to\n

well, that would have backfired.

And this time, it\nwould have taken longer

to find that number because\nit's way over here instead.

And so in the general case, going\n

is probably as correct as you can\n

about the order of these numbers-- and\n

Some of them are smaller,\nsome of them are bigger.

There doesn't seem to\nbe rhyme or reason.

Linear search is about as good as you\n

a priori about the numbers.

So I have a little thank you gift\nhere, a little CS stress ball.

Round of applause for\nour first volunteer.

Let's try to formalize what I\njust described as linear search

because indeed, no matter which\nend [? Nomira ?] had started on

I could have kind of\nchanged up the problem

to make sure that it\nappears to be running slow.

If zero were among those doors,\n

So let's now try to translate what\n

pseudo code as from week zero.

So with pseudo code, we\njust need a terse English

like, or any language, syntax\nto describe what we did.

So here might be one formulation\nof what [? Nomira ?] did.

For each door, from left to right,\n

Else, at the very end of the program,\n

And by the seventh door,\n[? Nomira ?] had indeed

returned true by saying,\nwell, there is the zero.

But let's consider if this\npseudo code is now correct

First of all, normally, when we've\n

And yet down here, return\nfalse is aligned with the for.

Why did I not indent the return\nfalse, or put another way

why did I not do if number is behind\n

Why would that version of this\ncode have been problematic?

DAVID J. MALAN: OK, I'm not sure\nit's because of redundancy.

Let me go ahead and\njust make this explicit.

If I had instead done\nelse return false, I

don't think it's so much redundancy\nthat I'd be worried about.

Let me bounce somewhere else.

AUDIENCE: Um, maybe\n[INAUDIBLE] for the entire list

after just checking one number.

DAVID J. MALAN: Yeah, it would\nbe returning falls for--

even though I'd only\nlooked at-- [? Nomira ?]

had only looked at one element.

And it would have been as though if\n

she opens this up and says, nope,\n

That would give me an incorrect\nresult because obviously

at that stage in the algorithm,\nshe wouldn't have even looked

through any of the other doors.

So just the original indentation\nof this, if you will

without the [? else, ?]\nis correct because only

if I get to the bottom of this\nalgorithm or the pseudo code does

it make sense to conclude\nat that point, once she's

gone through all of the doors,\nthat nope, there's in fact--

the number I'm looking for is,\nin fact, not actually there.

So how might we consider now the\nrunning time of this algorithm?

We have a few different\ntypes of vocabulary now.

And if we consider now how\nwe might think about this

let's start to translate it from\n

to something a little lower level.

We've been writing code using\nn and loops and the like.

So let's take this higher level\npseudo code and now just kind of

get a middle ground\nbetween English and C.

Let me propose that we think about\n

as being a little more pedantic.

For i from 0 to n minus 1, if number\n

Otherwise, at the end of\nthe program, return false.

Now I'm kind of mixing\nEnglish and C here

but that's reasonable if the\nreader is familiar with C

And notice this pattern here.

This is a way of just saying in pseudo\n

Start at 0 and then just\ncount up to n minus 1.

And recall n minus 1 is not one\nshy of the end of the array.

N minus 1 is the end of\nthe array because again, we

So this is a very common way\nof expressing this kind of loop

from the left all the way\nto the right of an array.

Doors I'm kind of implicitly\ntreating as the name of this array

like it's a variable from last\nweek that I defined as being

an array of integers in this case.

So doors bracket i means that\nwhen i is 0, it's this location.

When i is 7 or, more generally n minus--

sorry, 6 or, more generally, n\n

So same idea but a translation of it.

So now let's consider what the\n

If we have this menu of possible\nanswers to this question

how efficient or inefficient\nis this algorithm

let's take a look in the\ncontext of this pseudo code.

We don't even have to bother\ngoing all the way to C.

How do we go about analyzing\neach of these steps?

This outermost loop here for i from\n

is going to execute how many times?

How many times will that loop execute?

Let me give folks this\nmoment to think on it.

How many times is that\ngoing to loop here?

DAVID J. MALAN: n times, right?

Because it's from 0 to n minus 1.

And if it's a little weird to\nthink in from 0 to n minus 1

this is essentially the same\nmathematically as from 1 to n.

And that's perhaps a\nlittle more obviously more

So I might just make a note to myself\n

What about these inner steps?

Well, how many steps or seconds\ndoes it take to ask a question?

if the number you're looking\nfor is behind doors bracket i

well, as [? Nomira ?] did,\nthat's kind of like one step.

So you open the door and boom.

All right, maybe it's two steps,\n

So this is some constant\nnumber of steps.

Let's just call it one for simplicity.

How many steps or seconds\ndoes it take to return true?

I don't know exactly in\nthe computer's memory

but that feels like a single step.

So if this takes one\nstep, this takes one step

but only if the condition\nis true, it looks

like you're doing a constant\nnumber of things n times.

Or maybe you're doing\none additional step.

So in short, the only thing\nthat really matters here

in terms of the efficiency or\ninefficiency of the algorithm

is what are you doing again and again\n

the thing that's going to add up.

Doing one thing or two things\na constant number of times?

But looping, that's going to add up over\n

the bigger n is going to be and the\n

which is all to say if you\nwere to describe roughly

how many steps does this\nalgorithm take in big O notation

what might your instincts say?

How many steps is this algorithm on the\n

And indeed, that's going\nto be the case here.

Because you're essentially,\nat the end of the day

doing n things as an upper\nbound on running time.

And that's, in fact, what\nexactly what happened

with [? Nomira. ?] She had\nto look at all n lockers

before finally getting\nto the right answer.

But what if she got\nlucky and the number we

were looking for was not\nat the end of the array

but was at the beginning of the array?

How might we think about that?

Well, have a nomenclature for this\n

Remember, omega notation\nis a lower bound.

So given this menu of possible running\n

what might the omega notation be\n

DAVID J. MALAN: Omega of 1, and why that?

DAVID J. MALAN: Right, because if\njust by chance she gets lucky

and the number she's looking\nfor is right there where

she begins the algorithm, that's it.

Maybe it's two steps if you have\nto unlock the door and open it

but it's a constant number of steps.

And the way we describe\nconstant number of steps

is just with a single number like 1.

So the omega notation for linear\nsearch might be omega of 1

because in the best case, she might just\n

But in the worst case, we need to\n

So again there's this way\nnow of talking symbolically

about best cases and worst cases\n

Theta notation, just\nas a little trivia now

is it applicable based on the\ndefinition I gave earlier?

DAVID J. MALAN: OK, no, because you\n

when those two bounds,\nupper and lower, happen

to be the same for shorthand\nnotation, if you will.

So it suffices here to talk about\njust big O and omega notation.

Well, what if we are a\nlittle smarter about this?

Let me go ahead and sort\nof semi-secretly here

But first, how about\none other volunteer?

One other volunteer-- you have\nto be comfortable with your mask

and your being on the internet.

Yes, you want to come on down?

And don't look at what I'm\ndoing because I'm going to--

take your time and\ndon't look up this way

because I need a moment to\nrearrange all of the numbers.

And actually, if you could stay\nright there before coming up

just an awkward few seconds\nwhile I finish hiding the numbers

DAVID J. MALAN: I will be right with you.

Actually, if-- do you want to\nwarm up the crowd for a moment

So you want to introduce yourself?

DAVID J. MALAN: All right,\nI think I am ready.

Thank you for stalling there.

DAVID J. MALAN: And I didn't catch your name.

AUDIENCE: Rave, like a party.

So Rave has kindly volunteered now.

And I'm going to give you an\nadditional advantage this time.

DAVID J. MALAN: Unbeknownst to you, I\n

So they're not in the same\nrandom order like they

were for [? Nomira. ?]\nYou now have the advantage

to know that the numbers are\nsorted from small to big.

DAVID J. MALAN: Given that, and given perhaps\n

with the phone book, where might you\n

DAVID J. MALAN: Let's find\nnumber six this time.

Let's make things interesting.

DAVID J. MALAN: OK, so the middle.

DAVID J. MALAN: --that would be right here.

And you find, sadly, the number five.

DAVID J. MALAN: All right, and\njust to keep it uniform

just like I did, I opened to the\nright half of the phone book.

DAVID J. MALAN: Let's keep it similar.

DAVID J. MALAN: All right,\nand, uh, a little too far

even though I know you\nwanted to go one over.

AUDIENCE: All good, all good.

DAVID J. MALAN: And now we're\ngoing to go which direction?

AUDIENCE: Over here in the middle.

DAVID J. MALAN: Right, and\nvoila, the number six.

All right, so very nicely done.

A little stressful for you as well.

So here we see by nature\nof the locker door

still being open sort of an\nartifact of the greater efficiency

it would seem, of this\nalgorithm because now that Rave

was given the assumption that\n

on the left to large on the right,\n

and conquer algorithm from week zero\n

And simply by starting in\nthe middle and realizing

OK, too small, then by going to\n

went a little too far, then by\ngoing to the left half, which

Rave able to find in just\nthree steps instead of seven

the number six in this case that\nwe were actually searching for.

So you can see that this would\nseem to be more efficient.

Let's consider for just\na moment is it correct.

If I had used different numbers but\n

would it still have\nworked this algorithm?

Like, why would it still\nhave worked, do you think?

DAVID J. MALAN: Yeah, so\nso long as the numbers

are always in the same\norder from left to right

or, heck, they could even be in reverse\n

the decisions that Rave was making--\n

would guide us to the\nsolution no matter what.

And it would seem to take fewer steps.

So if we consider now the\npseudo code for this algorithm

let's take a look how we\nmight describe binary search.

So binary search we might\ndescribe with something like this.

If the number is behind the middle\n

then we can just return true.

Else if the number is\nless than the middle door

so if six is less than whatever\nis behind the middle door

then Rave would have\nsearched the left half.

Else if the number is\ngreater than the middle door

Rave would have searched the right half.

Else, if there are no doors-- and\n

this up top just to keep things clean.

If there's no doors, what should Rave\n

if I gave her no lockers to work with?

But this is an important\ncase to consider

because if in the process of\nsearching by locker by locker

we might have whittled down the\n

to one door to zero\ndoors-- and at that point

we might have had no\ndoors left to search.

So we have to naturally have a\nscenario for just considering

So it's not to say that maybe I don't\n

But as she divides and\ndivides and divides

if she runs out of lockers to ask those\n

if I ran out of phone book\npages to tear in half

I too might have had to\nreturn false as in this case.

So how can we now describe\nthis a little more like C

just to give ourselves a variable\n

Well, I might talk about\ndoors as being an array.

And so if I want to express the middle\n

I'm assuming that\nsomeone has done the math

to figure out what the middle door\n

And then doors, if the\nnumber we're looking for

is less than doors bracket\nmiddle, then search door

zero through doors middle minus 1.

So again, this is a more pedantic way of\n

search the left half,\nsearch the right half--

but start to now describe it in\n

like we did with our array notation.

The last scenario, of\ncourse, is if the number

is greater than the\ndoor's bracket middle

then Rave would have wanted to\nsearch the middle door plus 1--

so 1 over-- through doors n minus 1--

So again, just a way of sort of\n

So how might we translate\nthis now into big O notation?

Well, in the worst case, how many\n

Given seven doors or given\nmore generically n doors

how many times could she go left or go\n

What's the way to think about that?

And even if you're not feeling wholly\n

still, pretty much in programming and\n

any time we talk about some algorithm\n

in half, in half, in half,\nor any other multiple

it's probably involving\nlogarithms in some sense.

And log base n essentially\nrefers to the number

of times you can divide n by 2 until\n

or equivalently zero doors left.

So we might say that indeed,\nbinary search is in big O of log n

because the door that Rave\nopened last, this one

happened to be three doors away.

And actually, if you do\nthe math here, that roughly

works out to be exactly that case.

If we add one, that's sort of out\n

we were able to search it\nin just three total steps.

What about omega notation, though?

Like, in the best case, Rave\nmight have gotten lucky.

She opened the door, and there it is.

So how might we describe a lower bound\n

So here too, we see that in some cases\n

like, they're pretty equivalent.

And so this is why sometimes\n

case in the worst case\nbecause honestly, in general

who really cares if you just\nget lucky once in a while

and your algorithm is super fast?

What you probably care about\nis what's the worst case.

how long am I going to be sitting\n

or beach ball trying to give myself\n

Well, odds are, you're going to\n

So indeed, moving\nforward, will generally

talk about the running time of\n

a little less so in terms of omega.

But understanding the\nrange can be important

depending on the nature of the data that\n

All right let me pause and\nsee if there is any questions.

AUDIENCE: So this method\nis clearly more efficient

but it requires that the information\n

How do you ensure that you\ncan compile information

in a particular order at scale?

DAVID J. MALAN: Yeah, it's\na really good question.

And if I can generalize it, how do\n

at scale, which algorithm is better?

I've sort of led us down\nthis road of implying

that Rave's second\nalgorithm, binary search

is better because it's so much faster.

It's log of n in the worst\ncase instead of big O of n.

But Rave was given an advantage when\n

And so that sort of\ninvites the question

well, given a whole\nbunch of random data

either a small data set or, heck,\n

billions of pieces of data,\nshould you sort it first

from smallest to\nlargest and then search?

Or should you just dive right\nin and search it linearly?

Like, how might you think about that?

If you are Google, for\ninstance, and you've

got millions, billions of web pages,\n

because it's always going to work\neven though it might be slow?

Or should they invest the time\nin sorting all of that data--

and then search it more efficiently?

Like, how do you decide\nbetween those options?

AUDIENCE: If you're sorting\nthe data, then wouldn't you

have to go through all of the data?

DAVID J. MALAN: Yeah, if you had\nto sort the data first--

and we don't yet formally\nknow how to do this.

But obviously, as humans, we\ncould probably figure it out.

You do have to look at\nall of the data anyway.

And so you're sort of wasting your\n

But maybe it depends a bit more.

Like, that's absolutely\nright, and if you're just

searching for one thing in life,\n

to sort it and then search it because\n

But what's another scenario\nin which you might not

worry about that whereby it might\n

AUDIENCE: [INAUDIBLE] you can go\n

to find out what's happening.

DAVID J. MALAN: Yeah, exactly.

So if your problem is a\nGoogle-like problem where

you have more than just one user\n

website page, probably you\nshould incur the cost up front

and sort the whole thing because\n

is going to be faster,\nfaster, faster because it's

going to [INAUDIBLE] algorithm of binary\n

that's going to add up\nto be way fewer steps

than doing linear search multiple times.

So again, kind of\ndepends on the use case

and kind of depends on\nhow important it is.

And this happens even\nin real world contexts.

I think back always to graduate\n

to analyze some large data set.

And honestly, it was actually\neasier at the time for me

to write pretty inefficient\nbut hopefully correct

code because you know what?

I could just go to sleep for eight hours\n

I didn't have to bother writing\n

to run it more efficiently.

Because I was the only user, and I\n

And so this was kind of\na reasonable approach

reasonable until I woke up eight\n

And now I had to spend another eight\n

But even there, you\nsee an example where

what is your most precious resource?

Is it time to write the code?

Is it the amount of memory\nthe computer is using?

These are all resources we'll start\n

depends on what your goals are.

Any questions, then, on\nupper bounds, lower bounds

or each of these two\nsearches, linear or binary?

AUDIENCE: So just, when you're\ncalculating running time

does the sorting step\ncount for that time?

DAVID J. MALAN: When analyzing running\n

If you want it to if you actually do it.

At the moment, it did not apply.

I just gave Rave the luxury of\nknowing that the data was sorted.

But if I really wanted to charge\nher for the amount of time

it took to find that number six,\nI should have added the time

to sort plus the time to search.

And in fact, that's\na road we'll go down.

Why don't we go ahead and\npace ourselves as before?

Let's take a 10 minute break here.

And when we come back, we'll\nwrite some actual code.

So we've seen a couple of searches--\n

to be fair, we saw back in week zero.

But let's actually translate at\n

using this building block from\nlast week where we can actually

define an array if we want, like an\n

So let me switch over to VS Code here.

Let me go ahead and start\na program called numbers.c.

And in numbers.c, let me go ahead here.

And how about let's include\nour familiar header files?

I'll include standardio.h that we can\n

And now I'm going to go ahead\nand give myself int main void.

No command line arguments today.

So I'll leave that as void.

And I'm going to go\nahead and give myself

an array of how about seven numbers?

So I'll call it int number 7.

And then I can fill\nthis array with numbers.

Like, numbers brackets 0 can be\n

could be the number 6, and numbers\n

And this is the same list that\nwe saw with [? Nomira ?] a bit

ago where it was 4, then 6, then 8.

There's actually another\nsyntax I can show you here.

If you know in advance\nin a C program that you

want an array of certain values and you\n

you want, you can actually do this\n

You can say, don't worry\nabout how big this is.

It's going to be implicit by\nway of these curly braces.

Here, I can do 4, 6, 8, 2,\n7, 5, 0, close curly brace.

So it's a somewhat new\nuse of curly braces.

But this has the effect of giving\n

of which are a whole bunch of integers.

The compiler can infer it from what's\n

And it seems to be of\nsize 1, 2, 3, 4, 5, 6, 7.

And all seven elements will be\n

So just a minor optimization\ncode wise to tighten up

what would have otherwise been\n

Now let's go ahead and implement\nlinear search, as we called it.

And you can do this in a bunch of\n

For int i get 0, i is\nless than 7 i plus plus.

Then inside of my loop, I'm\ngoing to ask the question, well

if the numbers at location i\nequals equals, as we asked of

[? Nomira, ?] the number 0, then I'm\n

like printf found backslash n.

And then I'm going to return 0.

Just because of last week's\ndiscussion of returning

a value for main when all is well,\n

just to signal that indeed,\nI found what I'm looking for.

Otherwise, on what line do I want to\n

and return something other than 0?

Right, I don't think I want an else\n

So on what line would you prefer I\n

of not found and I'll return an error?

So at the end of the\nfor loop because you

want to give the\nprogram or our volunteer

earlier a chance to go through all\n

But if you go through the whole\nthing, through the whole loop

at the very end, you probably just\n

and then return\nsomething like positive 1

just to signify that an error happened.

And again, this was a\nminor detail last week.

Any time main is successful, the\n

And if something goes wrong, like you\n

you might return something other than\n

or even negative numbers if you want.

All right, well, let me\ngo ahead and save this.

All right, and it's found,\nas I would hope it would be.

And just as a little check, let's\n

not there, like the number negative 1.

Let me go ahead and recompile\nthe code with make numbers.

Let me rerun the code\nwith dot slash numbers

and hopefully-- whew, OK, not found.

So proof by example seems\nto be working correctly.

But let's make things a\nlittle more interesting now.

Right now, I'm using just\nan array of integers.

Let me go ahead and introduce\nmaybe an array of strings instead.

And maybe this time, I'll store a\n

but actual strings of names.

Well, let me go back to my code here.

I'm going to switch us over to\nmaybe a file called names.c.

And in here, I'll go\nahead and include cs50.h.

And I'm going to go ahead and\nfor now include a new friend

from last week, string.h, which gives\n

Int main void because I'm not going\n

And now if I want an array of strings,\n

And then I could start\ndoing like before.

Names bracket 0 could be someone\nlike Bill, and names bracket 1

could be someone like\nCharlie and so forth.

But there's this new\nimprovement I can make.

Let me just let the compiler figure\n

And using curly braces, I'll do Bill\n

George and then Ginny and then Percy and\n

All right, so now I have\nthese seven names as strings.

i is less than 7 as before,\ni plus plus as before.

And inside of the, loop lets this\n

and suppose we're searching\nfor Ron arbitrarily.

He is there, so we should\neventually find him.

Let me go ahead and say if names bracket\n

of my if condition, I'm going to\n

And I'm going to return 0\njust because all is well.

And I'm going to take your\nadvice from the get go this time

and, at the end of the loop, print out\n

I have not printed found, and\nI have not returned already.

So I'm just going to go ahead and\n

All right, let me go ahead and\ncross my fingers as always.

And it doesn't seem\nto like my code here.

This is perhaps a new\nerror that you might not

have seen yet in names.c line 11.

So that's this line\nhere, my if condition.

Result of comparison against a\nstring literal is unspecified.

Use an explicit string\ncomparison function instead.

I mean, that's kind of a mouthful,\n

you're probably not going to\nknow how to make sense of that.

But it does kind of draw our\nattention to something being awry

with the equality checking\nhere, with equal equals and Ron.

And here's where again\nwe've been telling

sort of a white lie for\nthe past couple of weeks.

Strings are a thing in C. Strings\nare a thing in programming.

But recall from last\nweek, I did disclaim

there's no such thing\nas a string data type

technically because it's not\na primitive in the way an int

and a float and a bool are that are\n

You can't just use equation\nequals to compare two strings.

You actually have to use\na special function that's

in this header file we talked\nbriefly about last week.

In that header file was\nstring length or strlen.

But there's other\nfunctions instead as well.

Let me, in fact, go ahead\nand open up the manual pages.

In string.h you can perhaps infer\n

the place of equals equals for today.

DAVID J. MALAN: So strcmp, S-T-R-C-M-P,\n

And if I click on that,\nwe'll see more information.

And indeed, if I click on strcmp,\nwe'll see under the synopsis

that, OK, I need to use the CS50 header\n

Here is its prototype,\nwhich is telling me

that strcmp takes two\nstrings, S1 and S2, that

are presumably going to be compared.

And it returns an integer,\nwhich is interesting.

The description of this function is\n

So uppercase or lowercase\nmatters, just FYI.

And then let's look it\nthe return value here.

The return value of this function\nreturns an int less than 0

if S1 comes before S2, 0 if S1 is the\n

So the reason that this function\n

bool, true or false, is\nthat it actually will

allow us to sort these things\n

if two strings come in this order or\n

you need three possible return values.

And a bool, of course,\nonly gives you two

but an int gives you like 4 billion\n

So 0 or a positive number or a negative\n

And the documentation goes on to explain\n

Recall that capital A\nis 65, capital B is 66

and it's those underlying\nASCII or Unicode

numbers that a computer uses to figure\n

or after it like in the dictionary.

But for our purposes now,\nwe only care about equality.

So I'm going to go ahead and do this.

If I want to compare names\nbracket i against Ron

I use stir compare or strcmp, names\n

So it's a little more\ninvolved than actually

using equals equals, which\ndoes work for integers, longs

But for strings, it turns out we\n

Well, last week, recall\nwhat a string really is.

It's an array of characters.

And so whereas you can use equals\nequals for single characters

strcmp, as we'll\neventually see, is going

to compare multiple characters for us.

There's a loop needed, and that's\n

But it doesn't just work out of\n

That would literally be comparing\n

And we'll come back to\nthis next week as to what's

really going on under the hood.

So let me go ahead and fix one\nbug that I just realized I made.

I want to check if the return\nvalue of str compare is equal to 0

because per the documentation,\nthat meant they're the same.

All right, let me go ahead\nand make names this time.

Dot slash names, Enter, found.

And just as a sanity check, let's\n

Searching now for Hermione\nafter recompiling the code

And she's not, in fact, found.

So here's just a similar\nimplementation of linear search

not for integers this time\nbut instead for strings

the subtlety really being we need\n

to actually do the legwork for us of\n

All right, questions on either of these\n

AUDIENCE: So, if I do [INAUDIBLE]

DAVID J. MALAN: Ah, good question.

If I had not fixed what I claimed was\n

and we saw an example of\nthis last week, actually.

If a function returns an integer,\n

when you get back 0, the\nexpression, the Boolean expression

If a function returns any positive\n

that's going to be\ninterpreted as true even

if it's positive or negative, whether\n

And so if I did this, this\nwould be saying the opposite.

So if I were to say this, if str compare\n

implicitly like saying this does not\n

but you don't want to check\nfor true because, again, we're

So the reason I did 0\nhere in this case is

that it explicitly checks for the return\n

DAVID J. MALAN: Yes, you might\nnot have seen this yet

but you can express the\nequivalent because if you

want to check if this is\nfalse, you can actually

use an exclamation point,\nknown as a bang in programming

So false becomes true,\ntrue becomes false.

So this would be another\nway of expressing it.

This is arguably a worse design, though,\n

says you should be checking\nfor 0 or a positive value

or a negative value, and this\nlittle trick, while correct

and I think you can make a reasonable\n

And I would argue instead\nfor the first way

checking for equals equals 0 instead.

And if that's a little\nsubtle, not to worry.

We'll come back to little syntactic\n

Other questions on linear\nsearch in these two forms.

Is there another hand or hands?

OK, just holler if I missed.

So let's now actually take\nthis one step further.

Suppose that we want to write a\n

a little more like a phone book that\n

just integers but actual phone numbers.

Well, we could escalate\nthings like this.

We could now have two arrays-- one\n

And I'm going to use\nstrings for the numbers now

the phone numbers, because\nin most communities

phone numbers might have dashes,\n

that really looks more like a string\n

Probably don't want to use an int lest\n

So let me switch back to VS Code here,\n

in a file called phonebook.c.

And now let me go ahead and do the same.

Let me include standardio.h,\nand let me include string.h.

I'm going to again do int main void.

And then inside of my program, I'm\n

String names will be\njust two of us this time.

And then I'll give myself--\noops, typo already.

If I want this to be an array, I\n

The compiler can count for me.

But I do need the square brackets.

Then for numbers, I'm again going to\n

the curly braces that how about\nCarter can be at 1-617-495-1000.

And how about my own number here--

1-949-468-- oh pattern appearing--

Well, I'm just kind of lined things up.

So Carter's number is\napparently first in this array

and I'm claiming that he'll be\n

I, David, will be the first--\nthe second in the names array

and second in the numbers array.

If you want to have a little fun\n

or call me some time at that number.

So now let's actually use\nthis data in some way.

Let's go ahead and actually search\n

There's two of us this time-- so i less\n

And now I'm going to practice\nwhat I preached earlier

and I'm going to use str compare\nto find my name in this case.

And I'm going to say if strcmp of names\n

and that equals 0,\nmeaning they're the same

then just as before, I'm going to\n

But this time, I'm going to\nmake the program more useful

and not just say found or not found.

Now I'm implementing a phone book, like\n

So I'm going to say something\nlike, quote unquote, found percent

s backslash n and then actually\nplug in numbers bracket i

to correspond to the\ncurrent name bracket i.

And then I'll return 0 as before.

And then down here if we get\nall the way through the loop

and David's not there for some reason,\n

So let me go ahead and compile this\n

and it seems to have found the number.

So this code I'm going\nto claim is correct.

It's kind of stupid because I've\n

app that only supports two people.

They're only going to be me and Carter.

This would be like downloading\nthe contacts app on a phone

and you can only call\ntwo people in the world.

There's no ability to\nadd names or edit things.

That, of course, could come later\n

But for now for the\nsake of discussion, I've

just hardcoded two\nnames and two numbers.

But for what it does, I\nclaim this is correct.

It's going to find me\nand print out my number.

Let's start to now consider if\nwe're not just using arrays

but are we using them, well?

We started to use them last week,\n

And what might I even mean by\nusing an array well or designing

Any critiques or concerns\nwith why this might not

be the best road for us\nto be going down when

I want to implement something like a\n

It seems all too vulnerable\nto just mistakes.

For instance, if I screw up the actual\n

such that it's now more or less than\n

it feels like there's not a tight\n

of data, and it's just sort of\nis trusting on the honor system

that any time I use names bracket i\n

If you're the one writing\nthe code, you're probably

not going to really screw this up.

But if you start collaborating\nwith someone else or the program

is getting much, much longer, the\n

remember that you're sort of just\n

like this is going to fail eventually.

Someone's not going to realize that,\n

And you're going to start out putting\n

is to say it'd be much nicer if\n

pieces of data, names and numbers,\n

that you're not just trusting that\n

and numbers, have this kind of\nrelationship with themselves.

So let's consider how\nwe might solve this.

A new feature today that we'll introduce\n

In C, we have the ability to\ninvent our own data types

if you will-- data types\nthat the authors of C decades

ago just didn't envision\nor just didn't think

were necessary because we can implement\n

just as you could create\ncustom puzzle pieces

or in C, you can create\ncustom functions.

So in C, can you create\nyour own types of data

that go beyond the built in ints\nand floats and even strings?

You can make, for instance, a\n

type in the context of\nelections or a person data type

more generically that might\nhave a name and a number.

Well, let me go here and propose\n

wouldn't it be nice if we\ncould have a person data type

and then we could have\nan array called people?

And maybe that array is our\nonly array with two things

But somehow, those data\ntypes, these persons

would have both a name and a\nnumber associated with them.

So we don't need two separate arrays.

We need one array of persons,\na brand new data type.

Well, if we want every\nperson in the world

or in this program to\nhave a name and a number

we literally right out\nfirst those two data types.

Give me a string called name.

Give me a string called\nnumber semicolon, after each.

And then we wrap that,\nthose two lines of code

with this syntax, which at first\nglance is a little cryptic.

It's a lot of words all of a sudden.

But typedef is a new keyword today\nthat defines a new data type.

This is the C key word that\nlets you create your own data

type for the very first time.

Struct is another related key word that\n

a simple data type, like an int or a\n

It's got some dimensions to it, like\n

or even 50 things inside of it.

The last word down here is the name\n

and it weirdly goes\nafter the curly braces.

But this is how you invent\na data type called person.

And what this code is\nimplying is that henceforth

the compiler clang will know that a\n

a string and a number that's a string.

And you don't have to worry\nabout having multiple arrays now.

You can just have an array\nof people moving forward.

So how can we go about using this?

Well, let me go back to\nmy code from before where

I was implementing a phone book.

And why don't we enhance the\nphone book code a little bit

by borrowing some of that new syntax?

Let me go to the top of\nmy program above main

and define a type that's\na structure or a data

structure that has a name inside of\n

And the name of this new structure\n

Inside of my code now, let me go ahead\n

Let me give myself an array\ncalled people of size 2.

And I'm going to use the\nnon-terse way to do this.

I'm not going to use the curly braces.

I'm going to more pedantic spell out\n

at location 0, which is the\nfirst person in an array

because you always start counting at 0.

I'm going to give that person\na name of quote unquote Carter.

And the dot is admittedly one\nnew piece of syntax today too.

The dot means go inside\nof that structure

and access the variable called\n

Similarly, if I'm going\nto give Carter a number

I can go into people bracket 0 dot\n

as before plus 1-617-495-1000.

And then I can do the\nsame for myself here--

people bracket-- where should I go?

OK, one because again, two elements.

But we started counting at zero.

Bracket name equals quote unquote David.

And then lastly, people bracket 1\n

So now if I scroll\ndown here to my logic

I don't think this part\nneeds to change too much.

I'm still, for the sake of discussion,\n

is 0 on up to but not through 2.

But I think this line\nof code needs to change.

How should I now refer to the\ni-th person's name as I iterate?

What should I compare quote\nunquote David to this time?

AUDIENCE: People bracket i dot name.

DAVID J. MALAN: Yeah, people\nbracket i dot name.

Because people is the name of the array.

Bracket i is the i-th person that we're\n

first zero, then one, maybe\nhigher if it had more people.

Then dot is our new syntax for\ngoing inside of a data structure

and accessing a variable therein\nwhich in this case is name.

And so I can compare\nDavid just as before.

So it's a little more verbose, but\n

because now these people are full\n

There's no more honor\nsystem inside of my loop

that this is going to line\nup because in just a moment

I'm going to fix this one last\nremnant of the previous version.

And if I can call back on\nyou again, what should I

change numbers bracket i to this time?

AUDIENCE: [INAUDIBLE] dot number.

DAVID J. MALAN: Dot number, exactly.

So gone is the honor\nsystem that just assumes

that bracket i in this array lines up\n

It's an array called people.

The things it stores are persons.

A person has a name and a number.

And so even though it's kind\nof marginal admittedly given

that this is a short program and\n

look more complicated\nat first glance, we're

now laying the foundation for just\n

can't screw up now the\nassociation of names

with numbers because every person's\n

encapsulated inside\nof the same data type.

And that's a term of art in CS.

Encapsulation means to\nencapsulate-- that is, contain--

related pieces of information.

And thus, we have a person that\n

And this just sets\nthe foundation for all

of the cool stuff we've talked\nabout and you use every day.

Well, recall that an image is a bunch\n

Every one of those dots\nhas RGB values associated

with it-- red, green, and blue.

You could imagine now creating\na structure in C probably where

maybe you have three values,\nthree variables-- one called red

one called green, one called blue.

And then you could name the\nthing not person but pixel.

And now you could store in C three\n

some green, some blue-- and collectively\n

And you could imagine doing something\n

Music, you might have three\n

the duration, the loudness of it.

And you can imagine coming up with\n

So this is a little low level.

We're just using like a\nfamiliar contacts application.

But we now have the way in code\nto express most any type of data

that we might want to implement\nor discuss ultimately.

So any questions now on struct\nor defining our own types

the purposes for which are to use\n

now in a better design but\nalso to lay the foundation

for implementing cooler and cooler\n

AUDIENCE: What's the [INAUDIBLE]

DAVID J. MALAN: What's the difference\n

So slight side note, C\nis not object-oriented.

Languages like Java and C++ and\n

of, programmed yourself, had friends\n

languages in those languages they have\n

And objects can store not\njust data, like variables.

Objects can also store functions, and\n

But it's not sort of conventional.

In C, you have data\nstructures that store data.

In languages like Java and C+, you have\n

Python is an object-oriented\nlanguage as well.

So we'll see this issue in a few weeks,\n

AUDIENCE: Could you\nuse this [INAUDIBLE]??

Could you use this struct to\nredefine how an int is defined?

We talked a couple of times\nnow about integer overflow.

And most recently, you might have seen\n

that was literally related\nto an int overflow.

That's the result of ints only\nstoring 4 bytes or 32 bits

or even as long as 64 bits or 8 bytes.

But if you want to implement\nsome financial software

or some scientific or\nmathematical software that

allows you to count way bigger\nthan a typical int or a long

you could imagine John coming\nup with your own structure.

And in fact, in some\nlanguages there is a structure

called big int, which allows you\nto express even bigger numbers.

Well, maybe you store inside of\na big ant an array of values.

And you somehow allow yourself\nto store more and more bits

based on how high you\nwant to be able to count.

We now have the ability now to do\n

even if it's not built in for us.

DAVID J. MALAN: Could you define a name\n

It starts to get\nsyntactically a little messy

so I did it a little more\npedantic line by line.

AUDIENCE: [INAUDIBLE] function\nyou use for the function

at the bottom of the [INAUDIBLE].

Could you do something\nlike that [INAUDIBLE]??

DAVID J. MALAN: Prototypes--\nyou have to do A and C. You

have to define anything you're going\n

to use before you actually use it.

So it is deliberate that I put it\n

Otherwise, the compiler would not know\n

use it here on what's line 14.

So it has to come first, or it has to\n

so that you include it at\nthe very top of your code.

DAVID J. MALAN: Yeah, good\nquestion, and we'll

come back to this later in the term when\n

and storing things in actual databases.

Generally speaking, even though we\n

or in the US, we have social security\n

often have other punctuation in it,\n

You could not store any of that syntax\n

You could only store numbers.

So one motivation for\nusing a string is just

I can store whatever the human wanted\n

Another reason for\nstoring things as strings

even if they look like\nnumbers, is in the context

of zip codes in the United States.

Again, we'll come back to this.

But long story short--\nyears ago, actually--

I was using Microsoft\nOutlook for my email client.

And eventually I switched to Gmail.

And this is like 10 plus years ago now.

And Outlook at the time lets you export\n

More on that in the weeks to come too.

And that just means I\ncould download a text

file with all of my friends and\n

Unfortunately, I open that same CSV\n

just to kind of spot\ncheck it and see if what's

in there was what it was expected.

And I must have instinctively hit,\n

And Excel at least has this habit\n

If things look like numbers,\nit treats them as numbers.

And Apple Numbers does this too.

Google Spreadsheets\ndoes this to nowadays.

But long story short, I then imported\n

And now 10 plus years later, I'm still\n

members whose zip codes are in\nCambridge, Massachusetts 2138

which is missing the 0 because\nwe here in Cambridge are 02138.

And that's because I\ntreated or I let Excel

treat what looks like a number\nas an actual number or int

and now leading zeros become a\n

mean nothing, but in the\nmail system, they do--

All right, other final questions here.

DAVID J. MALAN: Yeah, so could I have\n

array to solve the problem\nearlier of having just one array?

Yes, but one, I would argue\nit's less readable, especially

as I get lots of names and numbers.

And two, that too is also kind\nof relying on the honor system.

It would be all too easy to omit some\n

So I would argue it too is not\nas good as introducing a struct.

Two dimensional arrays just means\n

All right, so now that\nwe have this ability

to store different types of data\nlike contacts in a phone book

having names and\naddresses, let's actually

take a step back and\nconsider how we might now

solve one of the original problems by\n

given in advance and considering,\n

costly, how time consuming is\nthat because that might tip

the scales in favor of sorting,\nthen searching, or maybe just

not sorting and only searching.

It'll give us a sense of just\nhow expensive, so to speak

sorting something actually is.

Well, what's the\nformulation of this problem?

It's the same thing as week zero.

We want it to be output as sorted.

So for instance, if we're\ntaking unsorted input as input

we want the sorted output as\nthe result. More concretely

if we've got numbers like these--

63852741, which are just\nrandomly arranged numbers--

we want to get back out 12345678.

So we just want those\nthings to be sorted.

So again, inside of\nthe black box here is

going to be one or more algorithms\n

So how might we go about doing this?

Well, just to vary things a bit\n

for a bit more audience participation.

But this time, we need\neight people if we may.

All of you have to be comfortable\nappearing on the internet.

OK, so this is actually quite\n

How about 1, 2, 3, 4, 5, 6, 7--

oh, OK, and someone volunteering\ntheir friend-- number eight.

And if you could, I'm\ngoing to set things up.

If you all could join Valerie,\nmy colleague over there

to give you a prop to use here,\nwe'll go ahead in just a moment

and try to find some numbers at hand.

In just a moment, each of our volunteers\n

And that integer is initially\ngoing to be in unsorted order.

And I claim that using an algorithm,\nstep by step instructions

we can probably sort these folks in\n

So they're in wardrobe right now just\n

with a Jersey number on it, which will\n

Give us just a moment to finish\ngetting the attire ready.

They're being handed\na shirt and a number.

And let me ask the\naudience for just a moment.

As we have these numbers up here on the\n

They're just in random order.

And let me ask the audience.

How would you go about sorting\n

How would you go about sorting these?

Yeah, what are your thoughts?

AUDIENCE: [INAUDIBLE] the number\n

AUDIENCE: The following number is\n

AUDIENCE: If not, then [INAUDIBLE].

DAVID J. MALAN: OK, so just\nto recap, you would start

with one of the numbers on the end.

You would look to the number to\nthe right or to the left of it

depending on which end you start at.

And if it's out of order, you\nwould just start to swap things.

There's a whole bunch\nof mistakes to fix here

because things are pretty out of order.

But probably, if you start to\nsolve small problems at a time

you can achieve the end result of\n

Other instincts, if you were\njust handed these numbers, how

you might go about sorting them?

DAVID J. MALAN: OK, I like that.

So to recap there, find the smallest\n

And then presumably, you could do\n

And that would seem to give you\n

And if you all are attired here--

do you want to come\non up if you're ready?

We had some [? felt ?] volunteers too.

So if you all would like\nto line yourselves up

facing the audience in\nexactly this order-- so

whoever is number zero\nshould be way over here

and whoever is number five\nshould be way over there.

Feel free to distance as much as you'd\n

And make a little more room.

DAVID J. MALAN: 4, hopefully 1.

Yeah, keep them to the side.

All right, so here, we have\nan array of eight numbers--

eight integers if you will.

And do you want to each say\na quick hello to the group?

AUDIENCE: Hi, I'm\nCeleste, and go Strauss.

Well, welcome all to the stage,\nand let's just visualize

perhaps organically, how you\neight would solve this problem.

So we currently have the numbers\n0 through 7 quite out of order.

Could you go ahead and just\nyourselves from 0 through 7?

DAVID J. MALAN: OK, so what did they just do?

First of all, yes, very well done.

How would you describe\nwhat they just did?

Could you go back into\nthat order on the screen--

And could you do exactly\nwhat you just did again?

All right, so admittedly, there's kind\n

except number four, are doing something\n

And that's not really how\na computer typically works.

Just like a computer can only look at\n

at a time, so can a computer only move\n

a locker, checking what's\nthere, moving it as needed.

So let's try this more methodically\n

If you all could randomize\nyourself again to 52741630

let's take the second of\nthose approaches first.

I'm going to look at these numbers.

And even though I as the human\ncan obviously see all the numbers

and I just kind of have the\nintuition for how to fix this

we got to be more methodical\nbecause eventually, we've

got to translate this to\npseudo code and then code.

I'm going to search for, as you\nproposed, the smallest number.

And I'm going to start\nfrom left to right.

I could do it right to left, but left\n

All right, 5 at this moment is\nthe smallest number I've seen.

So I'm going to remember that\nin a variable, if you will.

Now I'm going to take one more step--

OK, 2 I'm going to compare to the\n

I'm going to forget about 5 and only\n

7, nope-- I'm going to ignore that\n

4, 1-- OK, I'm going to\nupdate the variable in mind

because that's indeed smaller.

Now obviously, we the humans\nknow that's getting pretty small.

I have to check all values to see\n

because 6 is not, 3 is not, but 0 is.

And what's your name again?

Where should Celeste or number 0 go\n

All right, I'm seeing a lot of this.

So at the beginning of the array,\nso before doing this for real

let's have you pop out in front.

And could you all shift\nand make room for Celeste?

Is this a good idea to have all\nof them move or equivalently

move everything in the array\nto make room for Celeste

That felt like a lot of work.

And even though it happened pretty\n

to happen just to move her in place.

So what would be marginally\nsmarter perhaps--

a little more efficient, perhaps?

DAVID J. MALAN: OK, replace two values.

So if you want to go back to where\n

he's not in the right place.

He's got to move eventually.

If that's where Celeste belongs,\nwhy don't we just swap 5 and 0?

So if you want to go ahead and\nexchange places with each other.

Notice what's just happened.

The problem I'm trying to\nsolve has gotten smaller.

Instead of being size\n8, now it's size 7.

Now granted, I moved 5 to\nanother wrong location.

But if these numbers\nstarted off randomly

it doesn't really matter where 5 goes\n

And now if I go back, my loop\nis sort of coming back around.

I can ignore Celeste and make this\n

because I know she's in the right place.

Now I know as a human this\nshould be my next smallest.

But why, intuitively, should\nI keep going, do you think?

I can't sort of optimize as a\nhuman and just say, number 1

let's get you into the right place.

I still want to check the whole array.

AUDIENCE: Perhaps there's another 1.

DAVID J. MALAN: Maybe there's\nanother 1, and that

could be another problem altogether.

AUDIENCE: Could be another 0

DAVID J. MALAN: There could\nbe another 0 indeed

but I did go through\nthe list once, right?

And I kind of know there isn't.

AUDIENCE: You don't know that\nevery value is represented.

So maybe there's a [INAUDIBLE] You\n

DAVID J. MALAN: Yeah, I don't\nnecessarily know what is there.

And honestly, I only stipulated earlier\n

I could use two and remember the\n

I could use three variables, four.

But then I'm going to start to use\n

So if I've stipulated that I only have\n

I don't know anything\nmore about these elements

because the only thing I'm\nremembering at this moment

is number 1 is the\nsmallest element I've seen.

OK, I know that number\n1, and your name was--

DAVID J. MALAN: --Hannah is\nthe next smallest element.

I could have everyone move\nover to make room, but nope.

You know, even though you're\nso close to where I want you

I'm just going to keep it\nsimple and swap you two.

So granted, I've made the\nproblem a little worse.

But on average, I could get\nlucky too and just pop number 2

Now let me just accelerate this.

I can now ignore Hannah and Celeste,\n

So let's go ahead and swap 2 and 7.

And now I'll just kind of\norchestrate it verbally.

4, you're about to have to do something.

OK, 3-- could you swap with 4?

All right, now we have 7, 6, 4, 5.

OK, 4, could you swap with 7?

And now perhaps round of applause.

OK, hang on there one minute.

So we'll do this one other approach.

And my God, that felt so much\nslower than the first approach

but that's, one, because I was\n

But two, we were doing one thing at a\n

had the luxury of moving\nlike eight different CPUs--

brains, if you will-- were all\noperating at the same time.

And computers like that exist.

If you have a computer with\nmultiple cores, so to speak

that's like having a\ncomputer that technically

can do multiple things at once.

But software typically, at least\nas we've written it thus far

can only do one thing at a time.

So in a bit, we'll add\nup all of these steps.

But for now, let's take\none other approach.

If you all could reorder\nyourselves like that--

52741630-- let's take\nthe other approach that

was recommended by just fixing small\n

So we're back in the original order.

5 and 2 are clearly out of order.

Let's just bite this problem off now.

Now let me take a next step.

There's a gap, yes, but that\nmight not be a big deal.

OK, 7 and 1, let's have you swap.

7 and 6, let's have you swap.

Now let me pause for just a moment.

But have I improved the problem?

Right, I can't see-- like\nbefore, I can't optimize like

before because 0 is obviously not here.

So unless they're still way back there,\n

But have I made any improvements?

In what sense is this improved?

What's a concrete thing you\ncould point to is better?

AUDIENCE: Sorted the highest number.

DAVID J. MALAN: I've sorted the\n

And conversely, if you prefer, Celeste\n

Now worst case, Celeste is going to\n

So I might need to do this\nthing like n total times

to move her all the way over.

But that might work out OK.

notice that the high\nvalues, as you noted

are sort of bubbling up, if you\nwill, to the end of the list.

5, 6, 7, of course, are good.

So now you can sort of see\nthe problem resolving itself.

And let's just do this part now faster.

All right, now 1 and 2,\n2, and 3, and 0, and good.

So we do have some optimization there.

We don't need to keep going\nbecause those all are sorted.

1 and 0-- and big round\nof applause in closing.

We need the puppets back,\nbut you can keep the shirts.

Thank you for volunteering here.

Feel free to make your\nway exits left or right.

And let's see if,\nthanks to our volunteers

here, we can't now formalize a little\n

I claim that the first algorithm\nour volunteers kindly acted out

is what's called selection sort.

And as the name implied, we selected\n

and again, working our\nway from left to right

putting Celeste into the right place,\n

So selection sort, as\nit's formally called

can be described, for instance,\nwith this pseudo code here--

This is just how talk about arrays.

The left end is 0, the right end\n

n happened to be eight people.

So for i from 0 to n\nminus 1, what did I do?

I found the smallest number between\n

It's a little cryptic at\nfirst glance, but this

is just a very pseudo\ncode-like way of saying

find the smallest element\namong all eight volunteers

because if i starts at 0 and n minus\n

8, 8 people, so 8 minus\n1 is 7, this first

says find the smallest number\nbetween numbers bracket 0

and numbers bracket 7, if you will.

Swap the smallest number\nwith numbers bracket i.

So that's how we got Celeste from\n

We just swapped those two values.

What then happens next\nin this pseudo code?

i, of course, goes from 0 to 1.

And that's the technical\nway of saying now

find the smallest element among\nthe 7 remaining volunteers

ignoring Celeste this time because she\n

So the problem went\nfrom size 8 to size 7.

And if we repeat, size 6,\n5, 4, 3, 2, 1, until boom

it's all done at the very end.

So this is just one way of\nexpressing in pseudo code what

we did a little more organically\n

volunteered out in the audience.

So if we consider, then, the\nefficiency of this algorithm

maybe abstracting it away\nnow as a bunch of doors

where the left most again is always\n

or equivalently, the second to last\n

is n minus 3 where n might\nbe 8 or anything else

how do we think about or quantify\n

I mean, that was a lot\nof steps to be adding up.

It's probably more than n, right,\n

It was like n plus n\nminus 1 plus n minus 2.

We got like the whole\nteam in the orchestra now.

Let me propose we think about it this\n

So the first time, I had to\nlook at n different volunteers.

n was 8 in this case, but generically,\n

in order to decide who was the smallest.

And sure enough, Celeste\nwas at the very end.

She happened to be all\nthe way to the right.

But I only knew that once I looked\nat all 8 or all n volunteers.

So that took me n steps first.

But once the list was swapped\ninto the right place, then

my problem with size n minus 1,\nand I had n minus 1 other people

Then after that, it's n minus 2 plus\n

dot until I had one final step.

And it's obvious that I only\nhave one human left to consider.

So we might wave our hands at\nthis with a little ellipsis

and just say dot dot dot\nplus 1 for the final step.

Now what does this actually equal?

Well, this is where you\nmight think back on, like

your high school math\nor physics textbook that

has a little cheat sheet at the end\n

That happens to work\nout mathematically to be

n times n plus 1 all divided by 2.

That's just what that recurrence,\n

So if you take on faith that\nthat math is correct, let's

just now multiply this\nout mathematically.

That's n squared plus n divided by 2 or\n

And here's where we're starting\n

Like, honestly, as n gets really\n

or a billion web pages in Google search\n

is going to matter the\nmost mathematically

Is n squared divided by\n2 the dominant factor

or is n divided by 2\nthe dominant factor?

DAVID J. MALAN: Yeah, n squared.

I mean, no matter what n\nis-- and the bigger it is

the bigger raising it to\nthe power 2 is going to be.

Let's just wave our hands at this\nbecause at the end of the day

as n gets really large, the dominant\n

Even the divided 2, as I claimed earlier\n

the two straight lines if you\nkeep zooming out essentially

looked the same when n is large enough,\n

So that is to say a computer scientist\n

on the order of n squared steps.

That's an oversimplification.

If we really added it up, it's\nactually this many steps-- n

squared divided by 2 plus n over 2.

But again, if we want to just be able\n

performance, I think it's going to\n

order term to get a sense of what the\n

or what it even looks like graphically.

All right, so with that said,\nwe might describe bubble sort

sorry, selection sort as\nbeing in big O of n squared.

But what if we consider now the\n

to talk about a lower bound?

In the best case, how many\nsteps does selection sort take?

Well, here, we need some context.

Like, what does it mean to be\nthe best case or the worst case

Like, what could you imagine meaning\n

trying to sort a bunch of numbers?

I got the whole crew here again.

AUDIENCE: They would already be sorted.

DAVID J. MALAN: All right, they're\nalready sorted, right?

I can't really imagine a better scenario\n

but they're already sorted for me.

But does this algorithm\nleverage that fact in practice?

Even if all of our humans\nhad lined up from 0 to 7

I'm pretty sure I would have\npretty naively started here.

And yes, Celeste happens to be here.

But I only know she needs to be here\n

And then I would have realized,\nwell, that was a waste of time.

But then what would I have done?

I would have ignored her position\n

I would have done the same thing now\n

So every time I walk through,\nI'm not doing much useful work.

But I am doing those\ncomparisons because I

don't know until I do the work that\n

So this would seem to imply that\n

scenario, even, a lower bound on the\n

DAVID J. MALAN: A little louder?

DAVID J. MALAN: It's still\ngoing to be n squared

in fact, because the code I'm giving\n

from any of that scenario because\nit just mindlessly continues

So in this case, yes, I would claim that\n

So those are the kinds\nof numbers to beat.

It seems like the upper bound\nand lower bound of selection

And so we can also describe\nselection sort, therefore

as being in theta of n squared.

That's the first algorithm we've\n

which is to say that it's kind of slow.

I mean, maybe other\nalgorithms are slower

but this isn't the best starting point.

Well, there's a reason that I guided us\n

Even though you verbally proposed\nthem in a different order

this second algorithm we did is\ngenerally known as bubble sort.

And I deliberately used\nthat word a bit ago

saying the big values are\nbubbling their way up to the right

to kind of capture the fact that,\nindeed, this algorithm works

But let's consider if\nit's better or worse.

So here, we have pseudo\ncode for bubble sort.

You could write this\ntoo in different ways.

But let's consider what\nwe did on the stage.

We repeated the following\nn minus 1 times.

We initialized at least, even though\n

a variable like i from 0\nto n minus 2, n minus 2.

And then I asked this question.

If numbers bracket i and numbers\n

So again, I just did it more\nintuitively by pointing

but this would be a way,\nwith a bit of pseudo code

to describe what's going on.

But notice that I'm doing something\na little differently here.

I'm iterating from if\nequals 0 to n minus 2.

Well, if I'm comparing two\nthings, left hand and right hand

I'd still want to start at 0.

But I don't want to go\nall the way to n minus 1

because then, I'd be going past\nthe boundary of my array, which

I want to make sure that my\nleft hand-- i, if you will--

stops at n minus 2 so that when\nI plus 1 in my pseudo code

I'm looking at the last two\nelements, not the last element

That's actually a common\nprogramming mistake

that we'll undoubtedly\nsoon make by going

beyond the boundaries of your array.

So this pseudo code, then, allows me to\n

and swap them if they're out of order.

Why do I repeat the whole\nthing n minus 1 times?

Like, why does it not suffice\njust to do this loop here?

Think what happened with Celeste.

Why do I repeat this whole\nthing n minus 1 times?

DAVID J. MALAN: Indeed, and I think\nif I can recap accurately

think back to Celeste again.

And I'm sorry to keep calling\non you as our number 0.

Each time through bubble\nsort, she only moved one step.

And so in total, if there's n\nlocations, at the end of the day

she needs to move n minus 1 steps to get\n

And so this inner loop, if you\n

that just fixes some of the problems.

But it doesn't fix all of the problems\n

And so how might we quantify the\nrunning time of this algorithm?

Well, one way to see it is to just\n

The outer loop repeats n\nminus 1 times by definition.

The inner loop, the for loop,\nalso iterates n minus 1 times.

Because it's going from 0 to n minus 2.

And if that's hard to think about,\n

if you just add 1 to\nboth ends of the formula.

So that means you're doing n\nminus 1 things n minus 1 times.

So I literally multiply how\nmany times the outer loop

is running by how many times the\n

sort of FOIL method n minus 1 squared.

And I could multiply\nthat whole thing out.

Well, let's consider this just\na little more methodically here.

If I have n minus 1 on the\nouter, n minus 1 on the inner--

let's go ahead and FOIL this.

So n squared minus n\nminus n plus 1, combine

like terms-- n squared minus 2n plus 1.

And now which of these terms is clearly\n

DAVID J. MALAN: --the n squared.

So yes, even though\nminus 2n is a good thing

because it's subtracting off\nsome of the time required

plus 1 is not that big a thing,\n

n gets really large, like\nin the millions or billions

certainly, that bubble sort 2\nis on the order of n squared.

It's not the same exactly\nas selection sort.

But as n gets big,\nhonestly, we're barely

going to be able to notice\nthe difference most likely.

And so it too might be said to\nbe on the order of n squared.

And if we consider now the lower\n

here's where things get\npotentially interesting.

What might you claim is the running\n

And the best case, I claim, is when\n

Is our pseudo code going\nto take that into account?

DAVID J. MALAN: Yes, and that's the key word.

To summarize, in bubble sort, I do have\n

don't look at all n elements,\nthat I'm theoretically

just guessing if it's sorted or not.

Like, I obviously\nintuitively have to look

at every element to decide yay\nor nay, it's in the right order.

And my original pseudo code,\nthough, is pretty naive.

It's just going to blindly go back and\n

But what if I add a\nbit of an optimization

that you might have glimpsed\non the slide a moment ago

where if I compare two people and I\n

don't swap them, and I go all the\nway through the list comparing

every pair of adjacent\npeople, and I make no swaps

it would be kind of not\njust naive but stupid

to do that same process again\n

I'm not going to make\nany different decisions.

I'm going to do nothing\nagain, nothing again.

So at that point, it would be stupid,\n

So if I modify our pseudo code with\n

Inside of that same pseudo code, what\n

Like quit, prematurely before\nthe loops are finished running.

One of the loops has gone\nthrough per the indentation here.

But if I do a loop from\nleft to right and I

have made no swaps, which you\ncan think of as just being

one other variable that's plus plusing\n

if I've made no swaps\nfrom left to right

I'm not going to make any swaps\nthe next time around either.

So let's just quit at that point.

And that is to say in the\nbest case, if you will

when the list is already sorted,\n

might indeed be omega of n\nif you add that optimization

so as to short circuit\nall of that inefficient

looping to do it only as\nmany times as is necessary.

Let me pause to see if\nthere's any questions here.

AUDIENCE: [INAUDIBLE] to optimize the\n

DAVID J. MALAN: Good question.

If the running time of selection sort\n

of n squared but selection sort is in\n

in omega of n, which sounds better--

I think if I may, should we\njust always use bubble sort?

Yes if we think that we\nmight benefit over time

from a lot of good case\nscenarios or best case scenarios.

However, the goal at\nhand in just a bit is

going to be to do even\nbetter than both of these.

So hold that question\nfurther for a moment.

AUDIENCE: [INAUDIBLE] n minus 1?

So I say omega of n, but is it\ntechnically omega of n minus 1?

Maybe, but again, we're\nthrowing away lower order terms.

And that's an advantage because we're\n

Just like I plotted with the\ngreen and yellow and red chart

I just want to get a sense of\nthe shape of these algorithms

so that when n gets really\nlarge, which of these choices

is going to matter the most?

At the end of the day, it's\nactually perfectly reasonable

to use selection sort\nor bubble sort if you

don't have that much data because\n

My God, our computers\nnowadays are 1 gigahertz

2 gigahertz, 1 billion things per\n

But if we have large data sets,\nas we will later in the term

and as you might in the real world,\n

then you're going to want\nto be more thoughtful.

And that's where we're going today.

All right, so let's actually see\nthis visualized a little bit.

In a moment, I'm going\nto change screens here

to open up what is a little\nvisualization tool that will give us

a sense of how these things actually\n

than our humans are able\nto do here on stage.

So here is another visualization of a\n

Short bars mean small numbers,\ntall bars mean big numbers.

So instead of having the\nnumbers on their torsos here

we just have bars that are small or tall\n

Let me go ahead, and I\npreconfigured this in advance

to operate somewhat quickly.

Let's go ahead and do selections\nsort by clicking this button.

And you'll see some pink bars flying by.

And that's like me walking\nleft and right, left and right

to select the next smallest number.

And so what you'll see happening on\n

is Celeste, if you will, and\nall of the other smaller numbers

are appearing on the left while\n

So again, we no longer have to\ntouch the smaller numbers here.

So that's why the problem is getting\n

But you can notice now\nvisually, look at how many times

This is why things\nthat are n squared tend

to be frowned upon if avoidable because\n

When I was walking through, I\nkept pointing at the same humans

So let's see if bubble sort looks\nor feels a little different.

Let me re-randomize the thing, and let\n

And as you might infer, there's\n

not all of which we'll look at.

Same pink coloration, but it's\ndoing something different.

It's two pink bars going through\nagain and again comparing

And you'll see that the largest\n

to the right, but the smaller\nnumbers, like our number 0 was

is only slowly making its way over.

And it's going to take a while\nto get all the way to the left.

And here too, notice how\nmany times the same bars

are becoming pink, how many times the\n

Because it's only solving one\nproblem at a time on each pass.

And each time we do that, we're stepping\n

And now granted, I could speed this\n

but my God, this is only, what, like\n

Like, this is what n squared\nlooks like and feels like.

And now I'm just trying to\ncome up with words to say

until we get to the finish line here.

Like, this would be annoying if\nthis is the speed of sorting

and this is why I sort of secretly\n

because it would have taken\nus an annoying number of steps

to get that in place for her.

So those two algorithms are n squared.

Can we do, in fact, better?

Well, to save the best algorithm for\n

And when we come back, we'll\ndo even better than n squared.

So the challenge at hand is to\ndo better than selection sort

and better than bubble sort\nand ideally not just marginally

better but fundamentally better.

Just like in week zero, that third\n

was sort of fundamentally\nfaster than the other two.

So can we do better than something\non the order of n squared?

Well, I bet we can if\nwe start to approach

the problem a little differently.

The sorts we've done\nthus far, generally known

as comparison sorts--\nand that kind of captures

the reality that we were doing a huge\n

And you kind of saw that in the vertical\n

was being compared again and again.

But there's this programming\ntechnique, and it's actually

a mathematical technique\nknown as recursion

that we've actually seen before.

And this is a building\nblock or a mental model

we can bring to bear on the problem\nto solve the sorting problem

sort of fundamentally differently.

But first, let's look at it\nin a more familiar context.

A little bit ago, I proposed this pseudo\n

And notice that what was\ninteresting about this code

even though I didn't call it out at the\n

Like, I claim this is\nan algorithm for search

and yet it seems a little unfair\nthat I'm using the verb search

inside of the algorithm for search.

It's like an English sort of\ndefining a word by using the word.

Normally, you shouldn't\nreally get away with that.

But there's something\ninteresting about this technique

here because even though this\nwhole thing is a search algorithm

and I'm using my own algorithm to\n

the key feature here\nthat doesn't normally

happen in English when you\ndefine a word in terms of a word

is that when I search the left\n

I'm using the same algorithm.

But the problem is, by\ndefinition, half as large.

So this isn't going to be a\ncyclical argument in the same way.

This approach, by using\nsearch within search

is going to whittle the problem down\n

one door or no doors remains.

And so recursion is a\nprogramming technique

whereby a function calls itself.

And we haven't seen this yet in C, and\n

But in C, you can have\na function call itself.

And the form that\ntakes is like literally

using the function's name inside of\n

We've actually seen an opportunity\nfor this once before too.

Here's that same pseudo code\nfor searching for someone

in an actual, physical phone book.

And notice these yellow lines here.

We described those in week zero\nas inducing a loop, a cycle.

And this is a very procedural approach,\n

are very mechanically,\nif you will, telling

me to go back to line three to\ndo this kind of looping thing.

But really, what that's doing in the\n

book is it's just telling me to search\n

I'm doing it more mechanically\nagain by sort of telling myself

what line number to go back to.

But that's equivalent to just telling\n

search the right half, the\nkey thing being the left

have and the right half are\nsmaller than the original problem.

It would be a bug if I just said search\n

because obviously, you\nnever get anywhere.

But if you search the\nhalf, the half, the half

problem gets smaller and smaller.

So let's reformulate week zero's phone\n

but recursive whereby in\nthis search algorithm

AKA binary search, formerly\ncalled divide and conquer, I'm

going to literally use also\nthe keyword search here.

Notice among the benefits\nof doing this is it

kind of tightens the code up,\nmakes it a little more succinct

even though that's kind\nof a fringe benefit here.

But it's an elegant\nway too of describing

a problem by just having\na function use itself

to solve a smaller puzzle at hand.

So let's now consider a\nfamiliar problem, a smaller

version than the one you've dabbled\nwith-- this sort of pyramid

this half pyramid from Mario.

And let's throw away the parts\nthat aren't that interesting

and just consider how we might, up\n

this left aligned pyramid, if you will.

Let me go over here, and let me create\n

And in this file, I'm going to\ngo ahead and include cs50.h.

And I'm going to include stdio.h.

And the goal at hand is to implement in\n

this and exactly this pyramid.

So no get string or any of that--\n

and print exactly this\npyramid of height 4 here.

Well, let me go ahead, and in main,\n

well, we'll go ahead and generalize it.

Let's go ahead and ask\nthe user for heights.

We're using getint as before.

And I'll store that in a\nvariable called height.

And then let me go ahead\nand simply call the function

draw passing in that height.

So for the moment, let me\nassume that someone somewhere

has implemented a draw function.

And this, then, is the\nentirety of my program.

All right, unfortunately, C does\nnot come with a draw function.

So let me go ahead and invent one.

It doesn't need to return a value.

It just needs to print\nsomething-- so-called side effect.

So I'm going to define a function\n

I'll call it n for number, but\nI could call it anything I want.

I'm going to go ahead and print out a\n

The salient features here are that this\n

And now in height four, the\nfirst row has one brick.

That's a nice pattern that I\ncan probably represent in code.

Well, how about 4 int i gets--

let me do it the old school way--

And then i is less than or equal to n.

so I'm going from 1 to 4 just\nto keep myself sane here.

And then inside of this\nloop, what do I want to do?

Well, let me keep it\nconventional, in fact.

Let me just change this to\nbe the more conventional 0

to n even though it might not be\n

On row 1, I want two\nbricks, dot dot dot.

But I'm being more conventional.

So on each row, how many\nbricks do I want to print?

Well, I think I want to do this.

For int j, for instance, common to\n

let's start j at 0 and do this\nso long as is less than i plus 1

Well, again, when I equals 0, that's\n

When i equals 1, that's the second row.

And dot dot dot, when i\nis 3, I want four bricks.

So again, I have to add 1 to i\nto get the total number of bricks

that I want to print to the screen.

So inside of this nested for loop,\n

I'm going to save the new\nline for about here instead.

All right, the last\nthing I'm going to do

is copy and paste the prototype\nat the top of the file.

And again, this is of\nnow week one, week two.

Wouldn't necessarily come to\nyour mind as quickly as it

might to mine after all this practice,\n

of what you yourself did\nalready for Mario-- printing out

a pyramid that hopefully in a\nmoment is going to look like this.

So let me go back to my code.

Let me run make iteration, and\nlet me do dot slash iteration.

Seems to be correct, and let's assume\n

So this is indeed an example\nof iteration-- doing something

Like, I literally have a function\n

But I can think about implementing\n

And it's not strictly\nnecessary for this problem

because this problem honestly\nis not that complicated

to solve once you have\npractice under your belt.

Certainly the first time around,\n

But now that you kind of\nassociate, OK, row one

with one brick, row two with two\n

But how else could we\nthink about this problem?

Well, this physical structure,\nthese bricks, in some sense

is a recursive structure, a structure\n

Well, if I were to ask you the question,\n

look like, you would point,\nof course, to this picture.

But you could also kind of\ncleverly say to me, well

it's actually a pyramid of\nheight 3 plus 1 additional row.

And here's that cyclical\nargument, right?

Kind of obnoxious to do typically\n

because you're defining one\nthing in terms of itself.

What's a pyramid of height 4?

Well, it's a pyramid of\nheight 3 plus 1 more row.

But we can kind of leverage\nthis logic in code.

Well, what's a pyramid of height 3?

Well, it's a pyramid of\nheight 2 plus 1 more row.

Fine, what's a pyramid of height 2?

Well, it's a pyramid of\nheight 1 plus 1 more row.

And then hopefully, this process\n

the pyramid is getting\nsmaller and smaller.

So you're not going to have this\n

infinitely many times because when\n

the end of the pyramid, fine.

What is a pyramid of height 1?

Well, it's a pyramid of no\nheight plus one more row.

And at that point, things\njust get negative--

Things just would otherwise go negative.

And so you can just kind of stop.

The base case is when\nthere is no more pyramid.

So there's a way to draw a line in the\n

But this idea of defining a physical\n

or code in terms of itself actually lets\n

Let me go back to my code here.

Let me go ahead and create one\n

that leverages this idea of this\n

Let me go ahead and include\nstandardio.h, int main void.

And then inside of main, I'm going\n

height equals get int,\nasking the user for height.

And then I'm going to go ahead\nand call draw passing in height.

So that's going to stay the same.

I even am going to make my prototype\n

And now I'm going to\nimplement void down here

with that same prototype, of course.

But the code now is going\nto be a little different.

Well, first of all, if you ask\nme to draw a pyramid of height n

I'm going to be kind of a wise\nass here and say, well, just

draw a pyramid of n minus 1--

All right, but there's still\na little more work to be done.

What happens after I print or\ndraw a pyramid of height n minus 1

according to our structural\ndefinition a moment ago?

What remains after drawing a pyramid\n

We need one more row of hashes.

OK, so I can do that, right?

I'm OK with the single loops.

There's no nesting necessary here.

I'm just going to do this-- for\nint i get 0, i is less than n

which is the height that's\npassed in, i plus plus.

And then inside of this\nloop, I'm very simply

going to print out a single hash.

And then down here, I'm going to\n

I might not be as comfortable\nwith nested loops.

What does this loop do\nhere on line 17 through 20?

It literally prints n hashes by\n

So that's sort of week one style syntax.

But this is kind of trippy\nnow because I've somehow

boiled down the implementation of\n

But this is problematic as\nis because in this case

my drawer function, notice, is always\n

But ideally, when do I want\nthis cyclical process to stop?

When do I want to not call draw anymore?

When I get to the top of\nthe pyramid, when n is 1

or heck, when the pyramids\nall gone and n equals 0.

I can pick any line in\nthe sand, so long as it's

sort of at the end of the process.

Then I don't want to call draw anymore.

So maybe what I should do is this.

If n equals equals 0, there's\nreally nothing to draw.

So I'm just going to go\nahead and return like this.

Otherwise, I'm going\nto go ahead and draw

n minus 1 rows and then one more row.

And I could express this differently.

I could do something like this,\nwhich would be equivalent.

I could say something like if n\nis greater than or equal to 0

then go ahead and draw the row.

But I like it this way first.

For now, I'm going to\ngo with the original way

just to ask a simple question and\n

And heck, just to be\nsuper safe, just in case

the user types in a\nnegative number, let me also

just check if n is a negative number,\n

I'm not returning a value because\nagain, the function is void.

It doesn't need or have a return value.

So just saying return suffices.

But if n equals 1 or 2\nor 3 or anything higher

it is reasonable to draw a pyramid of\n

of 4, 3, and then go ahead\nand print one more row.

So this is an example now of code\n

But this so-called base case\nensures, this conditional ensures

that we're not going to do this forever.

Otherwise, we literally would\ndo this infinitely many times

and something bad is\nprobably going to happen.

All right, let me go ahead and\n

OK, no syntax errors-- dot slash\nrecursion, Enter, height of 4

If only because some of you have run\n

let me get rid of the base case\n

Oh, and actually, now\nit's actually catching it.

So the compiler is smart\nenough here to realize

that all paths through this\nfunction will call itself.

AKA, It's going to loop forever.

So let me do the first thing.

Suppose I only check for n equaling 0.

Let me go ahead and recompile\nthis code with make recursion.

And now let me just be\nkind of uncooperative.

When I run this program, still\nworks for 4, still works for 0.

What if I do like negative 100?

Have any of you experienced a\nsegmentation fault or core dump?

Like, this means I have somehow\n

And in short, I actually called\nthis function thousands of times

accidentally, it would seem\nnow, until the program just

bailed on me because I eventually\ntouched memory in the computer

That'll make even more sense next week.

But for now, it's simply a bug.

And I can avoid that\nbug in this context

probably not your own pset context,\n

allow for negative numbers at all.

So with this building\nblock in place, what

can we now do in terms of\nthose same numbers to sort?

Well, it turns out there's a\n

And there's bunches of others too.

But merge sort is a nice one to discuss\n

is going to do better than\nselection sort and bubble

sort that is better than n squared.

But the catch is it's a\nlittle harder to think about.

In fact, I'll act it out myself with\n

rather than humans because recursion\n

to wrap your mind around,\ntypically a bit of practice.

But I'll see if we can't\nwalk through it methodically

enough such that this comes to light.

So here's the pseudo code I propose\n

In the spirit of recursion,\nthis sorting algorithm

literally calls itself by using\n

So how does merge sort work?

It sort of obnoxiously says, well, if\n

go sort the left half, then\ngo sort the right half

and then merge the two together.

Now obnoxious in what sense?

Well, if I just asked you to sort\n

well, go sort that\nthing and then go sort

that thing, what was the point\nof asking you in the first place?

But the key is that\neach of these lines is

sorting a smaller piece of the problem.

So eventually, we'll be\nable to pare this down

into something that doesn't go on\n

There's a scenario where we\njust check, wait a minute

if there's only one\nnumber to sort, that's it.

Quit then because you're all done.

So there has to be this base\ncase in any use of recursion

to make sure that you don't\nmindlessly call yourself forever.

You've got to stop at some point.

So let's focus on the\nthird of these steps.

What does it mean to merge two\nlists, two halves of a list

just because this is\napparently going to be

a key ingredient-- so\nhere, for instance

are two halves of a list of size 8.

We have the numbers 2-- and I'll call\n

Notice that the left half at the\n

and the right half, 0136,\nis also sorted as well.

So that's a good thing because\nit means that theoretically, I've

sorted the left half already.

I've sorted the right half\nalready before we began.

I just need to merge these two halves.

What does it mean to sort two halves?

Well, for the sake of\ndiscussion, I'm just

going to turn over most of the numbers\n

There's two halves here, left and right.

At the moment, I'm\nonly going to consider

the leftmost element of each half--\n

and the one on the left here.

How do I merge these two lists together?

Well, if I look at 2 and I look at 0,\n

So I'm going to grab\nthe 0, and I'm going

to put it into its own place\non this new shelf here.

And now I'm going to consider,\nas part of my iteration

the beginning of this list and\nthe new beginning of this list.

So I'm now comparing 2 and 1.

I'm going to go ahead and grab the 1.

Now I'm going to compare the\nbeginning of the left list

and the new beginning of\nthe right list, 2 and 3.

Now I'm going to compare the\nbeginning of the left list

and the beginning of\nthe right list, 4 and 3.

Now I'm going to compare the 4\nagainst the beginning and end

it turns out, of the second list--

Now I'm going to compare the\nbeginning of the left list

and the beginning of the right list--

I'm realizing this is not going\nto end well because I left

too much distance between the numbers.

But that has nothing to\ndo with the algorithm.

7 is the beginning of the left list.

6 is the beginning of the right list.

And at the risk of\nknocking all of these over

if I now make room for this\nelement, we have hopefully

sorted the whole thing by having merged\n

I'm a little worried that's\njust getting sarcastic now

but we now have merged two half lists.

We haven't done the guts of the\n

But I claim that that\nis how mechanically you

You keep looking at the\nbeginning of each list

and you just kind of\nweave them together based

on which one belongs\nfirst based on its size.

So if you agree that\nthat was a reasonable way

to merge two lists together,\nlet's go ahead and focus lastly

on what it means to\nactually sort the left half

and sort the right half of\na whole bunch of numbers.

And for this, I'm going\nto go ahead and order them

in this seemingly random order.

And I just have a little cheat\n

And I'm going to start at\nthe very top this time.

And hopefully, these will\nnot fall down at any point.

But I'm just deliberately putting\n

Hopefully this won't fall over.

Here is now an array of\nsize 8 with eight integers.

I could use selection sort and just\n

I could use bubble sort and just\ncompare pairs, pairs, pairs.

But those are going to be on\nthe order of big O of n squared.

My hope is to do\nfundamentally better here.

So let's see if we can do better.

All right, so let me\nlook now at my code.

How do I implement merge sort?

Well, if there's only\none number, I quit.

There's eight numbers,\nso that's not applicable.

I'm going to go ahead and\nsort the left half of numbers.

All right, here's the left half--

Do I sort an array of size 4?

Well, here's where the\nrecursion kicks in.

How do you sort a list of size 4?

Well, there's the pseudo\ncode on the board.

I sort the left half\nof the list of size 4.

All right, now I have a list of size 2.

If only one number, I'm done.

All right, what was the next step?

You have to now rewind in time.

I just sorted the left half of\nthe left half of the left half.

So now at this point in the story,\n

the 5 assorted, and the 2 is sorted.

But what's the third and final step\n

So here's the left,\nhere's the right list.

How do I merge these together?

I compare the lists,\nand I put the two there.

I only have the [? 5 ?]\nleft, and I do that.

So now we see some visible progress.

We started to sort the left half of\n

We've just sorted the left\nhalf of the left half.

So what comes after sorting\nthe left half of anything?

All right, here's the sort\nof same nonsensical thing.

So that's the 4, and that's the 7.

In total, I've now sorted the\nleft half of the original thing.

Wait a minute, wait a minute.

I have sorted the left\nhalf of the left half

and I've sorted the right\nhalf of the left half.

What do I now need to do lastly?

Merge those two lists together.

So again, I put my\nfinger on the beginning

of this list, the\nbeginning of this list.

And if you want, I'll do the same\nthing when I merged last time

to be clear what I'm comparing.

2 and 4-- the 2 obviously comes first.

The 5 comes next and then\nlastly, of course, the 7.

Notice that the 2457 are now sorted.

So the original left half is sorted.

And I'll do the rest a little\nfaster because, my God

this feels like it takes forever.

But I bet we're on to something here.

I've just sorted the left\nhalf of the original.

Sort the right half of the original.

I sort the left half of the right half.

I sort the left half of the left half.

I sort the right half of the left half.

Now I merge the two together.

The 1 comes first, the 6 comes next.

Now I sort the right\nhalf of the right half.

So that's the third step of that phase.

Now where are we in the stor-- oh\n

We have sorted the left\nhalf of the right half

and the right half of the right half.

So I'm going to compare,\nand I'm going to move those

down just to make clear\nwhat I'm comparing

the beginning of both sublists.

And then lastly comes the 6.

All right, where are we in the story?

We've now sorted the\nleft half of the original

and the right half of the original.

All right, so I'm going\nto make the same point.

And this is actually\nliterally what we did earlier

because I deliberately demoed those\n

And lastly-- this is when\nwe run out of memory--

the 7 over there is actually in place.

OK, so admittedly, a\nlittle harder to explain

and honestly, it gets a\nlittle trippy because it's

so easy to forget about\nwhere you are in the story

because we're constantly\ndiving into the algorithm

and then backing back out of it.

But in code, we could\nexpress this pretty correctly

and, it turns out, pretty\nefficiently because what

I was doing, even though it's\nlonger when I do it verbally

I was touching these elements a\nminimal amount of times, right?

I wasn't going back and forth, back\n

I was deliberately only ever merging\n

So every time we merge, even\nthough I was doing it quickly

my fingers were only touching\neach of the elements once.

And how many times did we divide,\n

Well, we started with\nall of the elements here

and there were eight of them.

And then we moved them\n1, 2, 3 positions.

So the height of this visualization,\n

If I started with 8, turns\nout if you do the arithmetic

this is log n height\nbecause 2 to the 3 is 8.

But for now, just trust\nthat this is a log n height.

Well, it's of width n because\nthere's n elements any time

So technically, I was kind of\n

is the first time I've needed shelves.

With the human examples, we just had the\n

Here, I was sort of using\nmore and more memory.

In fact, I was using like\nfour times as much memory

even though that was just\nfor visualization's sake.

Merge sort actually requires that you\n

to move the elements into when\nyou're merging them together.

But if I really wanted and if I\n

honestly, I could have just gone back\n

That would have been sufficient.

So merge sort uses more memory\nfor this merging process

but the advantage of\nusing more memory is

that the total running time, if you can\n

The big O notation for\nmerge sort, it turns out

is actually going to be n times log n.

And even if you're a little\nrusty still on your logarithms

we saw in week zero and again\n

That's faster than linear\nsearch, which was n.

So n times log n is, of course,\n

So it's sort of lower on this little\n

which is to suggest that it's running\n

And in fact, if we consider\nthe best case running time

turns out it's not quite as good\nas bubble sort with omega of n

where you can just sort of abort\nif you realize, wait a minute

Merge sort, you actually have to do that\n

So it's actually in omega and\n

So again, a trade off\nthere because if you

happen to have a data set\nthat is very often sorted

honestly, you might want\nto stick with bubble sort.

But in the general case,\nwhere the data is unsorted

n log n as sounding\nbetter than n squared.

Well, what does it\nactually look or feel like?

Give me a moment to just change\nover to our visualization here.

And we'll see with this example\nwhat merge sort looks like

depicted with now these vertical bars.

So same algorithm, but instead\nof my numbers on shelves

here is a random array\nof numbers being sorted.

And you can see it being\ndone half at a time.

And you see sort of remnants\nof the previous bars.

Let me zoom out so you can\nactually see the height here.

Let me go ahead and randomize\nthis again and run merge sort.

Now you can see the second array and\n

And even though this one looks way\n

it does seem to be moving faster.

And it seems to be merging halves\ntogether, and boom, it's done.

So let's actually see, in conclusion,\n

and consider that moving forward\nas we write more and more code

the goal is, again, not just to be\n

And one measure of design is\ngoing to indeed be efficiency.

So here we have, in final, a\nvisualization of three algorithms--

selection sort, bubble\nsort, and merge sort--

And let's see what these algorithms\n

Oh, if we can dim the\nlights for dramatic effect--

selection's on top, bubble on\nbottom, merge in the middle.

DAVID J. MALAN: Well, this is CS50,\n

and recall that last\nweek, week three, we

began to explore the inside of\na computer's memory a bit more.

We talked about arrays, which\nwere just chunks of memory

back to back to back that really\n

to bottom, and this is actually a\n

new to programming,\nand certainly new to C.

You've seen this approach of just using\n

So for instance, here is a photo taken\n

and this is an opportunity to\nexplore exactly what happens

if we start to zoom in and zoom in and\n

any TV show like CSI, or\nwhatever, or any movie that

explores forensic information might\n

on an image like this to see\nwhat the glint in someone's eye

is because that reveals the license\nplate number of someone that

Something that's a little\nover the top there

but there's an opportunity here to\n

For instance, let's zoom on\nthis puppet here's eye and let's

zoom in a little more to\nsee what might be reflected.

Let's zoom in a little\nmore, and that's it.

There's only finite\namount of information

if you have an image\nrepresented in this way.

We're using pixels-- these dots on\n

because if you're only using\na finite amount of memory

then at the end of the day, you can only\n

At least I don't really see in this\n

or something like that that you\n

So today we'll explore these\nkinds of representations

of how you might use memory\nin new and interesting ways

to represent now, very\nfamiliar things, but also

start to explore what some of the\n

But consider after all that this doesn't\n

as many pixels as something\nlike this other image

you can imagine just doing something\n

And if you think of an image as\njust having rows and columns

these rows otherwise known\nas scan lines-- something

we'll explore in the coming week--\n

by just using two different\nvalues, maybe a zero and a one.

Or yellow and purple, or vice versa,\n

Now in practice, recall we talked\n

but maybe an R, a G, and a B value--\n

but we'll come back to that.

That would just be a\nmore involved image.

But for fun, if today you want to tackle\n

if you go to this URL here,\nwe've put together an opportunity

If you go to this URL here, that'll\n

If you have a laptop\nwith you today that'll

look a little something like this, which\n

So if you'd like to go ahead and use\n

feature to color in those\nindividual squares if you'd like

see if you can't make something a little\n

and we'll exhibit some of the best or\n

So let's transition then to something\n

And not all of you have\nused, presumably, Photoshop

but you're probably generally familiar\n

and creating images\nor photos or the like.

And here is a screenshot\nof p's color picker

via which you can\nchange what color you're

going to draw with the paint\nbrush, or what color you're

going to fill in with the paint bucket.

It's representative of any\nkind of graphical tool.

And there's a lot of\ninformation in here

but there's perhaps some\nfamiliar terms now--

R, G, and B. In fact, right\nnow this is Photoshop's way

of saying you're about to fill\nin your background or foreground

with the color black,\nand that appears to be

represented with an R, a G, and\na B value of zero, zero, zero.

Or alternatively, using a\nhash symbol and then 000000.

And if some of you have\nalready made web pages before

and you know a little\nbit of HTML and CSS

you probably are familiar\nwith this kind of syntax--

a hash symbol and then six, or\n

And if we look at a few different\ncolors here, for instance

here might be the\nrepresentation of white.

Now the R, the G, and the B values\n

Or alternatively, it looks like\n

could represent that same\ncolor white with FFFFFF.

And let's just do a few others.

Here is red, and it turns out that\n

So there's perhaps a\npattern here emerging.

Here is green, zero, 255, zero, a.k.a.

00FF00, or lastly, here\nblue, which is no red

no green but apparently a lot\nof blue, 255 again, a.k.a.

Now some of you, again, might\nhave seen this notation before

these zeros and these F's and all of\n

but this is another form of notation.

And in fact, we'll explore\nthis today-- really

is just a precondition for\ntalking about some other concepts.

But the ideas, ultimately,\nare really no different.

What we're about to see is\na different base system--

not just binary, not just\ndecimal, but something

we're about to call hexadecimal.

But first, recall that with RGB\nwe previously did the following.

Any RGB value-- red,\ngreen, blue-- just combine

some amount of red or green or blue.

So here we have 72, 73, 33, which in the\n

Just hi with an exclamation\npoint, but in the context

of a Photoshop-like program, this\nmight instead be representing

collectively, this shade\nof yellow, for instance

when you combine that much red\nthat much green that much blue.

If you've got a lot of\nred, no green, no blue

together that's going to give us red.

If you've got no red, a\nlot of green, no blue

that's going to give\nus, of course, green.

If you've got no red, no green,\na lot of blue, that of course

So there's a pattern emerging here\n

And it's maybe somehow equated with 255,\n

Meanwhile, if we combine one last\n

that's actually going to give us\na single white pixel like this.

Here was binary-- in the world of binary\n

Could have been anything else--

A or B, X or Y, but the world\nstandardized on these numerals

In our world's decimal system, of\n

As of today though, we're going to\n

in the context of images and also\n

and there's some conveniences to it.

Where now, you're going\nto be able to count up

to F in a notation called hexadecimal.

From zero through nine, then you keep\n

the idea being each of these,\neven though it's weirdly

a letter of the English alphabet,\n

It's not one zero for 10, or 1 1\n

these digits, so to speak, are\nindeed still just single symbols

and that's a characteristic of just\n

So how do we get from 00 and FF to\n

Well, this hexadecimal system, a.k.a.

Base 16, just does the math\nfrom week zero and really

grade school, a little bit differently.

For instance, if you have a\nnumber that's got two digits

or hexadecimal digits as of today, the\n

Instead of powers of two or powers of\n

respectively, it's powers of 16.

So if we just do the math\nout, that's the ones column

this is the 16s column, and so forth.

Things get actually pretty big\npretty quickly in this system.

But now let's just consider how we\n

If you've got two hexadecimal\ndigits for which these hashes are

just placeholders, zero, zero\nis going to mathematically

equal the decimal number you\nand I know, of course, as zero.

16 times zero plus one times zero is\n

And we can count up from here.

This, in hexadecimal,\nwould be how a computer

represents the number we know as one.

It would be zero one in this case.

This would be two, three, four,\nfive, six, seven, eight, nine--

in decimal, we're about to go to 10.

But in hexadecimal, to be\nclear, what comes next?

So, apparently A, so 0A, 0B, which\n

So using hexadecimal is\njust an interesting way

of using single symbols\nnow, zero through F

to count from zero through 15.

And we'll see why it's 15 in a\n

anyone want to conjecture how\nin hexadecimal, a.k.a. hex

do we now count up one position higher?

What comes after 0F in hexadecimal?

So, one zero-- it's the\nsame kind of thing--

once you're at the highest\ndigit possible, F--

or in our decimal world\nthat would have been nine--

you add one more, nine wraps\naround to zero, or in this case

You carry the one and voila--\nnow we're representing

the number you and I know as 16.

And we could keep going\nforever, literally.

This could be 17, 18,\n19, 20, and decimal--

but let's just wave our\nhands at it and count

as high as we can-- dot,\ndot, dot-- the highest

we could count in hexadecimal\nwith two digits, just logically

would be what, in hexadecimal?

So yes, that's the biggest digit\n

So how high can you count in hexadecimal\n

Well, it's the same math as always.

15, so that's 16 times 15 plus\none times F, or one times 15--

that gives us 240 plus 15 in decimal,\n

So this hexadecimal system-- you may\n

and if you haven't we'll get to\n

or we just saw in the\ncontext of Photoshop-- just

has this shorthand notation of counting\n

Now it's marginal, but that's like\n

you need in order to count as high\n

In hexadecimal you can count\nas high using just two

and that difference is going to get\n

Let me stipulate for now, you're\n

in terms of just how many symbols\n

bigger and bigger numbers than that.

All right, let me pause here just to\n

on what we've called hexadecimal, which\n

as well as A through F.\nAny questions or confusion?

And if it feels like we're\nlingering a bit much on arithmetic

we're not really going to see other\n

These are the go-to three in a\nprogrammer's world, typically.

AUDIENCE: Does the hexadecimal\nsymbol take more storage

DAVID J. MALAN: Good question.

Does hexadecimal require more storage\n

Theoretically no, because this is\n

and we'll see in a concrete\nexample in a moment.

But inside of the computer, at the end\n

And using hexadecimal is not\nusing more or fewer bits

think of this as how\nyou might write it down

on a piece of paper, just how\nmany digits you're going to write

or on a computer screen, how many\n

but it doesn't change how the\n

because all they're representing at\n

If this-- a moment ago\nFF I claimed was 255--

let's just rewind to week\nzero and if we wanted

to count to 255 in binary, that's\n

And there's only a few\nof these numbers that

are useful to memorize, like 255 is as\n

if you start at zero, because two to the\n

So in binary, recall if you have\n

and I won't do out the\nmath pedantically here

but if I do do this plus\nthis plus this, dot, dot

dot-- that's also going to give me 255.

So this is what's interesting\nhere about hexadecimal.

It turns out that an upside of\nstoring values in hexadecimal

is that we're going to\nsee the first F represents

the left half of all these bits,\nand the second F in this case

represents the rightmost\nfour of these bits.

So it turns out hexadecimal\nis very useful when you

want to treat data in units of four.

It's not quite eight, but units\nof four, and that's not bad.

Which is why-- if you use two\ndigits like I have thus far

00 or FF or anything in between--

that's actually a convenient way of\n

One hex digit for the first four\n

And again, there's nothing new\nintellectually here per se

it's just a different way of\n

So in what context do we see this?

Well, we talked about\nmemory last week, and we're

going to talk more about it this week.

If this is my computer's\nRAM-- random access memory--

you can again think of each byte as\n

This might be zero, this might\nbe 2 billion, and so in the past

I've described these as just\nthis, using decimal numbers.

Here's byte zero, one, two, three,\n

would be here, and so forth.

But it turns out in the world of memory,\n

tend to count memory\nbytes using hexadecimal.

Partly just by convention,\nbut also partly

because it's a little more\nsuccinct and again, each digit

represents four bits, typically.

So what comes after F here?

Well, if I think about\nthe computer's memory

I normally might do\nafter F, which is 15, 16.

But instead, one zero, one\none, one two, one three-- this

is not 10, 11, 12, 13, because I claim\n

As per the previous\nslide, we already started

going into A's through\nF's, so you immediately

see here a possible problem.

Why is this now worrisome,\nif all of a sudden you're

seeing seemingly familiar\nnumbers like 10, 11, 12, 13?

We didn't really stumble\nacross this problem

when it was all zeros and ones before.

AUDIENCE: Try to do math [INAUDIBLE].

DAVID J. MALAN: Yeah, so if you're\nwriting some code in C that's

doing some math, you\nmight accidentally--

or the computer might accidentally\n

if they look in some context the same.

Any number on the board\nthat doesn't have a letter

is ambiguously hexadecimal\nor decimal at this point

and so how might we resolve this?

Well, it turns out that what\ncomputers typically do is this.

By convention, any time you\nsee 0x and then a number

that's a human convention of saying--

signaling to the reader that this\n

So if it's 0x10, that\nis not the number 10

that is the hexadecimal number one\n

And again, these are not the\nkinds of things to memorize

it's really just the system for\n

So henceforth today, we're going\nto start seeing hexadecimal

When you write code, you might even\n

but again, it's just a different\nway of representing numbers

and humans have different\nconventions for different contexts.

All right, so with that said, any\n

But here on out, we'll start\nusing it in some actual code.

So, let's go ahead and consider\nmaybe a familiar example.

Something where involving code,\n

to a value like 50, in this case.

And then let's start to tinker\naround with what's going

on inside of the computer's memory.

In a moment I'm going to load\nup VS Code on my computer

and I'm going to go ahead and whip\n

a value like the number\n50 to a variable called n

but today, keep in mind that\nthat variable n and that value 50

is going to be stored somewhere\nin my computer's memory

and it turns out today we'll introduce\n

see where things are being stored.

So let me click over to VS Code here.

I'm going to create a\nprogram called address.c just

to explore computer's\naddresses today, and I'm

going to do an include stdio.h,\nint main(void), as usual.

No command line arguments for now.

I'm going to declare that\nvariable n equals 50

and then I'm just going to\ngo ahead and print it out.

So nothing very interesting but I'll\n

Nothing here should be very\ninteresting to compile or run

but I'll do it just to make\nsure I didn't make any mistakes.

Looks like as expected, it simply\n

But let's consider then, what this\n

when it's actually run on your machine.

So here we have that grid of memory.

That variable n is an int,\nand if you think back

how many bytes typically\ndo we use for an int?

Four, so four bytes, or 32 bits.

So if each of these squares represents\n

in my memory, or RAM, is\nusing four of these squares.

Maybe it ends up over here just\n

used elsewhere, for instance.

Though I don't really\nknow, and frankly, I

don't really care where it ends\n

So the variable-- the value 50 is\n

Even though I've written it as\ndecimal, just like in my code--

let me again remind that this is 32\n

it's just going to be very tedious if\n

so I'll use the more comfortable\nhuman decimal system.

So that's what's going on\ninside of the computer's memory.

So what if I actually wanted to\n

or maybe just knowing its location?

Well, this variable n\nindeed has a name, n--

that's a label of sorts for it--\n

technically at a specific address,\n

0x123, and it's 123\nbecause I really don't

care what it is, I just want an\n

So way over here off screen might be\n

It's in hexadecimal\nnotation just by convention.

So how can I actually see where\nmy variables are ending up

in memory if I'm curious to do so?

Well, let me go back to my\ncode here and let me actually

change this just a little bit.

Let me go ahead and introduce,\nfor instance, another symbol

here and another topic\naltogether, namely pointers.

So a pointer is a variable that\n

the location of some value\nor more specifically

the specific byte in which\nthat value is stored.

So again, if you think of your memory\n

zero at top left, 2 billion\nor whatever at bottom right

depending on how much RAM you have--

each of those things has\na location, or an address.

A pointer is just a variable\nstoring one such address.

So it turns out that in the world of\n

we can use if we want to see what\n

and those two operators,\nas of today, are these.

You can use the ampersand\noperator in C in a couple of ways.

We already saw it very briefly\nto do ampersand ampersand--

it's kind of and two\nBoolean expressions together

in the context of a conditional.

A single ampersand is\nthe address of operator.

So literally, in your code, if you've\n

and you write &n, C is going to figure\n

variable n in the computer's memory.

And it's going to give you a number,\n

If you want to store that\naddress in a variable

even though yes, it's a number like\n

that you want to store not an int\n

And the syntax for doing that--\nsomewhat nonobviously-- is

to use an asterisk here,\na star operator, and you

say this when creating the variable.

If you want p to be a pointer, that\n

And the star just tells the computer,\n

this is the address of\nsomething that yes, is an int

but we're just being more precise.

So on the right hand side you\nhave the address of operator.

As always with the equal sign,\nyou copy from right to left.

Because &n is by definition the address\n

in a pointer, and the way to declare a\n

whose address you're storing, and then\n

indeed a pointer and not\njust a regular old int.

So let's see this in practice.

Let me go back to my own\nsource code here and let

me make just a couple of tweaks.

I'm going to leave n\nalone here but I'm going

to go ahead and initially just do this.

Let me say int star\np equals ampersand n

and then down here, I'm going to\n

And then even though yes, it's just\n

for integers, there's actually a special\n

pointers or addresses, and that's %p.

So now let's go ahead and\nrecompile this, make address--

so far so good-- ./address,\nEnter, and a little weirdly

but perhaps understandably now,\n

at which the variable n happened to\n

This computer has a lot\nmore memory so technically

it was stored at 0x7FFCB4578E5C.

Now that has no special\nsignificance to me.

It could have ended up\nsomewhere else altogether

but this is just where, in my\n

server to which I'm connected\nusing VS Code here--

that just happens to\nbe where n ended up.

And strictly speaking, I don't even\n

I could get rid of p\nand I could just say

print not just n, but the address\n

You don't need to temporarily\nstore it in a variable.

Let me just do make\naddress again, ./address

and now I see this address here.

And notice if I keep running the\n

There's other stuff presumably\ngoing on inside of the computer.

Maybe it's actually randomizing it so\n

That can actually be a security\nfeature underneath the hood

but this happens to be at that moment\n

quite like our picture a moment ago.

All right, so let me pause\nhere to see if there's now

any questions on what we just did.

AUDIENCE: Is there any\nway to control where

you are storing something in memory?

Does it even matter if\nit works, or does it just

matter that you could go in\nand locate where something is?

DAVID J. MALAN: Really good question.

Is there any way to control\nwhere something is in memory?

Short answer is yes, and this is\n

and we're going to do this today\n

because with this power of going to or\n

I could just arbitrarily\nright now write code

that stores a value at byte 2 billion,\n

But that also means potentially,\nI could start creepily looking

around at all of the computer's memory,\n

Maybe other programs, maybe\nother parts of programs

and indeed, this is a\npotential security threat

if suddenly you're able\nto just look anywhere

you want in the computer's memory.

Now, I'm overselling it a little bit\n

there are some defenses\nin place in compilers

and in our operating systems that\n

But this is still a very\nfrequent source of problems

and later today we'll\ntalk briefly about things

called stack overflow,\nwhich is not just a website

it is a problem that you can encounter.

Heap overflow, and more\ngenerally buffer overflows--

there's just so many things that can\n

and if any of you have encountered\na segmentation fault yet?

I think we saw a few\nhands for that already.

You touched memory\nthat you shouldn't have

and odds are you did it most recently\n

Going to the left, or negative in an\n

And we'll explain today why it\nis you were able to do that.

Other questions on\nthese primitives so far?

AUDIENCE: [INAUDIBLE] pointer star p,\n

DAVID J. MALAN: Good question.

Let me rewind in time to the\nprevious version of this code

where I actually had\na variable called p.

Just like with variable\ndeclarations in the past

once you've declared a variable to\n

star, a.k.a. a pointer,\nyou don't thereafter

keep using the word\nint or now, the star.

Once you've declared it, that's it.

You only refer to it by name.

And so it's very\ndeliberate what I did here

saying that the type here is int star--

that is a pointer to an int--

but here I just said the name\nof the variable, as always.

I didn't repeat int, and\nI also didn't repeat star.

But at the risk of bending\none's minds a little bit there

is unfortunately one other use for the\n

If you want to print out not\nthe address of something

but what is at a specific\naddress, you can actually do this.

If I want to print out the integer\n

I can actually use the star here, which\n

said but it has a different\nfunction here-- a different purpose.

So let me go ahead and do\nthis in two different ways.

I'm going to leave this\nline of code as is

but I'm going to add\nanother line of code now

that prints out what apparently\nwill be an integer, in a moment.

So %i backslash n, and I could\n

So there's really nothing\nspecial happening now, I'm

just adding a sort of\nmindless printing of n.

So make address, ./address--

there's the current address of\nn and there's the value of n.

But what's kind of\ncool about C here, too

is if you know that a value is\nat a specific address like p

there's one other use for this\nstar operator, the asterisk.

You can use it as the\nso-called dereference operator

which means go to that address.

And so here what we actually have\nis an example of a pointer p

which is an address like\n0x123 or 0x7FF and so forth.

But if you say star p now, you're\nnot redeclaring the variable

because I didn't mention int--

you're going to that address in p.

So let me recompile this now.

Make address, ./address,\nand just to be clear--

I'm first going to see the\npointer itself, 0x something.

What's the second line of output\nI should presumably see now?

So I'm hearing 50, and that's true\n

of n and print it in line seven, but\n

that's indeed going to just\nshow you the number n--

All right, any questions now on\n

I think this is confusing--\nthe fact that we

use the star for\nmultiplication, the fact

that we use the star\nto declare a pointer

but then we use a star in a third\nway to dereference the pointer

It's just too confusing, honestly,\n

DAVID J. MALAN: Good question.

Do you-- when you are using\nthe ampersand operator

to get the address of\nsomething, the onus

is on you at the moment to know\n

I wrote this code so I\nknow in line six that I'm

trying to get the address\nof what is an integer.

AUDIENCE: What about line eight?

DAVID J. MALAN: In line\neight you don't have

to worry about that-- good question.

Notice in line eight, I didn't tell\n

what kind of address I'm going\n

I told the compiler\nthat p, now and forever

is going to be the address of an int.

That's enough information in advance so\n

still knows on line eight\nthat p is a pointer to an int

and that way it will print out\nall four bytes at that address

not just part of it, and not\nmore than those four bytes.

AUDIENCE: Do pointers have pointers?

DAVID J. MALAN: Do\npointers have pointers?

We won't do this today by\nhaving pointers to pointers

but yes, you can use star\nstar, and then things get--

We won't do that today and\nwe won't do that often.

In fact Python, another language,\nis just a couple of weeks

That was-- more verbal\nfeedback like that

is helpful as we forge into\nthe more complicated stuff.

AUDIENCE: What's the\npoint of [INAUDIBLE]??

DAVID J. MALAN: What's the\npoint of printing the address?

AUDIENCE: Like, using the\naddress to [INAUDIBLE]..

What's the point of doing this?

If you don't mind, let me--\nlet's get there in a moment.

This is not the common use case,\njust printing out the address--

At the moment we care only\nfor the sake of discussion.

We're soon going to start\nusing these addresses.

So hang in there just a\nlittle bit for that one, too

but it will solve some\nproblems for us before long.

So let's actually just now depict what\n

So if I toggle back here, let\nme redraw my computer's memory

now let me plop into the memory n,\n

Where is p in my computer's memory?

Specifically, I don't know and\n

run the program so for\nthe sake of discussion

let's just propose that if 50 ended\n

p ends up over here, at address--

whoops-- at whatever\naddress this is here.

But notice a couple of curiosities now.

If p is a pointer, it's\nthe address of something.

So the value in p should be an address,\n

0x123, and technically there's not\n

there's not even a 123\nthere per se-- there's

a pattern of bits that\nrepresents the address 0x123.

But again, that's weak zero--\n

So if this is p, and this I claimed\n

Can someone conjecture here?

Because it turns out whether n\nis an int or a char or a bool

which are different\ntypes-- heck, even a long--

it turns out that p is always going\n

AUDIENCE: Perhaps it\nallocates eight bytes

but it doesn't know the type\nof the data [INAUDIBLE]..

Maybe it's allocating eight bytes\n

Turns out that's OK because\nan address is an address.

It's really up to the programmer to\n

AUDIENCE: Maybe the first four for\n

is some null that [INAUDIBLE]\nwhere the pointer ends.

DAVID J. MALAN: OK, possibly.

It could be that pointers have\n

or something curious like that,\n

Turns out that's not the case.

It turns out that pointers\nnowadays typically are, but not

always are eight bytes, a.k.a.

64 bits, because you and\nI-- our Macs, our PCs

heck-- even our phones have a lot\n

Back in the day, a\npointer might have only

been 32 bits, or even only\neight bits way back in the day.

It's considered 32 bits, because\n

How high can you count,\nroughly, if you've got 32 bits?

What's the number we keep rattling off?

32 bits is roughly 2 to\nthe 32, so it's 4 billion

and I keep saying it's 2 billion if you\n

there's a reason I keep saying\n2 billion bytes, two gigabytes

because for a very long time that\n

Because the pointers that\nthe computers were using

were only, for instance, 32 bits.

And with 32 bits, depending on whether\n

you can count as high as 2 billion,\nroughly, or maybe 4 billion

but you know what-- your\nMac, your PC, your phone

could not have had five gigabytes of\n

You certainly couldn't have had\n

which might be 8 gigabytes of memory--

Because with 4 bytes, or 32\nbits, you literally, physically

can't count that high, which means if I\n

would run out of numbers to describe\n

So pointers nowadays are\n64 bits, or eight bytes.

I can't even pronounce\nhow big that number is

but it's plenty for the\nnext many years, and so

we've drawn it that\nway on the board here.

Now let's just abstract this away.

Let's get rid of all\nthe other bytes that

are storing something or\nnothing else, and let's now

start to abstract away this\ncomplexity because the reality is

what is this useful for, or\nwhat do we-- do we actually

We're doing this so that\nyou see there's no magic.

We're just moving things around\nand poking around in memory.

But what a person would typically\ndo when talking about pointers

would literally be to\njust point at something.

I really don't care\nwhat address n is at

so it suffices when general, when\n

having a discussion\nwith another programmer

you just draw an arrow from the\n

because neither you nor I probably care\n

There's your pointer-- it's literally\n

So it turns out that these\npointers, these addresses

are not that dissimilar to what\nwe've done for hundreds of years

in the form of a postal system.

For instance, here is a post office--

here, no-- here is a\nmailbox, and suppose

that this is a mailbox labeled p.

It's a pointer, and suppose\nthere's another mailbox

way over there, which is just\n

What are we really talking about?

Well, you store in a computer's\n

or the word "hi" inside of your\n

But today we can also use\nthose same memory locations

to store the address of things.

For instance, if I\nopen this up here and I

see OK, the value inside of this\n

0x123-- that's like a\npointer, a breadcrumb leading

from one location in memory to another.

And in fact, would someone who's\nseated roughly over there--

do you mind getting the mail over there?

Any volunteers over in this section?

Just need you to get to\nthe mailbox before I do.

Whoever is gesturing most\nwildly, come on down.

OK, come on up to the edge of the\n

if this is p, that is\napparently n, but to make clear

what we're talking about when\nwe're storing 0x whatever values--

like 0x123, that's\nessentially equivalent to my

maybe pulling out something\nlike this and just

abstractly pointing\nto your mailbox there

or if you prefer,\npointing to the mailbox--

This is akin to me\npointing at your mailbox

and if you want to go\nahead and open your mailbox

and reveal to the crowd what's\ninside your mailbox labeled n.

We have a little CS50 stress\nball for your trouble.

So that's just to put a visual on\n

because it can get very abstract,\n

talking about addresses and memory and\n

But if you think about just walking\n

complex that's got a lot of\nmailboxes, those mailboxes

essentially are a big\nchunk of memory and each

of those mailboxes has an address--

this is apartment one, two,\nthree-- apartment 2 billion.

And inside of those\nmailboxes can go anything

that can be represented as information.

It could be a number\nlike n, or 50, or if you

prefer it could be a\nnumber that represents

the address of another mailbox.

And this is akin, really, if\nyou've ever had an apartment or you

and your parents have moved,\nto having a forwarding address.

It's like having the\nPost Office in the US

put some kind of piece of paper\nin your old mailbox saying

actually forward it\nto that other mailbox.

That really is all a pointer is doing.

At the end of the day,\nit's just a number

but it's a number being\nused in a different way

and it's the syntax\nthat we've introduced

not just int but int star,\nthat tells the computer how

to treat that number in\nthis slightly different way.

Are there any questions then, on this?

AUDIENCE: If you had a variable,\nlike int c, [INAUDIBLE]..

DAVID J. MALAN: If I did int c and--

Equal to n, so let me\nactually type it out.

If I give myself another\nline of code, tell me

one last time what to type.\nint is equal to n, like this?

So this is OK, and I can't draw it\n

but this would be like creating another\n

down here, that stores\nan identical copy of 50

because the assignment operator\n

So that would just add one\nmore rectangle of size four

If I'm answering your\nquestion as intended.

OK, so that is week one style use of\n

I could, though, start copying\npointers but again, we'll

come back to some of that complexity.

AUDIENCE: That was a great question.

does the same pointer point\nto the new replica as well?

DAVID J. MALAN: Ah, good question.

And to repeat for the camera, if I\n

int c equals n, and I claim without\n

that this gives me another rectangle,\n

And this is what's important\nand really characteristic

of C. Nothing happens\nautomatically for you.

p is not going to be updated\nunless you update p in some way

so creating a third\nvariable called c-- even

if you're copying its\nvalue from right to left

that has no effect on\nanything else in the program.

So what have we seen that's perhaps\n

Well, recall that we talked quite a\n

to recap in layperson's terms, what is\n

So say-- well, let me\ntake a specific hand here.

AUDIENCE: An array of characters.

An array of characters, and we--

I claimed-- or revealed last week\nthat string is not technically

a feature built into C. It's\nnot an official data type

but every programmer\nin most any language

refers to sequences of\ncharacters-- words, letters

So the vernacular exists but\nthe data type doesn't typically

exist per se in C. So what\nwe're about to do, if you will

for dramatic effect, is take\noff some training wheels today.

The CS50 library implemented in the\n

we claim has had a\nbunch of things in it.

Prototypes for GetString,\nprototypes for GetInt

and all of those other\nfunctions, but it turns out

it also is what defines the\nword "string" in such a way

that you all can use it\nthese past several weeks.

So let's take a look at an\nexample of a string in use.

Here, for instance,\nis a tiny bit of code

that uses the word "string,"\ncreating a variable called s

and then storing quote\nunquote, hi, exclamation point.

Let's consider what this looks\n

I don't care about all the other\n

and this per last week is\nhow "hi" might be stored.

h-i exclamation point and then\none more, as someone already

observed, that sentinel value--\nthat null character which

just means eight zero bits to\ndemarcate the end of that string

just in case there's\nsomething to the right of it

the computer can now distinguish\none string from another.

So last week we introduced\nthis new syntax.

Well, if strings are\njust arrays of characters

you can then very cleverly use\nthat square bracket notation

and go to location zero or one\nor two, which are like addresses

but they're relative to the string.

This could be at 0x123 or 0x456,\nbut with this bracket notation

zero is always the beginning\nof the string, one is the next

two is the next, and so forth.

So that was our array syntax\nfor indexing into an array.

But technically speaking, we\ncan go a little deeper today--

technically speaking, if hi is\n

it stands to reason that i is at\n

Now, I don't care about 123 per se,\n

Even in hex, if you just add\none when you start at 0x123

the next number is four,\nfive, six at the end.

I don't have to worry\nabout A's, B's, and C's

because I'm not counting\nthat high in this example.

So if that's the case, and\nmy computer is actually

laying out the word hi in memory\n

What exactly is s if,\nat the end of the day

H-I exclamation point null is storing--\n

Now that I've taken off\nthose training wheels

and showed you where H-I\nexclamation point null actually are

Well s, as always, is\nactually a variable.

Even in the code I\nproposed a moment ago

s is apparently a data type\nthat yes, doesn't come with C

but CS50's library makes it exist.

s is a variable of type string,\nso where is s in this picture?

Well, it turns out that\ns might be up here.

Again, I'm just drawing it anywhere\nfor the sake of discussion

but s is a variable\nper that line of code.

What s is storing,\napparently, I claim, is 0x123.

I actually don't really care about these\n

s is apparently, as of now, today,\n

Specifically, the first character in s.

And this is the last\npiece of the puzzle.

Last week we had this clever way\n

Well, it turns out that strings are\n

as a variable that is a\npointer, inside of which

is the address of the first\ncharacter in the string.

So if s points at the\nfirst character and you

can trust that backslash zero\nis at the end of the string

that's literally all you need to figure\n

Well, let's be a little more concrete.

In terms of this picture, if I've\n

it turns out all this time since\n

semi-secretly been an\nalias for char star.

So why does this make sense?

It's a little weird still,\nbut if in our previous example

we were able to store the address of\n

well, if as of now strings\nare just the address

of the first character in a string, then\n

because that means s is the\naddress of a character, the very

first character in the string.

Now, the string might have three letters\n

if it's a long paragraph,\nbut that's fine

because you can trust\nthat there's going to be

that null character at the very end.

So this is a general purpose\nway of representing strings

using this new mechanism in C.

So in fact, let me go ahead\nhere and introduce maybe

a couple of manipulations of this.

Let me go back to my code here, and\n

and let's instead now\ndo, for instance, this.

Let me add in the CS50 library,\nso we'll include CS50.H for now.

I'm going to go ahead\nand inside of main

give myself a string s\nequals hi exclamation point.

I don't type the backslash zero.

C does that for me automatically by\n

Now let me just go ahead and print it.

So this again is week 1 style stuff\n

So let me do make address, Enter,\n

But let's start to peel back\nsome of these layers here.

Let me first of all, get rid of\nthe CS50 library for a moment

and let me change string to char star.

And it's a little bit weird\nbut yes, the convention

is to say char, a space, then the\n

Strictly speaking though, you might\n

do it like this or like\nthis, but the canonical way

is typically to do it like that.

So now no more CS50 library, no\n

I'm just treating strings\nfor what they really are.

Let me go ahead and do\nmake address, Enter--

so far so good-- ./address--

So %s is a thing that comes with printf\n

terminology but strictly speaking\n

It's always been char star,\nso what this means now is I

can start to have some fun\nwith these basic ideas

even though this is not purposeful\n

But if s is this-- let me go back\n

Let's put those training wheels\nback on for just a moment

so that I can do one\nmanipulation at a time.

Here's my string s, as before.

Well, let me go ahead and\ndeclare a char called c

and let me store the first character\n

s bracket zero, and\nthat should give me h.

And then just for kicks, let\nme go ahead and do char star--

whoops-- let me go ahead and do\nchar star p equals ampersand c

and see what this\nactually prints for me.

Let me go ahead and\nprint out what p is here.

So we're just playing around.

So make address-- so\nfar so good-- ./address.

All right, so what have I just done?

I've just created a char c and\nstored in it the letter H, which

is the same thing as s bracket I, then\n

and that's apparently 0x7FF whatever.

But I technically\ndidn't have to do that.

Let me go ahead and do two things now.

Instead of just printing p, let me go\n

Let me go ahead and do\nmake address, Enter--

so far so good-- ./address and--

damn it, what did I do wrong.

Oh shoot, I didn't want to do that.

Oh, I really made a mess of this.

That was supposed to be impressive\nbut it was the opposite.

So if I intended to do this,\nwhy are lines nine and 10

Didn't really intend to go here,\nbut let me try to save this.

Why are we seeing different addresses,\n

AUDIENCE: [INAUDIBLE]\nis the character c is

its own sort of location\nof the [INAUDIBLE]

and it's taking off just\nthe values [INAUDIBLE]..

So if I really wanted to\nweasel my way out of this

this is a great answer to the\nprevious question which was about

what if I introduce another variable,\n

and not in this case an\nint, but an actual char.

Here, I've made c be a copy of the\n

So if I were to draw\nit on the screen that

would give me a different\nrectangle in which this copy of h

So I didn't intend to\ndo this, but what you're

seeing is yes, the address of s--

and apparently that's at a\npretty low address by default

here-- then you're\nseeing the address of c.

But even though each\nof them is h, I claim

one is at a different address in memory.

And this has always been happening.

Any time you created one variable\n

or here, or here, or\nsomewhere else in memory.

Now for the first time all we're\n

the computer's memory to\nsee what is actually there.

So let me actually back\nthis up a little bit

and do what I intended to do here,\n

So if string s equals quote\nunquote, hi, let's go ahead

and give myself a pointer, called\n

All right, so now let me go ahead and\n

So we're just going to\ndo one thing at a time.

So make address, Enter, ./address.

There, at the moment, is the\n

What I meant to do now, was this.

If I want to print out\ntwo things this time

let me print out not only what p is,\n

Because if I claim that everyone from\n

s bracket zero just representing\nthe first character in s

by definition of strings\nbeing arrays of characters.

Then s, as of today, is itself\nthe address of a character

So if I now do make\naddress, and do ./address

this time I see the same exact things.

This is really the lamest sort\nof thing to be applauding over

but what we're demonstrating here is\n

of the first character in c.

So if we borrow some of our\nmental model from last week--

well, if s bracket zero is the first\n

that expression should be the same as s.

Now this isn't to say that we\nwould jump through these hoops

all the time with this much syntax,\n

that s is in fact, as I claimed a moment\n

Not even multiple characters, it's\n

but the key thing is it's the address\n

and per last week we\ntrust that C is going

to look for that null\ncharacter at the very end just

to make sure it knows where\nthe string actually ends.

All right, a question came up over here.

To summarize, on line\neight, when I am using %p--

that just means print a pointer\nvalue, so 0x something--

Previously, when we used %s, printf knew\n

of s, but h, i, exclamation point, and\n

p is different. %p tells the\ncomputer to go to that address--

sorry, tells the computer to\nprint that address on the screen.

So this is where %s all\nthis time has been powerful.

The reason printf worked\nin week 1 and 2 and 3

was because printf was designed\nby some human years ago

to go to the address that's\nbeing passed in-- for instance

s-- and print out\ncharacter after character

after character until it sees the\nnull character backslash zero

So that's-- you're getting a lot\n

Today we're using\nsomething much simpler, %p

which just literally prints what s is.

And the reason we\ndon't do this in week 1

is just because this\nis like way too much

to be interesting when\nall you want to print out

is hi or hello, world, or the like.

But now what we're\nreally doing is revealing

what's been going on this whole time.

And let me make one other example here.

Let me go ahead and get\nrid of this variable

here and let me just print out a\n

I'm going to print out not just s\n

the address of every character in s.

So let's get the first letter\nin s and get its address

and I'm going to do copy\npaste for time's sake

but not something I would do frequently.

So let me print out the address of the\n

the third, and actually\neven the fourth, which

is the backslash zero, by doing this.

So when I compiled this program--\nmake address, ./address--

I should see two\nidentical values and then

additional values that\nare one byte away.

In my diagram a moment ago, my addresses\n

Now it starts at, by chance,\n0x402004, which is s.

0x402004 is the same thing\nas s because I'm just

saying go to the first character\nand then get its address.

Those are one in the same now.

And then after that\nis 0x402005, 006, 007

because that is just like the diagram.

Go to the i, to the exclamation\n

So all I'm doing now is using my\nnewfound understanding of what

ampersand does and what the star\n

I'm poking around in\nthe computer's memory.

Just to demonstrate there's no magic.

It's all there very deliberately\nbecause I or printf or someone

DAVID J. MALAN: Really good observation.

So it's indeed the case\nthat hi, unlike 50

is ending up at a very low address,\n

That's actually because,\nlong story short, strings

are often stored in a different\npart of the computer's memory--

more on that later\ntoday-- for efficiency.

There's actually only going to be one\n

point, and the computer is going to\n

but other values like\nints and floats and the

like-- they end up lower\nin memory by convention.

But a good observation, because\nthat is consistent here.

All right, so a couple final details\n

Let me go ahead and claim that\nwe implemented char star--

or rather, string as a\nchar star as follows.

As of last week we\nwere writing this code.

As of this week, we can now start\n

specifically, we invented\nin the CS50 library.

But it turns out you've seen a way\n

We played around last time with data\n

and briefly the typedef keyword,\nwhich defines a type for you.

And if I highlight\nwhat's interesting here

the way we invented a\nperson data type last time

was to define a person as having\ntwo variables inside of it--

a structure that encapsulates a\nname and encapsulates a number.

Now even though the syntax is a little\n

thing, notice that this could be a\n

If I want to create a type called\n

then I use typedef to make\nit defined to be char star.

So this is literally all\nthat has ever been in CS50.h

in addition to those prototypes\nof functions we've talked about.

typedef char star string\nis a one-line code

that brings the word string\nas a data type into existence

and that's all that's ever been there.

But the star, the char star,\nis just too much in week 1.

We wait until this point\nto peel back that layer.

are any questions, then,\non what a string is?

What star or the ampersand are doing?

If that is-- is that why when you\n

did, or almost did, problems arise.

And in fact yes, last\nweek we use str compare--

STRCMP-- for a very deliberate\n

accidentally would have compared two\n

All right, well, before we give\n

we have lots of pieces of paper.

If anyone wants to come on up and\n

if you want to make your own\neight by eight grid of something

to share with the class if you're\n

Otherwise, let's take 10 minutes\nand will return after 10.

All right, so let's come\nback to this question of how

we can start to use these pointers\n

The goal ultimately\nnext week is going to be

to use these addresses to really\n

structures than just persons,\nlike last week, or candidates

in the context of an\nelectoral algorithm

if you will, and actually really use\n

to represent not just\nimages but maybe videos

and other two-dimensional\nstructures as well.

But for now, let's come back\nto this address example

whittle it down to just a hi initially,\n

So let me re-add the\nCS50 library just so we

use our synonym for a moment,\nthat is the word string

and I'll redefine s as a string.

And what I didn't mention before\nis that these double quotes

that you've been using for some\n

The double quotes are\na clue to the compiler

that what is between them is in\nfact a string as we now know it

which means the compiler will\ndo all the work of figuring out

where to put the h, the\ni, the exclamation point

and even adding for you\nautomatically a backslash zero.

And what the compiler\nwill do for you, too

is figure out what address\nall four of those chars

ended up at and store it\nfor you in the variable s.

So that's why it just happens with\n

or even stars explicitly, but the star\n

string is just synonymous\nnow with char star.

It's not really as readable,\nbut it is now the same idea.

So I'll leave string in place\njust to do something week

1 style here for a moment, and let's go\n

So I'm going to use %c this time, and\n

and then I'm going to print out\ns bracket one and s bracket two

literally doing week three\nstyle from last week--

a printing of every character\nin s as though it were an array.

So ./address should give\nme h-i exclamation point.

And if I really want to get\ncurious, technically speaking

I could print out one more location,\n

make address ./address and there is,\n

I'm not seeing zero because I didn't\n

it's literally eight zero bits\n

if you will, in printf speak.

And so what I'm seeing here\nis like a blank symbol.

That just means there is\nsomething else there--

it's apparently all eight\nzero bits, but they are there

even though we're not seeing\nthem literally right now.

Well, let's go ahead and\npeel back one of these layers

and let me go ahead and get rid of\n

therefore, the word string because\n

I'm going to now do\nmake address, ./address

and it's the same exact thing.

And now, let's just focus on the hi\n

So I'm going to recompile one last time\n

Well, it turns out that the\narray notation we used last week

was technically some of\nthis syntactic sugar.

Sort of a neat way to use\nsyntax in a useful way

but we can see more explicitly today\n

Let me go ahead and do this.

Let me adventurously say I\nwant to print out not s bracket

zero, but I want to print out\n

So to be clear, what is s now?

It's the address of a string.

s is the address of the\nfirst char in a string

and again, that's sufficient for\n

the computer will see that there's\n

So s is specifically the address\n

So that means, using my\nnew syntax, if I want

to print out that first\ncharacter I can print out star

s, because recall that star is the\n

repeat the word char, you\ndon't repeat the word int--

That means go to that address.

Similarly, if I, in my newfound\nknowledge of how strings work

know that the h comes first,\nthen the i right after it

then the exclamation point, then\n

one byte apart, I could\nstart to do some arithmetic.

I could go to s plus 1 byte and\nprint out the second character

and I could print out\nwhatever is at s plus 2--

in fact, doing what's generally\nknown as pointer arithmetic.

Literally treating pointers\nas the numbers they are--

hexadecimal or decimal, doesn't really\n

And go ahead and add\none byte or two bytes

to them to start at the\nbeginning of a string

and just poke around from left to right.

So this now is equivalent to what we\n

notation, but now I'm re implementing\n

plumbing, understanding ampersand\n

so if I remake this\nprogram and do ./address

I should still see\nh-i exclamation point.

But what I'm really doing is\njust kind of demonstrating

hopefully, my understanding\nof what really

is going on in the computer's memory.

Now, programmers who are\nmaybe trying to show off

might actually write this syntax.

I think the more common syntax\nwould be what we did last week--

s bracket zero, s bracket one.

It's just a little more\nreadable and we don't

need to brag about or care about\nthis underlying representation.

The square brackets last week\nwe're an abstraction, if you will

on top of what is lower level math.

But that's all that's going\non underneath the hood.

We're poking around from\nbyte to byte to byte.

All right, let me pause here, see if\n

Let's do one more then, just\nto demonstrate that this is not

Let me go ahead and\nget rid of all of this

and let me give myself an array\nof numbers like I did last week.

So if I'm going to\ndeclare all the numbers

at once using this funky\ncurly brace notation

I can do like 4, 6, 8, 2, 7, 5, 0.

So seven different numbers inside\n

I don't, strictly speaking,\nneed to say seven.

The compiler is smart\nenough to figure out

how many numbers I put\nwith commas between them

and that just gives me an array\ncontaining 4, 6, 8, 2, 7, 5, 0.

So it turns out I can print each of\n

I can do a printf of %i backslash n,\n

and let me just do some quick copy/paste\n

Theoretically, that should\nprint out 4, 6, 8, and so forth.

But I can do the same sort\nof manipulation understanding

what pointers now are,\nusing pointer arithmetic.

So let me actually unwind this\nand just go back to one printf

and instead of printing numbers bracket\n

let me just go and print out\nwhatever is at that address--

Let me then print out\nthe second digit, which

is going to be whatever is at numbers\n

and do whatever is at numbers plus 2,\n

let me do it four more\ntimes and do what's

at location three, four, five, and six.

And that's seven total numbers\n

So let me just quickly run this.

There are those seven\ndigits being printed.

But there's something\nsubtle but also useful here.

Because I made an array of integers.

But think back-- how big is a\ntypical integer, have we claimed?

Four bytes, or 32 bits, so it's\nworth noting that I don't really

need to worry about that detail.

Notice that I did not do plus 4,\n

I, the programmer,\nstrictly speaking, don't

need to worry about how\nbig the data type is.

This is the power of pointer arithmetic.

The compiler is smart enough to know\n

that is the same as saying\ngo one more piece of data--

so if it's an int, move four.

If it's a second int, move eight.

If it's a third int, move 12.

Pointer arithmetic handles that\nannoying arithmetic for you

so you can just think of this\nas a number after a number

after a number that are back to\n

Which is only to say plus 1, plus 2,\n

Because the compiler knows what\n

Now, there's one other\ndetail I should reveal here

that I've taken for granted.

In the past I was using double\nquotes to represent strings

and I claim that the compiler's\nsmart enough to realize that oh

if I have double quote hi, that means\n

and then the backslash zero.

It turns out that you can actually treat\n

is itself a pointer,\nand this is actually

going to be something\nuseful in upcoming problems

when we want to pass arrays\naround in the computer's memory.

Notice that strictly speaking on line\n

There's no star, there's\nno ampersand-- there's

nothing new there, and yet\ninstantly on line seven

I'm pretending that it is the\naddress, and this is actually OK.

It turns out that an array\nreally can be treated

as the address of the first\nelement in that array.

The difference is that there's no\n

This is just part of\nthe phone number here

the ending in zero-- that's not\nlike a special backslash zero.

So this is something we're going to\n

There's this interrelationship\nbetween addresses and arrays

that just generally allows you to\n

but the math is taken care of for you.

Are any questions then on this before\n

DAVID J. MALAN: Potentially.

If you go beyond the end of an array,\n

The problem is that that symptom\nis sometimes nondeterministic

which means that sometimes it\nwill happen, sometimes it won't.

It often depends on how far off the\n

You'll often not induce\nthe segmentation fault

if you just poke a little too\nfar, but if you go way too far

But we'll give you a tool today\n

exactly that kind of situation.

So let's go ahead now and do\n

but that actually comes back\nto that spoiler from earlier.

Let me go ahead and create a program\n

I'm going to go ahead and\nallow myself the CS50 library

not so much for string but so that\n

which is way easier than the way we'll\n

Let me give myself stdio.h,\ndo an int main(void)

not worrying about command line\n

and get an int i using get int, and\n

then let me give myself an int j, ask\n

and then let me go ahead and kind of\n

if i equals equals j,\nthen let's go ahead

and print out something like "same,"\n

and print out "different" if\nthey are not, in fact, the same.

So that would seem to be a program that\n

All right, so let's go\nahead and run make compare--

OK, i will be 50, j will be 50--

i will be 50, j will be 42.

So so far, so good in this\nfirst version of comparison.

But as you might see\nwhere I'm going with this

let's move away from integers and let's\n

So I could do string s over here--

Then I could do string t over\nhere, and GetString over here

asking the user for t this time, here.

And then I can compare the two.

and this is a common convention.

If you've used s for string already you\n

for simple demonstrations like this.

I'm going to compare the two, just like\n

Make compare-- so far\nso good-- ./address--

Let me go ahead and\ntype in something like

hi, exclamation point and bye,\n

should definitely be different.

Let me run it again with hi, exclamation\n

Different-- maybe I messed up.

Let's maybe do it lowercase,\nmaybe that'll fix.

But no, those two are different.

So to come back to what I described\nas a spoiler earlier, what's

the fundamental issue here, to be clear?

Why is it saying different\neven though I'm pretty

sure I typed the same thing twice.

Yeah, this is where it's now\nuseful to know that string has been

an abstraction-- a training wheel, if\n

still use GetString because\nthat's convenient still--

but if I change string\nto be char star, it's

a little more explicit as to what s and\n

that is the address of\na char. t is a pointer

to a char, that is\nthe address of a char.

Specifically, the first character\nin s and the first character

So if I'm comparing\nthese two it should stand

to reason that they're\ngoing to be different.

Because s might end up here in memory\n

Each time I call GetString, it is\n

to know that, wait a minute--\nyou typed the same thing.

I'm just going to hand\nyou back the same address.

That doesn't happen because we\n

Each time I call GetString,\nit returns, apparently

a different copy of the\nstring that was typed in.

A hi over here and a hi over here.

They might look the same to\nthe human but to the computer

they are different chunks of memory,\n

And here, too, we can reveal\nwhat is GetString returning?

Well, up until today it was\nreturning a string, so to speak.

Technically, what\nGetString has always been

doing is returning the address\nof the first char in a string

and trusting that we put a backslash\n

typed in, and that's enough now\nfor printf, for strlen, for you

to know where a string begins and ends.

So GetString has actually\nalways returned a pointer.

It has not returned a quote\nunquote string per se

but there are functions that can\nsolve this comparison for us.

Recall that I could do\nsomething like this.

I could actually go\nin here and I could--

So if I include str compare here and\n

let's see now what happens\nwhen I make compare.

Implicitly declaring library\n

So you might have seen this error before\n

but there's some evidence of\nstars or pointers going on here.

It looks like I didn't include\nthe string.h header file

Include string.h which, despite its\n

called string, it just has\nstring-related functions in it

Now let's type in hi, exclamation\n

These are now-- oh, I used it wrong.

That was supposed to be\nimpressive, but it's the opposite.

DAVID J. MALAN: Yeah, it\nreturns three different values.

Zero if they're the same, positive\n1 becomes before the other

negative if the opposite is true.

I just forgot that, so like\nI did last week correctly

if I want to compare them for\nequality per the manual page

I should be checking for\nzero as the return value.

Now make compare, ./compare, Enter.

Let's try it one last time-- hi and hi.

OK now, they're in fact the same.

And indeed, not that it's\nreturning same all the time.

If I type in hi and\nthen bye, it's indeed

noticing that difference as well.

Well, let me go ahead and\ndo one other thing here.

Let me go ahead now and just reveal\n

Let's get rid of the string comparison\n

The simple way to print this out would\n

taking an address and start\nthere, print every character up

until the backslash n, so let's\njust hand it s and do that.

And then let's do one more, %s,t.

This is, again, sort of a\nmix of week 1 and this week

because I got rid of the word string.

I'm using char star, but I'm still\n

Let me go ahead and run compare\nnow, and if I type hi and hi

I should see the same thing twice.

So they look the same, but here\nnow we have the syntax today

to print out the actual\naddresses of these things.

So let me just change the s to a p,\n

and print it, it means just\nprint the address as a pointer.

So make compare, ./compare, and now\n

and I should see, indeed, two\nslightly different addresses given

One's got a B at the end,\none's got an F at the end

and they are indeed a few bytes apart.

So this is just confirming what\n

So what does this mean, perhaps\nin the computer's memory?

I've zoomed out so I have a little\n

Here might be s in memory when I do\n

I get a variable that's of size\n

claimed earlier that on modern systems,\n

nowadays so they can count even higher.

And inside of the computer's\nmemory, also, might be hi.

And I don't know where it ends\nup so for the sake of discussion

That's what was free\nwhen I ran the program.

h-i exclamation point, backslash zero.

Maybe it ended up, for the sake of\n

So to be clear, what is s\nstoring once the assignment

operator copies from right to left?

What is s storing if I\nadvance one more slide?

0x123, the presumption\nbeing that if a string is

defined by the address of its first\n

is 0x123, then that's indeed\nwhat should be in the variable s.

And so technically, that's what's\n

GetString indeed returns\na string, so to speak

but more properly it returns\nthe address of a char.

What's been then copied from right to\n

all these weeks is indeed that address.

Now technically, we don't really need\n

It suffices to just think about\nthem referentially, but let's

first consider where t might be.\n

created on my second line of code.

Maybe it ends up there,\nmaybe somewhere else.

For the sake of discussion\nI'll draw it left and right.

Where did the second word\nend up that I typed in?

Well, suppose the second copy of\nhi ended up at 0x456457458459.

I'll pluck this one off myself.

And so this is now a pictorial\nrepresentation of why

and let's abstract away everything else.

When I compared s against t using\n

they're obviously not the same.

One is over here, one is over here.

And per a moment ago, one is\n0x123, the other is 0x456.

Yes, technically they're pointing\nat something that's the same

but that just reveals\nhow str compare works.

str compare is apparently\na function that

takes in the address of\na string as its argument

and the address of another\nstring as its argument

it goes to the first character in\n

and probably has a for\nloop or a while loop

and just goes from left to\nright, comparing, looking

for the same chars left and right, and\n

If it does notice a difference it\n

And that's very similar, recall, to how\n

I used a for loop, I was\nlooking for a backslash zero.

str compare is probably a little similar\n

but comparing, this\ntime not just counting.

Are any questions then,\non string comparison

and why it is that we use str\ncompare and not equals equals?

AUDIENCE: Do pointers have addresses?

DAVID J. MALAN: Do\npointers have addresses?

So we won't do that today, but I could\n

That would give me the\nequivalent of a char star star

that itself could be\nstored elsewhere in memory.

We don't do that recursively forever.

There's star and there's star\nstar, but yes, that is a thing

and it's very often useful in the\n

which we haven't really talked about,\n

All right, so what might we now\ndo to take things up a notch?

Well let's go ahead and implement\na different program here

that maybe tries copying some\nvalues, just to demonstrate this.

Let me open up a file\ncalled, how about copy.c

and I'm going to start\noff with a few includes.

So let's include the CS50 library just\n

Let's include-- how about stdio\nas always, let's preemptively

include string.h and maybe\none other in a moment.

Let's do int main(void) as before.

And then in here, let's get a\nstring from the user and just

And heck, we can actually just\ncall this char star if we want

or string, since we're\nusing the RS50 library.

But we'll come back to that.

Let's now make a copy\nof s and do s equals t

using a single assignment operator and\n

Let's go into the first character\nof t, which is t bracket zero

and then let's uppercase\nit using that function

that we've used in the past of\n

And actually, I should go back up here.

If I'm using toupper or if you use\n

I might not remember this offhand,\n

There was a bunch of helpful\nfunctions in that library as well.

Now at the very last line of the program\n

are by simply printing out %s for each\n

of course, and let's\nsee what happens here.

oh my God, so many mistakes.

String t equals s, sorry, so\nI'm creating two variables

s and t respectively,\nand I'm copying s into t.

There we go. ./copy, and let's\nnow type in, for instance

how about hi exclamation point\nin all lowercase this time

I don't think that's what I\nintended, so to speak, here.

Because notice that I got s from\nthe user, so that checks out.

I then copied t into\ns, which looks correct.

That's what we always\nuse assignment for.

Then I uppercase the first\nletter in t, but not s--

then I printed s and t and then\nnoticed, apparently, both s

So if you're starting to get a\nlittle comfortable with what's

going on underneath the hood,\n

Why did both get capitalized?

Why did both get capitalized?

AUDIENCE: Could it be they're\nreferencing the same address?

DAVID J. MALAN: Yeah, they're\nrepresenting the same address.

If you create another variable called\n

you are literally assigning\nit the value in s

which is 0x123 or something like that.

And so at that point in the\nstory both s and t presumably

have a value of 0x123,\nwhich means they technically

point to the same h-i\nexclamation point in memory.

Nowhere did I tell the computer to give\n

per se, I literally said just copy s.

So here's where an understanding of what\n

I'm only copying the pointers.

So what actually went on in memory?

Let's take a look here at this grid.

If I created s initially,\nmaybe it ends up here.

And I created hi in lowercase,\nand it ended up down here.

Then the address was, again, like\n

If then I create a\nsecond variable called t

and I call it a string, a.k.a. char\n

But when I copy s into t by\ndoing t equals s semicolon

that literally just copies s into\n

So if we now abstract away all these\n

with arrows, what we've drawn in\nthe computer's memory is this.

Two different pointers but storing\nthe same address, which means

the breadcrumbs lead to the same place.

And so if you follow the t breadcrumb\n

it is functionally the\nsame as copying the--

changing the first letter\nin the version s as well.

So what's the solution, then,\nto this kind of problem?

Even if you have no idea\nhow to do it in code

what's the gist of what I\nreally intended, which is

I want a genuine copy of s, called t.

I want a new h-i exclamation\npoint backslash zero.

What do I need to do\nto make that happen?

AUDIENCE: I think there's\na function called str copy.

DAVID J. MALAN: So there is a\nfunction called str copy, strcpy

which is a possible\nanswer to this question.

The catch with stir copy is that you\n

what the source string is--\nthe one you want to copy--

you also need to pass in the\naddress of a chunk of memory

into which you can copy the string, and\n

and we need one more building\nblock today, if you will.

We haven't yet seen a way to\ncreate new chunks of memory

and then let some other\nfunction copy into them.

And for this, we're going to introduce\n

And this is the last and most\npowerful feature perhaps, today

whereby we're going to introduce two\n

malloc means memory allocate,\nwhich literally does just that.

It's a function that takes a number\n

do you want the operating system to\n

It's going to find it\nand it's going to return

to you the address of the first byte of\n

and then you can do anything you\nwant with that chunk of memory.

free is going to do the opposite.

When you're done using a chunk of\n

you can say free it, and that means you\n

and then the operating system can\n

So this is actually evidence of\na common problem in programming.

If your Mac your PC has ever been in\n

really slow, or it's slowing to a\n

one of the possible\nexplanations could be

that the program you're\nrunning by Apple or Microsoft

or whoever, maybe they're using\nmalloc or some equivalent

asking the operating system--

Mac OS or Windows-- for,\ngive me more memory.

The user is creating more images.

The user is typing a longer essay.

Give me more memory, more memory.

If the program has a bug and never\n

your computer might end up using\nall of the available memory

and honestly, humans are not very good\n

Very often programs, computers\njust freeze at that point

or get really, really slow because\n

when there's not enough memory left.

So one of the reasons for a\ncomputer really slowing down

might be calling for malloc a lot, or\n

Which is to say, you should\nalways use these two functions

in concert and free memory\nonce you are done with it.

So let me go ahead and do this in\n

Let me go ahead and do this.

Before I copy s into t using\nsomething like str copy

I first need to get a bunch\nof memory from the computer.

So to do that, let's make this super\n

so I'm going to change my strings\n

and what I technically\nam going to store in t

is the address of an\navailable chunk of memory.

To do that, I can ask the computer\nto allocate memory for me

If I want to create a copy\nof h-i exclamation point

Because I need the h, the i, the\n

It's up to me to understand\nthat and ask for it.

It's not going to happen magically.

Nothing does in C. So I could\njust naively type four there

and that would be correct\nif I type in h-i exclamation

point or any other three letter word\n

I should probably do\nsomething like strlen of s

plus 1 for the additional\nnull character.

Recall that string length\ndoes it in the English sense--

it returns the length of the string\n

the fact that I'm going\nto need that backslash n.

Now let me do this old\nschool style first.

Let me go ahead and manually\ncopy the string s into t first.

So for int i equals 0, i is less than\n

Then inside my for loop, I'm going\n

i, but actually I want\nthe null character too

so I want to do the length\nof the string plus 1 more

and heck, I think I learned\nan optimization last time.

If I'm doing this again\nand again, I could really

do n equals strlen of s plus 1\nand then do i is less than n

just as a nice design optimization.

I think this for loop will\nactually handle the process, then

of copying every character from s into\n

Or I could get rid of all of that\n

is to use str copy, which takes as\n

and its second argument the source.

So copy from right to left in this case,\n

automatically for me as well.

I can now capitalize safely.

The first character in t, which\n

than s, and then I can print them both\n

So make copy-- all right,\nwhat did I do wrong?

Implicitly declaring library\nfunction malloc dot, dot, dot.

So we've seen this kind of error before.

What is-- even if you don't\nknow quite how to solve it

what's the essence of the solution?

What do I need to do to fix this\n

declaring a library function?

I need to include the library.

And I could look this up in the manual,\n

There's another library\nwe'll occasionally

need now called standard lib--

standard library-- that contains\nmalloc and free prototypes

All right, let me just clear this\n

Now I'm good. ./copy, Enter, All right.\n

t and s now come back as intended.

s is untouched, it would seem,\nbut t is now capitalized.

Are any questions, then, on\nwhat we just did in code?

AUDIENCE: You said that\nmalloc and free go together.

There's a few improvements\nI want to make, so let

me actually do those right now.

Technically, I should practice what\n

when I'm done with t, free t.

Fortunately, I don't have\nto worry about how big t

was-- the computer remembers how many\n

all of them, not just the first.

I don't need to do free\ns, and I shouldn't

because that is handled\nautomatically by the CS50 library.

s, recall, came from\nGetString, and we actually

have some fancy code in\nplace that makes sure

that at the end of your\nprogram's execution

we free any memory that we\nallocated so we don't actually

waste memory like I described earlier.

But there's actually a\ncouple of other things

if I really want to be\npedantic I should put in here.

It turns out that\nsometimes malloc can fail

and sometimes malloc doesn't\nhave enough memory available

because maybe your\ncomputer's doing so much

stuff there's just no\nmore RAM available.

So technically, I should\ndo something like this--

if t equals equals null,\nwith two L's today

then I should just return 1 or something\n

I should probably print\nan error message too

but for now I'm going to keep it simple.

I should also probably check this.

This is a little risky of me.

If I'm doing t bracket zero, this is\n

But what if the human just\nhit Enter at the prompt

and didn't even type h, let\nalone h-i exclamation point?

What if there is no t bracket zero?

So technically, what I should probably\n

is at least greater than zero,\n

And then at the very\nend if all goes well

I can return zero, thereby signifying\n

So yes, these two functions, malloc\n

And so if you call malloc you\nshould call free eventually.

But you did not call malloc for s,\n

AUDIENCE: Here's a question.

Why do we do malloc plus 1?

DAVID J. MALAN: Why\ndid I do malloc plus 1?

So malloc-- sorry, malloc\nof string length of s

plus 1-- the string length is the\n

would perceive it in English.

So h-i exclamation\npoint-- strlen gives me 3

but I know now as of last week and\n

and a string always has an extra byte.

The onus is on me to\nunderstand and apply

that lesson learned so that I actually\n

And here's just an annoying thing when\n

week, it turns out that\nN-U-L-L is the same idea.

It's also zero, but it's zero\nin the context of pointer.

So long story short, you never\n

and we saw it on the screen.

You will start writing N-U-L-L when you\n

And what I mean by that is this.

If malloc fails and there's just\nnot enough memory left inside

of the computer for you, it's\ngot to return a special value

and that special value is\nN-U-L-L in all capital letters.

That signifies something went wrong.

Do not trust that I'm giving\nyou a useful return value.

Other questions on\nthese copies thus far?

DAVID J. MALAN: Good question.

Will str copy not work without malloc?

You kind of need both in\nthis case because str copy

by definition-- if I pull up its\n

to put the copied characters.

It's not sufficient just to\nsay char star t semicolon.

That only gives you a pointer.

But I need another\nchunk of memory that's

just as big as h-i exclamation\npoint backslash zero

so malloc gives me a\nwhole bunch of memory

and then str copy fills it with h-i\n

So again, that's why we're\ngoing down to this lower level

because once you understand\nwhat needs to be done

you now have the functions to do it.

So let's actually consider\nwhat we just solved.

So in this next version of the program\n

t was initialized for the\nreturn value of malloc

and maybe the memory that\nI got back was here--

I've left it blank\ninitially because nothing

is put there automatically by malloc.

I just get a chunk of memory that\n

I then assign t to that return value,\n

Notice there's no backslash zero.

This is not yet a string\nit's just a chunk of memory--

four bytes-- an array of four bytes.

What str copy eventually did\nfor me was it copied the h over

the i over, the exclamation point\nover, and the backslash zero.

And if I didn't want to use str copy or\n

would have done exactly the same thing.

Are any questions, then,\non these examples here.

DAVID J. MALAN: Good question.

After malloc, if I had then\nstill done just t equals s

it actually would have recreated\nthe same original problem

by just copying 0x123 from s into t.

So then I would have been left with\n

steps ago, I would have-- and\nI can't quite do it live--

this arrow, if I did\nwhat you just described

would now be pointing over here and so\n

the problem, I would have\njust additionally wasted

four bytes temporarily that\nI'm not actually using.

do you always use malloc\nand str copy together?

These are both solving\ntwo different problems.

malloc's giving me enough memory to\n

However, you could actually use an\n

and you could use str copy on that, and\n

But thus far, it's a\nreasonable mental model

to have that if you\nwant to copy strings

you use malloc and then str\ncopy, or your own homegrown loop.

DAVID J. MALAN: Say that once more.

str copy, per its documentation,\nwill copy the whole string

plus the null character at the end.

It just assumes there will be one there.

It's therefore up to you to pass str\n

If I only ask malloc\nfor three bytes, that

could have potentially\ncreated a memory problem

whereby str copy would just still\nblindly copy one, two, three

four bytes, but technically it should\n

You do not yet have access to the\n

because you never asked malloc for it.

AUDIENCE: So the number inside\n

The number inside malloc--\nit's one argument.

It's the number of bytes you want back.

AUDIENCE: Does that mean you\nhave to remember [INAUDIBLE]??

DAVID J. MALAN: Yes, the onus\nis on you, the programmer

to remember or frankly, use\na function to figure out

how many bytes you actually need.

That's why I did not ultimately\ntype in four manually

So the plus 1 is necessary if you\n

but using strlen means\nthat I can actually

play around with any types of\ninputs and it will dynamically

So suffice it to say,\nthere's so many ways

already where you can\nstart to break programs.

Let's give you at least one tool for\n

And indeed, in upcoming\nproblem sets you will

use this to find bugs in your own code.

Not just using printf, not just using\n

So let me go ahead and deliberately\n

that has some memory-related errors.

Let me include stdio.h at the top and\n

so I have access to malloc now.

Let me do int main(void) and then\n

I want to allocate\nmaybe how about three--

Just for the sake of discussion.

So I'm going to go ahead and do malloc\n

I want three integers and\nan integer is four bytes

so technically I could do this--

3 times 4, or I could do 12 but again,\n

and if I run this program on\na slightly different computer

int might be a different size.

so the better way to do this would be\n

And this is just an operator you can use\n

on this computer, how big is an int?

How big is a float, or something else?

So that's going to give me that many--

that much memory for three ints.

What do I want to assign this to?

Well, malloc returns an address.

Pointers are addresses, so I'm going\n

This is a little less obvious,\nbut again go back to basics.

The right hand side here gives me a\n

malloc returns the address of\nthe first byte of that chunk.

How do I store the address of anything?

The syntax for today\nis type of data, star

where the type of data in question\n

Again, it's kind of purposeless, only\n

here, but this is equivalent now to\n

in total, presumably, so I\ncan technically now do this.

I can go into maybe the first\n

Second location, the number 73, and the\n

Now I've deliberately\nmade two mistakes here

because I'm trying to trip\nover my newfound understanding

or my greenness with\nunderstanding pointers.

One, I didn't remember that I\n

malloc essentially returns an array,\n

An array of three ints,\nor more technically

the address of a chunk of memory\nthat could fit three ints.

So I can use my square bracket\n

and use pointer arithmetic, but\n

But I have made two mistakes.

I did not start indexing\nat zero, so line seven

should have been x bracket zero.

Line eight should have been x\nbracket 1, and then line nine

should have been x bracket 2.

The second mistake that\nI've made as a side effect

is I'm also touching\nmemory that I shouldn't.

x bracket 3 would mean go to the\n

I only asked for enough\nmemory for three ints

not four, so this is what's\ncalled a buffer overflow.

I am accidentally, but\ndeliberately at the moment

going beyond the boundaries of\nthis array, this chunk of memory.

So bad things happen,\nbut not necessarily

by just running your program.

Let me go ahead and just try this.

Make memory, and you'll see here\nthat it compiles OK. ./memory

and it actually does\nnot segmentation fault

which comes back to that\npoint of nondeterminism.

Sometimes it does, sometimes it\ndoesn't-- it depends on how bad

But there's a program that can\nspot these kinds of mistakes

and I'm going to go ahead and expand\n

and I'm going to run not just ./memory,\n

This is a command that comes\nwith a lot of computer systems

that's designed to find\nmemory-related bugs in code.

So it's a new tool in\nyour toolkit today

and you'll use it with\nthe coming problem sets.

It's output, honestly, it's hideous.

But there's a few things\nthat will start to jump out

and will help you with\ntools and the problems

sets to see these kinds of things.

That's on memory.c line\nnine, per my highlights.

So let me go look at line nine.

In what sense is this an\ninvalid write of size four?

Well, I'm touching memory\nthat I shouldn't, and I'm

touching it as though it's an int.

And an int is four bytes-- size four.

So again, this takes some practice to\n

but this is now a clue\nfor me, the programmer

that not only did I screw up, but\nI screwed up related to memory

and so this is just a hint, if you will.

It's not going to necessarily\ntell you exactly how to fix it

you have to wrestle with\nthe semantics, but invalid

write of size four-- oh, OK.

So I should not have indexed\npast the boundary here.

All right, so I\nshouldn't have done that.

So let me go ahead then and change this\n

All right, so let me go\nahead and recompile my code.

Make memory, ./memory, still doesn't\n

Let me go ahead and run Valgrind\n

And now there's fewer scary--

less scary output now, but\nthere's still something in there.

Notice this-- 12 bytes in one blocks--

no regard for grammar\nthere-- are definitely

lost in lost record one of one.

Super cryptic, but this is hinting\nat a so-called memory leak.

The blocks of memory are lost in\n

I asked for them but I never--

And this is the arcane way\nof saying, you've screwed up.

So this is an easy fix, fortunately.

Once I'm done with this memory I\n

So now let me go ahead\nand rerun make memory

it's still runs fine so all the while\n

But let me run Valgrind one more time.

All heap blocks were\nfreed, whatever that means.

And even though it's still a little\n

and in fact, it's pretty explicit--\n

So even though this is one of\nthe most arcane tools we'll use

it's also one of the most\npowerful because it can see things

that you, the human, might not, and\n

It does a much closer\nreading of your code

while it's running to figure\nout exactly what is going on.

Any questions, then, on this tool?

And we'll guide you after today\nwith actually using this, too.

Just helps you find\nmemory-related mistakes

that you might now be capable of making.

All right, let's do one\nother memory-related thing.

Let me shrink my terminal window here.

Let me create one other\nfile here called garbage.c.

It turns out there's a term of ours\n

that we can reveal as follows.

Let me include stdio.h,\nand let me include--

how about stdlib.h, and\nthen let me give myself int

main(void), and then in this\nrelatively short program

let me give myself three\nints using last week's

notation, just int scores bracket\n

Then let me go ahead and do for\n

i plus plus, then let me go ahead\nand print out, %i backslash n

This code, pretty sure is going\n

I've forgotten a step even though the\n

Yeah, I didn't provide the\nscores, so I didn't actually

initialize the array called scores\n

What's curious about this, though,\n

Let me go ahead and playfully\nmake garbage, Enter

and it's an apt description\nbecause what I'm about to see

are so-called garbage values.

When you, the programmer, do not\n

values, sometimes, who knows\nwhat's going to be there.

The computer's been\ndoing some other things

there's a bit of work that happens even\n

so there might be remnants\nof past ints, chars, strings

floats-- anything else in\nthere and what you're seeing

is those garbage values, which is\n

as I just did, to initialize\nthe value of some variable.

And this is actually\npretty dangerous, and there

have been many examples of\nsoftware being compromised

because of one of these issues\n

and all of a sudden users, maybe people\n

applications, could suddenly see the\n

Maybe someone's password that\nhad been previously typed in

or some other value like\na credit card number

that had been previously typed in.

There are different\ndefense mechanisms in place

to generally make this not\nso likely, but it's certainly

very possible, at least\nin this kind of context

to see values that you\nprobably shouldn't because they

might be remnants from\nsomething else that used them.

So this is to say again, you have this\n

but also now you have this great\nhacking ability to poke around

the contents of memory, and this is\n

trying to find ways to exploit systems.

All right, let's go ahead and\ntake a quick five minute break

and when we come back, we'll\nbuild on these final topics.

First, just a little programmer\n

will make a little bit of sense to you.

And what we'll also do next to take a\n

animates with claymation, if you\n

exactly what happens now if you have\n

values are and how they get there, and\n

It's one thing just to print\nthem out as I just did

it's another if you actually mistake\n

because garbage values are just zeros\n

But if you use that new\ndereference operator, the star

and try to go to a garbage value\nthinking incorrectly that it's

a valid pointer, bad things can happen.

Computers can crash or more familiarly,\n

So allow me to introduce, if we\n

our friend Binky from Stanford.

SPEAKER 1: Hey Binky, wake up.

SPEAKER 1: Well, to get\nstarted, I guess we're

going to need a couple of pointers.

BINKY: OK, this code allocates two\n

Well, I see the two pointers, but they\n

Initially, pointers\ndon't point to anything.

The things they point to are called\n

SPEAKER 1: Oh, right, right.

So how do you allocate a pointee?

BINKY: OK, well this code\nallocates a new integer pointee

and this part sets x to point to it.

SPEAKER 1: Hey, that looks better.

BINKY: OK, I'll dereference the\npointer x to store the number

For this trick, I'll need my\nmagic wand of dereferencing.

SPEAKER 1: Your magic\nwand of dereferencing?

BINKY: This is what the code looks like.

I'll just set up the number and--

So doing a dereference on x follows\n

in this case to store 42 in there.

Hey, try using it to store the number\n

I'll just go over here to y\nand get the number 13 set up

and then take the wand of\ndereferencing and just--

SPEAKER 1: Oh hey, that didn't work.

Say, Binky, I don't think\ndereferencing y is a good idea

because setting up the\npointee is a separate step

and I don't think we ever did it.

SPEAKER 1: Yeah, we\nallocated the pointer y

but we never set it\nto point to a pointee.

SPEAKER 1: Hey, you're\nlooking good there, Binky.

Can you fix it so that y points\nto the same pointee as x?

BINKY: Sure, I'll use my magic\nwand of pointer assignment.

SPEAKER 1: Is that going to\nbe a problem, like before?

BINKY: No, this doesn't\ntouch the pointees

it just changes one pointer to\n

Now y points to the same place as x.

It has a pointee so you can try\nthe wand of dereferencing again

SPEAKER 1: Hey, look at that.

Now dereferencing works on y.

And because the pointers are sharing\n

So are we going to switch places now?

SPEAKER 1: Oh look, we're out of time.

That's from our friend\nNick Parlante at Stanford.

So let's consider what\nNick did here as Binky.

So here is all the code together.

These first couple of lines were not\n

they move the stars to the left.

Again, more conventional\nmight be this syntax here.

It's OK to create\nvariables, even pointers

and not assign them a value initially\n

So we eventually do\nhere, with this line.

We assign to x the return\nvalue of malloc, which

is presumably the address of something.

To be fair, we should really\nbe checking for null as well

but that's not the biggest problem here.

The biggest problem is\nnot even this next line

which means go to the memory location\n

That's fine, because\nagain, malloc returns

the address of some chunk of memory.

This chunk of memory is\nbig enough for an int.

x is therefore going to store\nthe address of that chunk that's

Star x recalls the dereference\n

It's like going to the mailbox\nand putting the number 42 in it

instead of taking the number\n50 out, like we did before.

This is where Binky lost\nhis head, so to speak.

AUDIENCE: We haven't yet\nallocated space for it.

We haven't yet allocated space for y.

There's no mention of malloc,\nthere's no assignment of y

So this would be, go\nto the address in y

but if there is no known address in\n

which means go to some random address\n

that might cause what we've seen in the\n

Now this, fortunately,\nis the kind of thing

that if you don't quite have the eye\n

could help you find as well.

But it's just another example of\n

of having control now\nover memory at this level.

Well, let's go ahead\nand do one other thing.

Considering from last week\nthat this notion of swapping

was actually a really common operation.

We had all of our volunteers come\n

during bubble sorts and\neven selection sort

and we just took for\ngranted that the two

humans would swap themselves just fine.

But there needs to be code\nto do that if you actually

implement bubble sort, selection sort,\n

So let's consider some code like this.

We'll keep it simple\nlike last week, and where

we wanted to swap some values like\n

Void because I'm not going to return\n

So here, for instance,\nmight be some code for this.

But why is it so complicated?

Here, let's actually take a step back.

I think we have time\nfor one more volunteer.

Could we get someone to come on up?

You have to be comfy\non camera and you're

being asked to help with your-- oh,\n

So whoever has their\nfriend doing this here--

Now they're pointing it over here.

Now, literally an arm is being twisted.

Who were you trying to volunteer?

So here we have for Marina two\n

just so that they're super obvious.

And suppose that the problem\nat hand, like last week

it's just to swap two values, as\n

two people and we want to swap them.

But let's consider these glasses\n

in an array, and you know what?

I'd really like you to swap the values.

So orange has to go in there,\nand purple has to go in there.

And we'll see if we can\nthen translate that to code.

So presumably, you're\nstruggling mentally

with how you would do this without\n

Let me go ahead and we do have a\n

So if I hand you this, how would\nyou now solve this problem?

AUDIENCE: I would go\nlike that, but it's--

DAVID J. MALAN: No, that's--

Go do it-- go with your instincts.

Go to whatever your instincts are.

Yeah, so a little-- so\nstrictly speaking, probably

shouldn't have moved the\nglasses just because that

would be like moving\nthe array locations

so let's actually do it one\nmore time but the glasses now

have to go back where\nthey originally are.

So how would you swap these now,\nusing this temporary variable?

Otherwise we'd be completely\nuprooting the array, for instance

by just physically moving it around.

So you moved the orange into\nthis temporary variable

then you copied the purple\ninto where the orange was

and now, presumably, excellent.

The orange is going to end\nup where the purple once was

and this temporary variable,\nit stored up some extra memory.

It was necessary at the time,\nbut not necessary, ultimately.

But a round of applause if we could,\n

So the fact that it\ninstantly occurred to Mariana

that you need some temporary variable\n

and in fact this code here,\nthat we might glimpse now

is reminiscent of\nexactly that algorithm

where A and B, at the end of the\n

Just like the second\ntime, the two glasses

have to kind of stay put, even\n

but they're going back\nto where they were

is kind of like having\ntwo values, A and B

and you just have a temporary\nvariable into which you copy A

then you change A with\nB, then you go and change

B with whatever the\noriginal value of A was

because you temporarily stored it\n

Unfortunately, this code doesn't\nnecessarily work as intended.

So let me go over to my\nVS Code here and open up

a program called swap.c,\nand in swap.c, let

me whip up something really quickly\n

Inside of main let me do something\nlike x gets 1 and y gets 2.

Let me just print out as a\nvisual confirmation that x is %i

y is %i backslash n, plugging\nin x and y, respectively.

Then let me call a swap function\n

Swap x and y And then let me print out\n

just to print out again what they are,\n

2 first, then 2, 1 the second time.

Now how is swap going to be implemented?

Let me implement it exactly\nas on the screen a moment ago.

or let's call it int A\nfor consistency, int B.

But I could always call\nthose anything I want.

Int tmp gets A, A gets B, B gets tmp.

So exactly as I proposed\na moment ago, and exactly

as Mariana really implemented\nit using these glasses of water.

I need to now include my prototype,\n

And I'll just copy/paste that up here,\n

So make swap-- so far, so good-- swap--

x is now 1, y is 2, x is 1, y is 2.

So there seems to be a bit of a\nbug here, but why might this be?

This code does not in fact work, even\n

AUDIENCE: Because A and B have different\n

DAVID J. MALAN: Good,\nand let me summarize.

A and B do indeed have\ndifferent addresses of x and y

and in fact what happens when you\n

calling swap, passing in x and\ny, you are calling a function

And this is a term of\nart that just means

you are passing in copies of x and\n

A and B in the context of this\n

Now technically, these\nnames are local only.

I could have called this x,\nI could have called this y

I could have changed this to x,\n

The problem would still remain.

Just because you use the same names\n

that doesn't mean they're the same.

They just look the same to you.

But indeed, swap is going to get copies\n

x and y will be copies of the original.

So for clarity, let me\nrevert this back to A and B

just to make super clear that they're\n

but there's indeed a problem there.

This function actually works fine.

Let me go ahead and print out\ninside of this. printf A is %i

B is %i backslash n, and\nthen I'll print A and B.

And let me do that same thing at the\n

Make swap, ./swap,\nand this is promising.

Initially, x is 1, y is 2, A\nis 1, B is 2, A is 2, B is 1

but then nope-- x is 1, y is 2.

So if anything, I've confirmed\nthat the logic is right--

Mariana's logic is right, but\nthere's something about C.

There's something about using one\n

The fact that I'm passing in copies of\n

So what in fact is going on?

Well again, inside of your computer's\n

and we've been talking\nabout them abstractly

it's just this grid of memory locations.

It turns out that your\ncomputer uses this memory

in a pretty conventional way.

It's not just random, where it just\n

it actually uses different parts of\n

And you have control over a lot of\n

And let's go ahead\nand zoom out from this

and consider that within your computer's\n

do is actually store initially,\nall of the zeros and ones

that you compiled in the top of\n

So when you compile a program and\n

or on a Mac or PC you double\nclick on it, the computer first--

the operating system first-- loads all\n

Machine code, into just one big chunk\n

Below that it stores global\nvariables-- any variables

you have created in your program\n

Generally, the top of your file.

Globals tend to go at the top there.

Then there's this chunk of memory\n

and we saw that word\nbriefly in Valgin's output

and then there's this other\nchunk of memory called the stack.

And it turns out that up until this\n

Any time you use local variables in\n

Any time you use malloc, that\nmemory ends up on the heap.

Now as the arrow suggests,\nthis actually looks

like a problem waiting to happen because\n

heap, and more and more\nand more stack, it's

like two things barreling down the\n

And that's actually a problem.

If you've ever heard the phrase\n

this is the origin of its name.

When you start to use\nmore and more and more

memory by calling lots\nand lots of functions

or using lots and lots\nof local variables

you use a lot of this stack memory.

Or if you use malloc a lot and keep\n

and never really, or rarely calling\n

and eventually these two things might\n

The program will crash or\nsomething bad will happen.

So the onus is on you\njust to don't do that.

But this is the design,\ngenerally, of what's

going on inside of\nyour computer's memory.

Now within that memory, though,\nthere are certain conventions

focusing on here, the stack.

And in fact, let me go\nover here with a marker

and say that this represents the\n

And so here we have a whole bunch of\n

represents a byte of memory\nand this, for instance

might represent four bytes\naltogether-- good enough for an int

So in my original code that I wrote\n

what is in fact going on\ninside the swap function?

We can visualize it like this-- when\n

matter, main is the first function\n

and so I'm just going to label\n

And what were the two variables I\n

And each of those was an\nint, so that's four bytes

so it's deliberate\nthat I reserved four--

a chunk of wood here that's four bytes.

So let me just call this x, and I'm just\n

And then I had my other variable y, and\n

What happens when main calls swap\n

Well, it has two variables of its\n

and B is initially 2, but it\nhas a third variable, tmp

which is a local variable in\naddition to the arguments A and B

that are passed in, so I'm going\n

And what is the value of tmp?

Well, we have to look back at the code.

tmp initially gets the value of A.\n

That's step one in my\nthree line program.

OK, A equals B. So that is assigned\n

into the A So B is 2, A is\nthis, so let me go ahead

and erase this and just overwrite that.

So at this moment in the story\nyou have two copies of two

so that's OK though, because\nthe third line of code

says tmp gets copied\ninto B. So what's tmp--

1, gets copied into B, so let\nme overwrite this 2 with a 1

Now unfortunately, the code ends.

swap doesn't actually do anything\n

is that I could have had a return value.

I could go in there\nand change void to int

but which one am I going to return?

The whole goal is to\nswap two values, and it

seems kind of lame if you\ncan't write a function

to do something as common per\nlast week sorting algorithms

Well, even though when this\nprogram starts running

main is using this chunk of memory\n

and the stack is just like\na cafeteria stack of trays--

Here's main's memory on the stack.

Here's the swap function's\nmemory on the stack.

It's using three ints instead of two--

What happens when the function\n

The sort of recollection that\nthis is swap's memory goes away

and garbage values are left.

So, adorably, we get rid\nof these values here

and there's still data there--\n

are still there in the computer's\n

because the function has now returned.

So they're still in there and this\n

of why there's other stuff in memory\n

Sometimes you did put\nit there, but now once

swap returns you only should be\ntouching memory inside of main.

But we've never actually\ncopied one value into main.

We haven't returned anything and we\n

Well, what if we instead passed\ninto swap not copies of x and y

calling them A and B. What if they\n

sort of a treasure map that\nwill lead swap to the actual x

Today we have that\ncapability using pointers.

So suppose that we\nuse this code instead.

There's a lot of stars going on\nhere, which is a bit annoying

but let's consider what it\nis we're trying to achieve.

What if we pass in not x and y, but\n

respectively--\nbreadcrumbs, if you will--

that will lead swap to\nthe original values.

Then what we do is we still\ngive ourselves a tmp variable

It's still a glass, so\nwe still call it an int

but what do we want to put\ninto that temporary variable?

We don't want to put A into it,\nbecause that's an address now.

We want to go to that\naddress per the star

and put whatever's at that address.

Well, we want to then copy\ninto whatever's at location A

we want to copy over to\nlocation A's contents

whatever is at location B's\ncontents and then lastly, we

want to copy tmp into\nwhatever's at location B.

So again, we're very deliberately\nintroducing all of these stars

because we don't want to\nchange any of these addresses

we want to go to these addresses\nper the reference operator

and put values there,\nor get values from.

So what does this actually mean?

Well, if I kind of rewind in this story\n

although I'm going to delete its\n

and I still have A, but\nwhat's going to be different

this time is how I use A and B.\nSo let me finish erasing those.

That's A on the left,\nthis is B on the right.

At this point in the\nstory, we're rerunning swap

with this new and improved version,\nand let's see what happens.

Well, x is presumably at some address.

Maybe it's like 0x123, as always.

What then does A get\nwhen I'm using this code?

Well, I'm going to put 0x456,\nand the what am I going to do?

Based on these three\nlines of code, I'm going

to store in tmp whatever is at the\n

That's this thing here, so\nI'm going to put 1 in tmp.

Line two-- I'm going to go to B--

all right, B is 456, so\nI'm going to B and I'm

going to store 2 at whatever is\nat location A, and at location A

is 123, so that's this,\nso what am I going to do?

I'm going to change this 1 to a 2.

Last line of code-- get the\nvalue of tmp, which is 1

and then put it at whatever the\n

and change it to be the value\nof tmp, tmp, which puts 1 here.

There's still no return value.

swap returns, which means\nthese three temporary variables

They can be reused by\nsubsequent function calls

but now, I've actually\nswapped the values of x and y.

Which is to say what came as naturally\n

is not quite as simply\ndone in C because again

functions are isolated from each other.

You can pass in values but you\nget copies of those values.

If you want one function to affect the\n

you have to 1, understand\nwhat's going on but 2

pass things in as by a pointer here.

So if I go back to my code here,\n

Let me get rid of these extra printf's.

Let me go in and add all these stars.

So I'm dereferencing these\nactual addresses here and here

and I've got to make one more change.

How do I now call swap if swap is\n

That is, the address of an int\nand the address of another int.

What do I change on line 11 here?

DAVID J. MALAN: Sorry,\nthe address of operator.

So up here on line 11, we do\nampersand x and ampersand y.

So that yes, we're technically\npassing in a copy of a value

but this time the copy we're passing\n

and as soon as we have an address, just\n

the foamy finger-- I can point at\n

and actually get a value from the\n

So let's cross our fingers\nnow and do make swap, Enter.

Oh my God, so many mistakes.

Oh, I didn't remember\nto change my prototype

so let me go way up here and\nadd two more stars because I

Make swap, ./swap, and viola--\nnow I have actually swapped.

All right, so what more can we do here?

Well, let me consider\nthat all this time we've

been deliberately using\nGetString and GetInt and GetFloat

and so forth, but for a reason.

These aren't just training wheels\n

they're actually in place\nto make your code safer.

And to illustrate this, let me go\n

How about a file called scanf.c.

It turns out that the old\nschool way-- the way in C

really, of getting user input,\nis via functions like scanf

and let me go ahead and include\nstdio.h, int main(void)

and without using the CS50 library at\n

Let me give myself an int called x.

Let me just print out what the value of\n

or rather, ask the user for\nthe value by asking them for x.

And I'm going to use a function\n

in an integer using %i, and I'm going\n

And then I'm going to go ahead and,\n

I'm going to print out with %i\n

All right, so line eight\nis week 1 style code.

Line five and six is week 1 style code.

So the curiosity today is this new line.\n

I'm using the same syntax\nthat I use for printf

which is kind of a little clue-- a\n

want to scan in, that is, read\nfrom the human's keyboard--

and I'm telling it where to put\nwhatever the human typed in.

I can't just say x, because we run into\n

I have to give a little\nbreadcrumb to the variable

where I want scanf to\nput the human's integer.

And so this just tells the\ncomputer to get an int.

This is what you would have\nhad to type, essentially

in week 1 just to get\nan int from the user

and there's a whole bunch of\nthings that can go wrong still

but that's the cryptic syntax we\n

Let me go ahead and make scanf here--

Put the semicolon in the wrong place.

Non void doesn't return a value.

I'm going to type in a number like\n

So that is the traditional way of\n

The problem, though, is when you\n

Let me delete all of\nthis and give myself

a string s, although wait a\nminute-- we don't call it strings

anymore-- char star to store a string.

Then let me go ahead and just prompt the\n

Then let me go ahead and use scanf, ask\n

and store it at that address.

Then let me go ahead and print\nout whatever the human typed

in just by using the same notation.

So here, line five is the same thing\n

that layer today so it's char star s.

This is just week one this is\njust week one, line seven is new.

scanf will also read from the human's\n

But that's OK, because s is an address.

It's correct not to do the ampersand.

A string is and has always\nbeen a char star, a.k.a string.

The problem, though, arises as follows--

oh my God, what did I do wrong--

I can't-- OK, we have certain\ndefenses in place with make.

Let me do clang of scanf.c, an\noutput of program called scanf.

All right, so I'm overriding\nsome of our pedagogical defenses

that we have in place with make.

Let me now run scanf of this version,\n

So it didn't even store something\n

This time it's in lowercase,\nbut that is somewhat related.

What did I fundamentally\ndo wrong though, here?

Why is this getting\nmore and more dangerous?

And let me illustrate\nthe point even more.

What if I type in not just something\n

What if I do like, hellooooo and\n

Right, a really long,\nunexpectedly long string.

This is the nondeterminism kicking in.

I was trying to trigger\na segmentation fault

but it wouldn't, but\nthe point still remains.

It's still not working, but what's\n

and it's not storing my actual input?

AUDIENCE: Do you have to make a space?

DAVID J. MALAN: We have\nto make space for it.

So what we're missing here is\nmalloc, or something like that.

So I could do that, I could\ndo something like this.

Well, let the human type in\nat least a three letter word

so I could do malloc of 3\nplus 1 for the null character.

So let me give them four characters,\n

Nope, sorry. clang, I have to--

Oh, include stdlib.h-- there we go.

That gives me malloc, now I'm\n

now I'm going to rerun it, and now I'm\n

And let me get a little aggressive now\n

Still works, but I'm getting lucky.

Damn it, that still works, too.

But it actually-- not quite.

There's some weirdness\ngoing on there already.

It turns out I can also do this.

I could actually just say\nchar star four and give myself

an array of four characters.

Let me try this one more time.

So let me rerun clang ./scanf.

Hellooooooo, clearly exceeding\nthe four characters--

So the point here, though, is\nif we hadn't given you GetInt

you would have had to use the\nscanf thing-- not a huge deal

But if we hadn't given you GetString you\n

knowing about malloc already or\n

and even now there's a danger.

If the human types in five letters,\n

like with the Hello input, will\n

So GetString also has\nthis functionality built

in where we have a\nfancy loop inside such

that we allocate using malloc as\n

and we use malloc\nessentially every keystroke.

The moment you type in h-e-l-l-o, we're\n

allocating more and more memory so that\n

GetString even though\nit's this easy to crack--

this easy to crash your code\nusing scanf if you again

did it without the help of a library.

So where are we all going with this?

Well, let me show you a\nfew final examples that'll

pave the way for what\nwill be problem set four.

Let me go ahead and open\nup from today's code--

which is available on\nthe course's website--

for instance, a program like\nthis, called phonebook.c

and I'm just going to give\nyou a quick tour of it

that you'll see more details on in\n

We're going to introduce a few\n

You're going to see a function called\n

and it takes two arguments-- the\n

that you might manipulate in Excel or\n

separated values, and then something\n

W for write, depending on whether\nyou want to add to the file

just open it up, or change it.

We're going to introduce\nyou to a file pointer.

You'll see that capital file--

which is a little bit\nunconventional-- capital file is

a pointer to an actual file\non the computer's hard drive

so that you can actually access\nsomething like a CSV file

And we're going to see\ndown below that you're also

going to have the ability to write\n

You'll see functions like\nprintf printf for file printf.

Or fwrite-- file write-- which now that\n

you'll have the ability to\nactually not only read files--

text files, images, other\nthings-- but also write them out.

In fact for instance, just as a teaser\n

we focus on this week where\nwe give you a forensic image

and your goal is to\nrecover as many photographs

from this forensic image of a\n

And the way you're going to do\nthat is by knowing in advance

that every JPEG in the world starts\n

in hexadecimal, but these three numbers.

And so in fact, just as\na teaser, let me open up

an example you'll see on the\ncourse's website for today.

If I scroll through here,\nyou'll see a program

that does a little something like this.

if we could hit the button--

So here we have the notion of a byte\n

We'll see a data type called byte,\nwhich is a common convention.

And you're going to learn\nabout a function called fread

which reads from a file some number\n

We might then use code like this.

If bytes bracket zero\nequals equals 0xFF and bytes

bracket 1 equals 0xD8 and bytes bracket\n

bytes I just claimed represent a\n

Let me go ahead and run\nthis program as follows.

Let me copy jpeg.c into my\ndirectory from today's distribution.

Let me do make jpeg, and let me run\n

called lecture.jpeg, and I\nclaim yes, it's possibly a JPEG.

Let me open it up for us, called\n

is that same photo with which we began\n

But what we're also\ngoing to do this week

is start to implement our own sort\n

we might take images and actually\n

creates different versions thereof.

For instance, using a\ndifferent file format

called BMP, which essentially lays out\n

You're going to see a struct--

a data struct in C that's\nway more complicated

than the candidate\nstructure from the past

or the person structure\nfrom the past, that

looks like this, which is just\na whole bunch more values in it

but we'll walk you through\nthese in the p-set.

And we might take a\nphotograph like this and ask

you to run a few different\nfilters on it a la Instagram

like a black and white filter,\nor grayscale, a sepia filter

to give it some old school feel, or\n

or blur it, even in this way.

And just to end on a note\nhere, I have a version

of this code ready to go that doesn't\n

it just implements one filter initially.

Let me go ahead and just ready\nthis on my computer here.

I'm going to go into my\nown version of filter

and you'll see a few\nfiles that will give you

a tour of this coming week\nin bitmap.h, for instance

is a version of this structure that\n

And let me show you this file here,\n

called filter that I've already\nimplemented in advance today.

But the ones we give you for the piece\n

this function called filter\ntakes the height of an image

the width of an image, and\na two dimensional array.

So rows and columns\nof pixels, and then I

have a loop like this that iterates over\n

And then notice what\nI'm going to do here.

I'm going to change the blue\nvalue to be zero in this case

and the green value to\nbe zero in this case.

Well, the image I have\nhere in mind is this one

whereby we have this\nhidden image that simply

has old school style-- a\nsecret message embedded in it.

And if you don't happen to have in\n

glasses that essentially\nmake everything red--

getting rid of the green in the\n

you can actually-- I'm actually\nprobably the only one who

can read this right\nnow-- see what message

is hidden behind all of this red noise.

But if using my code written here in\n

in the picture and I get rid of\nall the green in the picture

essentially implementing\nthe idea of this filter--

this red filter where you only see red--

well, let's go ahead and\ncompile this program.

Make filter, run ./filter\non this hidden message.bmp.

I'm going to save it in a\nnew file called message.bmp

and with one final flourish\nwe're going to open up

message.bmp, which is the result\nof having put on these glasses

and hopefully now you\ntoo will see what I see.

All right, that's it for CS50!

And this is already week 5,\nwhich means this is actually

In fact, in just a few days'\ntime, what has looked like this

and much more cryptic\nthan this perhaps, is

going to be distilled into\nsomething much simpler next week.

When we transition to a\nlanguage called Python.

And with Python, we'll still have our\n

But a lot of the low-level plumbing\n

struggling with, frustrated by,\nover the past couple of weeks

especially, now that\nwe've introduced pointers.

And it feels like you probably\nhave to do everything yourself.

In Python, and in a lot\nof higher level languages

so to speak-- more modern,\nmore recent languages

you'll be able to do so much more\n

And indeed, we're going to start\n

Frameworks, which is collections of\n

And on top of all that, will you be\n

impressive projects, that actually solve\n

Particularly, by way of\nyour own final project.

So last week though, in week 4,\n

And we've been treating this\nmemory inside of your computer

At the end of the day, it's just\n

And it's really up to you\nwhat you do with those bytes.

And how you interconnect them, how\n

And arrays, were like\none of the simplest ways.

We started playing\naround with that memory.

Just contiguous chunks of memory.

But let's consider, for a\nmoment, some of the problems that

pretty quickly arise with arrays.

And then, today focus on what more\n

Using your computer's memory as\na much more versatile canvas

to create even\ntwo-dimensional structures.

To represent information,\nand, ultimately

to solve more interesting problems.

So here's an array of size 3.

Maybe, the size of 3 integers.

And suppose that this\nis inside of a program.

And at this point in the story,\n

And suppose, whatever the context,\n

Well, instinctively, where\nshould the number 4 go?

If this is your computer's\nmemory and we currently

have this array 1, 2, 3, from what.

Where should the number 4\njust, perhaps, naively go.

So you could replace number 1.

I don't really like\nthat, though, because I'd

like to keep number 1 around.

But I'm losing, of course, information.

So what else could I do if\nI want to add the number 4.

AUDIENCE: On the right side of 3.

So, I mean, it feels like\nif there's some ordering

to these, which seems kind\nof a reasonable inference

that it probably belongs\nsomewhere over here.

But recall last week, as we started\n

there's other stuff\npotentially going on.

And if fill that in, ideally, we'd\n

If we're maintaining this kind of order.

But recall in the context\nof your computer's memory

there might be other stuff there.

Some of these garbage\nvalues that might be usable

but we don't really know\nor care what they are.

As represented by Oscar here.

But there might actually\nbe useful data in use.

Like, if your program has not\njust a few integers in this array

but also a string that\nsays like, "Hello, world.

It could be that your computer has\n

Well, maybe, you created the\narray in one line of code

Maybe the next line of\ncode used GET-STRING.

Or maybe just hard coded a string\n

And so you painted yourself\ninto a corner, so to speak.

Now I think you might claim,\nwell, let's just overwrite the H.

But that's problematic\nfor the same reasons.

So where else could the 4 go?

Or how do we solve this problem\nif we want to add a number

and there's clearly memory available.

Because those garbage values are junk\n

So we could certainly reuse those.

Where could the 4, and\nperhaps this whole array, go?

So I'm hearing we could\nmove it somewhere.

Maybe, replace some of\nthose garbage values.

And honestly, we have a lot of options.

We could use any of these\ngarbage values up here.

We could use any of these down\nhere, or even further down.

The point is there is plenty\nof memory available as

indicated by these Oscars, where\nwe could put 4, maybe even, 5

The catch is that we\nchose poorly early on.

And 1, 2, 3 ended up back-to-back with\n

Let's go ahead and assume that\n

And we'll plop the new\narray in this location here.

So I'm going to go ahead\nand copy the 1 over.

And then, ultimately, once\nI'm ready to fill the 4

I can throw away, essentially,\nthe old array at this point.

Because I have it now\nentirely in duplicate.

And I can populate it with the number 4.

That is a correct potential\nsolution to this problem.

And this is something we're going to\n

What's the downside of having\nsolved this problem in this way?

I'm adding a lot of running time.

It took me a lot of effort to\ncopy those additional numbers.

Now, granted, it's a small array.

It's going to be over\nin the blink of an eye.

But if we start talking\nabout interesting data sets

web application data sets,\nmobile app data sets.

Where you have not just a few, but\n

a few million pieces of data.

This is probably a suboptimal\nsolution to just, oh

move all your data from\none place to another.

Because who's to say\nthat we're not going

to paint ourselves into a new corner.

And it would feel like you're wasting\n

And, ultimately, just costing\nyourself a huge amount of time.

In fact, if we put this now into\n

from a few weeks back, what might\nthe running time now of Search

A throwback a couple of weeks ago.

If you're using an array, to\nrecap, what was the running time

of a Search algorithm in Big O notation?

So, maybe, in the worst case.

If you've got n numbers, 3 in this\n

And what's your intuition for that?

So if we go through each element,\n

then Search is going to take\nthis a Big O running time.

If, though, we're talking about\nthese numbers, specifically.

And now I'll explicitly stipulate\nthat, yeah, they're sorted.

What would the Big O notation be\n

be it of size 3, or 4,\nor n, more generally.

SPEAKER 1: Big O of, not n, but rather?

Because we could use per week zero\n

we'd have to deal with some rounding.

Because there's not a perfect\nnumber of elements at the moment.

But you could use binary search.

And then go left or\nright, left or right

until you find the\nelement you care about.

So Search remains in Big O\nof log n when using arrays.

But what about insertion, now?

If we start to think\nabout other operations.

Like, adding a number to this array,\n

app, or Google finding\nanother page on the internet.

So insertion happens all the time.

What's the running time of Insert?

When it comes to inserting into\nan existing array of size n.

How many steps might that take?

Because in the worst case,\nwhere you're out of space

you have to allocate, it\nwould seem, a new array.

Maybe, taking over some of\nthe previous garbage values.

But the catch is, even\nthough you're only

inserting one new number,\nlike the number 4

you have to copy over all the darn\n

So if your original array of\nsize n, the copying of that

is going to take Big O of n plus 1.

But we can throw away the plus 1\n

So Insert now becomes Big O of n.

And that might not be ideal.

Because if you're in the habit\nof inserting things frequently

that could start to add\nup, and add up, and add up.

And this is why computer programs,\nand websites, and mobile apps

If you're not being mindful\nof these trade offs.

So what about, just for good\nmeasure, Omega notation.

Well just to recap\nhere, we could get lucky

and Search could just take one step.

Because you might just get\nlucky, and boom the number

you're looking for is right there in\n

Or even linear search, for that matter.

If there's enough room, and we didn't\n

1, 2, and 3, to a new location.

And we could have, as\nsomeone suggested, just

put the number 4 right there at the end.

And if we don't get lucky,\nit might take n steps.

If we do get lucky, it might just take\n

In fact, let me go ahead and do this.

How about we do something like this?

Let me switch over to some code here.

Let me start to make a\nprogram called List.C.

And in List.C, let's\nstart with the old way.

So we follow the breadcrumbs we've\n

So in this List.C, I'm going\nto include standardio.h.

Then inside of my code here, I'm\n

the first version of memory.

So int list 3 is now implemented\nat the moment, in an array.

So we're rewinding for\nnow to week 2 style code.

And then, let me just\ninitialize this thing.

At the first location will be 1.

At the next location will be 2.

And at the last location will be 3.

So the array is zero indexed always.

I, for just the sake\nof discussion though

am putting in the numbers 1, 2,\n3, like a normal person might.

So now let's just print these out.

Let's go ahead now and\nprint out using printf.

So very simple program, inspired\nby what we did in week 2.

Just to create and then print\nout the contents of an array.

So far, so good. ./list\nAnd voila, we see 1, 2, 3.

Now let's start to practice some of what\n

So let me go in now and get\nrid of the array version.

And let me zoom out a little bit\n

And now let's begin to\ncreate a list of size 3.

So if I'm going to do\nthis now, dynamically

so that I'm allocating these\nthings again and again

let me go ahead and do this.

Let me give myself a list that's of type\n

of 3 times the size of an int, so what\n

enough memory for that very first\npicture we drew on the board.

Which was the array\ncontaining 1, 2, and 3.

But laying the foundation\nto be able to resize it

which was ultimately the goal.

So my syntax is a little different here.

I'm going to use malloc and get memory\n

Instead of using the stack by just\n

That is to say this line of code from\n

identical to this line of\ncode in the second version.

But the first line of\ncode puts the memory

on the stack, automatically, for me.

The second line of code,\nthat I've left here now

is creating an array of size 3,\nbut it's putting it on the heap.

And that's important because it was only\n

That you can actually ask for more\n

When you just use the\nfirst notation int list 3

you have permanently given\nyourself an array of size 3.

You cannot add to that in code.

So let me go ahead and do this.

If list==null, something went wrong.

The computers out of memory.

So let's just return 1 and\nquit out of this program.

There's nothing to see here.

So just a good error check there.

Now let me go ahead and\ninitialize this list.

So list [0] will be 1 again.

So that's the same kind\nof syntax as before.

And notice this equivalence.

Recall that there's this relationship\n

And arrays are really just doing\npointer arithmetic for you

where the square bracket notation is.

So if I've asked myself here, in line\n

it is perfectly OK to treat it now like\n

Because the computer will\ndo the arithmetic for me

and find the first location,\nthe second, and the third.

If you really want to be\ncool and hacker-like, well

you could say list=1,\nlist+1=2, list+2=3.

That's the same thing\nusing very explicit

pointer arithmetic, which we\nlooked at briefly last week.

But this is atrocious to\nlook at for most people.

It's just not very user friendly.

It's longer to type, so\nmost people, even when

allocating memory dynamically\nas I did a second ago

would just use the more\nfamiliar notation of an array.

Now suppose time passes\nand I realize, oh shoot

I really wanted this array to\nbe of size 4 instead of size 3.

Now, obviously, I could just\nrewind and like fix the program.

But suppose that this is\na much larger program.

And I've realized, at\nthis point, that I need

to be able to dynamically add more\n

Well let me go ahead and do this.

Let me just say, all\nright, list should actually

be the result of asking for 4\nchunks of memory from malloc.

And then, I could do something\nlike this, list [3]=4.

Now this is buggy, potentially,\nin a couple of ways.

But let me ask first, what's really\n

The goal at hand is to start with\n

And I want to add a number 4 to it.

So at the moment, in line 17, I've asked\n

And then I'm adding the number 4 to it.

But I have skipped a few\nsteps and broken this somehow.

AUDIENCE: You don't know\nexactly [INAUDIBLE]..

I don't necessarily know where\n

It's probably not\ngoing to be immediately

adjacent to the previous chunk.

And so, yes, even though I'm\nputting the number for there

I haven't copied the 1, the 2, or\n

well, that's actually, indeed,\n

I am orphaning the\noriginal chunk of memory.

If you think of the picture that\n

up here on line 5 that allocates\n

But as soon as I do this, I'm\nclobbering the value of list.

And saying no, don't point\nat this chunk of memory.

Point at this chunk of memory, at\n

where the original chunk of memory is.

So the right way to do something like\n

Let me go ahead and give\nmyself a temporary variable.

And I'll literally call it TMP.

T-M-P, like I did last week.

So that I can now ask the computer for\n

I'm going to again say\nif TMP equals null

I'm going to say bad\nthings happened here.

And you know what,\njust to be tidy, let me

free the original list before I quit.

Because remember from\nlast week, any time

you use malloc you\neventually have to use free.

But this chunk of code here\nis just a safety check.

If there's no more memory,\nthere's nothing to see here.

I'm just going to clean\nup my state and quit.

But now, if I have asked\nfor this chunk of memory

now I can do this 4 int i gets 0.

What if I do something like this?

That would seem to have the effect\n

And then, I think I need to\ndo one last thing TMP [3]

gets the number 4, for instance.

Again, I'm hard coding the numbers\nfor the sake of discussion.

After I've done this,\nwhat could I now do?

I could now set list equals to TMP.

And now, I have updated\nmy linked list properly.

So let me go ahead and do this.

Let me go ahead and print each of these\n

And then, I'm going to return 0 just\n

Now so to recap, we\ninitialize the original array

of size 3 and plug-in\nthe values 1, 2, 3.

And then, I realize, wait a\nminute, I need more space.

And so I asked the computer\nfor a second chunk of memory.

Just as a safety check, I make\nsure that TMP doesn't equal null.

Because if it does I'm out of memory.

So I should just quit altogether.

But once I'm sure that\nit's not null, I'm

going to copy all the values from\n

And then, I'm going to add my new\n

And then, now that I'm done playing\n

I'm going to remember\nin my list variable what

the addresses of this\nnew chunk of memory.

And then, I'm going to print\nall of those values out.

So at least, aesthetically, when I\n

except for my missing semicolon.

Implicitly declaring a\nlibrary function malloc.

What's my mistake any time\nyou see that kind of error?

So up here, I forgot to do include\n

Let me go ahead and,\nagain, do make list.

And I should see 1, 2, 3, 4.

But they're still a bug here.

Does anyone see the\nthe-- bug or question?

AUDIENCE: You forgot to free them.

SPEAKER 1: I'm sorry, say again.

AUDIENCE: You forgot to free them.

SPEAKER 1: I forgot to\nfree the original list.

And we could see this, even if not\n

If I do something like\nValgrind of dot/list

remember our tool from this past week.

Let me increase the size of my\nterminal window, temporarily.

The output is crazy cryptic at first.

But, notice that I have definitely\n

And indeed, it's even\npointing at the line number

in which some of those bytes were lost.

So let me go ahead and back to my code.

And indeed, I think what I need to do\n

pointing it at this new chunk\nof memory instead of the old

I think I now need to\nfirst, proactively

say free the old list of memory.

So if I now do Make List and do dot\n

And, if I cross my fingers\nand run Valgrind again

after increasing my window\nsize, hopefully here.

It seems like less memory is lost.

What have I now forgotten to do?

AUDIENCE: You forgot to free the end.

SPEAKER 1: I forgot to free\nit at the very end, too.

Because I still have a chunk of\nmemory that I got from malloc.

So let me go to the very\nbottom of the program now.

And after I'm done senselessly\njust printing this thing out

And now let me do Make List, dot/list.

Now let's do Valgrind\nof dot/list, Enter.

And now, hopefully, all\nheap blocks were freed.

So this is perhaps the best output\n

I used the heap, but I freed\nall the memory as well.

So there were 2 fixes needed there.

Any questions then on this array-based\n

is statically allocating\nan array, so to speak.

By just hard coding the number 3.

The second version now is\ndynamically allocating the array

using not the stack but the heap.

But, it too, suffers from the\nslowness we described earlier

of having to copy all those\nvalues from one to the other.

AUDIENCE: Why do you not\nhave to free the TMP?

Why did I not have to free the TMP?

I essentially did eventually.

Because TMP was pointing\nat the chunk of 4 integers.

But on line 33 here,\nI assigned list to be

identical to what TMP was pointing at.

And so, when I finally freed the list,\n

In fact, if I wanted to, I could say\n

But conceptually, it's wrong.

Because at this point in the story, I\n

But they were the same at\nthat point in the story.

AUDIENCE: Is [? the line ?] part of it?

And long story short,\neverything we're doing thus far

is still in the world of arrays.

The only distinction\nwe're making is that

in version 1, when I said int list\n

So-called statically allocated\non the stack, as per last week.

This version now is still dealing with\n

and using dynamic memory allocation.

So that I can still use an\narray per the first pictures

But I can at least grow\nthe array if I want.

So we haven't even now solved this, even\n

AUDIENCE: How are you able to free\n

SPEAKER 1: How am I able to free list?

I freed the original address of list.

I, then, changed what list is storing.

I'm moving its arrow to\na new chunk of memory.

And that is perfectly reasonable\nfor me to now manipulate

because now list is pointing\nat the same value of TMP.

And TMP is what was given the return\n

So that chunk of memory is valid.

So these are just squares\non the board, right.

There's just pointers inside of them.

So what I'm technically\nsaying is, and I'm not

pointing I'm not freeing\nlist per se, I am

freeing the chunk of memory that begins\n

Therefore, if a few lines later, I\n

Totally reasonable to then touch that\n

Because you're not freeing\nthe variable per se

you're freeing the\naddress in the variable.

So let me back up here and\nnow make one final edit.

So let's finish this with\none final improvement here.

Because it turns out,\nthere's a somewhat better way

to actually resize an array\nas we've been doing here.

And there's another function in stdlib\n

And I'm just going to go in and\nmake a little bit of a change

here so that I can do the following.

Let me go ahead and\nfirst comment this now

just so we can keep track of what's\n

So dynamically allocate\nan array of size 3.

Assign 3 numbers to that array.

Allocate new array of size 4.

Copy numbers from old\narray into new array.

And add fourth number to new array.

Remember, if you will, new array\nusing my same list variable.

And we'll post this code online after\n

So it turns out that we can reduce\n

Not so much with the printing\nhere, but with this copying.

Turns out c does have a\nfunction called realloc

that can actually handle the resizing\n

I'm going to scroll up\nto where I previously

allocated a new array of size 4.

And I'm instead going to say this,\n

Now, previously this wasn't\nnecessarily possible.

Because recall that we\nhad painted ourselves

into a corner with the\nexample on the screen

where "Hello, world" happened to\n

Let me use realloc, for re-allocate.

And pass in not just the size\nof memory we want this time

but also the address\nthat we want to resize.

Which, again, is this array called list.

The code thereafter is\npretty much the same.

But what I don't need to do is this.

So realloc is a pretty handy\n

If at the very beginning of class,\n

And someone's instinct was to just plop\n

If there's available memory,\nrealloc will just do that.

And boom, it will just grow the array\n

If, though, it realizes, sorry, there's\n

or something else there,\nrealloc will handle

the trouble of moving that whole\narray from 1 chunk of memory

originally, to a new chunk of memory.

And then realloc will return to you,\n

And it will handle the process\nof freeing the old chunk for you.

So you do not need to do this yourself.

So in fact, let me go ahead\nand get rid of this as well.

So realloc just condenses, a lot of what\n

Whereby, realloc handles it for you.

So that's the final improvement\non this array-based approach.

So what now, knowing\nwhat your memory is

what can we now do with it that\nsolves that kind of problem?

Because the world is\ngoing to get really slow.

And our apps, and our phones, and our\n

if we're just constantly wasting\n

What could we perhaps do instead?

Well there's one new\npiece of syntax today

that builds on these 3 pieces\nof syntax from the past.

Recall, that we've\nlooked at struct, which

is a keyword in C, that just lets\nyou invent your own structure.

Your own variable, if you will,\nin conjunction with typedef.

Which lets you say a person has a name\n

Or a candidate has a name\nand some number of votes.

You can encapsulate multiple pieces of\n

What did we use the Dot Notation\nfor now, a couple of times?

What does the Dot operator do in C?

AUDIENCE: Access the structure.

To access the field\ninside of a structure.

So if you've got a person\nwith a name and a number

you could say something like\nperson.name or person.number

if person is the name\nof one such variable.

Star, of course, we've\nseen now in a few ways.

Like way back in week 1, we\nsaw it as like, multiplication.

Last week, we began to see it\nin the context of pointers

whereby, you use it\nto declare a pointer.

Like, int* p, or something like that.

But we also saw it in\none other context, which

was like the opposite, which\nwas the dereference operator.

Which says if this is\nan address, that is

if this is a variable like a pointer,\n

then with no int or no char,\nno data type in front of it.

That means go to that address.

And it dereferences the pointer\nand goes to that location.

So it turns out that using\nthese 3 building blocks

you can actually start to now use\n

And even next week, when\nwe transition to Python

and you start to get a\nlot of features for free.

Like a single line of\ncode will just do so much

more in Python than it does in C. It\n

And just so you've seen it already.

It turns out that it's so\ncommon in C to use this operator

to go inside of a structure and\n

that there's shorthand\nnotation for it, a.k.a.

That literally looks like an arrow.

So recall last week, I was in\nthe habit of pointing, even

This arrow notation, a\nhyphen and an angled bracket

denotes going to an address and\nlooking at a field inside of it.

But we'll see this in\npractice in just a bit.

So what might be the\nsolution, now, to this problem

we saw a moment ago whereby, we had\n

And our memory, a few moments\nago, looked like this.

We could just copy the whole existing\n

What would another, perhaps\nbetter solution longer term

be, that doesn't require\nconstantly moving stuff around?

Maybe hang in there for\nyour instincts if you

know the buzz phrase we're looking for\n

But if we want to avoid\nmoving the 1, 2, and the 3

but we still want to be able\nto add endless amounts of data.

So maybe create some kind\nof list using pointers that

just point at a new location, right.

In an ideal world, even\nthough this piece of memory

is being used by this h in\nthe string "Hello, world"

maybe we could somehow use\na pointer from last week.

Like an arrow, that says after the\n

And you just stitch together\nthese integers in memory

so that each one leads to the next.

It's not necessarily the case\nthat it's literally back-to-back.

That would have the\ndownside, it would seem

of costing us a little bit of space.

Like a pointer, which recall,\ntakes up some amount of space.

Typically 8 bytes or 64 bits.

But I don't have to copy potentially\na huge amount of data just

And so these things do have a name.

And indeed, these things\nare what generally

would be called a linked list.

A linked list captures\nexactly that intuition

of linking together things in memory.

So let's take a look at an example.

Here's a computer's\nmemory in the abstract.

Suppose that I'm trying\nto create an array.

Let's generalize it as\na list, now, of numbers.

An array has a very specific meaning.

It's memory that's contiguous,\nback, to back, to back.

At the end of the day, I as the\n

I don't really care how it's stored.

I don't care how it's stored\nwhen I'm writing the code

I just wanted to work\nat the end of the day.

So suppose that I first\ninsert my number 1.

And, who knows, it ends up,\nup there at location, 0X123

Maybe there's something already here.

And heck, maybe there's\nsomething already here

but there's plenty of other options\nfor where this thing can go.

And suppose that, for\nthe sake of discussion

the first available\nspot for the next number

happens to be over here at location\n

So that's where I'm going\nto plop the number 2.

And where might the number 3 end up?

Oh I don't know, maybe\ndown over there at 0X789.

The point being, I don't know\nwhat is, or really care about

everything else that's\nin the computer's memory.

I just care that there are at\nleast 3 locations available where

I can put my 1, my 2, and my 3.

But the catch is, now that\nwe're not using an array

we can't just naively assume that\n

Add 2 to an index, and boom\nyou're at the next, next number.

Now you have to leave these little\n

to lead from one to the other.

And sometimes, it might be\nclose, a few bytes away.

Maybe, it's a whole gigabyte away\n

Like where do these pointers\ngo, as you proposed?

All I have access to here are bytes.

I've already stored the\n1, the 2, and the 3.

So let me, you put the pointers\nright next to these numbers.

So let me at least plan ahead, so that\n

recall from last week, for some\nmemory, I don't just ask it now

for space for just the number.

Let me start getting\ninto the habit of asking

malloc for enough space for the number\n

So it's a little more aggressive\nof me to ask for more memory.

And here is an example of a trade off.

Almost any time in CS, when you start\n

Or if you try to conserve space,\nyou might have to lose time.

It's being that trade off there.

Well let me abstract this away.

And either next to or below, I'm\n

for the sake of discussion.

So the arrows are a bit prettier.

I've asked malloc for\nnow twice as much space

it would seem, than I previously needed.

But I'm going to use this second chunk\n

And I'm going to use this chunk\nof memory to refer to the next

essentially, stitching\nthis thing together.

So what should go in this first box?

Well, I claim the number, 0X456.

And it's written in hex because\nit represents a memory address.

But this is the equivalent of drawing\n

As a little check here, what\nshould go in this second box

if the goal is to stitch these\ntogether in order 1, 2, 3?

Feel free to just shout this out.

SPEAKER 1: OK, that worked well.

And you can't do that with the hands\n

So 0X789 should go here because that's\n

And then, we don't really have\nterribly many possibilities here.

This has to have a value, right.

Because at the end of the day, it's\n

So what value should go here,\nif this is the end of this list?

SPEAKER 1: So it could be 0X123.

The implication being that\nit would be a cyclical list.

Which is OK, but\npotentially problematic.

If any of you have accidentally\n

because you had an infinite loop,\n

to give yourself the accidental\nprobability of an infinite loop.

What might be simpler than\nthat and ward that off?

SPEAKER 1: So just the null character.

Not N-U-L, confusingly, which\nis at the end of strings.

But N-U-L-L, as we\nintroduced it last week.

So this is just a special value\nthat programmers decades ago

decided that if you store the address\n

There's never going to be\nanything useful at 0x0.

Therefore, it's a sentinel\nvalue, just a special value

There's nowhere further to go.

It's OK to come back to your\n

But we'd better be\nsmart enough to, maybe

remember where did the list start\nso that you can detect cycles.

If you start looping around\nin this structure, otherwise.

But these addresses, who really\ncares at the end of the day

It really just now looks like this.

And indeed, this is how most anyone\n

if having a discussion at work.

Talking about what data\nstructure we should

use to solve some problem\nin the real world.

We don't care generally\nabout the addresses.

We care that in code we can access them.

But in terms of the concept\nalone this would be, perhaps

the right way to think about this.

All right, let me pause\nhere and see if there's

any questions on this idea of creating\n

not just the numbers like 1,\n2, 3, but twice as much data.

So that you have little\nbreadcrumbs in the form of pointers

that can lead you from one to the next.

Any questions on these linked lists?

AUDIENCE: So does this takes\ntime more memory than an array?

SPEAKER 1: This does take\nmore memory than an array

because I now need space\nfor these pointers.

And to be clear, I technically\ndidn't really draw this to scale.

Thus far, in the class, we've\ngenerally thought about integers

like, 1, 2 and 3, as\nbeing 4 bytes, or 32 bits.

I made the claim last week that\non modern computer's pointers

tend to be 8 bytes or 64 bits.

So, technically, this box should\nactually be a little bigger.

It was just going to look a\nlittle stupid in the picture.

But, indeed, you're using\nmore space as a result.

SPEAKER 1: Oh, how does-- sorry.

How does the computer identify\nuseful data from used data?

So, for instance, garbage\nvalues or non-garbage values.

For now, think of that\nas the job of malloc.

So when you ask malloc for memory,\nas we started to last week

malloc keeps track of the\naddresses of the memory

it has handed to as valid values.

The other type of memory you\nuse, not just from the heap.

Because recall we briefly\ndiscussed that malloc uses space

from the heap, which was drawn at the\n

There's also stack memory, which is\n

And where all of the memory\nused by individual functions go.

And that was drawn in the\npicture is working its way up.

That's just an artist's\nrendition of direction.

The compiler, essentially,\nwill also help

keep track of which values are\nvalid or not inside of the stack.

Or really the underlying\ncode that you've written

will keep track of that for you.

So it's managed for you at that point.

Sorry it took me a bit to catch on.

So let's now translate\nthis to actual code.

How could we implement this idea\n

And that's a term of our NCS.

Whenever you have some data structure\n

N-O-D-E, is the generic term for that.

So each of these might\nbe said to be a node.

Well a couple of weeks ago, we saw\n

like a student or a candidate.

And a student, or rather a person,\n

And we used a few pieces of syntax here.

One, we use the struct keyword,\nwhich gives us a data structure.

We use typedef, which defines the\nname person to be our new data

type representing that whole structure.

So we probably have the\nright ingredients here

to build up this thing called a node.

And just to be clear, what should\n

It's not going to be a name\nor a number, obviously.

But what should a node have in\nterms of those fields, perhaps?

SPEAKER 1: So a number like a\nnumber and a pointer in some form.

So let's translate this to actual code.

So let's rename person to node\nto capture this notion here.

If it's just going to\nbe an int, that's fine.

We can just say int number,\nor int n, or whatever

you want to call that particular field.

The next one is a little non-obvious.

And this is where things\nget a little weird at first

but, in retrospect, it\nshould all fit together.

Let me propose that, ideally, we\n

And I could call the word\nnext anything I want.

Next just means what comes after\n

So a lot of CS people would\njust use next to represent

C and C compilers are\npretty naive, recall.

They only look at code top\nto bottom, left to right.

And any time they encounter\na word they have never

seen before, bad things happen.

Like, you can't compile your code.

You get some cryptic\nerror message or the like.

And that seems to be\nabout to happen here.

Because if the compiler is reading\nthis code from top to bottom

it's going to say, oh,\ninside of this struct

should be a variable called next.

Because it literally does\nnot find out until 2 lines

later, after that semicolon.

So the way to avoid this, which\nwe haven't quite seen before

is that you can temporarily name this\n

And then, down here inside of the\n

And then, you leave the rest alone.

This is a workaround this is\npossible because now you're

teaching the compiler, from\nthe first line, that here comes

a data structure called struct node.

Down here, you're shortening the name\n

It's just a little more convenient\n

But you do have to write struct\n

But that's OK because it's\nalready come into existence

now, as of that first line of code.

So that's the only\nfundamental difference

between what we did last week\nwith a person or a candidate.

We just now have to use this\nstruct workaround, syntactically.

AUDIENCE: So [INAUDIBLE] have like\n

SPEAKER 1: Why is the next variable\n

So think about the picture\nwe are trying to draw.

Technically, yes, each of these\narrows I deliberately drew

They need to point at the\nwhole data structure in memory.

Because the computer,\nultimately, and the compiler

in turn, needs to know that this\n

Inside of a node is a number\nand also another pointer.

So when you draw these\narrows, it would be

incorrect to point at just the number.

Because that throws\naway information that

would leave the compiler\nwondering, OK, I'm at a number.

Where the heck is the pointer?

You have to tell it that\nit's pointing at a whole node

so it knows a few bytes away\nis that corresponding pointer.

AUDIENCE: How do you [INAUDIBLE].

SPEAKER 1: Really good question.

It would seem that just as\ncopying the array earlier

required twice as much memory,\n

So, technically, twice as much\nplus 1 for the new number.

Here, too, it looks like we're\nusing twice as much memory, also.

And to my comment earlier, it's\n

because these pointers are 8 bytes, and\n

In the context of the array, you\n

So, yes, you needed\ntwice as much memory.

But then you were quickly\nfreeing the original array.

So you weren't consuming long-term,\n

The difference here, too, is\nthat, as we'll see in a moment

it turns out it's going to be\n

to insert new numbers in here.

Because I'm not going to have\nto do a huge amount of copying.

And even though I might still have\n

is going to take some\namount of time, I'm

not going to have to be asking for\n

And certain operations in the computer,\n

back memory, tends to be slower.

So we get to avoid\nthat situation as well.

There's going to be\nsome downsides, though.

But we'll see in a bit just what some\n

So from here, if we go back to the\n

let's start to now build up a\nlinked list with some actual code.

How do you go about, in C,\nrepresenting a linked list in code?

Well, at the moment, it would\nactually be as simple as this.

You declare a variable,\ncalled list, for instance.

That itself stores\nthe address of a node.

So if you want to store\na linked list in memory

you just create a variable\ncalled list, or whatever else.

And you just say that\nthis variable is going

to be pointing at the first node in a\n

Because malloc is ultimately going\n

get at any one particular\nnode in memory.

So let's actually do\nthis in pictorial form.

When you write a line of\ncode, like I just did here--

and I do not initialize it to\n

It does exist in memory as a box,\n

But I've deliberately\ndrawn Oscar inside of it.

SPEAKER 1: It's a garbage value.

I have been allocated the\nvariable in memory, called list.

Which is going to give me 64 bits\n

But if I myself have not\nused the assignment operator

it's not going to get magically\n

It's not going to even give me a node.

This is literally just going to be an\n

So what would be a solution here?

Suppose that I'm beginning\nto create my linked list

but I don't have any nodes yet.

What would be a sensible thing to\n

SPEAKER 1: So just null, right.

When in doubt with\npointers, generally it's

a good thing to\ninitialize things to null

so at least it's not a garbage value.

But it's a special\nvalue you can then check

for with a conditional, or the like.

So this might be a better\nway to create a linked list

even before you've inserted any\nnumbers into the thing itself.

So after that, how can we go about\n

So now the story looks like this.

Oscar is gone because inside\nof this box is all zero bits.

Just because it's nice and clean, and\n

Well, if I want to add the number 1\n

Well, perhaps I could\nstart with code like this.

Borrowing inspiration from last week.

Let's ask malloc for enough\nspace for the size of a node.

And this gets to your question earlier,\n

I don't just need space for an int and\n

And I gave that thing a name, node.

So size of node figures out\nand does the arithmetic for me.

And gives me back the\nright number of bytes.

This, then, stores the address\nof that chunk of memory

in what I'll temporarily called n.

Just to represent a generic new node.

Because just like last week when I\n

and I stored it in an int* pointer.

This week, if I'm asking\nfor memory for a node

I'm storing it in a node* pointer.

So technically, nothing new\nthere except for this new term

of art in data structure called node.

So what does that do for me?

It essentially draws a\npicture like this in memory.

I still have my list variable from\n

And that's why I've drawn it blank.

I also now have a\ntemporary variable called

n, which I initialize to\nthe return value of malloc.

Which gave me one of\nthese nodes in memory.

But I've drawn it having\ngarbage values, too

because I don't know what int is there.

I don't know what pointer is there.

It's garbage values because malloc does\n

There is another function for that.

But malloc alone just says,\nsure, use this chunk of memory.

Deal with whatever is there.

So how can I go about\ninitializing this to known values?

Well, suppose I want to insert the\n

A list of size 1, I could\ndo something like this.

And this is where you have to\n

My conditional here is asking the\n

So that is, if malloc\ngave me valid memory

and I don't have to quit altogether\n

If n does not equal null, but\nis equal to valid address

I'm going to go ahead and do this.

And this is cryptic looking syntax now.

But does someone want to take a stab\n

How might you explain what that\ninner line of code is doing? *n.

The place that n is pointing\nto, set it equal to 1.

Or using the vernacular of going\nthere, go to the address in n

and set it's number field to 1.

However you want to think\nabout it, that's fine.

But the * again is the\ndereference operator here.

And we're doing the\nparentheses, which we

haven't needed to do before because we\n

structures together until today.

This just means go there first.

And then once you're\nthere, go access number.

You don't want to do one\nthing before the other.

So this is just enforcing\norder of operations.

The parentheses just like\nin grade school math.

So this line of code is cryptic.

It's not something most\npeople easily remember.

Thankfully, there's that syntactic\n

And this, even though\nit's new to you today

should eventually feel\na little more familiar.

Because this now is shorthand\nnotation for saying, start at n.

Go there as by following the arrow.

And when you get there,\nchange the number field.

So most people would not\nwrite code like this.

It's a couple extra keystrokes.

This just looks more like the artist's\n

And how most CS people would think about\n

The picture now, after setting number to\n

So there's still one step missing.

And that's, of course, to\ninitialize, it would seem

the pointer in this new node\nto something known like null.

So I bet we could do this like this.

With a different line\nof code, I'm just going

to say if n does not equal null,\n

Or more pedantically, go\nto n, follow the arrow

and then update the next field\n

And again, this is just\ndoing some nice bookkeeping.

Technically speaking,\nwe might not need to set

this to null if we're going to keep\n

But I'm doing it step-by-step so\n

And there's no bugs in\nmy code at this point.

There's one last thing I'm\ngoing to have to do here.

If the goal, ultimately, was to insert\n

what's the last step I\nshould, perhaps, do here?

AUDIENCE: Set the pointer value to null.

I now need to update the actual\n

list, to point at this brand new node.

That is now perfectly initialized as\n

Yeah, technically, this\nis already pointing there.

But I describe this deliberately\nearlier as being temporary.

I just needed this to get it back from\n

This is the long term\nvariable I care about.

So I'm going to want to do\nsomething simple like this.

And this seems a little\nweird that list equals n.

But again, think about\nwhat's inside this box.

At the moment this is null\nbecause there is no linked

list at the beginning of our story.

N is the address of the beginning, and\n

So it stands to reason that\nif you set list equal to n

that has the effect of\ncopying this address up here.

Or really just copying the\narrow into that same location

so that now the picture looks like this.

And heck, if this was a temporary\n

And now, this is the picture.

So an annoying number\nof steps, certainly

to walk through verbally like this.

But it's just malloc to\ngive yourself a node

initialize the 2 fields inside of\n

I didn't have to copy anything.

I just had to insert\nsomething in this case.

Let me pause here to see if there's\n

And we'll see before long it all\n

AUDIENCE: So if the\nstatements [INAUDIBLE]..

I drew them separately just\nfor the sake of the voiceover

of doing each thing very methodically.

In real code, as we'll\ntransition to now

I could have and should\nhave just done it

all inside of one conditional after\n

I could set number to a value like 1.

And I could set the pointer\nitself to something like null.

Well let's translate, then,\nthis into some similar code

that allows us to build up a linked\n

But now, using this new primitive.

So I'm going to go\nback into VS Code here.

I'm going to go ahead now and delete\n

And now, inside of my main function,\n

I'm going to first give\nmyself a list of size 0.

And I'm going to call that node* list.

And I'm going to initialize that\n

But I'm also now going to have to\n

So recall that I might do something\nlike typedef, struct node.

Inside of this struct node, I'm\ngoing to have a number, which

I'll call number of type int.

And I'm going to have\na structure called node

with a * that says the next\npointer is called next.

And I'm going to call this whole\nthing, more succinctly, node

Now as an aside, for those of you\n

Technically, I could\ndo something like this.

Not use typedef and not\nuse the word node alone.

This syntax here would actually\ncreate for me a new data

type called, verbosely, struct node.

And I could use this throughout\nmy code saying struct node.

That just gets a little tedious.

And it would be nicer just to refer\n

So what typedef has\nbeen doing for us is it

again, lets us invent our own\nword that's even more succinct.

And this just has the effect\nnow of calling this whole thing

node without the need, subsequently, to\n

So now that this thing exists in\n

And to do this, I'm going to\ngive myself a temporary variable.

I'll call it n for consistency.

I'm going to use malloc to\ngive myself the size of a node

And then, I'm going to\ndo a little safety check.

If n equals equals null, I'm going\n

I'm just going to quit\nout of this program

because there's nothing useful\nto be done at this point.

But most likely my computer is\nnot going to run out of memory.

So I'm going to assume we can keep\n

If n does not equal null, and that\n

I'm going to build this up backwards.

That's OK, let's go ahead and do this.

And then n [arrow next] equals null.

And now, update list to point\nto new node, list equals n.

So at this point in the\nstory, we've essentially

constructed what was that first\npicture, which looks like this.

This is the corresponding code via\n

Suppose now, we want to add\nthe number 2 to the list.

Well, I don't need to\nredeclare n because I can use

the same temporary variables before.

So this time, I'm just going to say n\n

I'm, again, going to\nhave my safety check.

So if n equals equals null, then let's\n

But, I have to be a\nlittle more careful now.

Technically speaking,\nwhat do I still need

to do before I quit out of my\nprogram to be really proper?

Free the memory that did\nsucceed a little higher up.

So I think it suffices to free what\n

Now, if all was well, though, let's\n

And now, n [arrow next] equals null.

And now, let's go ahead\nand add it to the list.

If I go ahead and do\nlist arrow next equals n

I think what we've just done is\nbuild up the equivalent, now

of this in the computer's memory.

By going to the list\nfield's next field, which

is synonymous with the 1\nnodes, bottom-most box.

And store the address of what was n,\n

And I'm just throwing away, in the\n

Let me go down here and say, add\n

And clearly, in a real program, we\n

And do this dynamically or a function\n

But just to go through the\nsyntax here, this is fine.

If n equals equals null, out\nof memory for some reason.

Let's return 1, but we\nshould free the list itself

and even the second node, list [next].

But I've deliberately done this poorly.

This is a little more subtle now.

And let me get rid of the highlighting\n

If n happens to equal equal\nnull, and something really just

went wrong they're out of memory,\n

And again, it's not that I'm\nfreeing those variables per se.

I'm freeing the addresses\nat in those variables.

But there's also a\nbug with my code here.

This line here, 43, what is\nthat freeing specifically?

AUDIENCE: You're freeing list 2 times.

SPEAKER 1: I'm freeing, not so.

I'm not freeing list 2 times.

Technically, I'm freeing\nlist once and list next once.

But let me just ask the\nmore explicit question.

What am I freeing with\nline 43 at the moment?

Because if 1 is at the\nbeginning of the list

list contains the address\nof that number 1 node.

And so this frees that node.

This line of code, you might\nthink now intuitively, OK

it's probably freeing the node number 2.

Valgrind might help you catch this.

But by eyeing it, it's\nnot necessarily obvious.

You should never touch memory\nthat you have already freed.

And so, the fact that I did\nin this order, very bad.

Because I'm telling the\noperating system, I don't know.

I don't need the list address anymore.

And then, literally one line later,\n

Let me actually go to\nthat address for a moment

and look at the next\nfield of that first node.

You've already given up\ncontrol over the node.

So it's an easy fix in\nthis case, logically.

But we should be freeing\nthe second node first

and then the first one\nso that we're doing it

in, essentially, reverse order.

And again, Valgrind would\nhelp you catch that.

But that's the kind of thing one\nneeds to be careful about when

You cannot touch memory\nafter you freed it.

Let me go ahead and update\nthe number field of n to be 3.

The next node of n to be null.

And then, just like\nin the slide earlier

I think I can do list\nnext, next equals n.

And that has the effect now of\n

essentially, this data structure.

Like, in a better world, we'd\nhave a loop and some functions

that are automating this process.

But, for now, we're doing it just\n

So at this point, unfortunately,\n

It's no longer as easy as int\ni equals 0, i less than 3, i++.

Because you cannot just\ndo something like this.

Because pointer arithmetic\nno longer comes into play

when it's you, who are stitching\n

In all of our past examples\nwith arrays, you've

been trusting that all of the bytes in\n

So it's perfectly reasonable for\nthe compiler and the computer

to just figure out, oh, well if you\n

[1], it's one location over.

[2], it's one location over.

This is way less obvious now.

Because even though you might want to\n

list, or the second, or the third, you\n

Instead, you have to\nfollow all of those arrows.

So with linked lists, you can't use\n

because one node might be here,\nover here, over here, over here.

You can't just use some simple offset.

So I think our code is going\nto have to be a little fancier.

And this might look scary at\nfirst, but it's just an application

of some of the basic definitions here.

Let me do a for-loop that actually\n

I'm going to keep doing this, so\n

And on each iteration\nof this loop, I'm going

to update TMP to be\nwhatever TMP arrow next is.

And I'll remind you in a moment\nand explain in more detail.

But when I print something here\nwith printf, I can still use %i.

Because it's still a number\nat the end of the day.

But what I want to print out is the\n

So maybe the ugliest\nfor-loop we've ever seen.

Because it's mixing, not just\nthe idea of a for-loop, which

itself was a bit cryptic weeks ago.

But now, I'm using pointers\ninstead of integers.

But I'm not violating the\ndefinition of a for-loop.

Recall that a for-loop has 3\nmain things in parentheses.

What do you want to initialize first?

What condition do you want to\nkeep checking again and again?

And what update do you want to make\n

So with that basic\ndefinition in mind, this

is giving me a temporary\nvariable called TMP

that is initialized to\nthe beginning of the loop.

So it's like pointing my\nfinger at the number 1 node.

Then, I'm asking the question,\ndoes TMP not equal null?

Well, hopefully, not because\nI'm pointing at a valid node

So, of course, it\ndoesn't equal null yet.

Null won't be until we get\nto the end of the list.

I started this TMP variable.

I follow the arrow and go to\nthe number field they're in.

The for-loop says,\nchange TMP to be whatever

is at TMP, by following the arrow\nand grabbing the next field.

That, then, has the result of being\n

No, of course, it doesn't equal\nnull because the second node

Null is still at the very end.

So I print out the number 2.

Next step, I update TMP one more\ntime to be whatever is next.

That, then, does not yet equal null.

So I go ahead and print\nout the number 3 node.

Then one last time, I update TMP to\n

But after 1, 2, 3, that\nlast next field is null.

And so, I break out of\nthis for-loop altogether.

So if I do this in\npictorial form, all we're

doing, if I now use my finger\nto represent the TMP variable.

I initialize TMP to be whatever\nlist is, so it points here.

That's obviously not null\nso I print out whatever

is that TMP, follow the arrow\nin number, and I print that out.

Then I update TMP to point here.

Then I update TMP to point here.

Then I update TMP to point here.

So, again, admittedly much more cryptic\n

But it's just a different\nutilization of the for-loop syntax.

AUDIENCE: How does it happen that\n

Because it seems to me that addresses-

How is it that I'm actually printing\n

The compiler is helping me here.

Because I taught it, in the\nvery beginning of my program

The compiler knows that a node has\n

Because I'm iterating using a node*\n

the compiler knows that any\ntime I'm pointing at something

I'm pointing at the whole node.

Doesn't matter where specifically in\n

It's, ultimately, pointing\nat the whole node itself.

And the fact that I, then, use\nTMP arrow number means, OK

adjust your finger slightly.

So you're literally pointing at the\n

So that's sufficient information for\n

Other questions then\non this approach here.

SPEAKER 1: How would I use a for-loop\n

You will do something like this,\nif I may, in problem set 5.

We will give you some of the\nscaffolding for doing this.

But in this coming weeks materials\nwill we guide you to that.

But let me not spoil it just yet.

AUDIENCE: So I had a\nquestion about line 49.

AUDIENCE: Is line 49\npossible in line 43?

Is line 49 acceptable, even\nif we freed it earlier.

We didn't free it in line\n43, in this case, right.

You can only reach line 49,\nif n does not equal null.

And you do not return on line 45.

I was only doing those freeing, if I\n

AUDIENCE: I had a quick question.

SPEAKER 1: Correct You're asking\n

does that mean you\ndon't have to free it?

You never have to free pointers, per se.

You should only free addresses that\n

So I haven't finished\nthe program, to be fair.

But you're not freeing variables.

You're not freeing like, fields.

You are freeing specific\naddresses, whatever they may be.

So the last thing, and I\nwas stalling on showing this

because it too is a little cryptic.

Here is how you can free,\nnow, a whole linked list.

In the world of arrays,\nrecall, it was so easy.

You return 0 and you're done.

Because, again, the\ncomputer doesn't know

what you have stitched together\nusing all of these pointers

all over the computer's memory.

You need to follow those arrows.

So one way to do this\nwould be as follows.

While the list itself is not null,\n

I'm going to give myself a\ntemporary variable called TMP again.

And it's a different TMP because\nit's in a different scope.

It's inside of the while loop instead\n

I am going to initialize TMP to\nbe the address of the next node.

Just so I can get one\nstep ahead of things.

Because now, I can boldly\nfree the list itself

which does not mean the whole list.

Again, I'm freeing the\naddress in list, which

is the address of the number 1 node.

It's just the address\nof the number 1 node.

So if I first use TMP\nto point out the number

2 slightly in the middle of the picture,\n

at the moment, to free list.

That is the address of the first node.

Now I'm going to say, all right, once\n

I can update the list\nitself to be literally TMP.

If you think about this picture, TMP\n

So TMP, represented by my right hand\n

Totally safe and reasonable to\nfree now the list itself a.k.a.

the address of the number 1 node.

That has the effect of just\nthrowing away the number 1 node

telling the computer you can\nreuse that memory for you.

The last line of code I wrote\n

2, at which point my loop proceeded\n

And only once my finger is\nliterally pointing at nowhere

the null symbol, will the\nloop, by nature of a while

loop as I'll toggle back to, break out.

And there's nothing more to be freed.

So again, what you'll see,\nultimately, in problem set 5

more on that later, is an opportunity\n

But again, even though the syntax\nis admittedly pretty cryptic

we're still using basics like\nthese for-loops or while loops.

We're just starting to now\nfollow explicit addresses rather

than letting the computer do\nall of the arithmetic for us

as we previously benefited from.

At the very end of this thing, I'm\n

And I think, then, we're good to go.

Questions on this linked list code now?

And again, we'll walk through this\n

AUDIENCE: Can you explain the while\n

Can we explain this while loop\nhere for freeing the list.

So notice that, first, I'm just\nasking the obvious question.

Because if it is, there's\nno work to be done.

However, while the list is not\nnull, according to line 58

I want to create a temporary variable\n

that list arrow next is pointing at.

List arrow next is whatever\nthis thing is here.

So if my right hand represents\nthe temporary variable

I'm literally pointing at the\nsame thing as the list is itself.

The next line of code,\nrecall, was free the list.

And unlike, in our world of\narrays, like half an hour

ago where that just meant\nfree the whole darn list

you now have taken over control over the\n

in ways that you didn't with the array.

The computer knew how to free\nthe whole array because you

malloc the whole thing at once.

You are now mallocing the\nlinked list one node at a time.

And the operating system does\nnot keep track of for you

So when you free list,\nyou are literally freeing

the value of the list variable,\n

Then my last line of code, which I'll\n

list to now ignore the\nfree memory and point at 2.

So, again, it's just a\nvery pedantic way of using

this new syntax of star notation,\n

to do the equivalent of walking\ndown all of these arrows.

Following all of these breadcrumbs.

But it does take admittedly\nsome getting used to.

Syntax, you only have to do one week.

But, again, next week\nin Python will we begin

to abstract a lot of\nthis complexity away.

But none of this\ncomplexity is going away.

It's just that someone else, the\nauthors of Python for instance

will have automated this stuff for us.

The goal this week is\nto understand what it

is we're going to get for\nfree, so to speak, next week.

Questions on these length lists.

AUDIENCE: So are the while\nloops strictly necessary

for the freeing [INAUDIBLE].

Let me summarize as, could we\nhave freed this with a for-loop?

It just is a matter of style.

It's a little more elegant to do it\n

But other people will\nreasonably disagree.

Anything you can do with a while\n

Do while loops, recall,\nare a little different.

But they will always\ndo at least one thing.

But for-loops and while loops\nbehave the same in this case.

All right, well let's just\nvary things a little bit here.

Just to see what some of\nthe pitfalls might now be

without getting into the weeds of code.

Indeed, we'll try to save some of\n

But instead, let's imagine that we\n

I can offer, in exchange for a\nfew volunteers, some foam fingers

to bring to the next game, perhaps.

Could we get maybe just\none volunteer first?

You will be our linked\nlist from the get go.

SPEAKER 1: Pedro, come on up.

All right, thank you to Pedro.

And if you want to just\nstand roughly over here.

But you are a null pointer so\njust point sort of at the ground

as though you're pointing at 0.

So Pedro is our linked list\nof size 0, which pictorially

might look a little something like this\n

Now suppose that we want to go ahead\n

Can we get a volunteer\nto be on camera here?

You jumped out of your seat.

OK, you really want\nthe foam finger, I say.

So here is your number\n2 for your number field.

And come on, let's say that there\n

So Caleb got malloced,\nif you will, over here.

So now if we want to insert Caleb and\n

well what do we need to do?

I already initialized you to 2.

And pointing as you\nare to the ground means

you're initialized to\nnull for your next field.

Pedro, what you should you-- perfect.

So Pedro is now pointing at the list.

So now our list looks a\nlittle something like this.

So the first couple of these\nwill be pretty straightforward.

Let's insert one more, if anyone\n

Here, how about right in the middle.

And just in anticipation, how\nabout let's malloc someone else.

OK, your friends are pointing at you.

Do you want to come\ndown too, preemptively?

This is a pool of memory, if you will.

And hang there for just a moment.

So we've just malloced Hannah.

And Hannah, how about Hannah,\nsuppose you ended up over there

in just some random location.

So what should we now do, if the\n

So Pedro, do you have\nto update yourself?

Caleb, what do you have to do?

And Hannah what should you be doing?

I would, it's just for you for now, so\n

So, again demonstrating the fact\n

we had our nice, clean array\nback, to back, to back

contiguously, these guys are\ndeliberately all over the stage.

And pick your favorite place in memory.

So Jonathan's now over there.

So 5, we want to point\nHannah at number 5.

So you, of course, are\ngoing to point there.

And where should you be pointing?

Down to represent null, as well.

But now things get a little interesting.

And here, we'll use a chance\nto, without the weeds of code

point out how order of operations\nis really going to matter.

Suppose that I next want to\nallocate say, the number 1.

And I want to insert the\nnumber 1 into this list.

This is what the code would look like.

But if we act this out-- could\nwe get one more volunteer?

How about on the end\nthere in the sweater.

And how about, Lauren,\nwhy don't you go right

in here in front, if you don't mind.

So I've initialized\nLauren to the number 1.

And your pointer will be\nnull, pointing at the ground.

Where do you belong if we're\nmaintaining sorted order?

Looks like right at the beginning.

So Pedro has presumed\nto point now at Lauren.

But how do you know where to point?

SPEAKER 1: Pedro's undoing\nwhat he did a moment ago.

And that was perfect that Pedro\n

You literally just orphaned all of these\n

Because if Pedro was our only variable\n

this is the danger of using pointers,\n

and building your own data structures.

The moment you point\ntemporarily, if you could

to Lauren, I have no idea\nwhere he's pointing to.

I have no idea how to get back to Caleb,\n

I think we need Lauren\nto make a decision first.

SPEAKER 1: So pointing at Caleb.

Because you're pointing at\nliterally who Pedro is pointing at.

Pedro, now what are you safe to do?

So order of operations there matters.

And if we had just done this line\n

That was like Pedro's first\ninstinct, bad things happen.

And we orphaned the rest of the list.

But if we think through it logically and\n

we've now updated the list to look\n

We got one more foam finger\nhere for the number 3.

If you want to go maybe in the middle of\n

So here, too, the goal is\nto maintain sorted order.

So let's ask the audience, who or what\n

So we don't screw up and\norphan some of the memory.

And if we do orphan memory, this is\n

Your Mac, your PC, your\nphone can start to slow down

if you keep asking for memory but\n

So we want to get this right.

SPEAKER 1: 3 should point at 4.

So 3, do you want to point at 4.

And how did you know,\nMiriam, whom to point at?

Because if you look at where this\nlist is currently constructed

and you can cheat on the board\nhere, 2 is pointing to 4.

If you point at whoever Caleb,\nnumber 2, is pointing out

that, indeed, leads you\nto Hannah for number 4.

So now what's the next step\nto stitch this together?

So Caleb, I think it's now\nsafe for you to decouple.

Because someone is already\npointing at Hannah.

We haven't orphaned anyone.

So now, if we follow\nthe breadcrumbs, we've

got Pedro leading to 1,\nto 2, to 3, to 4, to 5.

We need the numbers back, but\nyou can keep the foam fingers.

Thank you to our volunteers here.

SPEAKER 1: You can just\nput the numbers here.

SPEAKER 1: Thank you to all.

So this is only to say that when you\n

and in the problem set, it's\ngoing to be very easy to lose

sight of the forest for the trees.

Because the code does get really dense.

But the idea is, again, really do bubble\n

And if you think about data\nstructures at this level.

If you go off in program\nafter a class like CS50

and your whiteboarding something\nwith a friend or a colleague

most people think at\nand talk at this level.

And they just assume that,\nyeah, if we went back and looked

at our textbooks or class notes, we\n

But the important stuff\nis the conversation.

Even though, via this week, will we\n

So when it comes to analyzing\nan algorithm like this

let's consider the following.

What might be now the running time of\n

We talked about arrays earlier.

And we had some binary search\npossibilities still, as soon

But as soon as we have a linked list,\n

And so you can't just\nassume that you can

jump arithmetically to the middle\n

You pretty much have to follow all\n

So how might that inform what we see?

Even though I keep drawing all these\n

And all of us humans\nin the room can easily

spot where the 1 is, where the 2 is,\n

just like with our lockers and arrays,\n

And the key thing with a linked\nlist is that the only address

we've fundamentally been remembering\n

He was the link to all\nof the other nodes.

And, in turn, each\nperson led to the next.

But without Pedro, we would have lost\n

So when you start with\na linked list, if you

want to find an element as via\n

Following all of the arrows.

Following all of the\npointers on the stage

in order to get to the node in question.

And only once you hit null can\nyou conclude, yep, it was there.

So given that if a\ncomputer, essentially

can only see the number 1, or the number\n

or the number 5, one\nat a time, how might we

think about the running time of search?

And it is indeed Big O of n.

Well, in the worst case, the\nnumber you might be looking for

And so, obviously, you're going to\n

And I drew these things\nwith boxes on top of them.

Because, again, even though\nyou and I can immediately see

where the 5 is for\ninstance, the computer

can only figure that out by starting\n

So there, too, is another trade off.

It would seem that, overnight,\nwe have lost the ability

to do a very powerful algorithm from\n

Because there's no way in this\npicture to jump mathematically

to the middle node, unless\nyou remember where it is.

And then, remember where\nevery other node is.

And at that point,\nyou're back to an array.

Linked list, by design, only\nremember the next node in the list.

How about something like insert?

In the worst case,\nperhaps, how many steps

might it take to insert\nsomething into a linked list?

Fortunately, it's not that bad.

It's not as bad as n squared.

That typically means\ndoing n things, n times.

And I think we can stay under\nthat, but not a bad thought.

SPEAKER 1: Why would it be n?

AUDIENCE: Because the [INAUDIBLE].

So to summarize, you're proposing n.

Because to find where\nthe thing goes, you

have to traverse,\npotentially, the whole list.

Because if I'm inserting the\nnumber 6 or the number 99

that numerically\nbelongs at the very end

I can only find its location\nby looking for all of them.

At this point, though, in the term.

And really, at this\npoint in the story, you

should start to question these very\n

Because the answer is almost\nalways going to depend, right.

If I've just got a link to\nlist that looks like this

the first question back to\nsomeone asking this question

would be, well does the list\nneed to be sorted, right?

I've drawn it as sorted\nand it might imply as much.

So that's a reasonable\nassumption to have made.

But if I don't care about\nmaintaining sorted order

I could actually insert into a\nlinked list in constant time.

I could just keep inserting into\n

And even though the\nlist is getting longer

the number of steps required to insert\n

If you want to keep it\nsorted though, yes, it's

going to be, indeed, Big O of n.

But again, these kinds\nof, now, assumptions

are going to start to matter.

So let's for the sake of\ndiscussion say it's Big O of n

if we do want to maintain sorted order.

But what about in the\ncase of not caring.

It might indeed be a Big O of 1.

And now these are the kinds of decisions\n

What about in the best case here?

If we're thinking about\nBig Omega notation

then, frankly, we could just\nget lucky in the best case.

And the element we're looking for\n

Or heck, we just blindly insert to the\n

that we want to keep things in.

So besides then, how can we\nimprove further on this design?

We don't need to stop at linked list.

Because, honestly, it's\nnot been a clear win.

Like, linked list allow us\nto use more of our memory

because we don't need massive\n

But they still require Big O of\nn time to find the end of it

We're using at least twice as\nmuch memory for the darn pointer.

So that seems like a sidestep.

It's not really a step forward.

Here's where we can now accelerate the\n

even if you haven't\nused this technique yet

we would seem to have an ability to\n

And anything you could\nimagine drawing with arrows

you can implement, it\nwould seem, in code.

So what if we leverage\na second dimension.

Instead of just stringing\ntogether things laterally

left to right, essentially,\neven though they

were bouncing around on the screen.

What if we start to leverage a\n

And build more interesting\nstructures in the computer's memory.

Well it turns out that\nin a computer's memory

we could create a tree,\nsimilar to a family tree.

If you've ever seen or draw on a family\n

So inverted branch of a\ntree that grows, typically

when it's drawn, downward instead\nof upward like a typical tree.

But that's something we could\ntranslate into code as well.

Specifically, let's do something\ncalled a binary search tree.

And what I mean by\nthis is the following.

This is an example of an\narray from like week 2

when we first talked about those.

And we had the lockers on stage.

And recall that what was nice\nabout an array, if 1, it's sorted.

And 2, all of its numbers\nare indeed contiguous

which is by definition an array.

We can just do some simple math.

For instance, if there are 7 elements\n

3 and 1/2, round down\nthrough truncation, that's 3.

That gives me the middle element,\narithmetically, in this thing.

And even though I have to be\ncareful about rounding, using

simple arithmetic, I can very quickly,\n

find for you the middle of the\nleft half, of the left half

of the right half, or whatever.

That's the power of arrays.

And that's what gave us binary search.

And how did binary search work?

Well, we looked at the middle.

And then, we went left or right.

And then, we went left or right again,\n

Wouldn't it be nice if we\nsomehow preserved the new upsides

today of dynamic memory\nallocation, giving ourselves

the ability to just add another\nelement, add another element

But retain the power of binary search.

Because log of n was much better than\n

Even the phone book\ndemonstrated as much weeks ago.

So what if I draw this same\npicture in 2 dimensions.

And I preserve the color scheme,\n

What are these things look like now?

Maybe, like, things we\nmight now call nodes, right.

A node is just a generic term\nfor like, storing some data.

What if the data these nodes\nare storing are numbers.

But what if we connected these\n

Whereby, every node has not one\npointer now, but as many as 2.

Maybe 0, like in the leaves\nat the bottom are in green.

But other nodes on the interior\nmight have as many as 2.

Like having 2 children, so to speak.

And indeed, the vernacular\nhere is exactly that.

This would be called\nthe root of the tree.

Or this would be a parent,\nwith respect to these children.

The green ones would be\ngrandchildren, respect to these.

The green ones would be siblings\nwith respect to each other.

So all the same jargon you\nmight use in the real world

applies in the world of data\nstructures and CS trees.

But this is interesting because I think\n

structure in the computer's memory.

Well, suppose that we defined\na node to be no longer just

this, a number in a next field.

What if we give ourselves\na bit more room here?

And give ourselves a pointer called\n

Both of which is a\npointer to a struct node.

So same idea as before, but now we\n

as pointing this way and\nthis way, not just this way.

Not just a single direction, but 2.

So you could imagine, in code, building\n

That creates, in essence,\nthis diagram here.

Suppose I want to find the number 3.

I want to search for the\nnumber 3 in this tree.

It would seem, just like Pedro was\n

in the world of trees,\nthe root, so to speak

is the beginning of your data structure.

You can retain and remember this entire\n

One variable can hang\non to this whole tree.

So how can I find the number 3?

Well, if I look at the root node and\n

Or if it's greater\nthan, I can go this way.

So I preserve that\nproperty of the phone book

or just assorted array in general.

If I'm looking for 3, I can\ngo to the right of the 2

because that number is\ngoing to be greater.

If I go left, it's going\nto be smaller instead.

And here's an example\nof actually recursion.

Recursion in a physical sense\nmuch like the Mario's pyramid.

Which was recursively to find.

I claim this whole thing is a tree.

Specifically, a binary search\ntree, which means every node

has 2, or maybe 1, or maybe 0 children.

And it's the case that every left\n

And every right child\nis larger than the root.

That definition certainly\nworks for 2, 4, and 6.

But it also works recursively for\n

Notice, if you think\nof this as the root

it is indeed bigger\nthan this left child.

And it's smaller than this right child.

And if you look even at\nthe leaves, so to speak.

This root node is bigger than\nits left child, if it existed.

So it's a meaningless statement.

And it's less than its right child.

Or it's not greater than, certainly,\nso that's meaningless too.

So we haven't violated the definition\n

And so, now, how many steps does\n

any number in a binary\nsearch tree, it would seem?

And the height of this\nthing is actually 3.

And so long story short, especially,\n

with your logarithms from yesteryear.

Log base 2 is the number of times you\n

and half, until you get down to 1.

This is like a logarithm\nin the reverse direction.

Here's a whole lot of elements.

And we're having, we're\nhaving until we get down to 1.

So the height of this tree, that\nis to say, is log base 2 of n.

Which means that even in the worst case,\n

it's all the way at the\nbottom in the leaves.

It's going to take log base 2\nof n steps, or log of n steps

to find, maximally, any\none of those numbers.

So, again, binary search is back.

But we've paid a price, right.

This isn't a linked list anymore.

But we've gained back binary search,\n

That's where the whole class\nbegan, on making that distinction.

But what price have we paid to retain\n

It's no longer sorted\nleft to right, but this

is a claim sorted, according to\n

Where, again, left child\nis smaller than root.

And right child is greater than root.

So it is sorted, but it's sorted in\n

AUDIENCE: [INAUDIBLE] nodes now.

Every node now needs not one\nnumber, but 2, 3 pieces of data.

So, again, there's that trade off again.

Where, well, if you want\nto save time, you've

got to give something if\nyou start giving space.

And you start using more\nspace, you can speed up time.

There's always a price paid.

And it's very often in space, or time,\n

the number of bugs you have to solve.

I mean, all of these\nare finite resources

that you have to juggle them on.

So if we consider now the code\nwith which we can implement this

And how might we actually\nuse something like this?

Well, let's take a look at,\nmaybe, one final program.

And see here, before we transition\n

Let me go ahead here and let me just\n

So let me, in a moment, copy\nover file called tree.c.

Which we'll have on\nthe course's websites.

And I'll walk you\nthrough some of the logic

here that I've written for tree.c.

So what do we have here first?

So here is an implementation of\n

And as before, I've played around and\n

Here is my definition of a node for a\n

from what I proposed on\nthe board a moment ago.

Here are 2 prototypes for\n2 functions, that I'll

show you in a moment,\nthat allow me to free

an entire tree, one node at a time.

And then, also allow me to\nprint the tree in order.

So even though they're\nnot sorted left to right

I bet if I'm clever about\nwhat child I print first

I can reconstruct the idea of\nprinting this tree properly.

So how might I implement\na binary search tree?

Here is how I might\nrepresent a tree of size 0.

It's just a null pointer called tree.

Here's how I might add\na number to that list.

So here, for instance, is me\nmalllocing space for a node.

Storing it in a temporary\nvariable called n.

Here is me just doing a safety check.

Make sure n does not equal null.

And then, here is me initializing this\n

Then, initializing the left\nchild of that node to be null.

And the right child of\nthat null node to be null.

And then, initializing the tree itself\n

So at this point in the story, there's\n

containing the number\n2 with no children.

Let's just add manually\nto this a little further.

Let's add another number to the\nlist, by mallocing another node.

I don't need to declare n as a node*\n

Here's a little safety check.

I'm going to not bother with my,\n

We want a free memory too,\nwhich I've not done here

but I'll save that for another time.

Here, I'm going to\ninitialize the number to 1.

I'm going to initialize the children\n

And now, I'm going to do this.

Initialize the tree's\nleft child to be n.

So what that's essentially\ndoing here is if this

is my root node, the single rectangle\n

has no children, neither left nor right.

Here's my new node with the number 1.

I want it to become the new left child.

So that line of code on the\nscreen there, tree left equals n

is like stitching these 2 together\n

The next lines of code,\nyou can probably guess

are me adding another\nnumber to the list.

So this is a simpler tree with\n2, 1, and, 3 respectively.

And this code, let me wave\nmy hands, is almost the same.

Except for the fact that I'm\nupdating the tree's right child

to be this new and third node.

Let's now run the code before\nlooking at those 2 functions.

So it sounds like the data structure\n

But how did I actually print this?

And then, eventually,\nfree the whole thing?

Well let's look at the\ndefinition of first print tree.

And this is where\nthings get interesting.

Print tree returns nothing\nso it's a void function.

But it takes a pointer to a root element\n

If root equals equals\nnull, there's obviously

nothing to print, just return.

But here's where things\nget a little magical.

Otherwise, print your left child.

Then, print your right child.

What is this an example of, even\n

What programming technique here?

So this is actually perhaps the most\n

It wasn't really that\ncompelling with the Mario thing

because we had such an easy\nimplementation with a for-loop loop

But here is a perfect application of\n

If you take any snip\nof any branch, it all

still looks like a tree,\njust a smaller one.

That lends itself to recursion.

So here is this leap of faith where I\n

tree, if you will, via\nmy child at the left.

Then, I'll print my own root\nnode here in the middle.

Then, go ahead and\nprint my right sub tree.

And because we have this base case that\n

there's nothing to do, you're\nnot going to recurse infinitely.

You're not going to call yourself\nagain, and again, and again

So it works out and prints\nthe 1, the 2, and the 3.

And notice what we could do, too.

If you wanted to print the tree in\n

Print your right tree\nfirst, the greater element.

Then, your smaller sub tree.

And if I do make tree\nhere and ./tree, well now

I've reversed the order of the list.

You can do it with a\nfor-loop in an array.

But you can also do it, even with\nthis 2-dimensional structure.

Let's lastly look at\nthis free tree function.

And this one's almost the same.

Order doesn't matter in quite the\n

Here's what I did with free tree.

Well, if the root of the tree is\n

Otherwise, go ahead and free your\n

Then free your right child\nand all of its descendants.

And again, free literally just\n

It doesn't free the whole darn thing.

It just frees literally\nwhat's at that address.

Why was it important that\nI did line 72 last, though?

Why did I free the left\nchild and the right child

before I freed myself, so to speak?

If you free yourself first, if I had\n

you're not allowed to touch the left\n

Because the memory address is\nno longer valid at that point.

You would get some\nmemory error, perhaps.

Valgrind definitely wouldn't like it.

Bad things would otherwise happen.

But here, then, is an\nexample of recursion.

And again, just a recursive use\nof an actual data structure.

And what's even cooler here\nis, relatively speaking

suppose we wanted to\nsearch something like this.

Binary search actually gets pretty\n

here might be the prototype for a search\n

You give me the root of a tree, and\n

and I can pretty easily now return true\n

Well, let's first ask a question.

If tree equals equals null,\nthen you just return false.

Because if there's no tree, there's no\n

Else if, the number you're looking for\n

which direction should we go?

Well, let's just return the\nanswer to this question.

Search the left sub tree,\nby way of my left child

looking for the same number.

And you just assume through\nthe beauty of recursion

that you're kicking the can\nand let yourself figure it out

Just that snipped left tree instead.

Else if, the number you're looking for\n

go to the right, as you might infer.

So I can just return the\nanswer to this question.

Search my right sub tree\nfor that same number.

And there's a fourth\nand final condition.

What's the fourth scenario we\nhave to consider, explicitly?

SPEAKER 1: If the number,\nitself, is right there.

So else if, the number I'm looking\n

then and only then,\nshould you return true.

And if you're thinking\nquickly here, there's

an optimization possible,\nbetter design opportunity.

Think back to even our scratch days.

What could we do a little better here?

Because if there's logically\nonly 4 things that could happen

you're wasting your time by asking\na fourth gratuitous question.

So here to, more so than the\nMario example a few weeks ago

there's just this elegance\narguably to recursion.

This is the code for binary\nsearch on a binary search tree.

And so, recursion tends\nto work in lockstep

with these kinds of data structures\n

Any questions, then, on binary search\n

AUDIENCE: About like third years.

So when returning a Boolean value, true\n

in a library called Standard\nBool, S-T-D-B-O-O-L dot H.

With a header file that you can use.

It is the case that true is, it's\n

But they would map indeed, yes.

But you should not compare\nthem explicitly to 0 and 1.

When you're using true and false, you\n

AUDIENCE: I meant if\nit's in a code return.

So if I am in my own code from\nearlier, an avoid function

it is totally fine to return.

You just can't return\nsomething explicitly.

So return just means that's it.

You're not actually\nhanding back a value.

So it's a way of short\ncircuiting the execution.

If you don't like that,\nand some people do frown

upon having code return from functions\n

If the root does not equal\nnull, do all of these things.

And then, indent all three\nof these lines underneath.

I happen to write it\nthe other way just so

that there was explicitly a base case\n

Whereas, now, it's\nimplicitly there for us only.

So let's ask the question as\nbefore about running time of this.

It would look like\nbinary search is back.

And we can now do things in logarithmic\n

Is this a binary search tree?

And again, a binary\nsearch tree is a tree

where the root is greater than its left\n

So you're nodding your head.

So this is a binary search tree.

Is this a binary search tree?

Or I'm hearing just my delay\nchanging the vote it would seem.

So this is one of those trick questions.

This is a binary search\ntree because I've not

violated the definition\nof what I gave you, right.

Is there any example of a left child\n

Or is there any example of a right\n

That's just the opposite way\nof describing the same thing.

No, this is a binary search tree.

Unfortunately, it also looks like,\n

But you could imagine\nthis happening, right.

Suppose that I hadn't been as\nthoughtful as I was earlier

by inserting 2, And then 1, and then 3.

Which nicely balanced everything out.

Suppose that instead, because\nof what the user is typing in

or whatever you contrive in your\n

Like, you've created a\nproblem for yourself.

Because if we follow the same logic\n

this is how you might implement\n

if you just blindly keep\nfollowing that definition.

I mean, this would be\nbetter designed as what?

If we rotated the whole thing around.

And those kinds of trees\nactually have names.

There's trees called AVL\ntrees in computer science.

There are red-black black\ntrees in computer science.

There are other types of\ntrees that, additionally

add some logic that tell you\nwhen you got to pivot the thing

and rotate it, and snip off the\n

But a binary search\ntree, in and of itself

does not guarantee that it\nwill be balanced, so to speak.

And so, if you consider\nthe worst case scenario

of even using a binary search tree.

If you're not smart about\nthe code you're writing

and you just blindly\nfollow this definition

you might accidentally create a\n

tree that essentially\nlooks like a linked list.

Because you're not even using\nany of the left children.

So unfortunately, the literal\nanswer to the question

here is what's the\nrunning time of search?

But not if you don't maintain\nthe balance of the tree.

Both, in certain search, could actually\n

If you don't somehow take\ninto account, and we're not

going to do the code for that here.

It's a higher level thing you\nmight explore down the road.

It can devolve into something\nthat you might not have intended.

And so, now that we're\ntalking about 2 dimensions

it's really the onus\nis on the programmer

to consider what kinds of\nperverse situations might happen.

Where the thing devolves\ninto a structure

that you don't actually\nwant it to devolve into.

We've got just a few structures to go.

Let's go ahead and take one\nmore 5 minute break here.

When we come back,\nwe'll talk at this level

about some final applications of this.

And as promised, we'll operate\nnow at this higher level.

Where if we take for granted that, even\n

to play with these techniques yet,\n

Both in a one dimension\nand even 2 dimensions

to build things like lists and trees.

So if we have these building blocks.

Things like now arrays,\nand lists, and trees

what if we start to amalgamate\n

of multiple data structures?

Can we start to get some of the best\n

something called a hash table.

So a hash table is a Swiss\narmy knife of data structures

in that it's so commonly used.

Because it allows you to associate\nkeys with value, so to speak.

So, for instance, it allows you to\n

Or anything where you have\nto take something as input

and get as output a corresponding\npiece of information.

A hash table is often a\ndata structure of choice.

And here's what it looks like.

It's actually looks like\nan array, at first glance.

But for discussion's sake, I've\ndrawn this array vertically

But it allows you, a hash table, to\n

So, for instance, there's actually\n26 locations in this array.

Because I want to, for\ninstance, store initially

names of people, for instance.

And wouldn't it be nice if the\nperson's name starts with A

I have a go to place for it.

And if it starts with Z,\nI put them at the bottom.

So that I can jump\ninstantly, arithmetically

using a little bit of\nAscii or Unicode fanciness

exactly to the location that\nthey want to they need to go.

So, for instance, here's\nour array 0 index.

If I think of this,\nthough, as A through Z

I'm going to think of\nthese 26 locations

now in the context of a hash table,\n

So buckets into which\nyou can put values.

So, for instance, suppose that we\n

And that name is say, Albus.

So Albus starting with A. Albus might\n

And then, we want to\ninsert another name.

This one happens to be Zacharias.

Starting with Z, so it goes all\nthe way at the end of this data

structure in location 25 a.k.a.

And then, maybe a third name like\n

according to that\nposition in the alphabet.

So this is great because\nin constant time

I can insert and conversely\nsearch for any of these names

based on the first letter of their name.

A, or Z, or H, in this case.

Let's fast forward and assume we\n

might look familiar,\ninto this hash table.

It's great because every\nname has its own location.

But if you're thinking of names\n

we eventually encounter a\nproblem with this, right.

When could something go wrong\nusing a hash table like this

if we wanted to insert even more names?

What's going to eventually happen?

There's already someone with\nthe first letter, right.

Like I haven't even mentioned\nHarry, for instance, or Hagrid.

And yet, Hermione's\nalready using that spot.

So that invites the\nquestion, well, what happens?

Maybe, if we want to insert Harry\n

But then if there's a location\nI, where do we put them?

And it just feels like the situation\ncould very quickly devolve.

But I've deliberately\ndrawn this data structure

that I claim as a hash\ntable, in 2 directions.

But what might this be hinting\nI'm using horizontally

even though I'm drawing the rectangles\n

Maybe another array, to be fair.

But, honestly, arrays are such a pain\n

These look like the beginnings\nof a linked list, if you will.

Where the name is where the number\n

horizontally now just\nfor discussion's sake.

And this seems to be a pointer\nthat isn't pointing anywhere yet.

But it looks like the array is 26\n

Some of which are pointing at\nthe first node in a linked list.

So that's really what a hash\ntable might be in your mind.

An amalgam of an array, whose\nelements are linked lists.

And in theory, this gives you\nthe best of both worlds, right.

You get random access with\nhigh probability, right.

You get to jump immediately to the\n

But, if you run into this perverse\n

It starts to devolve into a\nlinked list, but it's at least 26

Not one massive linked list,\nwhich would be Big O of n.

So if Harry gets inserted in Hagrid.

Yeah, you have to chain them\ntogether, so to speak, in this way.

But, at least you've not\npainted yourself into a corner.

And in fact, if we fast forward and\n

the data structure\nstarts to look like this.

So the chains not terribly long.

And some of them are actually\nof size 0 because there's just

some unpopular letters of the\nalphabet among these names.

But it seems better than\njust putting everyone

in one big array, or\none big linked list.

We're trying to balance these trade\n

Well, how might we represent\nsomething like this?

Here's how we could describe this thing.

A node in the context of a\nlinked list could be this.

I have an array called\nword of type char.

And it's big enough to fit the\n

And the plus 1 why, probably?

SPEAKER 1: The null character.

So I'm assuming that longest word\n

And it's something big\nlike 40, 100, whatever.

Whatever the longest word\nin the Harry Potter universe

is or the English dictionary is.

Longest word plus 1 should be sufficient\n

And then, what else does it\neach of these nodes have?

Well it has a pointer to another node.

So here's how we might\nimplement the notion of a node

in the context of storing\nnot integers, but names.

But how do we decide what\nthe hash table itself is?

Well, if we now have a definition of a\n

or even globally, called hash table.

That itself is an array\nof node* pointers.

That is an array of pointers to nodes.

The beginnings of linked lists.

I proposed, verbally, that it be 26.

But honestly, if you get a lot\nof collisions, so to speak.

A lot of H names trying\nto go to the same place.

Well, maybe, we need to be\nsmarter and not just look

at the first letter of their name.

But, maybe, the first and the second.

So it's H-A and H-E. But wait, no,\n

But we start to at least make\nthe problem a little less

impactful by tinkering with\nsomething like the number of buckets

But how do we decide where someone\n

Well, it's an old school\nproblem of input and output.

The input to the problem is going\nto be something like the name.

And the algorithm in\nthe middle, as of today

is going to be something\ncalled a hash function.

A hash function is\ngenerally something that

takes as input, a string, a\nnumber, whatever, and produces

as output a location in our context.

Or whatever the number\nof buckets you want is

it's going to just tell you where to\n

So, for instance, Albus, according to\n

So the hash function, in the\nmiddle of that black box

is pretty simplistic in this story.

It's just looking at the Ascii\n

And then, subtracting\noff what capital A is 65.

So like doing some math to get\nback in number between 0 and 25.

So that's how we got to\nthis point in the story.

And how might we, then, resolve\nthe problem further and use

this notion of hashing more generally?

Well just for demonstration\nsake here, here's

actually some buckets, literally.

And we've labeled, in advance,\nthese buckets with the suits

And we've got diamonds here.

And we've got, what else here?

So we have a deck of cards\nhere, for instance, right.

And this is something you,\nyourself, might do instinctively

if you're getting ready to\nstart playing a game of cards.

You're just cleaning up or\nyou want things in order.

Like, here is literally\na jumbo deck of cards.

What would be the easiest way\nfor me to sort these things?

Well we've got a whole bunch of\n

So I could go through like,\nhere's the 3 of diamonds.

And I could, here let me\nthrow this up on the screen.

Just so, if you're far in back.

I could do this in order here.

But a lot of us, honestly,\nif given a deck of cards.

And you just want to clean\nit up and sort it in order

you might do things like this.

Well here's my input, 3 of diamonds,\n

And if you keep going through the cards,\n

And it's still going\nto take you 52 steps.

But at the end of it, you\nhave hashed all of the cards

And now you have problems\nof size 13, which

is a little more tenable than\ndoing one massive 52 card problem.

You can now do 4, 13 size problems.

And so hashing is something that even\n

Taking as input some card, some name,\n

A temporary pile in which you\nwant to stage things, so to speak.

But these collisions are inevitable.

And honestly, if we kept going\n

some of these chains would get\nlonger, and longer and longer.

Which means that instead of\ngetting someone's name quickly

by searching for them\nor inserting them, might

start taking a decent amount of time.

So what could we do instead to\nresolve situations like this?

If the problem, fundamentally, is\n

popular, H, we need\nto take in more input.

Not just the first letter but\nmaybe the first 2 letters.

So if we do that, we\ncan go from A through Z

to something more extreme like maybe\n

So that now Harry and Hermione\nend up at different locations.

But, darn it, Hagrid\nstill collides with Harry.

The chains aren't quite as long.

But the problem isn't\nfundamentally gone.

And in this case here, anyone\nknow how many buckets we just

increased to, if we now look at not just\n

So the easy answer to\n26 squared are 676.

So that's a lot more buckets.

And this is why I only showed\na few of them on the screen.

And it spreads things out in particular.

What if we take this one step further?

Instead of H-A, we do like H-A-A,\n

Well now, we have an\neven better situation.

Because Hermoine has her one spot.

But there's a trade off here.

The upside is now, arithmetically,\nwe can find their locations

But 3 is constant, no matter how many\n

But what's the downside here?

We're now up to 17,576 buckets, which\n

Computers have a lot\nof memory these days.

But as you can infer,\nI can't really think

of someone whose name started with\n

And if we keep going,\ndefinitely don't know of anyone

whose name started with\nZ-Z-Z or A-A-A. There's

a lot of not useful combinations\n

so that you can do a bit of math\n

But they're just going to be empty.

So it's a very sparsely\npopulated array, so to speak.

So what does that really mean\nfor performance, ultimately?

Well let's consider, again, in\n

It turns out that a hash\ntable, technically speaking

is still just going to give us\nBig O of n in the worst case.

If you have some crazy perverse\n

has a name that starts with A, or\n

you just get really unlucky.

And your chain is massively long.

Well then, at that point,\nit's just a linked list.

It's like the perverse\nsituation with the tree, where

if you insert it without any mind for\n

But there's a difference here\nbetween a theoretical performance

If you look back at the\nthe hash table here

this is absolutely, in practice, going\n

Mathematically, asymptotically,\nbig O notation, sure.

But if what we're really caring about\n

there's something to be said\nfor crafting a data structure.

That technically, if this data\nwere uniformly distributed

is 26 times faster than\na linked list alone.

And so, there's this tension too\nbetween systems, types of CS

Where yeah, theoretically,\nthese are all the same.

But in practice, for\nmaking real-world software

improving this speed by a factor of 26\n

might actually make a big difference.

But there's going to be a trade off.

And that's typically some other\n

How about another data\nstructure we could build.

Let me fast forward to\nsomething here called a trie.

So a trie, a weird\nname in pronunciation.

Short for retrieval,\npronounced trie typically.

A trie is a tree that actually\ngives us constant time lookup

In the world of a trie, you\ncreate a tree out of arrays.

So we're really getting into\nthe Frankenstein territory

of just building things up with\nspare parts of data structures

But the root of a trie\nis, itself, an array.

Where each element in that\ntrie points to another node

which is to say another array.

And each of those locations in\nthe array represents a letter

of the alphabet like A through Z.

So for instance, if you wanted to store\n

not in a hash table, not in a linked\n

What you would do is hash on every\n

So a trie is like a multi-tier\nhash table, in a sense.

Where you first look\nat the first letter

then the second letter, then the\n

For instance, each of these\nlocations represents a letter A

through Z. Suppose I wanted to\ninsert someone's name into this

that starts with the letter\nH, like Hagrid for instance.

Well, I go to the location\nH. I see it's null

which means I need to malloc myself\n

Then, suppose I want to store the\n

an A. So I go to that\nlocation in the second node.

And I see, OK, it's currently null.

So I allocate another node\nusing malloc or the like.

And now I have H-A-G. And\nI continue this with R-I-D.

And then, when I get to the\nbottom of this person's name

I just have to indicate\nhere in color, but probably

with a Boolean value or something.

Like a true value that\nsays, a name stops here.

So that it's clear that the person's\n

or H-A-G-R-I. It's H-A-G-R-I-D.\nAnd the D is green

just to indicate there's like some\n

This is the node in\nwhich the name stops.

And if I continue this logic, here's\n

And here's how I might\ninsert someone like Hermione.

And what's interesting about the\n

Which starts to get compelling\nbecause you're reusing space.

You're using the same nodes\nfor names like H-A-G and H-A-R

because they share H and an A in common.

And they all share an H in common.

So you have this data structure\nnow that, itself, is a tree.

Each node in the tree\nis, itself, an array.

And we, therefore, might implement\n

Every node is containing, I'll\ndo it in reverse order, an array.

I'll call it children because\nthat's what it really represents.

Up to 26 children for\neach of these nodes.

So I might have used just\na constant for number 26

to give myself 26\nletters of the alphabet.

And each of those arrays\nstores that many node stars.

That many pointers to another node.

And here's an example of the Bool.

This is what I represented in\ngreen on the slide a moment ago.

I also need another piece of data.

Just a 0 or 1, a true\nor false, that says yes.

A name stops in this node or it's just\n

But the upside of this is\nthat the height of this tree

is only as tall as the\nperson's longest name.

H-A-G-R-I-D or H-E-R-M-O-I-N-E. And\n

people are in this data structure,\nthere's 3 at the moment

if there were 3 million, it would\n

H-E-R-M-I-O-N-E. So, 8 steps total.

No matter if there's 2 other people,\n

Because the path to her name\nis always on the same path.

And if you assume that there's a\n

Maybe it's 40, 100, whatever.

Whatever the longest\nname in the world is.

Maybe it's 40, 100, but that's constant.

Which is to say that with a\ntrie, technically speaking

it is the case that your lookup\n

It's constant time, because\nunlike every other data structure

we've looked at, with a trie, the amount\n

or insert one person is\ncompletely independent of how

many other pieces of data are\nalready in the data structure.

And this holds true even if one\nname is a prefix of another.

I don't think there was a Daniel or\n

But, D-A-N-I-E-L could be one name.

And, therefore, we have\na true there in green.

And if there's a longer\nname like Danielle.

Then, you keep going\nuntil you get to the E.

So you can still have with\na trie, one name that's

a substring of another name.

So it's not as though we've\ncreated a problem there.

That, too, is still possible.

But at the end of the day, it only\n

to find any of these people.

And again, that's what's\nparticularly compelling.

That you effectively have\nconstant time lookup.

We've gone through this whole story\n

And then, it went up to n squared.

And now constant time, what's the price\n

And in fact, tries are not\nactually used that often

amazing as they might sound\non some CS level here.

AUDIENCE: Much like a [INAUDIBLE].

If you're storing all\nof these darn arrays

it's, again, a sparsely\npopulated data structure.

Granted there's only 3 names, but most\n

So this is an incredibly wide\ndata structure, if you will.

It uses a huge amount of\nmemory to store the names.

But again, you've got to pick a lane.

Either you're going to minimize space\n

It's not really possible to get\ntruly the best of both worlds.

You have to decide where\nthe inflection point is

for the device you're writing\n

And again, taking all of\nthese things into account.

So lastly, let's do one\nfurther abstraction.

So even higher level to discuss\nsomething that are generally

known as abstract data structures.

It turns out we could\nspend like all day

all week, talking about\ndifferent things we

could build with these data structures.

But for the most part,\nnow that we have arrays.

Now that we have linked lists\nor their cousin's trees, which

And beyond that, there's\neven graphs, where

the arrows can go in multiple\n

Now that we have this ability\nto stitch things together

we can solve all different\ntypes of problems.

So, for instance, a very\ncommon type of data structure

to use in a program, or even our\n

A queue being a data structure\nlike a line outside of a store.

Where it has what's\ncalled a FIFO property.

Which is great for fairness,\nat least in the human world.

And if you've ever waited outside\n

or some other restaurant\nnearby, presumably

if you're queuing up at\nthe counter, you want

them store to maintain a FIFO system.

So that whoever's first in line gets\n

So a queue is actually a\ncomputer science term, too.

And even if you're still in the\n

there are things you might\nhave heard called printer

queues, which also do things in order.

The first person to send\ntheir essay to the printer

should, ideally, be printed\nbefore the last person

to send their essay to the printer.

Again, in the interest of fairness.

But how can you implement a queue?

Well, you typically have to\nimplement 2 fundamental operations

So adding something to it and\nremoving something from it.

And the interesting thing here is\n

Well in the human world, you would\n

for humans to line up from left\nto right, or right to left.

Like a printer queue, if you send a\n

a whole bunch of essays\nor documents, well, you

need a chunk of memory like an array.

Well, if you use an\narray, what's a problem

that could happen in the world\nof printing, for instance?

If you use an array to store all of\n

AUDIENCE: It can be filled.

SPEAKER 1: It could be filled, right.

So if the programmer decided, HP or\n

oh, you can send like a megabyte worth\n

At some point you might\nget an error message

which says, sorry out of memory.

Which is maybe a reasonable\nsolution, but a little annoy.

Or HP could write code that maybe\ndynamically resizes the array

But at that point, maybe they\nshould just use a linked list.

So there, too, you could\nimplement the notion of a queue

using a linked list instead.

You're going to spend more\nmemory, but you're not

going to run out of space in your array.

Which might be more compelling.

This happens even in the physical world.

You go to the store and you start having\n

And like, for a really busy store,\n

But in that case, it tends to\nbe more of an array just because

of the physical notion\nof humans lining up.

But there's other data structures, too.

If you've ever gone to the dining hall\n

tray, you're typically picking up\n

not the first tray that was cleaned.

Because these cafeteria trays\nstack up on top of each other.

And indeed a stack is another\ntype of abstract data structure.

In the physical world, it's\nliterally something physical

Which have what we would\ncall a LIFO property.

So as these things\ncome out of the washer

they're putting the most\nrecent ones on the top.

And then you, the human, are probably\n

Which means in the\nextreme, no one on campus

might ever use that very first tray.

Which is probably fine\nin the world of trays

but would really be bad in the world of\n

were the property being implemented.

But here, too, it could be an array.

And you see this, honestly, every day.

If you're using Gmail\nand your Gmail inbox.

That is actually a stack,\nat least by default

where your newest message\nlast in are the first ones

That's a LIFO data structure.

And it means that you see\nyour most recent emails.

But if you have a busy day,\nyou're getting a lot of emails

it might not be a good thing.

Because now you're ignoring\nthe people who wrote you

way earlier in the day or the week.

So LIFO and FIFO are\njust properties that you

can achieve with these very\nspecific types of data structures.

And the parliaments\nin the world of stacks

is to push something onto a\nstack or pop something out.

These are here, for instance,\nas an example of why

might you always wear the same color.

Well, if you're storing all\nof your clothes in a stack

you might not ever get\nto the different colored

clothes at the bottom of the list.

And in fact, to paint this picture,\n

Just to paint this here, made\nby a faculty member elsewhere.

Let's go ahead and dim the lights\nfor just a minute or 2 here.

So that we can take a look\nat Jack learning some facts.

SPEAKER 2: Once upon a time,\nthere was a guy named Jack.

When it came to making friends\nJack did not have the knack.

So Jack went to talk to the\nmost popular guy he knew.

He went up to Lou and\nasked, what do I do?

Lou saw that his friend\nwas really distressed.

Well, Lou began, just\nlook how you're dressed.

Don't you have any clothes\nwith a different look?

Come to my house and\nI'll showed them to you.

So they went off the Jack's.

And Jack showed Lou the box, where he\n

Lou said, I see you have\nall your clothes in a pile.

Why don't you wear some\nothers once in a while?

Jack said, well, when I\nremove clothes and socks

I wash them and put\nthem away in the box.

Then comes the next\nmorning and up I hop.

I go to the box and get\nmy clothes off the top.

Lou quickly realized\nthe problem with Jack.

He kept clothes, CDs,\nand books in a stack.

When he'd reached for\nsomething to read or to wear

he chose a top book or underwear.

Then when he was done he\nwould put it right back.

Back it would go on top of the stack.

I know the solution,\nsaid a triumphant Lou.

You need to learn to\nstart using a queue.

Lou took Jack's clothes\nand hung them in a closet.

And when he had emptied\nthe box, he just tossed it.

Then he said, now Jack, at the end of\n

Then tomorrow morning when\nyou see the sunshine, get

your clothes from the right,\nfrom the end of the line.

Don't you see, said\nLou, it will be so nice.

You'll wear everything once\nbefore you wear something twice.

And with everything in queues\nin his closet and shelf

Jack started to feel\nquite sure of himself.

All thanks to Lou and\nhis wonderful queue.

SPEAKER 1: So just to help you realize\n

If you've ever lined up at this place.

OK, so sweetgreen, little\nsalad place in the square.

This is if you order\nonline or in advance

your food ends up according to\nthe first letter in your name.

Which actually sounds awfully\nreminiscent of something

And in fact, no matter whether\n

did, with an array and linked list.

Or with 3 shelves like this.

This is actually an abstract\ndata type called a dictionary.

And a dictionary, just like in our\n

Words and their definitions.

This just has letters of the\nalphabet and salads as their value.

But here, too, there's\na real world constraint.

In what kind of scenario does\nthis system at sweetgreen

devolve into a problem, for instance?

Because they, too, are using only\nfinite space, finite storage.

If they run out of space\non the shelf and there's

a lot of people whose names\nstart with D, or E, or whatever.

And then, maybe, they kind of\noverflow into the E's or the F's.

And they probably don't\nreally care because any human

is going to come by, and just\n

But in the world of a\ncomputer, you're the one coding

and have to be ever so precise.

We thought we would lastly\ndo one final thing here.

In advance, we prepared a linked\nlist of sorts in the audience.

Since this has become a bit of a thing.

I am starting to represent the\nbeginning of this linked list.

And so far as I have a pointer\nhere with seat location G9.

Whoever is in G9, would\nyou mind standing up?

And what letter is on your sheet there?

SPEAKER 1: OK, so you\nhave S15 and your letter--

So I see you're holding\na C in your node.

You are pointing to, if\nyou could physically, F15.

SPEAKER 1: You have an S. And\nwho should you be pointing at?

F12, if you'd like to stand up holding\n

DAVID J. MALAN: All right, this is\n

And this is the week in which\nyou learn yet another language.

But the goal is not just to\nteach you another language

for languages sake,\nas we transition today

and in the coming weeks from C, where\n

The goal ultimately is to teach you all\n

so that by the end of this\ncourse, it's not in your mind

the fact that you learned\nhow to program in C

or learned some weeks back\nhow to program in Scratch

but really how you learned\nhow to program fundamentally

in a paradigm known as\nprocedural programming

as well as with some taste\ntoday, and in the weeks to come

of other aspects of\nprogramming languages

like object-oriented\nprogramming, and more.

So recall, though, back\nin week zero, Hello, world

looked a little something like this.

And the world was quite simple.

All you had to do was drag\nand drop these puzzle pieces.

But there were still functions and\n

and all of those kinds of primitives.

We then transitioned, of course,\n

looked a little something like this.

And even now, some weeks\nlater, you might still

be struggling with some of the\nsyntax or getting annoying bugs

when you try to compile your\ncode, and it just doesn't work.

But there, too, the\npast few weeks, we've

been focusing on functions and loops\n

And so what we begin to do today\n

we're using, transitioning from C now\n

program in Python, and look\nat its relative simplicity

but also transitioning\nto look at how you

can implement these\nsame kinds of features

just using a different language.

So we're going to see\na lot of code today.

And you won't have nearly as much\n

But that's because so many of the\n

And, really, it's going to be a\n

I know how to do it in C.\nHow do I do this in Python?

How do I do the same with conditionals?

How do I declare\nvariables, and the like

and moving forward, not just in\nCS50, but in life in general

if you continue programming and learn\n

if in 5-10 years, there's a new, more\n

it's just going to be a\nmatter of googling and looking

at websites like Stack\nOverflow and the like

to look at just basic building\nblocks of programming languages

because you already speak,\nafter these past 6 plus weeks

you already speak programming\nitself fundamentally.

All right, so let's do a few quick\n

something might have\nlooked like in Scratch

and what it then looked\nlike in C, but now

as of today, what it's going\nto look like in Python.

Then we'll turn our attention\nto the command line

ultimately, in order to\nimplement some actual programs.

So in Scratch, we had\nfunctions like this, say Hello

In C it looked a little\nsomething like this

and a bit of a cryptic mess the\nfirst week, you had the printf

You had the semicolon, the parentheses.

So there's a lot more syntax\njust to do the same thing.

We're not going to get rid of all\n

in Python, that same statement is going\n

And just to perhaps call\nout the obvious, what

is different or, now, simpler\nin Python versus C, even

in this simple example here?

AUDIENCE: Now print, instead of\n

DAVID J. MALAN: Good, so it's\nnow print instead of printf.

And there's also no semicolon.

And there's one other\nsubtlety, over here.

DAVID J. MALAN: Yeah,\nso no new line, and that

doesn't mean it's not\ngoing to be printed.

It just turns out that one\nof the differences we'll see

is that, with print, you\nget the new line for free.

It automatically gets outputted by\n

But you can override it,\nwe'll see, ultimately, too.

We had multiple functions like\n

on the screen, but\nalso asked a question

thereby being another function that\n

In C we saw code that\nlooked a little something

like this, whereby that first line\n

sets it equal to the\nreturn value of getString

one of the functions\nfrom the CS50 library

and then the same double quotes\nand parentheses and semicolon.

Then we had this format code\nin C that allowed us, with %S

to actually print out that same value.

In Python, this, too, is going\nto look a little bit simpler.

Instead, we're going to have\nanswer equals getString

quote unquote "What\'s your\nname," and then print

with a plus sign and a\nlittle bit of new syntax.

But let's see if we can't just\ninfer from this example what

Well, first missing on the left is what?

To the left of the equal sign,\nthere's no what this time?

Feel free to just call it out.

DAVID J. MALAN: So there's no type.

There's no type, like\nthe word string, which

even though that was a type in\nCS50, every other variable in C

did we use Int or string or\nfloat, or Bool or something else.

In Python, there are still\ngoing to be data types

today onward, but you,\nthe programmer, don't

have to bother telling the\ncomputer what types you're using.

The computer is going\nto be smart enough

the language, really, is going to be\n

Meanwhile, on the right\nhand side, getString

is going to be a\nfunction we'll use today

and this week, which comes from a\n

But we'll also start to take off\n

see how to do things without\nany CS50 library moving forward

using a different function instead.

As before, no semicolon, but the rest\n

This starts, of course, to get\na little bit different, though.

We're using print instead of printf.

But now, even though this\nlooks a little cryptic

perhaps, if you've never\nprogrammed before CS50

what might that plus be doing,\njust based on inference here.

AUDIENCE: Adding answer\nto the string Hello.

DAVID J. MALAN: Yeah, so adding\nanswer to the string Hello

and adding, so to speak,\nnot mathematically

but in the form of joining\nthem together, much like we

saw the joined block in Scratch, or\n

This plus sign appends,\nif you will, whatever's

in answer to whatever is quoted here.

And I deliberately left a space\nthere, so that grammatically it

looks nice, after the comma as well.

Now there's another way to do this.

And it, too, is going to\nlook cryptic at first glance.

But it just gets easier and\nmore convenient over time.

You can also change this second\nline to be this, instead.

This is actually a relatively new\n

of years, where now what\nyou're seeing is, yes

a string, between these\nsame double quotes

but this is what Python would\ncall a format string, or Fstring.

And it literally starts with the letter\n

But that just indicates\nthat Python should

assume that anything inside of\ncurly braces inside of the string

should be interpolated, so to\n

substitute the value of\nany variables therein.

And it can do some other things as well.

So answer is a variable, declared,\n

This Fstring, then, says to Python,\n

If, by contrast, you\nomitted the curly braces

just take a guess, what would happen?

What would the symptom of that\nbug be, if you accidentally

forgot the curly braces, but\nmaybe still had the F there?

AUDIENCE: It would print below it, too.

DAVID J. MALAN: Yeah, it would literally\n

So the curly braces just kind\nof allow you to plug things in.

And, again, it looks\na little more cryptic

but it's just going to\nsave us time over time.

And if any of you programmed in\n

you saw plus in that context,\ntoo, for concatenation.

This just kind of makes your code a\n

So it's a convenient\nfeature now in Python.

All right, this was an example\nin Scratch of a variable

setting a variable like\ncounter equal to 0.

In C it looked like this, where\nyou specify the type, the name

and then the value, with a semicolon.

In Python, it's going to look like this.

And I'll state the obvious here.

You don't need to mention the\n

And you don't need a semicolon.

If you want a variable, just write\n

But the single equal sign\nstill behaves the same as in C.

Suppose we wanted to\nincrement counter by one.

In Scratch, we use\nthis puzzle piece here.

In C, we could do this, actually,\nin a few different ways.

There was this way, if\ncounter already exists

you just say counter\nequals counter plus 1.

There was the slightly less verbose\n

Let me do the first sentence first.

In Python, that same\nthing, as you might guess

is actually going to be almost the\n

And the mathematics are ultimately\n

via the assignment operator.

Now, recall, in C, that\nwe had this shorthand

notation, which did the same thing.

In Python, you can similarly do the same\n

The only step backwards\nwe're taking, if you

were a big fan of counter plus\n

You have to do the plus equals 1\nor plus/minus or minus equals 1

to achieve that same result. All\nright, how about in Python 2?

Here in Scratch, recall,\nwas a conditional

asking a silly question like is x less\n

In C, that looked a little\nsomething like this, printf and if

with the parentheses, the curly\n

In Python, this is going to get a\n

And if someone wants to call out\n

what has been simplified now in Python\n

Yeah, what's missing, or changed?

DAVID J. MALAN: So no curly braces.

AUDIENCE: Using the colon instead.

DAVID J. MALAN: And we're\nusing the colon instead.

So I got rid of the\ncurly braces in Python.

But I'm using a colon instead.

And even though this is\na single line of code

so long as you indent subsequent\nlines along with the printf

that's going to imply that everything,\n

should be executed below it, until you\n

a different line of code altogether.

So indentation in Python is important.

So this is among the reasons\nwe've emphasized axes like style

just how well styled your code is.

And honestly, we've seen,\ncertainly, in office hours

and you've seen in your own code,\nsort of a tendency sometimes

to be a little lax when it\ncomes to indentation, right?

If you're one of those folks\nwho likes to indent everything

on the left hand side of the window,\n

But it's not particularly\nreadable by you or anyone else.

Python actually addresses this\nby just requiring indentation

So Python is going to force you to start\n

perhaps, a tendency otherwise.

Well, we have no semicolon here.

Of course, it's print instead of printf.

But otherwise, those seem to\nbe the primary differences.

What about something larger in Scratch?

If an if-else block, like\nthis, you can perhaps

guess what it's going to look like.

In C it looks like this, curly\nbraces semicolons, and so forth.

In Python, it's going to now\nlook like this, almost the same

but indentation is important.

And there's one other difference\nthat's now again visible here

but we didn't call it out a second ago.

What else is different in Python\n

AUDIENCE: You don't have any\nparentheses around the condition.

We don't have any parentheses\naround the condition

the Boolean expression itself.

Well, it's just simpler to type.

You can still use parentheses.

And, in fact, you might\nwant to or need to

if you want to combine thoughts and\n

But by default, you no longer need\n

Lastly, with conditionals,\nwe had something like this

an if else if else statement.

In C, it looked a little\nsomething like this.

In Python, it's going to\nget really tighter now.

It's just if, and this is the\ncuriosity, elif x greater than y.

So it's not else if, it's literally\n

remain now on each of the three lines.

But the indentation is important.

And if we did want to\ndo multiple things

we could just indent below each\nof these conditionals, as well.

All right, let me pause\nthere first, to see

if there's any questions on\nthese syntactic differences.

AUDIENCE: My thought is\nmaybe like, it's good

though, does it matter if there's\n

DAVID J. MALAN: In between,\nbetween what and what?

AUDIENCE: So like the left-hand\n

DAVID J. MALAN: Ah, good\nquestion, is Python sensitive

to spaces and where they go?

Sometimes no, sometimes\nyes, is the short answer.

Stylistically, though, you should be\n

whereby you do have spaces to the\n

that they're called,\nsomething like less than

or greater than is a binary\noperator, because there's

two operands to the left\nand to the right of them.

And in fact, in Python,\nmore so than the world of C

there's actually formal\nstyle conventions.

Not only within CS50 have we had a\n

for instance, that just dictates how you\n

In the Python community, they\ntake this one step further

and there's an actual standard whereby\n

but generally speaking, in the real\n

would reject your code, if you're trying\n

if you don't adhere to these standards.

So while you could be lax\nwith some of this white space

And that's Python theme, for the\n

All right, so let's take a look\nat a couple of other constructs

before transitioning\nto some actual code.

This, of course, in Scratch\nwas a loop, meowing forever.

In C, the closest we could get was\n

So it's sort of a simple way\nof just saying do this forever.

In Python, it's pretty\nmuch the same thing

but a couple of small differences here.

No semicolon, and there's\none other subtle difference.

AUDIENCE: True is capitalized?

DAVID J. MALAN: True is\ncapitalized, just because.

Both true and false are\nBoolean values in Python.

But you've got to start\ncapitalizing them, just because.

All right, how about a\nloop like this, where

you repeat something a finite number\n

In C, we could do this\na few different ways.

There's this very mechanical way,\n

You then use a while loop and\ncheck if i is less than 3

the total number of\ntimes you want to meow.

Then you print what you want to print.

You increment i using this syntax,\n

with plus equals or whatnot.

And then you do it again\nand again and again.

In Python, you can do it\nfunctionally the same way, same idea

You just don't bother saying\nwhat type of variable you want.

Python will infer from the fact\nthat there's a 0 right there.

You don't need the parentheses.

You can't do the i plus plus, but\n

as we could have done in C, as well.

How else might we do this, though, too?

Well. it turns out in\nC, we could do something

like this, which, again, sort\nof cryptic at first glance

became perhaps more familiar,\nwhere you have initialization

a conditional, and then an update\n

In Python, there isn't really an analog.

There is no analog in\nPython, where you have

the parentheses and the multiple\nsemicolons in the same line.

Instead, there is a for loop, but\n

like English, for i in 0, 1, and 2.

So we'll see in a bit, these square\n

to be called a list in Python.

So lists in Python are more like\n

So this just means for i and the\nfollowing list of three values.

And on each iteration of this loop,\n

Then it sets i to two, so that you\n

But this doesn't necessarily scale,\n

Suppose you took this\nat face value as the way

you iterate some number of times\nin Python, using a for loop.

At what point does this approach\nperhaps get bad, or bad design?

Let me give folks just\na moment to think.

AUDIENCE: If you don't know how\nmany times, last time, you know

you've got the link in there.

DAVID J. MALAN: Sure, if you\ndon't know how many times you

want to loop or iterate, you can't\n

AUDIENCE: So you want to say raise\na large number of allowances.

DAVID J. MALAN: Yeah, if you're\n

this list is going to\nget longer and longer

and you're just kind of\nstupidly going to be typing out

like comma 3, comma 4, comma 5, comma\n

I mean, your code would start\nto look atrocious, eventually.

In Python, there is a function,\nor technically a type

called range, that essentially magically\n

from 0 on up to, but\nnot through a value.

So the effect of this line of\n

essentially hands you back\na list of three values

thereby letting you do\nsomething three times.

And if you want to do something\n

AUDIENCE: Is there a way to start\n

at a number or an integer that's higher\n

DAVID J. MALAN: A really\ngood question, can

you start counting at a higher number.

So not 0, which is the implied default,\n

Yes, so it turns out the range function\n

but maybe two or even three, that\n

So you can customize where it begins.

You can customize the increment.

By default, it's one,\nbut if you want to do

every two values, for like evens\n

And before long, we'll take a\nlook at some Python documentation

that will become your authoritative\n

Like, what can this function do.

Other questions on this thus far?

Seeing none, so what else might\nwe compare and contrast here.

Well, in the world of C, recall that\n

types, like these here, Bool and char\n

string, which happened to\ncome from the CS50 library.

But the language C itself certainly\n

because the backslash 0, the support\n

built into C, not a CS50 simplification.

All we did, and revealed,\nas of a couple of weeks

ago, is that string,\nthis data type, is just

a synonym for a typedef for char star,\n

In Python now, this list actually\n

for these common primitive data types.

Still going to have bulls, we're\ngoing to have floats, and Ints

and we're going to have strings,\n

And this is not a CS50\nthing from the library

STR, S-T-R, is, in fact,\na data type in Python

that's going to do a lot more than\n

Ints and floats, meanwhile, don't need\n

because, in fact, among the\nproblems Python solves for us

too, Ints can get as big as you want.

Integer overflow is no\nlonger going to be an issue.

Per week 1, the language\nsolves that for us.

Floating point\nimprecision, unfortunately

is still a problem that remains.

But there are libraries, code that\n

discussed in weeks past,\nthat allow you to do

scientific or financial computing,\nusing libraries that build

on top of these data types, as well.

So there's other data types, too,\n

gives us a whole bunch of\nmore power and capability

things called ranges,\nlike we just saw, lists

like I called out verbally,\nwith the square brackets

things called tuples, for\nthings like x comma y

or latitude, longitude,\ndictionaries, or Dicts

which allow you to store keys and\n

from last time, and then sets in the\n

out duplicates for you, and you can\n

a whole bunch of words or whatnot,\n

will filter out duplicates for you.

Now there's going to be a few functions\n

training wheels that we're then\ngoing to very quickly take off

just because, as we'll see today, they\n

user input correctly, without\naccidentally writing buggy code

just when you're trying to get Hello,\n

And we'll give you functions, not\n

but a subset of these,\nget float, get Int

and get string, that'll\nautomate the process of getting

user input in a way that's more\n

But we'll see what those bugs might be.

And the way we're going to do\nthis is similar in spirit to C.

Instead of doing include,\nCS50.h, like we did in C

you're going to now\nstart saying import CS50.

Python supports,\nsimilar to C, libraries

but there aren't header files anymore.

You just use the name of\nthe library in Python.

And if you want to import CS50's\n

Or, if you want to be more precise, and\n

could be slow, if you've got a really\n

in it, you can be more precise and\n

From CS50 import get Int,\nfrom CSM 50 import get string

or you can just separate\nthem by commas and import 3

and only 3 things from a\nparticular library, like ours.

But starting today and\nonward, we're going

to start making much more\nheavy use of libraries, code

that other people wrote, so that\n

We're not making our own linked lists,\n

We're going to start standing\non the shoulders of others

so that you can get real work\ndone, so to speak, faster

by building your software on\ntop of others' code as well.

All right, so that's it for the\nsyntactic tour of the language

and the sort of core features.

Soon we'll transition\nto application thereof.

But let me pause here to see if there's\n

AUDIENCE: Why don't Python\nhave the increment operators.

DAVID J. MALAN: I'm sorry,\nsay it again, why doesn't

Python have what kind of operators?

AUDIENCE: Why doesn't Python\nhave the increment operator?

DAVID J. MALAN: Sorry, someone coughed\n

DAVID J. MALAN: Oh,\nthe increment operator?

I'd have to check the history, honestly.

Python has tended to be a\nfairly minimus language.

And if you can do something one\nway, the community, arguably

has tended to not give you multiple\n

There's probably a better answer.

And I'll see if I can dig in and post\n

All right, so before we transition\n

let me go ahead and consider exactly\n

In the world of C, recall that it's\n

We create a file called like Hello.c,\n

Or, if you think back to week\ntwo, when we sort of peeled back

the layer of what Hello,\nof what make was doing

you could more verbosely type out\n

Clang in our case, command line\narguments like dash Oh, Hello

to specify what name you want to create.

And then you can specify the file name.

And then you can specify what\nlibraries you want to link in.

So that was a very verbose approach.

But it was always a two-step approach.

And so, even as you've been\ndoing recent problem sets

odds are you've realized that, any time\n

or make a change to your code\nand try and test your code again

you're constantly doing those two steps.

Moving forward in Python,\nit's going to become simpler

and it's going to be just this.

The file name is going to change,\n

It's going to be something like\n

And that's just a convention,\nusing a different file extension.

But there's no compilation step per se.

You jump right to the\nexecution of your code.

And so Python, it turns out, is\n

we're going to start using, it's also\n

assuming it's been pre-installed,\n

This is to say that Python is generally\n

And by that, I mean you get to skip,\n

There is no manual step in the world of\n

and then compiling it to zeros and ones,\n

Instead, these kind of\ntwo steps get collapsed

into the illusion of one, whereby you,\n

and let the computer figure\nout how to actually convert it

to something the computer understands.

And the way we do that is via this\n

But now, when you have\nsource code, it's going

to be passed into an\ninterpreter, not a compiler.

And the best analog of this\nis just to perhaps point out

that, in the human world, if\nyou speak, or don't speak

multiple human languages, it can\n

from one language to another.

For instance, here are step-by-step\n

in a phone book,\nunfortunately, in Spanish.

Unfortunately, if you don't\nspeak or read Spanish.

You could run this algorithm, but you're\n

or you're going to have to open\n

to English and convert this.

And the catch with translating\nany language, human or computer

or otherwise, is that you're going\n

And so converting this in\nSpanish to this in English

is just going to take you\nlonger than if this were already

And that's going to be one of the\n

Yes, it's a feature that you can\n

to bother compiling it manually first.

And things might be a little slower.

Now, there's ways to chip away at that.

But we'll see an example thereof.

In fact, let me transition now\nto just a couple of examples

that demonstrate how Python is\nnot only easier for many people

to use, perhaps yourselves\ntoo, because it throws away

a lot of the annoying syntax,\nit shortens the number of lines

you have to write, and also it\n

you can just do so much more without\n

So, as an example of this,\nlet me switch over here

to this image from problem set 4, which\n

And this is the original\nphoto, pretty clear

and it's even higher res if we looked\n

But there have been no filters, a\n

Recall, for problem set four, you\n

And among them might have been blur.

And blur was probably among the\nmore challenging of the ones

because you had to iterate\nover all of the pixels

you had to take into account what's\n

I mean, there was a lot\nof math and arithmetic.

And if you ultimately got it, it was\n

But that was probably\nseveral hours later.

In a language like\nPython, where there might

be libraries that had been written\nby others, on whose shoulders

you can stand, we could\nperhaps do something like this.

Let me go ahead and run a program, or\n

And in Blur.py, in VS\nCode, let me just do this.

Let me import from a library,\nnot the CS50 library

but the Pillow library, so to\nspeak, a keyword called image

and another one called image\nfilter, then let me go ahead

and say, let me open the current\nversion of this image, which

So the before version\nof the image will be

the result of calling image.open\nquote unquote "Bridge.bmp

and then, let me create\nan after version.

So you'll see before and after.

After equals the before version\n.filter of image filter.

And there is, if I\nread the documentation

I'll see that there's something\ncalled a box blur, that

allows you to blur in box\nformat, like one pixel above

So I'll do one pixel there.

And then, after that's done, let\nme go ahead and save the file

Assuming this library\nworks as described

I am opening the file\nin Python, using line 3.

And this is somewhat new syntax.

In the world of Python, we're going to\n

more, because in the\nworld of Python, you have

what's called object-oriented\n

And what this means is that\nyou still have functions

you still have variables,\nbut sometimes those functions

are embedded inside of the\nvariables, or, more specifically

inside of the data types themselves.

Think back to C. When you wanted\n

there was a to upper function that takes\n

And you can pass in any char you\n

Well, you know what, if that's\nsuch a common paradigm, where

upper-casing chars is a useful\n

is it embeds into the string\ndata type, or char if you will

the ability just to uppercase any char\n

as though it's a struct\nin C. Recall that structs

encapsulate multiple types of values.

In object-oriented programming,\nin a language like Python

you can encapsulate not just\nvalues, but also functionality.

Functions can now be inside of structs.

But we're not going to\ncall them structs anymore.

We're going to call them objects.

But that's just a different vernacular.

Inside of the image library,\nthere's a function called open

and it takes an argument, the\nname of the file, to open.

Once I have a variable called before,\n

an object, inside of\nwhich is now, because it

was returned from this\nfunction, a function

called filter, that takes an argument.

The argument here happens\nto be image.boxblur1

But it just returns the filter to use.

And then, after, dot save\ndoes what you might think.

So instead of using fopen and\nfwrite, you just say dot save

and that does all of\nthat messy work for you.

So it's just, what, four\nlines of code total?

Let me go ahead and go\ndown to my terminal window.

Let me go ahead and show you\nwith LS that, at the moment

whoops, sorry, let me\nnot bother showing that

because I have other examples to come.

I'm going to go ahead and do Python\n

I did need to make a command.

OK, let me go ahead and type LS\n

is among the sample code online today.

There's only one file\ncalled Bridge.bmp, dammit

I'm trying to get these\nthings ready at the same time.

Let me move this code into place.

All right, I've gone ahead\nand moved this file, Blur.py

into a folder called\nfilter, inside of which

there's another file called Bridge.bmp,\n

Let me now go ahead\nand run Python, which

is my interpreter, and also\nthe name of the language

and run Python on this file.

So much like running\nthe Spanish algorithm

through Google Translate,\nor something like that

as input, to get back\nthe English output

this is going to translate the\nPython language to something

this computer, or this\ncloud-based environment

understands, and then run the\ncorresponding code, top to bottom

I'm going to go ahead and Enter.

No error message is\ngenerally a good thing.

If I type LS you'll now see out.bmp.

Let me go ahead and open that.

And, you know what, just to make\nclear what's really happening

let me blur it even further.

Let's make a box that's not\njust one pixel around, but 10.

And let me just go ahead and\nrerun it with Python of Blur.py.

Let me go ahead and open Out.bmp\nand show you first the before

And now, crossing my fingers,\nfour lines of code later

the result of blurring it, as well.

So the library is doing all\nof the same kind of legwork

that you all did for\nthe assignment, but it's

encapsulated it all into a single\n

Those of you who might have\nbeen feeling more comfortable

might have done a little\nsomething like this.

Let me go ahead and open up one\nother file, called Edges.py.

And in Edges.py, I'm again going\n

the image keyword, and the image filter.

Then I'm going to go ahead and\ncreate a before image, that's

a result of calling image.open\nof the same thing, Bridge.bmp

then I'm going to go ahead and run a\n

image filter.find edges, which\nis like a content, if you will

defined inside of this library for us.

And then I'm going to do\nafter.save quote unquote

Out.bmp," using the same file name.

I'm now going to run Python of\n

We'll see what syntax error means soon.

Let me go ahead and run\nthe code now, Edges.py.

Let me now open that new file, Out.bmp.

And before we had this, and now,\n

if we did the more comfortable\nversion of P set 4

we now get this, after\njust four lines of code.

So again, suggesting the power\nof using a language that's better

optimized for the tool at hand.

And at the risk of really\nmaking folks sad, let's go ahead

and re-implement, if we could,\n

Let me go ahead and open\nanother version of this code

wherein I have a C\nversion, just from problem

set five, wherein you\nimplemented a spell checker

loading 100,000 plus words into memory.

And then you kept track of just\n

And that probably took\na while, implementing

all of those functions in Dictionary.c.

Let me instead now go into a\nnew file, called Dictionary.py.

And let me stipulate, for\nthe sake of discussion

that we already wrote\nin advance, Speller.py

which corresponds to Speller.c.

You didn't write either of those.

Recall for problem set\nfive, we gave you Speller.c.

Assume that we're going\nto give you Speller.py.

So the onus on us right now is only\n

All right, so I'm going to go\nahead and define a few functions.

And we're going to see now the syntax\n

I want to go ahead and define\nfirst, a hash table, which

was the very first thing\nyou defined in Dictionary.c.

I'm going to go ahead, then, and say\n

otherwise known as a hash table.

All right, now let me\ndefine a function called

check, which was the first function\nyou might have implemented.

Check is going to take a word,\nand you'll see in Python

the syntax is a little different.

You don't specify the return type.

You use the word Def instead to define.

You still specify the name of the\n

But you omit any mention of types.

But you do use a colon and indent.

So how do I check if a word is in\n

Well, in Python, I can\njust say, if word in words

go ahead and return true, else\ngo ahead and return false, done

All right, now I want to do like load.

That was the heavy lift, where you\n

So let me define a function called load.

It takes a string, the\nname of a file to load.

So I'll call that Dictionary,\njust like in C, but no data type.

Let me go ahead and open a file by\n

by opening that Dictionary in read mode.

So this is a little similar to fopen,\n

Then let me iterate over\nevery line in the file.

In Python, this is pretty pleasant,\n

How, now, do I get at the current\n

because in this file of\nwords, 140,000 words

there's word backslash n,\nword backslash n, all right?

Well, let me go ahead and get\na word from the current line

but strip off, from the right end\n

the Rstrip function\nin Python does for me.

Then let me go ahead and add to my\n

Let me go ahead and close\nthe file for good measure.

And then let me go ahead and\nreturn true, because all was well.

That's it for the load\nfunction in Python.

How about the size function?

This did not take any arguments, it\n

I can do that by returning the\n

And then lastly, gone from the\n

So no matter what I do,\nthere's nothing to unload.

The computer will do that for me.

So I give you, in these functions,\nproblem set five in Python.

So, I'm sorry, we made\nyou write it in C first.

But the implication now is that,\nwhat are you getting for free

Well, encapsulated in\nthis one line of code

is much of what you wrote for\nproblem set five, implementing

your array for all of your\nletters of the alphabet or more

all of the linked lists that you\nimplemented to create chains

to store all of those words.

It's just someone else in the\nworld wrote that code for you.

And you can now use it\nby way of a dictionary.

And actually, I can\nchange this a little bit

because add is technically not\nthe right function to use here.

I'm actually treating the dictionary\n

So I'm going to make one tweak, set\n

But set just allows it\nto handle duplicates

and it allows me to just throw\nthings into it by literally

using a function as simple as add.

And I'm going to make\none other tweak here

because, when I'm checking a word,\n

to me in uppercase or capitalized.

It's not going to necessarily come\n

I can force every word to\nlowercase by using word.lower.

And I don't have to do it\ncharacter for character

I can do the whole darn string at\n

All right, let me go ahead and\nopen up a terminal window here.

And let me go into, first,\nmy C version, on the left.

And actually I'm going to go ahead\n

And on the right, I'm going to go into\n

But it's also available online, if\n

I'm going to go ahead and\nmake speller in C on the left

and note that it takes\na moment to compile.

Then I'm going to be ready to\nrun speller of dictionaries

let's do like the Sherlock\nHolmes text, which is pretty big.

And then over here, let me get\nready to run Python of speller

So the syntax is a little\ndifferent at the command prompt.

I just, on the left, have to\ncompile the code, with make

and then run it with ./speller.

On the right, I don't\nneed to compile it.

But I do need to use the interpreter.

So even though the lines are\nwrapping a little bit here

let me go ahead and run it on the right.

And I'm going to count how\nlong it takes, verbally

One Mississippi, two Mississippi,\nthree Mississippi, OK

so it's like three\nseconds, give or take.

Now running it in\nPython, keeping in mind

I spent way fewer hours implementing\na spell checker in Python

than you might have in problem set five.

But what's the trade-off going to be,\n

do we all now need to\nbe making consciously?

Here we go, on the right, in Python.

One Mississippi, two Mississippi,\n

five Mississippi, six Mississippi,\n

nine Mississippi, 10\nMississippi, 11 Mississippi

all right, so 10 or 11 seconds.

Let's go to the group here, which\n

How might you answer that question,\n

AUDIENCE: I think Python's\nbetter for the programmer

more comfortable for the programmer,\n

DAVID J. MALAN: OK, so\nPython, to summarize

is better for the programmer,\n

but C is maybe better for the computer,\n

I think that's a reasonable formulation.

AUDIENCE: I think it depends\non the size of the project

So if it's going to be something\nthat's relatively quick

I might not care that it\ntakes 10 seconds to do it.

And it could be way faster\nto do it with Python.

Whereas with C, if I'm dealing\n

set or something huge, then that\n

it might be worth it to put in the\n

so the process continually will run\n

DAVID J. MALAN: Absolutely,\na really good answer.

And let me summarize, is it depends\n

If you have a very large\ndata set, you might

want to optimize your code to be as\n

especially if you're running\nthat code again and again.

Maybe you're a company like Google.

People are searching a\nhuge database all the time.

You really want to squeeze\nevery bit of performance

as you can out of the computer.

You might want to have someone\nsmart take a language like C

and write it at a very low level.

They're going to have to deal with\n

But if and when it works correctly, it's\n

By contrast, if you have\na data set that's big

and 140,000 words is\nnot small, but you don't

want to spend like 5 hours,\n10 hours, a week of your time

building a spell\nchecker or a dictionary

you can instead leverage a different\n

and build on top of it, in order to\n

AUDIENCE: Would you,\nbecause with Python

doesn't it also like\nconvert the words, or like

convert the words, for a lesson?

When we convert that into\nthe same version again

do we just take that into view?

DAVID J. MALAN: That's a perfect\n

wanted to make, which was, is\nthere something in between?

I'm oversimplifying what this\nlanguage is actually doing.

It's not as stark a difference\nas saying, like, hey

Python is four times slower than C.\n

There are absolutely ways that\nengineers can optimize languages

as they have already done for Python.

And in fact, I've configured\nmy settings in such a way

that I've kind of dramatized\njust how big the difference is.

It is going to be slower,\nPython, typically

than the equivalent C program.

But it doesn't have\nto be as big of a gap

as it is here, because, indeed, among\n

is to save some intermediate results.

Technically speaking, yes,\nPython is interpreting

Dictionary.py and these\nother files, translating them

from one language to another.

But that doesn't mean it has to do that\n

As you propose, you can save, or cache,\n

So that the second time and the third\n

And, in fact, Python itself, the\n

thereof, itself is\nactually implemented in C.

So you can make sure that your\n

And what then is maybe\nthe high level takeaway?

Yes, if you are going to try to\nsqueeze every bit of performance

out of your code, and\nmaybe code is constrained.

Maybe you have very small devices.

Maybe it's like a watch nowadays.

Or maybe it's a sensor that's installed\n

or in infrastructure, where you\ndon't have much battery life

and you don't have much\nsize, you might want

to minimize just how\nmuch work is being done.

And so the faster the code runs,\n

if it's implemented something low level.

So C is still very commonly used\n

But, again, if you just want\nto solve real world problems

and get real work done, and your time\n

than the device you're\nrunning it on, long term

you know what, Python is among the\n

And frankly, if I were implementing\n

I'm probably starting with Python.

And I'm not going to\nwaste time implementing

all of that low-level stuff, because\n

modern languages is to use abstractions\n

And by abstraction, I mean something\n

that just gives you a\ndictionary, or hash table

or the equivalent version that I\n

All right, any questions,\nthen, on Python thus far?

AUDIENCE: Could you\ncompile the Python code

or is there some, I'd imagine that\n

but it feels like if you can just\n

that would give you the\nbest of both worlds.

DAVID J. MALAN: Really good\nquestion or observation

could you just compile Python code?

Yes, absolutely, this idea of\n

is not native to the language itself.

It tends to be native to the\nconventions that we humans use.

So you could actually\nwrite an interpreter for C

that would read it top to bottom, left\n

something the computer understands, but\n

C is generally a compiled language.

What Python nowadays is actually\n

It technically is, sort\nof unbeknownst to us

compiling the code, technically\n

into something called byte code,\n

just doesn't take as much time as it\n

And this is an area of research\nfor computer scientists working

in programming languages, to\nimprove these kinds of paradigms.

Well, honestly, for you and I, the\n

one, run the code and not worry\nabout the stupid second step

of compiling it all the time.

It's literally half as many\nsteps for me, the human.

And that's a nice thing to optimize for.

And ultimately, too, you might\n

come with these other languages.

So you should really\njust be fine-tuning how

you can enable these features, as\n

And, in fact, the only time\nI personally ever use C

is from like September to October\nof every year, during CS50.

Almost every other month\ndo I reach for Python

or another language called JavaScript,\n

which is not to impugn C. It's just that\n

fits for the amount of time I have to\n

All right, let's go ahead and\ntake a five minute break here.

And when we come back, we'll start\n

So let's go ahead and start writing\nsome code from the beginning

here, whereby we start small\nwith some simple examples

and then we'll build our way up to\n

But what we'll do\nalong the way is first

look side by side at\nwhat the C code looked

like way back in week 1\nor 2 or 3 and so forth

and then write the corresponding\nPython code at right.

And then we'll transition just\nto focusing on Python itself.

What I've done in advance today is\n

from the course's website,\nmy source 6 directory, which

contains all of the pre-written\nC code from weeks past.

But it'll also have\ncopies of the Python code

we'll write here together and look at.

So first, here is\nHello.c back from week 0.

And this was version 0 of it.

I'm going to go ahead and do this.

I'm going to go ahead and\nsplit my code window up here.

I'm going to go ahead and create\na new file called Hello.py.

And this isn't something\nyou'll typically have to do

laying your code out side by side.

But I've just clicked the\nlittle icon in VS Code

that looks like two columns, that\n

so that we can, in fact, see\nthings, for now, side by side

with my terminal window down below.

All right, now I'm going to go ahead\n

program on the right, which,\nrecall, was just print, quote

unquote, "Hello, world," and that\'s it.

Now down in my terminal\nwindow, I'm going

to go ahead and run Python of\nHello.py, Enter, and voila

So again, I'm not going to play\nany further with the C code.

It's there just to jog\nyour memory left and right.

So let's now look at a second\nversion of Hello, world

from that first week, whereby\nif I go and get Hello1.c

I'm going to drag that\nover to the right.

Whoops, I'm going to go ahead and\n

And now, on the right,\nlet's modify Hello.py

to look a little more like this\nsecond version in C, all right?

I want to get an answer from\nthe user as a return value

but I also want to get\nsome input from them.

So from CS50, I'm going to import the\n

We're going to get rid\nof that eventually

but for now, it's a\nhelpful training wheel.

And then down here, I'm\ngoing to say, answer

equals getString quote\nunquote, "What\'s your name"?

But no semicolon, no data type.

And then I'm going to\ngo ahead and print, just

like the first example on the slide,\n

And now let me go ahead and run this.

Python, of Hello.py, all right,\nit's asking me what's my name.

But it's worth calling attention to the\n

It's not just that the\nindividual functions are simpler.

What is also now glaringly omitted\nfrom my Python code at right

both in this version,\nand the previous version.

What did I not bother implementing?

DAVID J. MALAN: Yeah, so I didn't\neven need to implement main.

We'll revisit the main function,\nbecause having a main function

actually does solve problems sometimes.

But it's no longer required.

In C you have to have that to kick-start\n

And in fact, if you were missing\n

if you accidentally compiled\nHelpers.c instead of the file

that contained main, you would\nhave seen a compiler error.

In Python it's not necessary.

In Python you can just jump right\n

Especially if it's a\nsmall program like this

you don't need the added overhead\n

So that's one other difference here.

All right, there are a few other\nways we could say Hello, world.

Recall that I could use a format string.

So I could put this whole thing in\n

And then let me go ahead and\nrun Python of Hello.py again.

You can perhaps see where\nwe're going with this.

Let me type my name,\nDavid, and here we go.

OK, that's the mistake that\nsomeone identified earlier

Otherwise no variables are\ninterpolated, that is substituted

So if I go back in and add those\ncurly braces to the F string

now let me run Python of Hello.py,\n

But generally speaking, making\nshorter, more concise code

So stylistically, the F string is\n

All right, well, what more\ncan we do besides this?

Well, let me go ahead here and\n

Let me get rid of the CS50\nlibrary, which we will ultimately

in a couple of weeks, anyway.

I can't use getString,\nbut I can use a function

that comes with Python called input.

And, in fact, this is actually a\n

There's really no downside to\nusing input instead of getString.

We implement getString\njust for consistency

with what you saw in C. Python of\n

Still actually works the same.

So gone are the CS50\nspecific training wheels.

But we're going to bring\nthem back shortly, just

to deal with integers or\nfloats or other values

too, because it's going to make\nour lives a little simpler

All right, any questions, before we\n

from week 1, but now in Python?

All right, let me go\nahead and open up now.

Let's say Calculator0.c, which was one\n

math and operators like that, as\nwell as functions like getInt

let me go ahead and create a new\nfile now called Calculator.py

at right, so that I have\nmy C code at left still

and my Python code at right.

All right, let me go dive into a\n

I am going to use getInt\nfrom the CS50 library.

I'm going to go ahead now\nand get an Int from the user.

So x equals getInt, and I'll\nask them for an x value

No need to specify a semicolon,\nthough, or an Int for the x.

Y is going to get\nanother Int via y colon

and then down here, I'm going to\n

So this is already a bit new.

Recall, the C version required that\n

Python is just a little\nmore user-friendly.

If all you want to do is print out a\n

Don't futz with any percent\nsigns or format codes.

It's not printf, it's\nindeed just print now.

All right, let me go ahead and\nrun Python of Calculator.py

Enter, just do a quick sample,\n1 plus 2 indeed equals 3.

As an aside, suppose I had\ntaken a different approach

to importing the whole CS50 library,\n

You're not to notice any\nperformance impact here.

But notice what does not\nwork now, whereas it did work

in C. Python of Calculator.py, Enter,\n

So a traceback is just\na term of art that

says, here is a trace back\nthrough all of the functions

In the world of C, you\nmight call this a stack

trace, stack being the operative word.

Recall that when we talked\nabout the stack and the heap

the stack, like a stack of trays,\nwas all of the functions that

might get called, one after the other.

We had main, we had swap, then swap went\n

So here's a trace back of all of the\n

There's not really any functions\nother than my file itself.

Otherwise there'd be more detail.

But even though it's a little cryptic,\n

here, name error, so something related\n

And this of course, happens\non line 3 over there.

Well, Python essentially\nallows us to namespace

our functions that come from libraries.

There was a problem in C. If\nyou were using the CS50 library

and thus had access\nto getInt, getString

and so forth, you could\nnot use another library

that had the same function names.

They would collide, and\nthe compiler would not

know how to link them\ntogether correctly.

In Python, and other languages\nlike JavaScript, and in Java

you have support for effectively\n

You can isolate variables and\n

like their own container in memory.

And what this means is,\nif you import all of CS50

you have to say that the getInt you\n

So just like with the image\nblurring, and the image edges

before, where I had to specify image dot\n

am I specifying with a dot operator,\n

want CS50.getInt in both places.

And now if I rerun Python\nof Calculator.py, 1 and 2

Generally speaking, it depends\non just how many functions

you're using from the library.

If you're using a whole bunch of\n

If you're only using maybe one\nor two, import them line by line.

All right, so let's go ahead\nand make a little tweak here.

Let's get rid of this library\nand take this training wheel off

too, as quickly as we introduced\n

you'll be able to use all\nof these same functions.

Suppose I get rid of this, and\nI just use the input function

just like I did by\nreplacing getString earlier.

Let me go ahead now and run\nthis version of the code.

Python of Calculator.py, OK,\nhow about 1 plus 2 equals 3.

All right, obviously wrong, incorrect.

Can anyone explain what just\nhappened, based on instincts?

AUDIENCE: You want an answer?

DAVID J. MALAN: Sure, yeah.

AUDIENCE: Say you have a number\nof strings that don't have Ints

so you would part with them and\nsay, printing one, two, better.

DAVID J. MALAN: Exactly, Python\nis interpreting, or treating

both x and y as strings,\nwhich is actually

what the input function\nreturns by default.

And so plus is now being interpreted\n

So x plus y isn't x\nplus y mathematically

but in terms of string\njoining, just like in Scratch.

So that's why we're getting\n12, or really one two

which isn't itself a number.

So we somehow need to convert things.

And we didn't have this\nability quite as easily in C.

We did have like the A to i\nfunction, ASCII to integer

which did allow you to do this.

The analog in Python is actually just\n

So just like in C, you\ncan use the keyword Int

but you use it a little differently.

Notice that I'm not doing parenthesis\n

I'm using Int as a function.

So indeed, in Python, Int is a function.

Float is a function, that\nyou can pass values into

to do this kind of conversion.

So now, if I run Python\nof Calculator.py, 1 and 2

now we're back in business,\nand getting the answer of 3.

But there's kind of a catch here.

There's always going to be a trade-off.

Like that sounds amazing that\nit just works in this way.

We can throw away the\nCS50 library already.

But what if the user accidentally\n

like a cat, instead of a number.

Damn, well, there's one\nof these trace backs.

Like, now my program has crashed.

This is similar in spirit\nto the kinds of segfaults

that you might have had in C.

But they're not segfaults per se.

It doesn't necessarily relate to memory.

This time it relates to actual\n

So this time it's not a name\nerror, it's a value error

invalid literal for Int with\nbase 10 quote unquote "cat.

So, again, it's written for sort\nof a programmer, more than sort

of a typical person, because it's\n

But let's try to interpret it.

Invalid literal, a literal is just\n

is the function name, with base 10.

It's just defaulting to decimal numbers.

Cat is apparently not a decimal number.

It doesn't look like it, therefore\nit can't be treated like it.

Therefore, there's a value error.

Unfortunately, you would have\nto somehow catch this error.

And the only way to do\nthat in Python really

is by way of another\nfeature that C did not have

namely, what are called exceptions.

An exception is exactly what just\n

They are things that can go wrong\n

that aren't necessarily going to be\n

So in Python, and in JavaScript, and in\n

there's this ability to\nactually try to do something

except if something goes wrong.

And in fact, I'm going to\nintroduce a bit of syntax

here, even though we won't\nhave to use this much just yet.

Instead of just blindly converting\nx to an Int, let me go ahead

And if there's an exception,\ngo ahead and say something

like print, that is not an Int.

And then I'm going to do\nsomething like exit, right there.

And let me go ahead and do this here.

Let me try to get y, except\nif there's an exception.

Then let me go ahead and say, again,\n

And then I'm going to exit\nfrom there to, otherwise I'll

go ahead and print x plus y.

If I run Python of\nCalculator.py now, whoops, oh

forgot my close quote, sorry.

All right, so close quote, Python of\n

But if I try to type in\nsomething wrong like cat, now

it actually detects the error.

So what is the CS50\nlibrary in Python doing?

It's actually doing that try and accept\n

otherwise your programs for\nsomething simple, like a calculator

start to get longer and longer.

So we factored that kind of\nlogic out to the CS50 getInt

function and get float function.

But underneath the hood, they're\n

but they're being a little more precise.

They're detecting a specific error,\n

so that these functions will\nget executed again and again.

In fact, the best way to do this is to\n

then print that error\nmessage out to the user.

And again, let's not get too into\n

We've already put into the CS50 library.

But that's why, for instance,\nwe bootstrap things

by just using these\nfunctions out of the box.

All right, let's do something\nmore with our calculator here.

In the world of C, we\nhad another version

of this code, which actually\ndid some division by way of--

which actually did division of\n

So let me go ahead and close the C\n

now, doing some of these\nsame lines of codes.

But I'm going to go\nahead and just assume

that the user is going to\ncooperate and use proper input.

So from CS50, import getInt, that\n

X gets getInt, ask the user\nfor an Int x, y equals getInt

And then, let's go ahead and do this.

Let's declare a variable called\n

Then let's go ahead and print z.

Still no need for a format string, I\n

Let me go ahead and run\nPython of Calculator.py.

Let me do 1, 10, and I get 0.1.

What did I get in C,\nthough, if you think back.

What would we have happened in C?

DAVID J. MALAN: Yeah, we\nwould have gotten zero in C.

But why, in C, when you\ndivide one Int by another

and those Ints are like\n1 and 10 respectively?

AUDIENCE: It'll give\nyou an integer back.

DAVID J. MALAN: It will give you what?

DAVID J. MALAN: It will give you an\n

the integer part of it is indeed zero.

So this was an example of truncation.

So truncation was an\nissue in C. But it would

seem as though this is no\nlonger a problem in Python

insofar as the division operator\nactually handles that for us.

As an aside, if you want the old\nbehavior, because it actually

is sometimes useful for\nrounding or flooring values

you can actually use two slashes.

And now you get the C behavior.

So that now 1 divided by 10 is zero.

So you don't give up that\ncapability, but at least it

does a more sensible default.

Most people, especially new programmers,\n

would want to get 0.1,\nnot 0, for reasons

that indeed we had to explain weeks ago.

But what about another problem we\n

whereby there is imprecision?

Let me go ahead and, somewhat\n

I'm going to format\nit using an f-string.

And I'm going to go ahead and format,\n

Notice this, if I do Python\nof Calculator.py, 1 and 10

I get, by default, just\none significant digit.

But if I use this syntax in Python,\n

I can actually do in\nC like I did before

50 significant digits\nafter the decimal point.

So now let me rerun Python\nof Calculator.py 1 and 10

and let's see if floating point\nimprecision is still with us.

And you can see as much here,\nthe f-string, the format string

is just showing us now 50 digits\ninstead of the default one.

So we've not solved all problems.

But we have solved at least some.

All right, before we pivot away from\n

now on syntax or concepts or the like?

AUDIENCE: Do you think\nthe double slash you get

has merit, how do you comment on that?

DAVID J. MALAN: How do you what?

Really good question, if you're\nusing double slash for division

with flooring or truncation,\nlike I described

how do you do a comment in Python.

And the convention is actually\nto use a complete sentence

like with a capital T here.

You don't need a period unless\nthere's multiple sentences.

And technically, it should be above\n

So you would use a hash symbol instead.

All right, let's go ahead and make\n

Let me go ahead and\nopen up, for instance

an example called Points1.c,\nwhich we saw a few weeks back.

And let me go ahead on the other side\n

This was a program, recall, that\n

lost on the first assignment.

And then it went ahead\nand just printed out

whether they lost fewer points\nthan me, because I lost two

if you recall the photo, more points\n

Let me go ahead and zoom out so\nwe can see a bit more of this.

And let me now, on the top right here,\n

So I want to first prompt the\nuser for some number of points.

So from CS50 let's import getInt,\n

Let's then do points\nequals getInt, and ask

the user, how many points\ndid you lose, question mark.

Then let's go ahead and say, if points\n

print, you lost fewer points than me.

Otherwise, if it's else if points\n

you lost more points than me.

Else let's go ahead and handle\nthe final scenario, which is you

lost the same number of points as me.

Before I run this, does anyone want to\n

AUDIENCE: Else if has to be elif.

DAVID J. MALAN: Yeah, so else if in\n

So let me change this to elif, and now\n

suppose you lost three\npoints on some assignment.

You lost more points than my two.

If you only lost one point,\nyou lost fewer points than me.

But notice the code is much tighter.

In 10 total lines, we did in\nwhat was 24 lines, because we've

thrown away a lot of the syntax.

The curly braces are\nno longer necessary.

The parentheses are\ngone, the semicolons.

So this is why it just tends to\nbe more pleasant pretty quickly

All right, let's do\none other example here.

In C, recall that we were able to\n

if something is even or odd.

Well, in Python, let me go ahead\n

and let's look for a moment\nat the C version at left.

Here was the code in C that we used\n

And, really, the key\ntakeaway from all these lines

was just the remainder operator.

And that one is still with us.

So this is a simple demonstration,\njust to make that point

if in Python, I want to determine\n

Well, let's go ahead and from CS50,\n

and get a number like n from the user,\n

And then let's go ahead and say,\nif n percent sign 2 equals 0

then let\'s go ahead and\nprint quote unquote "Even.

Else let's go ahead and print\nout Odd, but before I run this

anyone want to instinctively, even\n

DAVID J. MALAN: Yeah, so double equals.

Again, so even though some of the stuff\n

So this, too, should\nbe a double equal sign

because I'm comparing for equality here.

And why is this the right math?

Well, if you divide a\nnumber by 2, it's either

going to have 0 or 1 as a remainder.

And that's going to determine\nif it's even or odd for us.

So let's run Python of Parity.py,\ntype in a number like 50

and hopefully we get, indeed, even.

So again, same idea, but now\nwe're down to eight lines

Well, let's now do something\na little more interactive

and a little representative of tools\n

In C, recall that we had this\nagreement program, Agree.c.

And then let's go ahead and implement\n

And let's look at the C version first.

On the left, we used get char here.

And then we used the\ndouble vertical bars

to check if C is equal to\ncapital Y or lowercase y.

And then we did the\nsame thing for n for no.

And so let's go over here and\nlet's do from CS50, import get--

OK, get char is not a thing.

And this here is another\ndifference with Python.

There is no data type for\nindividual characters.

You have strings, STRs,\nand, honestly, those

are fine, because if\nyou have a STR that's

just one character, for\nall intents and purposes

it is just a single character.

So it's just a simplification.

You don't have to think as much.

You don't have to worry about\ndouble quotes, single quotes.

In fact, in Python, you can use\ndouble quotes or single quotes

so long as you're consistent.

So long as you're\nconsistent, the single quotes

do not mean something\ndifferent, like they do in C.

So I'm going to go ahead\nand use getString here

although, strictly speaking, I\n

I'm going to get a string from the\n

quote unquote, "Do you agree," like a\n

where you have to say yes or no, you\n

And then let's translate the\nconditionals to Python, now, too.

So if S equals equals quote-unquote\n

let's go ahead and print out agreed,\n

equals N or S equals equals little n.

Let's go ahead, then,\nand print out not agreed.

And you can already see, perhaps,\n

Is Python a little more\nEnglish-like, in that

you just literally use the English word\n

But it's ultimately\ndoing the same thing.

Can we simplify this code a bit, though.

This would be a little\nannoying if we wanted

to add support, not just\nfor big Y and little y

but Yes or big Yes or little yes or\n

There's a lot of permutations\nof Y-E-S or just y

that we ideally should tolerate.

Otherwise, the user is going to\n

which isn't very user-friendly.

Any intuition for how\nwe could logically

even if you don't know how to\ndo it in code, make this better?

AUDIENCE: Write way over\nthe list, and then up

it's like the things in the list.

DAVID J. MALAN: Nice, yeah, we saw an\n

Why don't we take that same\nidea and ask a similar question.

If S is in the following list\nof values, Y or little y

or heck, let me add to the list\n

And it's going to get a\nlittle annoying, admittedly

but this is still better than the\n

I could do things like\nthis, and so forth.

There's a whole bunch more permutations.

But let's leave this alone,\nand let me just go into here

and change this to, if S is in the\n

and I won't do as, let's just not\n

Python of Agree.py, do I agree?

All right, how about big Yes.

OK, that does not seem to work.

Notice it did not say agreed,\nand it did not say not agreed.

Well, you know what I could\ndo, what I don't really

need the uppercase and lowercase.

Let me tighten this\nlist up a little bit.

And why don't I just\nforce S to be lowercase.

S.lower, recall, whether\nit's one character or more

is a function built into\nSTRs now, strings in Python

that forces the whole\nthing to lowercase.

Python of Agree.py, little y,\nthat works, big Y, that works.

Big Yes, that works, big Y,\nlittle e, big S, that also works.

So we've now handled, in one fell\n

And you know what, we can\ntighten this up a bit.

Here's an opportunity, in Python,\nfor slightly better design.

What have I done in here\nthat's a little redundant?

Does anyone see an opportunity\nto eliminate a redundancy

doing something more\ntimes than you need.

AUDIENCE: You can do S dot lower, above.

DAVID J. MALAN: We could\nmove the S dot lower above.

Notice that I'm using S dot lower twice.

But it's going to give me\nthe same answer both times.

So I could do a couple of things here.

I could, first of all, get rid of\n

and then above this, maybe I could\n

I can't just do this, because\nthat throws the value away.

It does the math, but it doesn't\nconvert the string itself.

It's going to return a value.

So I have to say S equals s.lower.

Or, honestly, I can chain\nthese things together.

And this is not something we saw in\n

and strings have functions\nlike lower in them

you can chain these functions\n

dot that, dot this other thing.

And eventually you want to stop,\n

But this is reasonable,\nstill fits on the screen.

It does in one place\nwhat I was doing in two.

Let me go ahead and do Python\nof Agree.py one last time.

And it's still working as intended.

Also if I tried those\nother inputs as well.

AUDIENCE: Could you add on like a for\n

and then cover all the functions where\n

where it's uppercase as well, or\n

DAVID J. MALAN: Let me summarize.

Could we handle uppercase and\nlowercase together in some form?

I'm actually doing that already.

I have to either be all lowercase\nin my logic or all uppercase

and not worry about\nwhat the human types in

because no matter what\nthe human types in, I'm

forcing their input to lowercase.

And then I am using a\nlowercase list of values.

If I want to flip that, fine.

I just have to be self-consistent.

But I'm handling that already.

AUDIENCE: Are strings no\nlonger an array of characters?

DAVID J. MALAN: A really\ngood loaded questions

are strings no longer\nan array of characters?

Conceptually, yes,\nunderneath the hood, no.

They're a little more\nsophisticated than that

because with strings,\nyou have a few changes.

Not only do they have\nfunctions built into them

because strings are now\nwhat we call objects

in what's called\nobject-oriented programming.

And we're going to keep seeing\nexamples of this dot operator.

They are also immutable, so\nto speak, I-M-M-U-T-A-B-L-E.

Immutable means they cannot be\nchanged, which means, unlike C

you can't go into a string and\nchange its individual characters.

You can make a copy of the\nstring that makes a change

but you can't change the\noriginal string itself.

This is both a little\nannoying, maybe, sometimes.

But it's also pretty protective,\nbecause you can't do screw-ups

like I did weeks ago, when I was\ntrying to copy S and call it T.

And then one affected the other.

Python, underneath the hood, is\n

and the pointers and all of that.

There are no pointers in Python.

So If that wasn't clear, all of that\n

is now handled by the language\n

All right, so let's\nintroduce maybe some loops

like we've been in the habit of doing.

Let me open up Meow.c, which was\nan example in C, just meowing

Let me create a file called\nMeow.py here on the right.

And notice on the left,\nthis was correct code in C

but it was kind of poorly designed.

Because it was a missed\nopportunity for a loop.

Why say something three times\nwhen you can say it just once?

So in Python, let me do it\nthe poorly designed way first.

And, like I generally should not,\n

run Python of Meow.py, and it works.

So let me go ahead and\nimprove this a little bit.

And there's a few ways to do this.

If I wanted to do this three times, I\n

For i in range of 3, recall that\nthat was the better version

rather than arbitrarily enumerate\n

and print out quote unquote "Meow.

Now if I run Python of\nMeow, still seems to work.

So it's a little tighter,\nand, my God, like

programs can't really get\nmuch shorter than this.

We're down to two lines of code, no\n

Let's now improve the\ndesign further, like we

did in C, by introducing\na function called

meow, that actually does the meowing.

So this was our first\nabstraction, recall

both in Scratch and in C. Let me focus\n

Let me go ahead and\nfirst define a function.

Let me first go ahead and do\nthis, for i in range of 3

let's assume for the moment\nthat there's a meow function

that I'm just going to call.

Let's now go ahead and define, using\n

with the speller\ndemonstration, a function

called meow that takes no arguments.

And all it does for now is print meow.

Let me now go ahead and run\nPython of Meow.py Enter, huh, one

So this is another name error.

And, again, name meow is not defined.

What's your instinct here,\neven though we've not

tripped over this yet in Python?

Where does your mind go here?

AUDIENCE: Does it read top\nto bottom, left to right?

I'm guessing we could find a new case.

DAVID J. MALAN: Perfect, as smart,\n

it still makes certain assumptions.

And if it hasn't seen a keyword\nyet, it just doesn't exist.

So if you want it to exist, we\nhave to be a little clever here.

I could just put it, flip\nit around, like this.

But this honestly isn't\nparticularly good design.

Because now, if you, the reader\nof your code, whether you

wrote it or someone else, you\nkind of have to go fishing now.

Like where does this program begin?

And even though, yes, it's obvious\n

like, if the file were longer,\nyou're going to be annoyed

and fishing visually for\nthe right lines of code.

And indeed, this would\nbe a common paradigm.

When you want to start having\n

just put your own code in main, so that,\n

you can solve the problem\nwe just encountered.

So let me define a function called\nmain that has that same loop

Let me go into my terminal and\nrun Python of Meow.py, Enter.

All right, investigate this.

What could explain this symptom.

I have not told you the answer yet.

So all you have is\nyour instinct, assuming

you've never touched Python before.

What might explain this symptom,\nwhere nothing is meowing?

AUDIENCE: Didn't run the main function.

DAVID J. MALAN: Yeah, I\ndidn't run the main function.

So in C, this is functionality\nyou get for free.

You have to have a main function.

But, heck, so long as you make\nit, it will be called for you.

In Python, this is just a convention,\nto create a main function

borrowing a very common name for it.

But if you want to call that\nmain function, you have to do it.

So this looks a little\nweird, admittedly

that you have to call your\nown main function now

and it has to be at\nthe bottom of the file

because only once the interpreter\n

have all of your functions\nbeen defined, higher up.

But this solves both problems.

It keeps your code, that's\nthe main part of your code

at the very top of the file.

So it's just obvious to you, and\n

where the program logically starts.

But it also ensures that main is not\n

So this is another\nperfect example of we're

learning a new language\nfor the first time.

You're not going to have heard\nall of the answers before.

Just apply some logic, as to, like, all\n

Start to infer how the\nlanguage does or doesn't work.

If I now go and run this, Python of\n

And just so you have\nseen it, there is a quote

unquote "better" way of doing this,\n

are not going to encounter,\ncertainly in these initial days.

Typically, you would see in\nonline tutorials or books

something that looks like this, where\n

That's functionally the same thing,\n

if we ourselves were implementing a\n

But we're going to keep things simpler\n

because we're not going to\nencounter that problem just yet.

All right, let's make one change to\n

In C, the last version of meow also\n

took arguments to the function meow.

So suppose that I want\nto factor this out.

And I want to just call meow as a\n

say meow this number of times.

And I figure out how many times\n

or using getInt or something\nlike that, to figure out

Well, now, I have to define\ninside my meow function, in input

let's call it n, and then use that,\n

let me go ahead and print\nout meow that many times.

So again, the only thing\nthat's different in C

is we don't bother specifying return\n

and we don't bother specifying the\n

So same ideas, simpler in some sense.

We're just throwing away keystrokes.

All right, let me run this one\nfinal time, Python of Meow.py

and we still have the same program.

All right, let me pause here.

And I know this is going fast.

But hopefully, the C code\nis still somewhat familiar.

AUDIENCE: Is there any difference\n

DAVID J. MALAN: Good question.

Is there any difference between\nglobal and local variables?

Short answer, yes, and we would\nrun into that same problem

if we declare a variable\nin one function

another function is not\ngoing to have access to it.

We can solve that by\nputting variables globally.

But we don't have all of\nthe features we had in C

like there's no such thing\nas a constant in Python.

The mentality in the\nPython community is

if you don't want some value\nto change, don't touch it.

So there's trade-offs here, too.

Some languages are stronger\nor more defensive than that.

But that, too, is part of the mindset\n

AUDIENCE: There is really\nonly one green line, in the--

DAVID J. MALAN: Oh, sorry, where's--

AUDIENCE: There has only been\none green line printed at a time.

DAVID J. MALAN: That\nis an amazing segue.

Let's come to that in just\na moment, because we're

going to recreate also\nthat Mario example, where

we had like the question marks for\n

So let's come back to that in a second.

AUDIENCE: If strings are immutable,\n

DAVID J. MALAN: Correct,\nstrings are immutable.

Any time you seem to be modifying\n

So it's taking a little\nmore memory somewhere.

But you don't have to deal with\nit Python's doing that for you.

AUDIENCE: So you don't free anything.

DAVID J. MALAN: Say it again?

AUDIENCE: You don't free\nlike taking leave on stuff.

DAVID J. MALAN: You don't free anything.

So if you weren't a big fan,\nover the past couple of weeks

of malloc or free or\nmemory or addresses, or all

of those low level\nimplementation details

Python is the language for\nyou, because all of that

is handled for you automatically.

AUDIENCE: Each up for the variable, you\n

Well, if there isn't a main function in\n

DAVID J. MALAN: How do you\ndefine a global variable

if there's no main function in Python?

Global variables, by definition, always\n

If I wanted to have a\nfunction that's outside of

and, therefore, global to\nall of these, like global--

actually, don't use the word global,\n

variable equals Foo, F-O-O,\njust as an arbitrary string

value that a computer scientist would\n

There are some caveats, though,\nas to how you access that.

But let's come back\nto that another time.

But that problem is solvable, too.

So let's go ahead and do this.

To come back to the question about\n

and create a file now called Mario.py.

Won't bother showing the C code anymore.

We'll focus just on\nthe new language here.

But recall that, in Python, in Mario, we\n

This was a random screen from\nthe side scroller version 1

And we just want to print like three\n

Well, in Python, we could\ndo something like this

print, oh, sorry, for i in the range of\n

And I think this is\npretty straightforward.

Python of Mario.py, we\nget our three hashes.

You could imagine\nparameterizing this now, though

and getting actual user input.

Let me go up here and let me go\n

and then let's get the\ninput from the user.

So it actually is a\nvalue n, like, all right

getInt the height of the column\nof bricks that you want to do.

And then, let's go ahead and print\n

Let's print out like five hashes.

OK, one, two, three, four,\nfive, that seems to work, too.

And it's going to work\nfor any positive value.

But it's not going to work\nfor, how about negative 1?

That just doesn't do anything.

But also recall that it's not going\n

weird, like, oh, sorry, it is going\n

We're using CS50's\ngetInt function, which is

handling all of those headaches for us.

But, what if the user indeed\ntypes a negative number?

So that was the bug I\nwanted to highlight.

It would be nice to re-prompt\nthem and re-prompt them.

And in C, what was the\nprogramming construct we

used when we wanted to\nask the user a question.

And then, if they didn't cooperate,\n

DAVID J. MALAN: Yeah,\ndo while loop, right?

That was useful, because it's\nalmost the same as a while loop.

But instead of checking a\ncondition, and then doing something

you do something and\nthen check a condition

which makes sense with user\ninput, because what are you

even going to check if the\nuser hasn't done anything yet?

You need that inverted logic.

Unfortunately in Python,\nthere is no do while loop.

And frankly, those are\nenough to recreate this idea.

And the way to do this in\nPython, the Pythonic way, which

is another term of art in the\ncommunity, is to say this.

Deliberately induce an infinite loop,\n

And then do what you got to do,\nlike get an Int from a user

asking them for the\nheight of this thing.

And then, if that is what you want, like\n

So this is how, in Python, you could\n

You deliberately induce\nan infinite loop.

So something's going to\nhappen at least once.

Then, if you get the answer\nyou want, you break out of it

effectively achieving the same logic.

So this is the Pythonic way\nof doing a do while loop.

Let me go ahead and run Python\nof Mario.py, type in 3 this time.

And now I get back just\nthe 3 hashes as well.

What if, though, I wanted to\nget rid of, how about ultimately

that CS50 library function, and\n

Well, let's go ahead and\ntweak this a little bit.

Let me go ahead and\nremove this temporarily.

Give myself a main function, so\nI don't make the same mistake

And let me give myself a function called\n

And inside of that function\nis going to be that same code.

But I don't want to break in\nthis case, I want to return n.

So, recall, that if you return\nfrom a function, you're done

you're going to exit\nfrom right at that point.

You can just say return\nn inside of the loop

or, if you would prefer\nto break out, you

could do something like this instead.

Break, and then down here,\nyou could return, down here

And let me make one point here\nbefore we go back up to main.

This is a little different\nfrom C. And this one's subtle.

What have I done here that in C would\n

It's super subtle, this one.

AUDIENCE: So aren't we like\ndefining mostly object

like we're using it\nfirst, defining an object?

DAVID J. MALAN: So similar, it's\n

So it's OK not to declare a\nvariable with like the data type.

We've addressed that before, but on line\n

And then we return n on line 12.

In the world of C, if we had declared\n

it would have been scoped\nto that loop, which

means as soon as you get out of that\n

It would be local to the\ncurly braces therein.

Here, logically, curly braces\nare gone, but the indentation

makes clear that n is still inside of\n

But n is actually still\nin scope in Python.

The moment you create a variable\n

It is available everywhere within\nthat function, even outside

of the loop in which you defined it.

So this logic is actually OK in Python.

In C, recall, to solve\nthis same problem

we would have had to do something\na little hackish like this

like define n up here on line 8,\n

and so that it exists on line 13.

That is no longer an\nissue or need, in Python.

Once you create a variable,\neven if it's nested

nested, nested inside of\nsome loops or conditionals

it still exists within\nthe function itself.

All right, any questions then on this,\n

rid of the CS50 library again?

OK, so let me go ahead and\nget the height from the user.

Let's go ahead and create a\nvariable in main called height.

Let's call this get height function.

And then let's use that height value,\n

And let me see if this all works now.

Hopefully, I haven't\nmessed up, but I did.

But this is an easy fix now.

AUDIENCE: Got to call main.

DAVID J. MALAN: I got to call main.

So again, I deleted that earlier.

So I'm actually calling main.

Let me rerun Python of\nMario.py, there we go, height 3.

So let's do one last\nthing with Mario, just

to tie together that idea now\nof exceptions from before.

Again, exceptions are\na feature of Python

whereby you can try to do something.

And if there's a problem, you can\n

Previously, I handled it by just yelling\n

But let's actually use this to\nre-implement CS50's own getInt

Let me throw away\nCS50's getInt function.

And now let me go ahead and\nreplace getInt with input.

But it's not sufficient\nto just use input.

What do I have to add to\nthis line of code on line 8?

If I want to get back an Int?

DAVID J. MALAN: Yeah, I\nhave to cast it to an Int

by calling the Int\nfunction around that value

or I could do it on a separate\nline, just to be clear.

I could also do n equals Int of n.

That would work too, but it's\nsort of an unnecessary extra line.

This is not sufficient, because\nthat does not change the value.

But then it throws it away.

So the conventional way to do this\n

just to keep things nice and tight.

If I run Python of Mario.py, I can\n

I can still type in negative 1, because\n

What I'm not yet handling\nis weird input like cat

or some string that is\nnot a base 10 number.

So here, again, is my traceback.

And notice that here, let\nme scroll up a little bit

here we can actually see\nmore detail in the traceback.

Notice that, just like in C, or just\n

You can see mention of module, that\n

is my main function, and get height.

So notice, it's kind of backwards.

It's top to bottom instead\nof bottom up, as we drew it

on the board the other\nday, and as we envisioned

stacks of trays in the cafeteria.

But this is your stack,\nof functions that

have been called, from top to bottom.

Get height is the most recent,\nmain is the very first

So let's try to do, let's try to do this\n

I'm going to go in here, and I'm\n

Whoops, try to do the following, except\n

then go ahead and say something,\nwell, like before, print

that's not an integer exclamation point.

But the difference this time is\nbecause I'm in a loop, the user

is going to have a chance\nto recover from this issue.

So if I run Mario.py, 3\nstill works as before.

If I run Mario.py and type\nin cat, I detect it now

and because I'm still in that loop,\n

because I've caught, so to speak, the\n

here, that's the way in Python\nto detect these kinds of errors

that would otherwise end up\nbeing on the user's own screen.

If I type in cat, dog,\nthat doesn't work.

If I type in, though, 2, I get my two\n

Are any questions on\nthis, and we're not going

to spend too much time on\nexceptions, but just wanted

to show you what's involved with\n

AUDIENCE: Then the hash marks in line.

DAVID J. MALAN: OK, so let's do this.

That actually comes to\nthe earlier question

about printing the\nhashes on the same line

or maybe something like this,\nwhere we have the little bricks

in the sky, or little question marks.

Let's recreate this idea,\nbecause the problem with print

as was noted earlier, is you're\n

But what if we don't want that.

Well, let's change\nthis program entirely.

Let me throw away all the functions.

Let's just go to a simpler world,\nwhere we're just doing this.

So let me start fresh in Mario.py.

I'm not going to bother with\nexceptions or functions.

Let's just do a very simple program, to\n

this time, because there are\nfour of these things in the sky.

Let's go ahead and just\nprint out a question mark

to represent each of those bricks.

Odds are you know this not going to end\n

as you've predicted, on separate lines.

So it turns out that the\nprint function actually

takes in multiple arguments, not\n

but also some additional arguments,\nthat allow you to specify

what the default line ending should be.

But what's interesting\nabout this is that, if you

want to change the line\nending to be something like

quote unquote, "that is\nnothing," instead of backslash n

this is not sufficient,\nbecause in Python, you

can have two types of\narguments, or parameters.

Some arguments are positional, which\n

a comma separated list of arguments.

And that's what we did all the time\n

comma, something, we did\nit in printf all the time

and in other functions that\ntook multiple arguments.

In Python, you have, not\nonly positional arguments

where you just separate them by commas,\n

There are also named arguments,\nwhich looks weird but is

helpful for reasons like this.

If you read the\ndocumentation, you will see

that there is a named argument\nthat Python accepts, called end.

And if you set that\nequal to something, that

will be used as the end\nof every line, instead

of the default, which the\ndocumentation will also say

is quote unquote backslash n.

So this line here has no effect\non my logic at the moment.

But if I change it to just quote\nunquote, essentially overriding

the default new line character, and\n

There's a bit of a bug, though.

My prompt is not meant\nto be on the same line.

So I can fix that by\njust printing nothing.

But, really, it's not nothing,\n

So let me run Python of\nMario.py again, and now we

have what I intended in the first\n

And this is just one example\nof an argument that has a name.

But this is a common\nparadigm in Python 2

to not just separate things by\ncommas, but to be very specific

because the print function might take\n

And my God, if you had to\nenumerate like 10 or 20 commas

You're going to get\nthings in the wrong order.

Named arguments allow you to\nbe resilient against that.

So you only specify\narguments by name, and it

doesn't matter what order they are in.

All right, any questions, then, on\n

And to be clear, you can do\nsomething like, very weird

but logically expected, like this, by\n

But the right way to\nsolve the Mario problem

would be just to override\nit to be nothing like this.

All right, how about this for cool.

And this is why a lot\nof people like Python.

Suppose you don't really like loops.

You don't really like\nthree-line programs

because that was kind of three\ntimes longer than it needs to be.

What if you just printed out\na question mark four times?

Python, whoops, Python of\nMario.py, that also works.

So it turns out that, just like\nthe plus operator in Python

can join things together,\nthe multiply operator is not

It actually means, take this and\nconcatenate it four times over.

So that's a way of just\ndistilling into one line what

would have otherwise taken multiple\n

lines in Python, but is really\nnow rather succinct in Python

Let's do one last Mario example, which\n

If this is another part\nof the Mario interface

this is like a grid of like\n3 by 3 bricks, for instance.

So two dimensions now, just not just\n

Let's print out something\nlike that, using hashes.

Well, how about, how do I do this.

So how about for i in range of 3.

Then I could do for j in range of\n

and that's reasonable for counting.

I could now print out a hash symbol,\n

Python of Mario.py, OK, that's\njust one crazy long column.

What do I need to fix and where\n

So 3 by 3 bricks, instead\nof one long column.

AUDIENCE: Why don't we create\na line and then we'll skip it.

DAVID J. MALAN: OK, so after\nprinting 3, we want to skip a line.

So maybe like print\nout a blank line here.

I like that instinct, right, print\n

Let's go ahead and run\nPython of Mario.py.

OK, it's more visible, what\nI'm doing, but still wrong.

What can I, what's the\nremaining fix, though?

AUDIENCE: So right behind the two.

DAVID J. MALAN: Yeah, I'm\ngetting an extra new line here

which I don't want\nwhile I'm on this row.

So let me do n equals quote unquote,\n

Python of Mario.py, voila, now\nwe've got it, in two dimensions.

And even this, we can tighten up.

Like, we could just use the\nlittle trick we learned.

So we could just say,\nprint a hash times 3 times

and we can get rid of one\nof those loops altogether.

All it's doing is, whoops, all it's\n

But, no, I don't want to do that.

What do I, how do I fix this here.

I don't think I want\nthis anymore, right?

Because that's giving\nme an extra new line.

So now this program is\nreally tightened up.

Same thing, two lines of code.

But we're now implementing this\n

All right, any questions here on these?

AUDIENCE: Is there any practical reason\n

the print function, you\ndon't put any spaces in it.

DAVID J. MALAN: If I\nprint n, any spaces.

AUDIENCE: Whenever we\nwrite n, for example

the print function\nis, you know, in order

to stop it from going to a new\nline, it seems like any spaces

we did like n equals and then too close.

So in a previous version, let me\n

The convention in Python\nis not to do that.

It just starts to add too much space.

And this is a little\ninconsistent, because, earlier

when we talked about\nlike pluses or spaces

around the less than or equal\nsigns, I did say add it.

Here it's actually\nclearer and recommended

to keep them tighter together.

Otherwise it just becomes harder\nto read where the gaps are.

All right, let's do, how about,\nanother five minute break.

And then we're going to dive into\n

and then ultimately build with some\n

All right, so almost all\nof the examples we just did

were recreations of\nwhat we did in week 1.

And recall that week 1 was like\nour most syntax-heavy week.

It was when we were first learning\n

we began to focus a bit\nmore on ideas, like arrays

and other higher-level constructs.

And we'll do that again here, condensing\n

into a fewer set of examples in Python.

And we'll culminate by actually\ntaking Python out for a spin

and doing things that\nwould be way harder to do

and way more time-consuming to do in C,\n

But how do you go about figuring\nout what functions exist

if you didn't hear it in\nclass, you don't see it online

but you want to see it officially, you\n

And I will disclaim that, honestly,\n

Google will often be your\nfriend, so googling something

you're interested in, to find your way\n

or StackOverflow.com is\nanother popular website.

As always, though, the\nline should be googling

things like, how do I convert\na string to lowercase.

Like that's reasonable to Google.

Or how to convert to uppercase or\n

But googling, of course, things like\n

of course, crosses the line.

But moving forward, and really with\n

and Stack Overflow are\nyour friends, but the line

is between the reasonable\nand the unreasonable.

So let me officially use the\nPython documentation search, just

to search for something\nlike the lowercase function.

Like, I know I can\nlowercase things in Python.

So let me just search\nfor the word lower.

You're going to get, often, an\noverwhelming number of results

because Python is a pretty big\n

And you're going to want to\nlook for familiar patterns.

For whatever reason,\nstring.lower, which is probably

more popular or more commonly used than\n

But it's purple, because I clicked\n

So str.lower is probably\nwhat I want, because I

am interested at the moment\nin lower casing strings.

When I click on that, this is an example\n

It's in this general format.

Here's my str.lower function.

This returns a copy of\nthe string, with all

of the cased characters\nconverted to lowercase

and the lower-casing\nalgorithm, dot dot dot.

So that doesn't give me much.

It doesn't give me sample code.

But it does say what the function does.

And if we keep looking, you'll see\n

I used its analog, Rstrip before, right\n

that is strip, from the end of a\n

like a new line, or even something else.

And if you scroll through\nstring, this web page here.

And we're halfway down the page already.

If you see my scroll\nbar, tiny on the right

there's a huge amount of functionality\n

And this is just testament to just\n

But it's also reason to\nreassure that the goal, when

playing around with some new\nlanguage and learning it

is not to learn it exhaustively.

Just like in English\nor any human language

there's always going to be\nvocab words you don't know

ways of presenting the same\ninformation in some language.

That's going to be the case with Python.

And what we'll do today and this\nweek in problem set 6 is really

get your footing with this language.

But you won't know all of Python,\n

And, honestly, you won't know all of\n

unless you're, perhaps, using\nthem full time professionally

and even then, there's more libraries\n

So let's actually now\npivot to a few other ideas

that we'll implement\nin Python, in a moment.

Let me switch back over to VS Code here.

And let me whip up, say, a recreation\n

where we averaged like\nthree scores together.

And that was an opportunity\nin week 2 to play with arrays

to realize how constrained arrays are.

You have to decide in advance.

But let's see what's\ndifferent here in Python.

So let me do Scores.py, and let\n

called scores, sorry, let me give myself\n

Set it equal to a list\nof three scores, which

are the same ones we've used\nbefore, 72, 73, 33, in this context

meant to be scores, not ASCII values.

And then let's just do\nthe average of these.

So average will be another variable.

And it turns out I can do, well,\nhow did I sum these before?

I probably had a for loop to add\n

Turns out in Python, you\ncan just say sum of scores

divided by the length of scores.

That's going to give me my average.

So sum is a function that takes\na list, in this case, as input

and it just does the sum for\nyou, with a for loop or whatever

Len gives you the length of the\nlist, how many things are in it.

So I can dynamically figure that out.

Now let me go ahead and print out,\n

in curly braces, the actual\naverage, close quote.

All right, so let's run this\ncode, Python of Scores.py.

And there is my average, in this\ncase, 59.33333 and so forth

Well, let's actually, now,\nchange this a little bit

and make it a little more interesting,\n

rather than hard coding this.

Let me go back up here and\nuse from CS50 import getInt

because I don't want to deal with\n

Like, I just want to use\nsomeone else's function here.

Let me give myself an\nempty list called scores.

And this is not something we\nwere able to do in C, right?

Because in C, if you tried\nto make an empty array

well, that's pretty stupid,\nbecause you can't add things to it.

So it wouldn't even let you do that.

But I can just create\nan empty list in Python

because lists, unlike arrays,\nare really lengthless.

But you and I are not dealing with\n

So now, let's go ahead and get a\n

How about three of them in total.

So for i in range of 3, let's go\n

using getInt, asking them for score.

And then let's go ahead and append, to\n

So it turns out that a list,\nand I could read the Python

documentation to confirm as much,\n

and functions built into objects\nare generally known as methods

if you've heard that term before.

Same idea, but whereas a function\nkind of stands on its own

a method is a function built\ninto an object, like a list here.

That's going to achieve the\nsame result. Strictly speaking

Just like in C, I could tighten this\n

But, I don't know, I\nkind of like it this way.

It's more clear, to me, at least, that\n

and then appending it to the list.

Now the rest of the\ncode can stay the same.

Python of Scores.py,\nscore will be 72, 73, 33.

But now the program's a little\nmore dynamic, which is nice.

But there's other\nsyntax I could use here.

Just so you've seen it, Python does\n

whereby, if you don't\nwant to do scores.append

you can actually say scores\nplus equals this score.

So you can actually concatenate\nlists together in Python 2.

Just as we used plus to\njoin two strings together

you can use plus to\njoin two lists together.

The catch is, you need\nto put the one score I'm

adding here in a list of its\nown, which is kind of silly.

But it's necessary, so that this\n

To do this more verbosely,\nwhich most programmers wouldn't

do, but just for clarity,\nthis is the same thing

as saying scores plus this score.

So now maybe it's a little more\n

plural, sorry, singular, are both\n

So two different ways, not sure\none is better than the other.

This way is pretty common, but .append\n

All right, how about another\nexample from week two.

This one was called uppercase.

So let me do this in\nUppercase.py, though, this time.

And let me import from\nCS50, get string again.

And let me go ahead and say,\nbefore will be my first variable.

Let me get a string from the user,\n

And then let me go ahead and say,\n

upper-casing to this string.

Let me change my line ending to\nbe that, using our new trick.

And this is where things get cool\n

If I want to iterate over all\nof the characters in a string

and print them out in uppercase,\n

For c in the before string, go ahead and\n

but don't end the line yet, because I\n

Python of Uppercase.py, let me\ntype in Hello in all lowercase.

I've just upper-cased the whole string.

I first get string, calling it before.

I then just print out some fluffy\ntext that says after colon

and I get rid of the line ending,\n

Notice I hit the spacebar\na couple of times

just so letters line up to be pretty.

For c and before, this is new.

This is powerful in C,\nsorry, in Python, whereby

you don't have to do like Int i\nequals 0 and i less than this

you could just say, for c in the\n

And then here is just upper-casing\nthat specific character

and making sure we don't\noutput a new line too soon.

But this is actually more\nwork than I need to do.

Based on what we've seen thus far,\n

can I tighten this up further?

Can I collapse lines 5 and 6,\nmaybe even 7, all together?

If the goal of this program is just\n

AUDIENCE: Would it be str.upper?

DAVID J. MALAN: Str.upper,\nyeah, so I could do something

like this, after gets before.upper.

So it's not stir\nliterally dot upper, stir

just represents the string in question.

So it would be before.upper,\nbut right idea otherwise.

And so let me go ahead and just tweak\n

Let me just go ahead and print out the\n

So this line is the same, I'm\ngetting a string called before.

I'm creating another variable\ncalled after, and, as you propose

I'm calling upper on the whole\n

And, again, in Python, there aren't\n

There's only strings, anyway.

So I might as well do them all at once.

So if I rerun the code now,\nPython of Uppercase.py.

Now I'll type in Hello in all\nlowercase, and, oh, so close

I think I can get rid of\nthis override, because I'm

printing the whole thing out at\n

So now if I type in Hello before,\n

All right, any questions,\nthen, on lists or on strings

and what this kind of function,\n

All right, so a couple other\nbuilding blocks before we start.

DAVID J. MALAN: To the right, right.

AUDIENCE: Could you write, very close to\n

you start creating a variable upper.

DAVID J. MALAN: Yes, do I have\nto create this variable, upper?

I could actually tighten\nthis up, and, if you really

want to see something neat,\ninside of the curly braces

you don't have to just put\nthe names of variables.

You can put a small\namount of logic, so long

as it doesn't start to look stupid and\n

that it's sort of bad\ndesign at that point.

I can tighten this up like this.

And now we're in Python of\nUppercase.py, writing Hello again.

But I would be careful about this.

You want to resist the temptation of\n

inside the curly braces, because\n

But, absolutely, you\ncould indeed do that, too.

All right, how about command line\narguments, which was one thing

we introduced in week two also, so\n

to take input from the user, whoops.

So we could actually take input\n

so as to take literally\ncommand line arguments.

These are a little different,\nbut it follows the same paradigm.

There's no main by default.\nAnd there's no Def main int

arg c char, or we called it string,\n

So if you want access to the\n

And it turns out, there's another\n

called CIS, and you can import from\n

So same idea, different place.

Now I'm going to go ahead and do this.

Let's write a program that just requires\n

after the program's\nname, or none at all.

So if the length of argv equals 2,\n

Hello comma argv bracket 1 close quote,\n

total at the prompt, let's just say\n

So the only thing that's new here\n

and we're using this fancy f-string\n

too, it's putting more complex\nlogic in the curly braces.

In this case, it's a list called argv,\n

Let's do Python of Argv.py,\nEnter, Hello, world.

What if I do Argv.py\nDavid at the command line.

So there's one curiosity here.

Python is not included in\nargv, whereas in C, dot

slash whatever was the first thing.

If the analog in Python is that\nthe name of your Python program

is the first thing, in bracket 0,\n

the word Python does not appear in\n

But otherwise, the\nidea of these arguments

is exactly the same as before.

And in fact, what you can\ndo, which is kind of cool

is, because argv is a list,\nyou can do things like this.

For arg in argv, go ahead\nand print out each argument.

So instead of using a\nfor loop and i and all

of this, if I do Python of argv Enter,\n

If I do Python of argv Foo,\nit puts Argv.py and Foo.

If I do, sorry, if I do Foo and\nbar, those words all print out.

If I do Foobar baz, those print out too.

And Foo and bar or baz are like\na mathematician's x and y and z

for computer scientists, when you\n

It reads a little more like English, and\n

allows you to iterate very quickly\n

Suppose I only wanted the real\nwords that the human typed

Like, suppose I want to ignore Argv.py.

I mean I could do something\nhackish like this.

If arg equals Argv.py,\nI could just ignore

you know, let's invert the logic.

I could do this, for instance.

So if the arg does not\nequal the program name

then go ahead and print out the word.

So I get Foobar and baz only.

Or, this is what's kind of neat\n

And let me just take a slice of\nthe array of the list instead.

So it turns out, if argv is\na list, I can actually say

you know what, go into that list,\n

and then go all the way to the end.

And we have not seen this\nsyntax in C. But this

is a way of slicing a list in Python.

If I run Python of\nArgv.py, Foo bar baz Enter

I get only a subset of the\nlist, starting at position 1

going all of the way to the end.

And you can even do\nkind of the opposite.

If, for whatever reason, you\nwant to ignore the last element

you can say colon, we\ncould say colon negative 1

and use a negative number,\nwhich we've not seen before

which slices off the end\nof the list, as well.

So there's some syntactic tricks\n

even if at first glance, you might\n

All right, let's do one\nother example with exit

and then we'll start actually\napplying some algorithms

to make things interesting.

So in one last program here, let's do\n

before we introduce some algorithms.

Let's import from CIS, import argv.

Let's make sure the user gives\nme one command line argument.

So if the length of argv does not\n

and print out something like\nmissing command line argument

just to explain what the problem is.

But I'm going to use a\nbetter version of exit here.

Let me import two functions from CIS.

Turns out the better way to do this is\n

specifically 2, with this exit code.

Otherwise, down here, I'm going\nto go ahead and print out

something like Hello, comma\nargv bracket 1, same as before.

And then I'm going to exit with zero.

So, again, this was a\nsubtle thing we introduced

in week two, where you can\nactually have your programs exit

with some number, where\n0 signifies success

and anything else signifies error.

This is just the same idea in Python.

So if I, for instance, just run the\n

I meant to say exit here and exit here.

If I run this like this, I'm\nmissing a command line argument.

So let me rerun it with\nlike my name at the prompt.

So I have exactly two command line\n

And if I do David Malan, it's\nnot going to work either

because now argv does not equal 2.

But the difference here is\nthat we're exiting with 1

so that special programs can detect an\n

And now there's one other\nway to do this, too.

Suppose that you're\nimporting a lot of functions

and you don't really want\nto make a mess of things

and just have all of these\nfunction names available

without it being clear\nwhere they came from.

Let's just import all of CIS.

And let's just change our syntax,\n

where we just prepend to all\nof these library functions

CIS, just to be super-explicit\nwhere they came from

and if there's another\nexit or argv value

that we want to import from a library,\n

So if I do it one last time here,\nmissing command line argument.

But David still actually worked.

All right, only to demonstrate how\n

Let's now do something more\npowerful, like a search algorithm

I'm going to go ahead and open\nup a file called Numbers.py

and let's just do some searching\nor linear search, rather

How about import CIS as before.

Let me give myself a list of\nnumbers, like 4, 6, 8, 2, 7, 5, 0

so just a bunch of integers.

If you recall from week three,\nwe searched for the number 0

at the end of the lockers on stage.

So let's just ask that\nquestion in Python.

No need for a loop or\nanything like that.

If 0 is in the numbers, go\nahead and print out found.

And then let's just exit successfully,\n

let's just say print not found.

And then we'll CIS exit with 1.

So this is where Python\nstarts to get powerful again.

Here is your loop, that's doing\nall of the checking for you.

Underneath the hood, Python\nis going to use linear search.

You don't have to implement it yourself.

No while loop, no for loop,\nyou just ask a question.

If 0 is in numbers,\nthen do the following.

So that's one feature\nwe now get with Python

and get to throw away\na lot of that code.

We can do it with strings, too.

Let me open a file\ncalled Names.py instead

and do something that was\neven more involved in C

because we needed Str Comp and\nthe for loop, and so forth.

Let me import CIS for this file.

Let's give myself a bunch\nof names like we did in C.

And those were Bill and Charlie\nand Fred and George and Ginny

and two more, Percy, and lastly Ron.

And recall, at the\ntime, we looked for Ron.

And so we had to iterate\nthrough the whole thing

doing Str Comp and i plus\nplus and all of that.

Now just ask the question, if Ron\n

and, whoops, let me hide that.

Let me go ahead and say\nprint, found, as before.

CIS exit 1, just to indicate\nsuccess, and then down here

if we get to this point,\nwe can say not found.

And then we'll just CIS exit 1 instead.

So, again, this just does linear search\n

we found Ron, because, indeed, he's\n

But we don't need to deal with\nall of the mechanics of it.

All right, let's take\nthings one step further.

In week three, we also\nimplemented the idea

of a phone book, that actually\nassociated keys with values.

But remember, the phone book in\nC, was kind of a hack, right?

Because we first had two arrays,\n

Then we introduced structs, and\n

And then we had an array of persons.

You can do this in Python, using\n

But we can also just use a\ngeneral purpose dictionary

because just like in P set 5, you\n

Well, similarly, can\nPython just do this for us.

From CS50, let's import get string.

And now let's give myself\na dictionary of people

D-I-C-T () open paren closed\nparen gives you a dictionary.

Or you can simplify\nthe syntax, actually

and a dictionary again is just keys\n

You can also just use\ncurly braces instead.

That gives me an empty dictionary.

But if I know what I want to put in it\n

with a number of plus 1-617-495-1000,\n

David, with plus 1-949-468-2750.

And it came to my attention,\ntragically, after class that day

that we had a bug in\nour little Easter egg.

If today, you would like to call\nme or text me, at that number

we have fixed the code that\nunderlies that little Easter egg.

All right, so this now\ngives me a variable

called people, that's\nassociating keys with values.

There is some new syntax here in\n

but the colons, and the quotes\non the left and the right.

This is a way, in Python,\nof associating keys

with values, words with definitions,\n

And it's going to be a super-common\n

when we look at CSS and HTML and\n

are like this omnipresent idea in\n

because it's just a really useful way\n

So, at this point in the story, we\n

if you will, of people, associating\nnames with phone numbers

just like a real world phone book.

So let's write a program that gets\n

whose number they would like to look up.

Then, let's go ahead and say, if that\n

go ahead and print out\nthat person's number

by going into the people\ndictionary and going

to that specific name, within there,\n

So this is similar in spirit to before.

Linear search and dictionary lookups\n

in Python, by just asking the\nquestion, if name and people.

And this line is just\ngoing to print out

whoever is in the people\ndictionary, at that name.

So I'm using square brackets, because\n

just like you can index into\nan array, or a list in Python

using numbers, 0, 1, 2, you\ncan very conveniently index

into a dictionary in Python,\nusing square brackets, as well.

And just to make clear what's\ngoing on here, let me go

and create a temporary variable,\n

And then let's just, or, sorry, let's\n

And that will just print\nout the number in question.

In C, and previously in Python,\n

would have been go to a location in\n

But that can actually be a string,\n

And this is what's amazing\nabout dictionaries

it's not like a big\nline, a big linear thing.

It's this table, that you can\nlook up in one column the name

and get back in the\nother column the number.

So let's go ahead and run\nPython of Phonebook.py

That's not what's\nsupposed to happen at all.

I think I'm in the wrong play.

Python of Phonebook.py, what the--

What am I not understanding here?

OK, Roxanne, Carter, do you\nsee what I'm doing wrong?

SPEAKER 47: When you found the test\n

DAVID J. MALAN: Oh, yeah, found,\nOK, we're going to do this.

All this is coming out of the video.

I will try to figure out\nwhat was going wrong.

The best I can tell, it was\nrunning the wrong program.

I don't quite understand why.

So we will diagnose this later.

I just put the file into a temporary\n

So let me go ahead and just run\nthis, Python of Phonebook.py

type in, for instance, my name.

And there's my corresponding number.

Have no idea what was just happening.

But I will get to the\nbottom of it and update you

if we can put our finger on it.

So this was just an example, now,\nof implementing a phone book.

Let's now consider what we\ncan do that's a little more

powerful, in these examples,\nlike a phone book that

actually keeps this information around.

Thus far, these simple phone book\n

But using CSV files,\ncomma separated values

maybe we could actually keep\naround the names and numbers

so that, like on your\nphone, you can actually

keep your contacts around long-term.

So I'm going to go ahead now and\n

And let me just hide this\ndetail, so it's not confusing.

Whoops, I'm going to change\nmy prompt temporarily.

So let me go ahead now and\nrefine this example as follows.

I'm going to go into\nPhonebook.py, and I'm

going to import a whole\nlibrary called CSV.

And this is a powerful\none, because Python

comes with a library that just\nhandles CSV files for you.

A CSV file is just a file\nwith comma separated values.

And, in fact, to demonstrate\nthis, let me check on one thing

here, just to make this\na little more real.

To demonstrate this, let's\ngo ahead and do this.

Let me import the CSV library from CS50.

Let me then open a file,\nusing the open function

open a file called\nPhonebook.csv, in append format

in contrast with read\nformat and write format.

Write just blows it away if it exists,\n

So I keep this phone book\naround, just like you might

keep adding contacts to your phone.

Now let me go ahead and get a\ncouple of values from the user.

Let me say getString and\nask the user for a name.

Then let me getString again, and\nask the user for their number.

And now, let me go ahead and do this.

And this is new, and\nthis is Python-specific.

And you would only know this\nby following a tutorial

or reading the documentation.

Let me give myself a\nvariable called writer

and ask the CSV library\nfor a writer to that file.

Then, let me go ahead and\nuse that writer variable

use a function or a method\ninside of it, called write row

to write out a list containing\nthat person's name and number.

Notice the square brackets\ninside the parentheses

because I'm just printing a list\n

And then I'm just going\nto close the file.

So what is the effect of all of this?

Well, let me go ahead and run\nthis version of Phonebook.py

and I'm prompted for a name.

Let's do Carter's first, plus\n1-617-495-1000, and then

Notice in my current directory,\n

which I wrote, and\napparently Phonebook.csv.

CSV just stands for\ncomma separated values.

And it's like a very simple way\n

if you will, where the comma represents\n

There's only two columns\nhere, name and number.

But, because I'm writing to\nthis file in append mode

let me run it one more time,\nPython of Phonebook.py

and let me go ahead and do David\nand plus 1-949-468-2750, Enter.

And notice what happened\nin the CSV file.

It automatically updated,\nbecause I'm now persisting

this data to the file in question.

So if I wanted to now\nread this file in, I

could actually go ahead and\ndo linear search on the data

using a read function to\nactually read from the CSV.

But, for now, we'll just leave\nit a little simply as write.

And let me make one refinement here.

It turns out that, if you're in\nthe habit of re-opening a file

you don't have to even\nclose it explicitly.

You can instead say, with the opening\n

in append mode, calling the thing file,\n

So the with keyword is\na new thing in Python.

And it's used in a few different\n

is to tighten up code here.

And I'm going to move my\nvariables to the outside

because they don't need to be\ninside of the with statement

This just has the effect of\nensuring that you, the programmer

don't screw up, and accidentally\ndon't close your file.

In fact, you might\nrecall, from C, Valgrind

might have complained at you, if you had\n

you might have had a memory leak\nas a result. The with keyword

takes care of all of\nthat for you, as well.

How about let's do, want to do this.

How about, let's do one other thing.

Let me go ahead and propose,\nthat on your phone or laptop

here, or online, go to this URL here,\n

And just to show that these CSVs\n

and if you've ever\nlike used a Google Form

or managed a student group,\nor something where you've

collected data via Google\nForms, you can actually

export all of that data via CSV files.

So go ahead to this URL here.

And those of you\nwatching on demand later

will find that the form\nis no longer working

since we're only doing this live.

But that will lead to\na Google Form that's

going to let everyone input\ntheir answer to a question

like what house do you\nwant to end up into

sort of an approximation of the\nsorting hat in Harry Potter.

And via this form, will we then\nhave the ability to export

So let's give you a moment to do that.

In just a moment, I'll share\nmy version of the screen, which

is going to let me actually\nopen the file, the form itself.

And in just a moment, I'll switch over.

OK, so this is now my\nversion of the form

here, where we have 200 plus responses\n

house do you belong in, Gryffindor,\n

If I go over to responses, I'll see all\n

So graphical user interface,\nand we could flip through this.

And it looks like, interestingly,\n40% of Harvard students

want to be in Gryffindor, 22%\nin Slytherin, and everyone else

But you might have noticed,\nif ever using a Google Form

this Google Spreadsheets link.

So I'm going to go ahead and click that.

And that's going to automatically open,\n

But you can do the same thing\nwith Office 365 as well.

And now you see the raw\ndata as a spreadsheet.

But in Google Spreadsheets, if I go\n

notice I can download this as\nan Excel file, a PDF, and also

a CSV, comma separated values.

So let me go ahead and do that.

That gives me a file in my\nDownloads folder on my computer.

I'm going to now go back\nto my code editor here.

And what I'm going to go\nahead and do is upload

this file, from my\nDownloads folder to VS Code

so that we can actually\nsee it within here.

And now you can see this open file.

And I'm going to shorten its name,\n

I'm going to rename this using the\n

And then we can see, in the file, that\n

house, where you have a\nwhole bunch of time stamps

when people filled out the form,\n

And then everyone else\njust a moment ago.

And the second value, after each\n

Well, let me go ahead here\nand implement a program

in a file called Hogwarts.py,\nthat processes this data.

So in Hogwarts.py, let's\njust write a program

that now reads a CSV, in\nthis case not a phone book

but everyone's sorting hat information.

And I'm going to go\nahead and Import CSV.

And suppose I want to answer a\nreasonable question, ignoring

the fact that Google's GUI or graphical\n

I just want to count up who's\ngoing to be in which house.

So let me give myself a dictionary\n

And let me pre-create a few keys.

Let me say Gryffindor is\ngoing to be initialized to 0

Hufflepuff will be initialized\nto 0 as well, Ravenclaw

And finally, Slytherin\nwill be initialized to 0.

So here's another example of\na dictionary, or a hash table

just being a very\ngeneral-purpose piece of data.

You can have keys and values.

The keys, in this case, are the houses.

The values are initially zero,\nbut I'm going to use this

instead of like four separate variables,\n

With opening Hogwarts.csv, in read mode,\n

I just want to read it, as\nfile as my variable name.

Let's go ahead and create\na reader this time

that is using the reader function in\n

I'm going to go ahead and ignore\nthe first line of the file

because, recall, that the first\n

I want to get the real data.

So this next function\nis just a little trick

for ignoring the first line of the file.

For every other row in the\nreader, that is line by line

get the current person's house,\nwhich is in row bracket 1.

This is what the CSV reader\nlibrary is doing for us.

It's handling all of the\nreading of this file.

It figures out where the comma is,\n

it hands you back a list of size 2.

In bracket 0 is the time stamp,\nin bracket 1 is the house name.

So, in my code, I can say\nhouse equals row bracket 1.

I don't care about the time\nstamp for this program.

And then let's go into my dictionary\n

into it at the house location, by\n

And now, at the end\nof this block of code

that has the effect of iterating\nover every line of the file

updating my dictionary\nin four different places

based on whether someone typed\n

And notice that I'm using the name of\n

to essentially go up to this little\n

the 1 to a 2, the 2 to\na 3, instead of having

like four separate\nvariables, which would just

be much more annoying to maintain.

Down at the bottom, let's\njust print out the results.

For each house in those\nhouses, iterating over

the keys they're in\nby default in Python

let's go ahead and print\nout an f-string that says

the current house has the current count.

And count will be the result of indexing\n

So let's run this to summarize\nthe data, Hogwarts.py, 140 of you

answered Gryffindor, 54 Hufflepuff,\n

And that's just my now way\nof code, and this is, oh

my God, so much easier than C, to\n

And one of the reasons that Python is so\n

more generally, is that it's actually\n

And let me clean this up slightly.

It's a little annoying that\nI just have to know and trust

that the house name is in bracket\n

There's something called a\nDictionary Reader in the CSV library

Capital D, capital R, this means\n

because what a dictionary\nreader does is it

still returns to me every row from\n

but it doesn't just give me a list\n

And it uses, as the keys in that\n

for every row in the\nfile, which is just to say

it makes my code a little\nmore readable, because instead

of doing this little\ntrickery, bracket 1

I can say quote unquote "Bracket\nHouse" with a capital H

because it's capitalized\nin the Google Form itself.

So the code now is\njust minorly different

but it's way more resilient, especially\n

and I'm moving the columns around\nor doing something like that

where the numbers might get messed up.

Now I can run this on Hogwarts.py\n

But I now don't have to worry about\n

All right, any questions on\nthose capabilities there.

And that's a teaser of sorts,\nfor some of the manipulation

All right, so some final\nexamples and flair, to intrigue

with what you can do with Python.

I'm going to actually switch over\n

so that I can actually use\naudio a little more effectively.

So here's just a terminal\nwindow on Mac OS.

I before class have preinstalled\n

that won't really work\nin VS Code in the cloud

because they require audio that the\n

But I'm going to go ahead\nand write an example here

that involves writing a speech-based\n

And I'm going to go ahead\nand import a library

that, again, I pre-installed,\ncalled Python text to speech

and I'm going to go ahead\nand, per its documentation

give myself a speech engine, by\n

I'm then going to use this\nengine's save function

to do something fun, like Hello, world.

And then I'm going to go ahead and\n

All right, I'm going to save this file.

I'm not using VS Code at the moment.

I'm using another popular program\n

called Vim, which is a\ncommand line program that's

just in this black and white window.

Let me go ahead now and run\nPython of Speech.py, and--

DAVID J. MALAN: All right, so\nit's a little computerized

but it is speech that has been\nsynthesized from this example.

Let's change it a little\nbit to be more interesting.

Let's do something like this.

Let's ask the user for their name,\n

And then, let's use the little F\n

but Hello to that person's name.

Let me save my file, run\nPython of Speech.py, Enter.

DAVID J. MALAN: All right,\nso we pronounce my name OK

might struggle with different\nnames, depending on the phonetics.

But that one seemed to be OK.

Let's do something else with\nPython, using similarly

Let me go into today's examples.

And I'm going to go into a folder\n

And in this folder, that\nI've written in advance

are a few files,\nDetect.py, Recognize.py

and two full of photos,\nOffice.jpeg and Toby.jpeg.

If you're familiar with the\nshow, here, for instance

is the cast photo from The Office here.

Suppose I want to do\nsomething very Facebook-style

where I want to analyze\nall of the faces

or detect all of the faces in there.

Well, let me go ahead\nand show you a program

I wrote in advance,\nthat's not terribly long.

Much of it is actually comments.

But let's see what I'm doing.

I'm importing the Pillow library,\n

I'm importing a library called face\n

According to its documentation,\nyou go into that library

and you call a function\ncalled load image

file, to load something\nlike Office.jpeg

and then you can use the\nline of code like this.

Call a function called face\nlocations, passing the images input

and you get back a list of\nall of the faces in the image.

And then down here, a for loop,\nthat iterates over all of those

And inside of this loop, I\njust do a bit of trickery.

I figure out the top, right, bottom,\n

And then, using these\nlines of code here

I'm using that image library,\nto just draw a box, essentially.

And the code looks cryptic.

Honestly, I would have to look\nthis up to write it again.

But per the documentation, this\njust draws a nice little box

So let me go ahead and zoom out here,\n

All right, it's analyzing, analyzing,\n

And here is every face that my,\nwhat, 10 lines of Python code

Presumably the library\nis looking for something

maybe without a mask, that has\ntwo eyes, a nose, and a mouth

in some kind of arrangement,\nsome kind of pattern.

So it would seem pretty reliable, at\n

What if we want to look\nfor someone specific

for instance, someone that's\nalways getting picked on.

Well, we could do something like this.

Recognize.py, which is taking two files\n

of one person in particular.

And if you're trying to\nfind Toby in a crowd

here I conflated the program,\nsorry, this is the version that

draws a box around the given face.

Here we have Toby as identified.

Because that program, Recognize.py,\n

but long story short, it additionally\nloads as input Toby.jpeg

in order to recognize\nthat specific face.

And that specific face is a\ncompletely different photo

but it looks similar enough to the\n

Let's do one other that's a\nlittle sensitive to microphones.

Let me go into, how about my listen\n

And let's just run Python of Listen0.py.

I'm going to type in like David.

Oh, sorry, no, I'm going to--

Oh, no, that's the wrong version.

[CHUCKLES] OK, I looked like an idiot.

And if I say goodbye, I'm talking\n

Now it's detecting what I'm saying here.

So this first version of the program is\n

elif elif, and it's just asking\n

And that was my mistake\nwith the first example.

And then, I'm just checking,\nis Hello in the user's words?

Is how are you in the user's words?

Didn't see that, but it's there.

Is goodbye in the user's words?

Now let's do a cooler version, using a\n

Let's do version 2 of this, that\n

OK, so now it's artificial intelligence.

Now let's do something a\nlittle more interesting.

The third version of this program that\n

Hello, world, my name is David.

OK, so that time, it not\nonly analyzed what I said

but it plucked my name out of it.

Let's do two final examples.

This one will generate a QR code.

Let me go ahead and\nwrite a program called

QR.py, that very simply does this.

Let me import a library called OS.

Let me import a library called QR code.

Let me grab an image\nhere, that's QRcode.make.

And let me give you the URL of like a\n

Let me just type this,\nso I don't get it wrong.

OK, so if I now use this URL here,\nof a video on YouTube, making

sure I haven't made any\ntypos, I'm now going

to go ahead and do two\nlines of code in Python.

I'm going to first save that as\na file called QR.png, which is

a two dimensional barcode, a QR code.

And, indeed, I'm going\nto use this format.

And I'm going to use the OS.system\n

And if you'd like to take\nout your phone at this point

you can see the result of my barcode,\n

Hopefully from afar that will scan.

And I think that's an\nappropriate line to end on.

DAVID J. MALAN: This is CS50.

And this is week 7, the\nweek, here, of Halloween.

Indeed, special thanks to\nCS50's own Valerie and her mom

for having created this very festive\n

Today, we pick up where\nwe left off last time

which, recall, we introduced Python.

And that was our big transition\nfrom C, where suddenly things

started to look new again,\nprobably, syntactically.

But also, probably things\nhopefully started to feel easier.

Well, with that said, problem set\n

But hopefully you've begun to appreciate\n

You get more out of the box\nwith the language itself.

And that's going to be so\nuseful over the coming weeks

as we transition further to introducing\n

web programming next\nweek and the week after.

So that by term's end, and perhaps\neven for your final project

you really are building\nsomething from scratch

using all of these various\ntools somehow together.

So before we do that,\nthough, today, let's consider

what we weren't really able to\ndo last week, which was actually

create and store data ourselves.

In Python, we've played around with the\n

And you've been able to\nread in CSVs from disk

so to speak, that is, from files\n

But we haven't necessarily started\n

And that's a huge limitation, because\n

we've done thus far with\na couple of exceptions

have involved my providing input\n

But then nothing happens to it.

It disappears the moment\nthe program quits

because it was only\nbeing stored in memory.

But today, we'll start to focus all\n

that is, storing things\nin files and folders

so that you can actually\nwrite programs that remember

what it is the human did last time.

And ultimately, you can\nactually make mobile or web apps

that actually begin to grow, and\ngrow, and grow their data sets

as might happen if you get more and\n

To play, then, with this new capability\n

let's go ahead and\njust collect some data.

In fact, those of you\nhere in person, if you

want to pull up this URL\non your phone or laptop

that's going to lead\nyou to a Google Form.

And that Google Form is going to\n

And it's going to ask\nyou to categorize it

according to a genre, like comedy,\n

And this is useful,\nbecause if you've ever

used a Google Form before, or\n

it's a really useful mechanism at\n

and then ultimately, putting\nit into a spreadsheet form.

So this is a screenshot of\nthe form that those of you

here in person or tuning in on\nZoom are currently filling out.

It's asking only two questions.

What's the title of\nyour favorite TV show?

And what are one or more genres\ninto which your TV show falls?

And I'll go ahead and\npivot now to the view

that I'll be able to see as the\n

is quite simply a Google spreadsheet.

Google Forms has this nice\nfeature, if you've never noticed

that allows you to export your\ndata to a Google Spreadsheet.

And then from there, we\ncan actually grab the file

and download it to my\nown Mac or your own PC

so that we can actually play around\n

So in fact, let me go\nahead and slide over

to this, the live Google Spreadsheet.

And you'll see, probably, a whole\n

And if we keep scrolling, and\nscrolling, and scrolling--

There we go, up to 50 plus already.

If you need that URL again\nhere, if you're just tuning in

you can go to this URL here.

And in just a moment,\nwe'll have a bunch of data

with which we can start to experiment.

I'll give you a moment or so there.

Let me hang in there a little longer.

OK, we've got over 100 submissions.

Good, even more coming in now.

And we can see them coming in live.

Here, let me switch\nback to the spreadsheet.

The list is growing, and\ngrowing, and growing.

let me give Carter a moment to\nhelp me export it in real time.

Carter, just give me a heads\nup when it's reasonable for me

All right, and I'll begin\nto do this very slowly.

So I'm going to go up to the File\n

Download-- you can download a whole\n

But more simply, and the one\nwe'll start to play with here

So CSV files we used this past\nweek, why are they useful?

Now that you've played with them\n

what's the utility of a CSV file versus\n

AUDIENCE: Because it's just a text file?

DAVID J. MALAN: OK, so\nstorage is compelling.

A simple text file with ASCII or\n

DAVID J. MALAN: Yeah, well said.

It's just a simple text\nformat, but using conventions

like commas you can represent the\n

backslash ends invisibly\nat the end of your lines

you can create the idea of rows.

So it's a very simple\nway of implementing what

we might call a flat-file database.

It's a way of storing\ndata in a flat, that is

very simple file that's just\npure ASCII or Unicode text.

And more compellingly, I dare\nsay, is that with a CSV file

Something is portable in\nthe world of computing

if it means you can use it on a Mac\n

And portability is nice because if\n

there'd be a whole bunch of\npeople in this room and online

who couldn't download it because\n

Or if they have a Mac, or if it's\n

a PC user might not be\nable to download it.

So a CSV is indeed very portable.

So I'm going to go ahead and\ndownload, quite simply, the CSV

That's going to put it onto\nmy own Mac's Downloads folder.

And let me go ahead here, and in just a\n

Because it actually downloads\nit at a pretty large name.

And give me just one moment here,\nand you'll see that, indeed

on my Mac I have a file\ncalled favorites.csv.

I shortened the name real quick.

And now what I'm going to do is go\n

I'm going to open my File Explorer.

And if I minimize my window here for\n

is that you can just drag and drop a\n

And voila, it's going to\nautomatically upload it for you.

So let me go ahead and full\nscreen here, close my Explorer

temporarily close my Terminal window.

And you'll see here a\nCSV file, favorites.csv.

And the first row, by\nconvention, has whatever

the columns were in Google\nSpreadsheets, or Office 365

in Excel online, timestamp,\ncomma, title, comma, genres.

Then, we have timestamps,\nwhich indicates

when people started submitting.

Looks like a couple of people\nwere super eager to get

And then, you have the\ntitle next, after a comma.

But there's kind of a\ncuriosity after that.

Sometimes I see the genre\nlike comedy, comedy, comedy

but sometimes it's like crime, comma,\n

And those things are quoted.

And yet, I didn't do any quotes.

You probably didn't type any quotes.

Where are those quotes\ncoming from in this CSV file?

Why are they there if we infer?

DAVID J. MALAN: Yeah, so you\nhave a corner case, if you will.

Because if you're using\ncommas, as you described

to separate your data into what\nare effectively columns, well

you've painted yourself into\na corner if your actual data

So what Google has done, what\nMicrosoft does, what Apple does

is, they quote any strings\nof text that themselves

have commas so that these are\nnow English grammatical commas

So it's a way of escaping\nyour data, if you will.

And escaping just means to call\nout a symbol in a special way

so it's not misinterpreted\nas something else.

All right, so this is\nall to say that we now

have all of this data with which we\n

start calling a flat-file database.

So suppose I wanted to now\nstart manipulating this data

and I want to store it ultimately,\nindeed, in this CSV format.

How can I actually\nstart to read this data

maybe clean it up, maybe\ndo some analytics on it

and actually figure out, what's the most\n

here over the past few minutes?

Well, let me go ahead and close this.

Let me go ahead, then, and open up,\n

And let's code up a file\ncalled favorites.py.

And let's go ahead and iteratively start\n

and printing out what's inside of it.

So you might recall that we can do\n

to give myself some CSV\nreading functionality.

Then, I can go ahead and do something\n

that I want to open in read mode.

Quote, unquote, "r" means to read it.

And then, I can say as\nfile, or whatever other name

for a variable to say that\nI want to open this file

and essentially store some kind of\n

Then, I can give myself a\nreader, and I can say csv.reader

passing in that file as input.

And this is the magic of that library.

It deals with the process of opening\n

back something that you can just\n

I do want to skip the first row,\nand recall that I can do this.

Next, reader, is this little trick\n

Because the first one is special.

It said timestamp, title, genres.

That's not your data, that was mine.

But this means now that\nI've skipped that first row.

Everything hereafter is going\nto be the title of a show

that you all like, so let me do this.

For row in the reader, let's go\nahead and print out the title

of the show each of you typed in.

How do I get at the title of\nthe show each of you typed in?

It's somewhere inside of row.

So what do I want to\ntype next in order to get

at the title of the current\nrow just as a quick check here?

What do I want to type to\nget at the title of the row

keeping in mind, again, that it\nwas timestamp, title, genres?

DAVID J. MALAN: So row\nbracket 1 would give me

the second column, 0 index, that is,\n

So this program isn't\nthat interesting yet

but it's a quick and dirty way to\n

Let me actually just do a\nlittle bit of a check here

and see if it contains\nthe data I think it does.

Let me maximize my Terminal window here.

Let me run Python of\nfavorites.py, hitting Enter.

And you'll see now a purely\ntextual list of all of the shows

But what's noteworthy about it?

Specific shows aside,\njudgment aside as to people's

TV tastes, what's interesting or\nnoteworthy about the data that

might create some problems for us\n

and figure out what's the most popular?

How many people like this or that?

AUDIENCE: User errors [INAUDIBLE].

DAVID J. MALAN: Yeah,\nthere might be user errors

or just stylistic differences that\n

Let's see if I can see an\nexample on the screen here.

Yeah, so friends here is an all\n

We can sort of mitigate that.

But this is just a tiny example\nof where data in the real world

And that probably wasn't even a typo.

It was just someone not caring as much\n

Your users are going to type\nwhat they're going to type.

So let's see if we can't now begin\nto get at more specific data

and maybe even clean\nsome of this data up.

Let me go back into my file\ncalled favorites.py here

and let's actually do something a\n

Instead of a reader, recall that there\n

just a little more user friendly.

And it means I can type in dictionary\n

But now, when I iterate over this\n

When using a DictReader instead\nof a reader, recall, and this

is just a peculiarity\nof the CSV library

this gives me back, not a list\nof cells, but what instead

which is marginally more\nuser friendly for me?

I can now use open bracket,\nquotes, and the title.

Because what's coming back\nnow is a dict object, that is

a dictionary which has keys and values.

The keys of which are\nthe column headings.

The values of which are the\ndata I actually care about.

So this is just marginally\nbetter because, one, it's

just way more obvious to me, the\n

I don't remember what\ncolumn the title was.

That's something you're\ngoing to forget over time.

And God forbid someone changes the\n

the columns in Excel, or Apple\nNumbers, or Google Spreadsheets.

That's going to break all\nof your numeric indices.

And so a dictionary\nreader is arguably just

better design because it's\nmore robust against changes

and potential errors like that.

Now the effect of this change isn't\n

If I run Python of favorites.py,\n

But I've now not made any assumptions\n

Well, let's go ahead and now\nfilter out some duplicates.

Because there's a lot of commonality\n

see if we can't filter out duplicates.

If I'm reading a CSV file top to bottom,\n

I want to implement to\nfilter out duplicates?

It's not going to be quite as simple as\n

I'm going to have to build this.

But logically, if you're reading\na file from top to bottom

how might you go about, in\nPython or just any context

getting rid of duplicate values?

I could use a list and I could\nadd each title to the list

but first check if I put\nthis into the list before.

So let's try a little\nsomething like that.

Let me go ahead and create a variable\n

I'll call it titles, for instance,\ninitialize to an empty list

open bracket, close bracket.

And then, inside of my loop\nhere, instead of printing it out

let's start to make a decision.

So if the current row's\ntitle is in the titles list

I don't want to put it there.

And actually, let me invert the logic\n

So if it's not the case that\nrow bracket title is in titles

then, go ahead and do something like\n

And recall that we saw\n.append a week or so ago

where it just allows you to\nappend to the current list.

And then, what can I do at\nthe very end, after I'm all

done reading the whole file?

Why don't I go ahead and\nsay, for title in titles

go ahead and print\nout the current title?

So it's two loops now, and we can come\n

But let me go ahead here and\nrerun Python of favorites.py.

Let me increase the size of my Terminal\n

I don't think I'm seeing\nduplicates, although I

am seeing some near duplicates.

For instance, there's Friends again.

And if we keep going, and\ngoing, and going, and going

Oh, interesting, so that's curious\n

and I have this one here, too.

So how might we clean this up further?

I like your instincts, and\nit's a step closer to it.

What are we going to have\nto do to really filter out

AUDIENCE: You could set\neverything to lower [INAUDIBLE]..

What are the common\nmistakes to summarize?

We could ignore the capitalization\naltogether and maybe

just force everything to lowercase,\nor everything to uppercase.

Doesn't matter which, but\nlet's just be consistent.

And for those of you who might have\n

the spacebar at the beginning of\nyour input or even at the end

Stripping whitespace is a common\n

So let me go back into my\ncode here, and let me go ahead

and tweak the title a little bit.

Let me say that the current\ntitle inside of this loop

is not going to be just\nthe current row's title.

But let me go ahead and strip off,\n

If you read the documentation for the\n

It gets rid of whitespace to the\nleft, whitespace to the right.

And then, if I want to force\neverything to maybe uppercase

I can just uppercase the entire string.

And remember, what's handy about Python\n

calls together by just\nusing dots again and again.

And that just takes\nwhatever just happened

like the whitespace got stripped\noff, then, it additionally

uppercases the whole thing as well.

So now, I'm going to just check whether\n

And if not, I'm going to go\nahead and append that title

massaged into this different\nformat, if you will.

So I'm throwing away some information.

I'm sacrificing all of the\nnuances of your grammar and input

But at least I'm trying to\ncanonicalize size, that is

standardize what the\ndata actually looks like.

So let me go ahead and run Python\n

Oh, and this is just user error.

Maybe you haven't seen this before.

This just looks like\na mistake on my part.

I meant to say not even uppercase.

The function is called upper,\nnow that I think of it.

Let's go and increase the size\nof the Terminal window again.

And now, it's a little more overwhelming\n

But I don't think I'm seeing\nmultiple Friends, so to speak.

There's one Friends\nup here and that's it.

I'm back up at my prompt already.

So we seem now to be\nfiltering out duplicates.

Now, before we dive in further and\n

what else could we have done?

Well, it turns out that\nin Python 2 you often

do get a lot of functionality\nbuilt into the language.

And I'm kind of implementing\nmyself the idea of a set.

If you think back to\nmathematics, a set is typically

something with a bunch of values\n

Recall that Python\nalready has this for us.

And we saw it really briefly\nwhen I whipped up the dictionary

implementation a couple of weeks back.

So I could actually define my titles\n

and this would just modestly allow\n

that I don't have to bother\nchecking for duplicates anyway.

I can instead just say\nsomething like, titles.add

the current title, like this.

Marginally better design if you know\n

getting more functionality out of this.

All right, so let's clean\nthe data up further.

We've now gone ahead and fixed\nthe problem of case sensitivity.

We threw away whitespace in case\nsomeone had hit the spacebar

Let's go ahead now and sort these\n

So instead of just printing out\nthe titles in the same order

you all inputted them, but filtering\n

and use another function in\nPython you might not have seen

which is literally\ncalled sorted, and will

take care of the process of\nactually sorting titles for you.

Let me go ahead and increase\nthe font size of my Terminal

run Python of favorites.py,\nand hit Enter.

And now you can really see how many of\n

Now it's a little easier\nto wrap our minds around

just because it's at least\nsorted alphabetically.

But now you can really see some of\n

But a few of you decided to stylize\n

Brooklyn 99 is a couple\nof different ways here.

And I think if we keep going we'll see\n

did not fix by focusing on\nwhitespace and capitalization alone.

So already here, this is only,\nwhat, 100 plus, 200 rows.

Already real-world data\nstarts to get messy quickly

and that might not bode\nwell when we actually

want to keep around real\ndata from real users.

You can imagine an actual\nwebsite or a mobile application

dealing with this kind\nof thing on scale.

Well, let's go ahead and do this.

Let's actually figure out the\npopularity of these various shows

by now iterating over my data, and\n

We're going to ignore the problems\n

Sorry, yeah, Avatar,\nwhere there was things

that were different beyond just\nwhitespace and capitalization.

But let's go ahead and\nkeep track of, now

how many of you inputted\neach of these titles.

I'm still going to take this\napproach of iterating over

the CSV file from top to bottom.

We've used a couple of\ndata structures thus far

a list to keep track of titles,\n

But what if I now want to keep\naround a little more information?

For each title, I want to keep around\n

I'm throwing away the total\nnumber of times I see these shows.

How could I start to keep that around?

AUDIENCE: Use a dictionary.

DAVID J. MALAN: We could\nuse a dictionary, and how?

DAVID J. MALAN: Perfect,\nreally good instincts.

Using a dictionary,\ninsofar as it lets us

store keys and values, that is,\n

This is why a dictionary\nor hash tables more

generally are such a useful,\npractical data structure.

Because they just let you remember\n

So if the keys are going\nto be the titles I've seen

the values could be the number of\n

And so it's kind of like just\n

For instance, if I were going\nto do this on a piece of paper

I might just have two\ncolumns here, where

maybe this is the title that I've\n

This is, in effect, a\ndictionary in Python.

It's two columns, keys on the\nleft, values on the right.

And this, if I can implement\nin code, will actually

allow me to store this data, and\n

to figure out which is the most popular.

Let me go ahead and change my titles\n

Let's have it be a dictionary instead,\n

two curly braces that are empty gives\n

I think most of my\ncode can stay the same.

But down here, I don't want\nto just blindly add titles

I somehow need to keep\ntrack of the count.

And unfortunately, if I just\ndo this-- let's do titles

bracket, title, plus equals 1.

This is a reasonable\nfirst attempt at this.

If titles is a dictionary and I want\n

the syntax for that, like before,\nis titles, bracket, and then

the key you want to use to\nindex into the dictionary.

It's not a number in this case,\nit's an actual word, a title.

And you're just going\nto increment it by one

and then eventually I'll come\nback and finish my second loop

and do things in terms of the order.

But for now, let's just keep\ntrack of the total counts.

Let me go ahead and\nincrease my Terminal window.

Let me do Python of\nfavorites.py and hit Enter.

How I Met Your Mother is\ngiving me a key error.

And in fact, just to give a\nlittle bit of a breadcrumb here

Let me open up the CSV\nfile again real quickly.

And wow, we didn't even get\npast the second row in the file

or the first show in the file.

Notice that How I Met Your\nMother, somewhat lowercased

is the very first show in therein.

What's your instinct for\nwhy this is happening?

AUDIENCE: You don't\nhave a starting point.

DAVID J. MALAN: I don't\nhave a starting point.

I'm blindly indexing into the dictionary\n

that doesn't yet exist\nin the dictionary.

And so Python throws\nwhat's called a key error

because the key you're trying\nto use just doesn't exist yet.

So logically, how could we fix this?

We got half of the problem solved,\n

case of nothing being there.

AUDIENCE: Creating a counter.

DAVID J. MALAN: Creating a--

DAVID J. MALAN: Creating\nthe counter itself.

So maybe I could do something like this.

Let me close my Terminal window\nand let me ask a question first.

If the current title is in the\n

that's going to give me a\ntrue-false answer it turns out.

Then, I can safely say, titles,\nbracket, title, plus equals 1.

And recall, this is just shorthand\n

That's the same thing as this\nbut it's a little more succinct

Else, if it's logically not the case\n

dictionary, then I probably want to\n

Feel free to just shout it out.

I just have to put some value there\n

So now that I've got this\ngoing on, let me go ahead

and undo my sorting temporarily.

And now let me go ahead and do this.

I can, as a quick check, let me\ngo ahead and just run the code

as is, Python of favorites.py.

It's printing correctly, no key\nerrors, but it's not sorted.

And I'm not seeing any of the counts.

Let me just quickly add\nthe counts, and there's

a couple of ways I could do this.

I could, say, print out the title, and\n

how about just, comma,\ntitles, bracket, title?

So I'm going to print\ntwo things at once

both the current title\nin the dictionary

and whatever its value\nis by indexing into it.

Let me increase my Terminal window.

Let me run Python of\nfavorites.py, Enter, and OK.

None of you said a whole\nlot of TV shows, it seems.

What's the logical error here?

What did I do wrong if I\nlook back at my code here?

To summarize, I initialized the\n

but I should have initialized it at\n

Or I should change my code a bit.

So for instance, if I go back\nin here, the simplest fix

is probably to initialize to 1,\n

obviously, I'm seeing this\ntitle for the very first time.

Or I could change my logic a little bit.

I could do something like this instead.

If the current title is not in titles,\n

And then I could get rid of\nthe else, and now blindly index

Because now, on line 11, I\ncan trust that lines 9 and 10

took care of the initialization\nfor me if need be.

This one's a little nicer, maybe\nbecause it's one line fewer.

But I think both approaches are\n

But the key thing, no\npun intended, is that we

have to make sure the key exists\n

So otherwise, everyone would have\n

how many people said the same thing.

Now the code is as it should be.

So let me go ahead and open\nup my Terminal window again.

Let me run Python of favorites.py,\n

Some shows weren't that popular.

There's just 1s and maybe 2s.

But I bet if we sort these things we\n

Well, turns out, when dealing\nwith a dictionary like this--

let's go ahead and just\nsort the titles themselves.

So let's reintroduce the sorted function\n

Let me go ahead now and\nrun Python of favorites.py.

Now it's just a little easier\nto wrap your mind around it

because at least it's alphabetical.

But it's not sorted by\nvalue, it's sorted by key.

But sure enough, if we scroll\ndown, there's something down here

for instance, like,\nlet's see, The Office.

That's definitely\ngoing to be a contender

for most popular, 15 responses.

But let's see what's actually\ngoing to bubble up to the top.

Unfortunately, the sorted function\n

But it turns out, in Python,\nif you read the documentation

for the sorted function,\nyou can actually

pass in other arguments that\ntell it how to sort things.

For instance, if I want to\ndo things in reverse order

I can add a second parameter to\n

You literally say,\nreverse equals true, so

that the position of it in the\n

If I now rerun this after\nincreasing my Terminal window

you'll see now that it's\nin the opposite order.

Now adventure and Anne\nwith an E is at the bottom

of the output instead of the top.

How can I tell it to sort\nby values instead of by key?

Well, let's go ahead and do this.

Let me go ahead and define a function.

I'm just going to call it\nf to keep things simple.

And this f function is going\nto take a title as input.

And given a given title, it's going\n

So actually, maybe a better name\nfor this would be get value

and/or we could come up\nwith something else as well.

The purpose of the get\nvalue function, to be clear

is to take it as input a title and\n

Well, it turns out that the\nsorted function in Python

according to its documentation,\nalso takes a key parameter

where you can pass in, crazy\nenough, the name of a function

that it will use in order to determine\n

or by the value, or in other cases,\n

So there's a curiosity here,\nthough, that's very deliberate.

Key is the name of the\nparameter, just like reverse

was the name of this other parameter.

The value of it, though,\nis not a function call.

Notice I am not doing\nthis, no parentheses.

I'm instead passing in get value,\n

And this is a feature of Python\nand certain other languages.

Just like variables, you can\nactually pass whole functions

around so that they can be called\n

So what this means is that the\n

they didn't know what you're\ngoing to want to sort by today.

But if you provide them with a function\n

their sorted function\nwill use that function

to determine, OK, if you don't want to\n

This is going to tell\nit to sort by the value

by returning the specific\nvalue we care about.

So let me go ahead now and rerun this\n

Here we have now an example\nof all of the titles you all

typed in, albeit forced to uppercase\n

And now, The Office is\nan easy win over Friends

versus Community, versus Game of\nThrones, Breaking Bad, and then

a lot of variants thereafter.

So there's a lot of steps to go through.

This isn't that bad once\nyou've done it once

and you know what these\nfunctions are, and you

know that these parameters exist.

That's 17 lines of code\njust to analyze a CSV file

that you all created by way of\nthose Google Form submissions.

But it took me a lot of work just\n

And indeed, that's going\nto be among the goals

for today, ultimately, is, how\ncan we just make this easier?

It's one thing to learn\nnew things in Python

but if we can avoid writing\ncode, or this much code

that's going to be a good thing.

And so one other technique\nwe can introduce here

that does allow us to\nwrite a little less code

is, we can actually get\nrid of this function.

It turns out, in Python, if you\njust need to make a function

but it's going to be used and\nthen essentially thrown away

it's not something you're going\n

it's not like a library function\nthat you want to keep around--

you can actually just do this.

You can change the value\nof this key parameter

to be what's called a\nlambda function, which

is a fancy way of saying a function\n

Well, it's kind of stupid that\nI invented this name on line 13.

I used it on line 16, and\nthen I never again used it.

If there's only being used in one place,\n

So if you instead, in\nPython, say lambda

and then type out the\nname of the parameter

you want this anonymous\nfunction to take

you can then say, go ahead\nand return this value.

Now let's notice the\ninconsistencies here.

When you use this special lambda\nkeyword that says, hey Python

give me an anonymous function,\na function with no name

it then says, Python, this anonymous\n

Notice there's no parentheses.

And that's deliberate, if confusing.

It just tightens things up a little bit.

Notice that there's no return keyword,\n

up a bit, albeit inconsistently.

But this line of code\nI've just highlighted

is actually identical in\nfunctionality to this.

But it throws away the word [INAUDIBLE].

It throws away the word get value.

It throws away the parentheses, and\n

And it's well suited\nfor a problem like this

where I just want to pass in\na tiny little function that

But it's not something\nI'm going to reuse.

It doesn't need multiple\nlines to take up space.

It's just a nice, elegant one liner.

That's all a lambda function does.

It allows you to create an anonymous\n

And then the function you're passing it\n

Indeed, if I run Python of favorites.py\n

the result is exactly the same.

And we see at the bottom here\nall of those small results.

Are any questions, then, on\nthis syntax, on these ideas?

The goal here has been to write\n

to analyze or clean up data like this.

DAVID J. MALAN: Could you use the lambda\n

It's really meant for one\nline of code, generally.

So you don't use the return keyword.

You just say what it\nis you want to return.

DAVID J. MALAN: Good question.

Could you do more in\nthat one line if it's

got to be a more involved algorithm?

Yes, but you would just ultimately\nreturn the value in question.

In short, if it's getting\nat all sophisticated

you don't use the lambda\nfunction in Python.

You go ahead and actually\njust define a name for it

even if it's a one-off name.

JavaScript, another language\nwe'll look at in a few weeks

makes heavier use, I dare\nsay, of lambda functions.

And those can actually be\nmultiple, multiple lines

but Python does not\nsupport that instinct.

So let's go ahead and\ndo one other thing.

Office was clearly popping out\nof the code here quite a bit.

Let's go ahead and write a\nslightly different program

that maybe just focuses on\nThe Office for the moment

So let me go ahead and throw most of\n

when I'm inside of my inner loop.

And let me go ahead, and I don't\n

All I want to do is focus\non the current title.

How could I detect if\nsomeone likes The Office?

Well, I could say something like--

We'll just focus on The Office.

If title equals, equals The Office,\n

There's no dictionary involved now.

It's just a simple integer variable.

And then, down here\nI'll say something like

number of people who like The\nOffice is, whatever this value is.

And I'll put in counter in\ncurly braces, and then I'll

turn this whole thing into an F string.

All right, let me go ahead and run this.

Python of favorites.py, Enter.

Number of people who\nlike The Office is 15.

But let's go ahead now and\ndeliberately muddy the data a bit.

All of you were very nice in\nthat you typed in The Office.

But you can imagine\nsomeone just typing Office

for instance, maybe there, maybe there.

And many people might just\nwrite Office, you could imagine.

Didn't happen here, but\nsuppose it did, and probably

would have if we had even more\nand more submissions over time.

Now let's go ahead and rerun this\n

Now only 13 people like The Office.

The data is now as I mutated it to have\n

How could I change my Python code to\n

What could I change up here in\norder to improve this situation?

AUDIENCE: You write\nthe title [INAUDIBLE]..

DAVID J. MALAN: Yeah, so I could\n

If title equals The Office,\nor title equals, equals just

And I'm still don't have to\nworry about capitalization.

I don't have to worry about spaces\n

Now I can go ahead and rerun this code.

Let me go run it a third time.

You could imagine this\nnot scaling very well.

Avatar had three different\n

if we dug deeper that there\nmight have been more variants.

Could we do something a\nlittle more general purpose?

Well, we could do something like this.

this is kind of a cool thing\nyou can do with Python.

It's very English-like, just ask\nthe question, albeit tersely.

This, interesting, just\ngot me into trouble.

Now, all of a sudden, we're up to 16.

Does anyone know what the other one is?

AUDIENCE: Someone put V Office.

DAVID J. MALAN: What Office?

AUDIENCE: Someone entered\na V Office, [INAUDIBLE]..

DAVID J. MALAN: Oh, interesting.

OK, this one's actually going\nto be hard to correct for.

I can't really think of a general--

well, this is actually a good\nexample of data gets messy fast.

And you could imagine doing\nsomething where, OK, we

could have like 26 conditions if someone\n

You could imagine doing that.

But then there's surely going to\n

So that's actually a hard one to fix.

But it turns out we got lucky and now\n

But the data is itself messy.

Let me show another way that just\n

It turns out that there's this feature\n

among them, called regular expressions.

And this is actually a\nreally powerful technique

that we'll just scratch\nthe surface of here.

But it's going to be really useful,\n

in web programming, any time you want\n

And actually, just to make\nthis clear, give me a moment

before I switch screens here.

And let me open up a\nGoogle Form from scratch.

Give me just a moment to\ncreate something real quick.

If you've never noticed this\nbefore when creating a Google Form

And if you want the user\nto type in something

very specific as a short\ntext answer like this

you might know that there's toggles\nlike this in Google's world

Or you can do response validation.

You could say, what's your email?

And then you could say something\nlike, text is an email.

So here's an example in Google Forms\n

But a feature most of you have probably\n

is this thing called a\nregular expression, where

you can actually define a pattern.

And I could actually reimplement that\n

I can say, let the user type in anything\n

then something else, then a\nliteral period, then, for instance

So it's very cryptic,\nadmittedly, at first glance.

But this means any\ncharacter 0 more times.

This means any character 0 more times.

This means a literal\nperiod, because apparently

dot means any character in\nthe context of these patterns.

Then this thing means any\ncharacter 0 more times.

So I should actually be\na little more nitpicky.

You don't want 0 or more times,\nyou want 1 or more times.

So this with the plus means\nany character 1 or more time.

So there has to be something there.

And I think I want the same thing\n

Or heck, if I want to restrict this\n

I could change that last\nthing to literally .edu.

And so long story short,\neven though this looks

I'm sure, pretty cryptic, there's\n

and JavaScript, and Java, and other\n

patterns in a standardized way.

And this pattern is actually something\n

And let me switch back to\nPython for a second just

to do the same kind of idea.

Let me toggle back to my code here.

Let me put up, for instance, a\nsummary of what it is you can do.

And here's just a quick summary\n

A period may represent any character.\n

So the dot means anything,\nso it can be A or nothing.

It can be A, B, A, B, C. It can be any\n

Change that to a plus and you now\n

Question mark means\nsomething is optional.

Caret symbol means start matching at\n

Dollar sign means stop matching\nat the end of the user's input.

So we won't play with\nall of these just now.

But let me go over here and\nactually tackle this Office problem.

Let me go ahead and import a new library\n

And then, down here, let me say this.

Let's just search for Office, quote,\n

Then we're going to go ahead\nand increase the counter.

So it turns out that the\nregular expression library

has a function called search that\n

and then, as its second\nargument the string you

want to analyze for that pattern.

So it's sort of looking for a needle\n

Let me go ahead now and run this\nversion of the program, Enter.

And now I screwed up because I forgot\n

Number of people who\nlike The Office is now 0.

thank you-- big step backwards.

I forced all my input to uppercase,\n

So we'll come back to\nother approaches there.

OK, now we're back up to 16.

But I could even, let's say--

I could tolerate just The Office.

How about this, or how about\nsomething like, or The Office?

And let me use these\nother special characters.

This caret sign means the\nbeginning of the string.

This dollar sign weirdly\nrepresents the end of the string.

I'm adding in some parentheses just\n

And this is saying start matching\n

Check if the beginning of the string is\n

And then, you better be\nat the end of the string.

So they can't keep typing words\nbefore or after that input.

Let me go ahead and rerun the program.

And now we're down to 15, which\nused to be our correct answer

but then we noticed The V Office.

It's going to be messier\nto deal with that.

How about if I tolerate any\ncharacter represented by dot

Now if I rerun it, now I really\nhave this expressive capability.

So this is only to say, there are so\n

And some of these tools are\nmore sophisticated than others.

This is one that you've actually\n

in the context of Google\nForms for years if you're

in the habit of creating these for\n

But it's now something\nyou can start to leverage.

And we're just scratching the surface\n

But let's now do one final example\n

And let's actually\nwrite a program that's

a little more general purpose that\n

and figure out its popularity.

So let me go ahead and simplify this.

Let's get rid of our\nregular expressions.

Let's go ahead and continue\ncapitalizing the title.

at the beginning of this program,\n

So title equals, let's\nask the user for input

which is essentially the same thing\n

And then whatever they type in,\n

and uppercase the thing again.

And now, inside of my loop, I\ncould say something like this.

If the current row's title after\n

it to uppercase, too, equals\nthe user's title, then, go ahead

and maybe increment a counter.

So I still need that counter back.

So let me go ahead and define this\n

And then, at the very\nend of this program

let me go ahead and print\nout just the popularity

of whatever the human typed in.

So again, the only difference is\n

I'm initializing my\ncounter to 0, then I'm

searching for their\ntitle in the CSV file

by doing the same massaging of the\n

and getting rid of the whitespace.

So now, when I run Python\nof favorites.py, Enter

I could type in the office all lowercase\n

Because I'm the one that went in and\n

If we fixed those, we\nwould be back up to 15.

If we added support for The V\n

All right, any questions then\non these various manipulations?

And if you're feeling\nlike, oh, my god, this

is so much Python code just to do\n

And indeed, even though\nit's a powerful language

and can solve these kinds of problems,\n

just to ask a single question like this.

But any questions on how we did\n

Let's take a five-minute break here.

When we come back, we'll do it better.

And the rest of today\nis ultimately about, how

can we store, and manipulate,\nand change, and retrieve data

more efficiently than we might\nby just writing raw code?

This isn't to say that you shouldn't\n

And in fact, it might be super common\n

from users that you might\nwant to clean it up.

And maybe the best way to do that is\n

you can make all of the\nrequisite changes and fixes

like we did with The Office,\nfor instance, again and again

and reuse that code, especially\nif more and more submissions are

But another theme of\ntoday, ultimately, is

that sometimes there are different,\n

And in fact, now at\nthis point in the term

as we begin to introduce not\njust Python, but in a moment

a language called SQL, and next\n

and the week after that, synthesizing\n

together is to just kind\nof paint a picture of how

you might decide what the trade-offs are\n

Because undoubtedly you can\nsolve problems moving forward

in many different ways\nwith many different tools.

So let's give you another\ntool, one with which

you can implement a proper\nrelational database.

What we just saw in\nthe form of CSV files

are what we might call\nflat-file databases.

Again, just a very simple file, flat\n

And that is all ultimately\nstoring ASCII or Unicode text.

A relational database, though,\nis something that's actually

closer to a proper spreadsheet program.

A CSV is an individual\nsheet, if you will

from a spreadsheet when you export it.

If you had multiple\nsheets in a spreadsheet

you would have to export multiple CSVs.

And that gets annoying\nquickly in code if you

have to open up this CSV,\nthis CSV, all of which

represent different sheets or\ntabs in a proper spreadsheet.

A relational database is more\nlike a spreadsheet program

that you, a programmer,\nnow can interact with.

You can read data from it, and you\n

tables storing all of your data.

So whereas Excel and numbers\nin Google spreadsheet

are meant to be reused really by humans\n

clicking, and pointing, and\nmanipulating things graphically

a relational database\nusing a language called

SQL is one in which the programmer\nhas similar capabilities

Specifically, using a language\ncalled SQL, and at a scale

that's much grander\nthan spreadsheets alone.

In fact, if you try on your Mac\n

got tens of thousands\nof rows, it'll probably

work fine, hundreds of thousands\n

At some point your Mac or\nPC is going to struggle

to open particularly large data sets.

And that, too, is where\nproper databases come

into play and proper\nlanguages for databases come

into play, when it's all about scale.

And indeed, most any mobile app or\n

might write should probably plan\n

So we need the right\ntools for that problem.

So fortunately, even though we're\n

it only does four things fundamentally,\n

SQL, this language for\ndatabases, supports the ability

to create data, read data,\nupdate data, and delete data.

There's a few more keywords that\n

But at the end of the\nday, even if you're

starting to feel like this\nis a lot very quickly

it all boils down to these\nfour basic operations.

And the four commands\nin SQL, if you will

functions in a sense that implement\n

They're almost the same but\nwith some slight variance.

The ability to create or insert data\n

Delete is the same, but drop\nis also a keyword as well.

So we'll see these and\na few other keywords

in SQL that, at the end of the day, just\n

data using verbs, if\nyou will, like these.

So to do that, what's\nthe syntax going to be?

Well, we won't get into the\nweeds too quickly on this.

But here's a representative\nsyntax of how

you can create using this\nlanguage called SQL, in your very

own database, a brand new table.

This is so easy in Excel, and Google\n

You want a new sheet, you\nclick the plus button.

You give it a name,\nand boom, you're done.

In the world of programming, though, if\n

spreadsheet in the computer's memory,\n

like a sheet, that has a name, and then\n

But unlike Google Spreadsheets,\nand Apple Numbers, and Excel

you have to decide as the\nprogrammer what types of data

you're going to be storing\nin each of these columns.

Now even though Excel,\nand Google Spreadsheets

and Numbers does allow you to format\n

it's not strongly typed data like it\n

And heck, even in Python\nthere's underlying data types.

Even if you don't have\nto type them explicitly

databases are going to want to\nknow, are you storing integers?

Are you storing real numbers or floats?

Because especially as your\ndata scales, the more hints

you give the database about your\n

the faster it can help you\nget at and store that data.

So types are about to\nbe important again

but there's not going to be\nthat many of them, fortunately.

Now how can I go about converting,\nfor instance, some real data

like that from you,\nmy favorites.csv file

into a proper relational database?

Well, it turns out that\nusing SQL I can do this

in VS Code on my own Mac,\nor PC, or in the cloud

here by just importing\nthe CSV into a database.

We'll see eventually\nhow to do this manually.

For now, I'm going to use\nmore of an automated process.

So let me go over to VS Code here.

Let me type ls to see\nwhere we left off before.

I had two files favorites.csv, which\n

Recall that I made a couple of changes.

We deleted a couple of Thes\nfrom the file for The Office.

But this is the same file\nas before, and then we

have favorites.py, which\nwe'll set aside for now.

I'm going to go ahead now\nand run a command SQLite3.

So in the world of\nrelational databases, there's

many different products out there,\nmany different software that

implements the SQL language.

There's something called MySQL\n

Facebook, for instance,\nused it early on.

PostgreSQL, Microsoft\nAccess Server, Oracle

and maybe a whole bunch\nof other product names

you might have encountered\nover time, which

is to say there's many different\ntypes of tools, and servers

and software in which you can use SQL.

We're going to use a very lightweight\n

This is the version of\nSQL that's generally

used on iPhones and\nAndroid devices these days.

If you download an app that stores\ndata like your own contacts

typically is stored using SQLite.

Because it's fairly lightweight,\n

thousands, even tens of\nthousands of pieces of data

even using this lightweight\nversion thereof.

SQLite3 is like version 3 of this tool.

We're going to go ahead and run SQLite3\n

It's conventional in the world of\n

I'm going to create a\ndatabase called favorites.db.

Once I'm inside of the program, now I'm\n

Again, not something\nyou have to memorize

just something you\ncan look up as needed.

And then, I'm going to\nimport favorites.csv

into a table, that is, a sheet, if\n

Now I'm going to hit Enter and I'm\n

Now I have three files\nin my current directory--

the CSV file, the Python file\nfrom before, and now favorites.db.

But if I did this right, all of the\n

has now been loaded into a proper\ndatabase where I can now use

this SQL language to access it instead.

So let's go ahead again and run SQLite3\n

And now, at the SQLite\nprompt I can start

to play around and\nsee what this data is.

For instance, I can\nlook, by typing .schema

at what the schema is of\nmy data, what's the design.

Now no thought was put into the\n

because I automated the whole process.

Once we start creating\nour own databases we'll

give more thought to the data\n

But we can see what SQLite\npresumed I wanted just

by importing the data by default.

What the import command did for me a\n

It automated the process of creating\n

And then notice, in parentheses\nit gave me three columns--

timestamp, title, and genres, which\n

All three of which have\nbeen decreed to be text.

Again, once we're more comfortable\nwe'll create our own tables

choose our own types and column names.

But for now, I just automated\nthe whole process just

to get us started by using this\nbuilt-in import command as well.

So what now can I begin to do?

Well, if I wanted to, for instance,\n

I might execute a couple\nof different commands.

Let me find the right one here--\none of which would be select.

Select being one of our\nmost versatile tools

to select data from this database.

So if I have these three\ncolumns here-- timestamp

title, and genres, suppose I\nwant to select all of the titles.

Doing that earlier in Python\nrequired importing the CSV library

opening the file, creating a reader or\n

adding every title to a dictionary\nor just printing it out

There was a dozen or so lines\nof code when we first began.

Select title from\nfavorites, semicolon, done.

So now, with this particular\n

and it's simulating what it looks like\n

Select title from\nfavorites is a distillation

in a different language called\nSQL of all the lines of code

I wrote early on when we first\n

SQL is therefore optimized for\n

and ultimately, deleting data.

So here's perhaps a better tool\n

Tossing it into a more\npowerful, versatile format

might allow you now to get\nmore work done more quickly

without having to reinvent the wheel.

Someone else has figured out\nhow to select data like this.

Well, let me go ahead and pull\n

Give me one second to find this.

So suppose I want to now select\ndata a little more powerfully.

So here's what I just\ndid in a canonical way.

So select typically works like this.

You select columns from a\nspecific table, semicolon.

Unfortunately, stupid\nsemicolons are back.

Select columns from table then, is\n

More specifically, I selected one\n

Favorites is the name of the table.

Suppose I wanted to get two things, like\n

I could instead do select title,\ncomma, genres from favorites

and then, a semicolon, and Enter.

It's going to look a\nlittle ugly on my screen

because some of these titles and--

OK, one of you really went\nall out with Community.

You can see that it's just\nwrapping in an ugly way

but it's just now\nshowing me two columns.

If we scroll up to the very top\nagain, the left most of one

Black Mirror went all out, too.

And now, OK, we're going to\nhave to clean some of these up.

Game of Thrones, good comedy, yes.

Keep going, keep going, keep going.

So now we've selected two of\nthe columns that we care about.

OK, so it's crazy wide because\nof all of those genres.

But it allows me to select\nexactly the data I want.

Let's go back to the titles, though,\n

For instance, it turns out, using\n

You've got a lot of functions, similar\n

where you can have formulas.

SQL provides you with some\nof the same heuristics that

allow you to apply operations\nlike these on entire columns.

For instance, you can take\naverages, count the total

get the distinct values, force\n

So let's try distinct, for instance.

Let me go back to my Terminal,\nand let's say, select

how about the distinct titles\nfrom the favorites table?

I didn't bother selecting\nthe genres because I

want it to be a little prettier.

And you can see here that we\nhave just the distinct titles

except for issues of formatting.

So whitespace is going\nto be an issue again.

Capitalization is going\nto be a thing again.

One of the things I was doing in Python\n

and then getting rid of whitespace.

But we could combine some of these.

I could do something like\nforce every title to uppercase

then get the distinct value.

And that's actually going to get\n

And again, I did it all in\none simple line that was fast.

So let me pull up at the\nbottom of the screen again.

I selected distinct upper\ntitles from favorites

and that did everything for\nme at once in just one breath.

Suppose I want to get the total\nnumber of counts of titles.

How about select count of all\nof those titles from favorites?

Semicolon, Enter, and now\nyou get back a mini table

that contains just your\nanswer, 158 in this case.

So that's the total\nnumber of, not distinct

but total titles that\nwe had in the file.

And we could continue to manipulate\n

But there's also additional\nfiltration we can do.

We can also qualify our selections by\n

So just as in Scratch, and C, and\n

you can have the same in SQL as well,\n

Like allows me to do approximations.

If I want to get something\nthat's like The Office

but not necessarily\nT-H-E, space, Office

I could do pattern\nmatching using like here.

Order by, limit, and grouped by are\n

So let me go back and do\na couple of these here.

How about, let me just get, oh, I don't\n

but limit it to 10 results.

That might be one thing that's helpful\n

of the data at the top there instead.

How about, select all of the titles\n

is like, quote, unquote, "Office?

And this will give me only two answers.

Those are the two rows, recall, that I\n

Notice that like allows me too\ntolerate uppercase and lowercase.

Because if I instead\njust use the equal sign

and in SQL a single equal sign\ndoes, in fact, mean equality.

For comparison's sake,\nit's not doing assignment.

This is not how you assign data in SQL.

I got back no answers there.

So indeed, the equal sign\nis giving me literal answers

that searches just for what I typed in.

How could I get all of these?

Well, similar in spirit to regular\n

in SQL, I could do something like this.

I can select the title from favorites\n

But I can add, a bit weirdly, percent\n

So the language SQL supports the\nsame notion of pattern matching

but much more limited out of the box.

If we want more powerful\nregular expressions

we probably do want\nto use Python instead.

But the percent sign here\nmeans 0 or more characters

on the left, 0 or more\ncharacters on the right.

So this will just grab any title that\n

And now I get all 16, it would\nseem, of those results, again.

Well, I can just get the\ncount of those titles

and get back that\nanswer instead as well.

So again, it takes some\ngetting used to, the vocabulary

and the syntax that you can use.

There's these building\nblocks and others.

But SQL is really designed, again,\n

For instance, I've never really\n

So right now if I do select,\nhow about title from favorites

where title like, quote, unquote,\n

We can see that there's\na whole bunch of them.

Let's just do a quick count.

Well, delete from favorites.

OK, you and me, delete from favorites,\n

Nothing seems to happen,\nbut bye-bye Friends.

So now we've actually changed the data.

And this is what's compelling\nabout a proper database.

Yes, you could technically write Python\n

You can change using quote,\nunquote, "A" for append

or quote, unquote, "W" for\nwrite, instead of quote, unquote

But it's definitely a little more\ninvolved to do that in Python.

But with SQL, you can update\nthe data in real time.

And if I were actually running a\n

for a mobile app, that\nchange, theoretically

would be reflected everywhere\non your own devices

if you're somehow talking\nto this application.

So that's the direction we're headed.

This other thing has been bothering me.

So select, how about title from\nfavorites, where title equals

How about we update\nfavorites by setting title

equal to The Office, where title\n

And now, if I select\nthe same thing again

I can go up and down with\nmy arrow keys quickly.

Now there is no The V Office.

We've actually changed that value.

Select genres from favorites,\nwhere the title is title

equals Game of Thrones, semicolon.

These were kind of long, and I\n

So how about we update favorites,\nset genres equal to, sure

action, adventure, sure, drama?

Fantasy, sure, thriller, war.

OK, anything really but\ncomedy, I would say.

Let's go ahead and hit Enter now.

And now, if I select genres again, same\n

So whether or not that\nis right is probably

a bit subjective and argumentative.

But I have at least cleaned up my\n

Create, read, update, delete,\nyou can do it that easily.

Beware worse using drop, whereby\nyou can drop an entire table.

But via these kinds of\ncommands, can we actually now

manipulate our data much more\nrapidly and with single thoughts.

And in fact, if you're an aspiring\n

or analyst in the real world, SQL\n

because it allows you to really\ndive into data quickly, and ask

questions of the data, and get\nback answers quite quickly.

And this is a simple data set.

You can do this with much larger\ndata sets as we soon will, too.

Or any questions on what\nwe've seen of SQL thus far?

Only scratched the\nsurface, but again, it

boils down to creating, reading,\nupdating, and deleting data.

Well, let's consider\nthe design of this data.

Recall that if I do .schema, that\n

the so-called schema of my data.

It gets the job done, and frankly,\neverything the user typed in

was arguably text, including the\n

But so the data set\nitself is somewhat simple.

But if we look at the data set itself,\n

Select genres from favorites.

And let me point out one other\nthing stylistically, too.

I am very deliberately capitalizing\n

and I'm lowercasing all of the\ncolumn names and the table names.

This is a convention, and\nhonestly, it just helps you read

I think, the code when you're\nco-mingling your names for columns

and tables with proper SQL keywords.

But I could just as easily do\nselect genres from favorites

but again, the SQL specific keywords\n

So stylistically, we would\nrecommend this, selecting genres

I accidentally made\nevery show, including

The Office about action, adventure,\n

How did I do that accidentally?

I think I did say\nbeware around this time.

So the SQL database took me--\nliterally, I updated favorites

setting genres equal to that,\nsemicolon, end of thought.

I really wanted to say\nwhere title equals

quote, unquote, "Game of Thrones.

Unfortunately, there isn't an\nundo command or time machine

with a SQL database, so\nthe best we can do here

is, let's actually get\nrid of favorites.db.

Let's run SQLite of favorites.db\n

Let me change myself into CSV mode.

Let me import, into my\nfavorites table, the CSV file.

And now, Friends is back,\nfor better or for worse

but so are all of our genres.

If I now reload the file\nand do select, star, from--

Select genres from favorites,\nthat was the result I was getting.

It's much messier, but that's\n

But now we're back to the original data.

Lesson here, be sure\nto back up your work.

So what more can we\nnow do with this data?

Well, I don't love the design of the\n

One, we didn't have\nany sort of validation

but user input is going to be messy.

There's just a lot of\nredundancy in here.

Let me select all the\ncomedies you all typed in.

So select title from\nfavorites, where genres equals

OK, so there's all of the shows\nthat are explicitly comedies.

But I think there might\nactually be others.

What was a comedy and a drama?

How about let's search for the-- oops,\n

OK, so The Office, in this case, was\n

It's Always Sunny in Philadelphia,\nand Gilmore Girls as well.

But notice that I get many more\nwhen I just search for comedy.

So the catch here is that, because I\n

the way Google did, as\na comma-separated list

it's actually really hard and messy\n

that are somewhere described as comedy.

Because if I search for quote,\n

I'm going to get are this one, whatever\n

But I'm not going to get this one.

I'm not going to get this one.

If I'm searching for, where genres\n

why am I missing those other shows?

It's not just a comedy,\nit's a comedy and a drama

and a comedy or a news\nshow, and so forth.

So I have to search for these commas,\n

Let me copy this so I can do this.

Let me search for where\ngenres equals comedy.

How about, or genres equals\ncomedy, drama, or genres

equals this whole thing,\ncomedy, news, talk show?

I'm going to get more and more results.

But that's not going to scale well.

What could I do instead\nof enumerating with ors

all of the different permutations\nof genres, do you think?

So I could use the keyword is,\nsimilar in Python to the word in.

I could use the like\nkeyword so that so long

as the genres is like\ncomedy somewhere in there

that's going to give me all of them,\n

But let me go ahead and just\nopen the form from earlier.

Let me see if I can open this\nreal quick before I toggle over.

If we look back at the\nform, recall that there

were all of those radio buttons\nasking for the specific genres

And if I open this, let me full screen\n

You'll see all of the\ngenres here, none of which

are that worrisome except for a\n

Where might the like keyword\nalone get me into trouble?

DAVID J. MALAN: Yeah, music and musical\n

Because, one, they're separate genres.

But if I just search for\nsomething that's like music

I'm going to accidentally suck\nin all of the musicals, which

If music is a music video or\nwhatever, and musical is actually

a different type of show, I\ndon't want to just do that.

So it seems just very messy.

I could probably hack something together\n

But this is just not a\ngood design for the data.

Google has done it this\nway because it's just

simple to actually keep the user's\ndata all in a single column

and just as they did,\nseparate it by commas.

But this is a real\nmessy way to use CSV is

by putting comma-separated values\n

Arguably, the folks at\nGoogle probably just did this

And they didn't want to\ngive people multiple sheets

or complicate things using some other\n

But I bet there's a better\nway for us to do this.

And let me go ahead and do this.

Let me go back into my code here.

And in just a moment, I'm\ngoing to grab a program

that I wrote in advance that's going\n

iterate over all of the rows, and load\n

two tables, one called\nshows, and one called genres

so as to actually separate\nthese two things out.

Give me just a moment to grab the code.

And when I run this, I'll\nonly have to run it once.

Let me go ahead and\nrun Python in a moment

and I'll reveal the results in a sec.

This is going to be version\n8 of the code online.

When I do this, let me go\nahead and open up this file.

Give me a second to move\nit into this directory.

So here we have version 8 of\nthis that's available online

that's going to do the following.

And I'll gloss over some\nof the details just so

that we don't get stuck in the\nweeds of some of this code.

I'm going to be using, at\nthe top of this program

as we'll soon see, a CS50 library,\n

or get_int, or get_float, but\nbecause there's some built-in SQL

functionality that we didn't discuss\n

But inside of the CS50 library we'll\n

SQL that gives you the ability using\n

technically called a URI, that allows\n

And long story short, all\nof the subsequent code

is going to iterate over this\n

And it's going to import it\ninto the SQLite database

but it's going to use two\ntables instead of just one.

So give me just a moment\nto run this, and then I'll

This is going to be\nrun on favorites.csv.

And taking a look here,\ngive me just a moment.

This program should not\nbe taking this long.

Let me just skim this code real\n

Reader, title, show ID\nin certain two shows.

[INAUDIBLE] genres split, DB execute.

This is me debugging in real time.

All those times we encourage you to use\n

We'll see how quickly I\ncan recover from this.

Python of favorites version 8.

OK, so here's me debugging in real time.

Oh, maybe I just didn't\nwait long enough.

What I'm doing is printing out\nthe dictionary that represents

each row that you all typed in.

And we're actually making progress.

I was too impatient and\ndidn't wait long enough.

All right, so all we have\nto do sometimes is wait.

Let me go ahead now and open\nthis file using SQLite3.

So in SQLite3 I now have a\ndifferent version of favorites.db.

I named it number 8 for consistency.

Once I've run the program I can\ndo .schema to look inside of it.

And here's what the two tables in\n

I've created a table called shows, this\n

that are favorites,\nthat has two columns.

One is called ID, one is called Title.

But now I'm going to start\ntaking out for a spin some

of the other features of SQL.

And besides there being text, it turns\n

Besides there being a\ndata type called text

there's also a special key\nphrase that you can specify

that the title can never be null.

Think back to our use\nof null in C. Think back

to the keyword none in Python.

This is a database constraint that\n

can't have of favorite TV show.

If you submit the form, you have\nto have typed in a title for it

to end up in our database here.

And you'll notice one other new feature.

It turns out, on this\ntable I'm defining what's

called a primary key,\nspecifically to be the ID column.

More on that in just a moment.

Meanwhile, the second table my code\n

gives me a column called\nshow ID, and then, a genre

the value of which is text\nthat can also not be null.

And then more on this in a moment.

This table has what we're\ngoing to call a foreign key

specifically the show ID column\nthat references shows ID.

So before we get into\nthe weeds of this, this

is now a way of creating the\nrelation in relational database.

If I have two tables now, not\njust one, they can somehow

be linked together by a common column.

In other words, the shows column--

shows table is going to give\nme a table with two columns--

Every title you gave me, I'm\ngoing to assign a unique value.

The genre's table, meanwhile, is\n

singular with that same idea.

And the result of this, to pop back to\n

Select star from shows\nof this new database

and you'll see that I've given,\n

I didn't filter out duplicates or do\n

So there's going to be some\nduplicates here because I didn't

want to get rid of anyone's data.

But you'll see that,\nindeed, I've given everyone

a unique identifier, from\nthe very first person who

typed How I Met Your Mother, all\n

Meanwhile, if I do select star from\n

a column in the original\ndata, now you'll

see a much better design for this data.

Notice what I've done here.

Let me go all the way to the top and\n

is called show ID, the other\nof which is called genre.

And again, I wrote some\ncode to do this because I

had to take Google's messy output where\n

I had to tear away the commas and\n

Even though we haven't\nintroduced the syntax via which

we can reconstitute the\ndata and reassociate

your genres with your\ntitles, why, at a glance

might this be a better design now?

Even though I've doubled the\nnumber of tables from one to two

why is this probably on the\ndirection toward a better design?

What might your instincts be?

Again, first time with SQL,\nwhy is it better, perhaps

that we've done this\nwith our genre's table?

Oh, just because we had the\n

We've cleaned up the data by giving\n

column in the original\nGoogle Spreadsheet

its own cell in this table, if you will.

And now notice show ID\nmight appear multiple times.

Whoever typed in How I Met Your Mother,\n

And so we see that\nshow ID 1 is a comedy.

I forget the name of\nthe second show offhand.

But that person, whoever was\nassigned show ID 2 checked off

a whole bunch of the genre's boxes.

That happened again with show ID 3, 4.

Persons 5, 6, 7 only checked one box.

And so you can see now that we've\n

might call a one-to-many relationship.

A one-to-many relationship, whereby\n

it can now have many genres\nassociated with it, each of which

is represented by a separate row here.

So again, if I go ahead and\nselect star from shows--

let's limit it to the first 10 just\n

How I Met Your Mother, The Sopranos\nwas the second input there.

It would seem that now that I've\ncreated the data in this way

I could ideally somehow search the\n

I don't have to worry about the commas.

I don't have to worry about\nthe hackish approach of music

being a substring of musical.

But how can I actually\nget back at this data?

Well, let's go ahead and do this.

Suppose I did want to get back\nmaybe all of the comedies.

All of the comedies, no matter whether\n

box or multiple boxes instead.

How now, given that I\nhave two tables, could I

go about selecting only\nthe titles of comedies?

I've actually made the\nproblem a little harder

but again, SQL is going to\ngive me a solution for this.

The problem is that if I\nwant to search for comedies

I have to check the genres table first.

And then what's that going to give me?

If I search the genres\ntable for comedies

what's that going to\ngive me back potentially?

DAVID J. MALAN: Maybe show ID.

Let me do select show ID from genres,\n

equals quote, unquote, "comedy.

No commas, no like, no percent signs.

Because literally, that column now is\n

Let me go ahead and hit Enter here.

OK, so I got back a whole\nbunch of ID numbers.

Now this could very\nquickly get annoying.

It looks like show ID 1, 2, 4, 5, 6,\n

So I could do something really\n

where ID equals 1, or ID equals 2.

This is not going to\nscale very well, but this

is why SQL is especially powerful.

You can actually compose one\nSQL question from multiple ones.

Why don't I select the title\nwhere the ID of the show

is in the following list of IDs?

Select show ID from genres, where the\n

So I've got two SQL queries.

One is deliberately nested\ninside of parentheses.

That's going to give me back\nthat whole list of show IDs.

But that's exactly what\nI want to then look up

the titles for by selecting title\n

And so now if I hit Enter,\nI get back only those shows

that were somehow flagged as\ncomedy, whether you in the audience

checked one box for comedy,\ntwo boxes, or all of the boxes.

Somehow we teased out\ncomedy, again, just

by using that Python script,\nwhich loaded this data not

into one big table, but instead, two.

And if we want to clean this\nup, let's do a couple of things.

Let's, outside of the\nparentheses, do order by title.

This is a way of sorting\nthe data in SQL very easily.

Now we have a whole list of the\nsame titles that are now sorted.

And what was the keyword with which\n

Same query, but let's select only the\n

And notice, I've very\ndeliberately done it this way.

And to this day, any\ntime I'm using SQL, I

don't just start at the beginning\nand type out my whole thought

and just get it right on the first try.

I very commonly start\nwith the subquery, if you

will, the thing in\nparentheses, just to get myself

one step toward what I care about.

Then I add to it, just like\nwe've encouraged in Python and C

taking baby steps in order to get to\n

And other than this\nmistake, which we didn't

fix because I re-imported the data after\n

we now have an alphabetized\nlist of all of the same data.

But now it's better designed, because we\n

What questions do we have, if any here?

DAVID J. MALAN: Oh, now\nthat we have a database

how do we transfer it to a CSV?

And in fact, there's a\ncommand within SQLite

that allows you to export\nyour data back to a CSV file.

If you want to email\nit to someone and you

want them to be able to open it in\n

Numbers, or the like, you can\ngo in the other direction.

Generally though, once\nyou're in the world of SQL

you're probably storing\nyour data there long term.

And you're probably updating it,\n

For instance, the one command\nI did not show earlier

is, suppose someone forgot a show.

Let's see, did I see this in the output?

All right, so Curb Your Enthusiasm.

Did anyone see it last night?

All right, well, just the one person\n

What's another show that\ndidn't make the list?

It's now on Netflix, apparently.

Well, we want to insert\nmaybe an ID and a title.

But I don't actually\ncare what the ID is

so I'm just going to insert a title.

And the value I'm going\nto give to that title

is going to be, quote,\nunquote, "Seinfeld.

And then, let me go\nahead and hit semicolon.

Nothing seems to happen, but\nlet me rerun the big query

from before looking for comedies.

And unfortunately, Seinfeld has\n

so let's get this right, too.

What intuitively I'm going to\nhave to do to associate, now

I just inserted into the show's table.

What more needs to happen before\n

So I need to insert into the\ngenres table two things now

a show ID, like this, and\nthen, the name of the genre

What values do I want to insert?

Well, the show ID, I better grab that.

Oh, I don't even know what it is.

I'm going to have to\nfigure out what that is.

So I could do this in a couple of ways.

Select star from shows,\nwhere title equals

quote, unquote,\n"Seinfeld" semicolon 159.

So now I could do, insert\ninto genres a show ID

and a genre name, the values 159, and,\n

And now, if I scroll back in my history\n

again, looking for\nall distinct comedies

now Seinfeld has made the list.

But I did this manually so I\ndidn't actually capitalize it.

Set title equals to Seinfeld semicolon.

OK, thank you, where title equals,\nquote, unquote, "Seinfeld.

Let's not make that mistake again.

And now, if I execute that really\nbig query, now Seinfeld is

indeed, considered a comedy.

So where are we going with this?

Well, thus far we've been doing\nall of this pretty manually.

And this is absolutely what an\n

might do if just manipulating\na pretty large data set just

to get at interesting answers\nthat might be across one

two, or even many more tables.

Eventually, in a few weeks, we're\n

by writing code in Python\nthat generates SQL to do this.

If you go to most any website\non the internet today

and you, for instance, log in, odds are\n

Well, the website might not\nbe implemented in Python

but it's probably implemented in some\n

And that language is probably using\n

to use SQL to get your\nusername, get your password

and compare the two against\nwhat you've typed in.

And actually, it's hopefully not\ngetting your actual password

but something called the hash thereof.

But there's probably a\ndatabase involved doing that.

When you buy something on\nAmazon.com and you click Check Out

odds are there's some\ncode on Amazon's server

that's looking at what it is\nyou added to your shopping cart

and then maybe using a for loop of some\n

It's doing a whole bunch of SQL\n

There's other types of databases,\ntoo, but SQL databases

or relational databases\nare quite popular.

So let's go ahead and write\none other program here

in Python that now merges these\ntwo languages together, whereby

I'm going to use SQL\ninside of a Python program

so I can implement my logic\nof my program in Python

But when I want to get at some data I\n

So let me go ahead\nand open favorites.py.

And let me go ahead and throw away\n

just now add a SQL to the mix.

From the CS50 library, let's\nimport the SQL function.

This will be useful to use\nbecause most third-party libraries

that deal with SQL and Python are\n

So I think you'll find\nthis library easier to use.

Let's then do the following.

Create a variable\ncalled db for database.

But I could call it anything I want.

Let's use that you URI, which is\na fancy way of saying something

that looks like a URL, but that actually\n

Let's now ask the user for a title by\n

And let's strip off any whitespace\n

And then, let's go ahead and do this.

I'm going to go ahead now and write\n

to talk to the original favorites.db.

So again, I'm not using the two-table\n

I'm using the original that we\nimported from your own data

and I'm going to do the following.

I'm going to use db.execute to execute\n

I'm going to select the count\nof shows from the favorites

table, where the title the user\n

And why I'm doing that is as follows.

Just like in C, when we had\npercent S, in SQL for now

the analogue is going\nto be a question mark.

So same idea, different syntax.

Instead of percent S,\nit's just a question mark.

And using a comma outside of this\n

function I can pass in\na SQL string, a command

then any arguments I want to plug\n

So the goal at hand is to\nactually write a program that's

going to search favorites.csv, a.k.a.,\n

of people that liked a particular show.

So this is going to select the count\n

where the title they typed in is like\n

This db execute function returns a list.

And you would only know that\nby my telling you or reading

And therefore, if I want to\nget back to the total count

I'm going to go ahead and grab\nthe first row from those rows.

Because it's only going\nto give me back the count.

And then I'm going to go ahead and\n

But it's going to be a little weird.

Technically the column is going to be\n

Let me add one more feature to the mix.

You can actually give\nnicknames to columns

that are coming back, especially if they\n

I can just call that column\ncounter, in all lowercase.

That means I can now say get back the\n

So just to recap, what have we done?

We've imported the CS50\nlibrary SQL function.

We've, with this line of\ncode, opened the favorites.db

file that you and I created earlier\n

I'm now just asking the user for\n

I'm now executing this SQL\nquery on that database

plugging in whatever the\nhuman typed in as their title

in order to get back a total count.

And I'm giving the count a\nnickname, an alias of counter

just so it's more self-explanatory.

This function, db execute, no matter\n

even if there's only\none row inside of it.

So this line of code just gives\nme the first and only row.

And then, this goes inside of that row,\n

and gives me the key counter\nand the value it corresponds to.

So what, to be clear, is this doing?

Let's go ahead and run this manually\n

Let me run SQLite3 on favorites--

On favorites.db, let me\nimport the data again.

So mode csv.import in from\nfavorites.csv into a favorites table.

So I've just recreated the\nsame data set that you all

gave me earlier in favorites.db.

If I were to do this manually,\n

Select, count star from favorites,\nwhere title like, and let's

just manually type it\nin for now, The Office.

We'll search for the one\nwith the word The, semicolon.

But technically, notice what I get back.

I technically get back a miniature\n

What if I want to rename that column?

That's where the as keyword comes in.

So select count star as counter.

I just get back-- same\nsimple table, but I've

renamed the column to be counter\njust because it's a little more

self-explanatory as to what it is.

So what am I doing\nwith this line of code?

This line of code is returning to\n

in the form of a list of dictionaries.

The list contains one\nrow, as we'll see, and it

contains one column, as we'll\nsee, the key for which is counter.

So let's now run the code itself.

I'm going to get out of SQLite3 and I'm\n

I'm being prompted for a title.

I'm going to type in The Office and\n

Well, there's a typo again\nbecause I re-imported the CSV.

I had deleted two of the Thes, so\n

So there\'s 12 total that have,\nquote, unquote, "The Office

We've combined some\nPython with some SQL

but we've relegated all of the\n

the selecting of something,\ngotten rid of all

of the with keyword, the\nopen keyword, the for loop

the reader the DictReader,\nand all of that.

And it's just one line of SQL now,\n

All right, any questions on what we've\n

DAVID J. MALAN: When does this\n

So let's do that by changing\nthe problem at hand.

This program was designed just\nto select the total count.

Let's go ahead and\nselect, for instance, all

of the ways you all typed in The Office\n

If I do this in SQLite3, let\nme go ahead and do this again

after increasing my Terminal window.

Select title from favorites,\nwhere the title is like

quote, unquote, "The Office," semicolon.

I get back all of these different rows,\n

There's actually another\nlittle typo in there

with some capitalization of the\nE, and the C, and the E. That

would be an example of a query\nthat gives me back therefore

So let's now change my Python program.

If I now, in my Python program, do\n

containing all of those titles.

I can now do, for row in rows, I can\n

and now manipulate all\nof those things together.

Let me keep both on the screen.

Let me run Python of favorites.py.

And that for loop now should\niterate, what, 10 or more times

once for each of those titles.

And indeed, if I type in\nThe Office again, Enter.

Oh, I should not be renaming\ntitle to counter this time.

So that's just a dumb\nmistake on my part.

And now I should see after\ntyping in The Office

Enter, a whole bunch of The Offices.

And because I'm using\nlike, even the missed

capitalizations are coming through,\n

It doesn't matter if it's\nuppercase or lowercase.

Whereas had I used the equal sign\n

All right, any questions on this next?

All right, so let's transition\nto a larger, juicier data

set, and consider some\nof the issues that

arise when actually now using SQL and\n

using SQL for mobile apps, web\napps, and generally speaking

So let's start with a larger\ndata set just like that.

Give me just a moment to switch screens\n

which is an actual relational\ndatabase that we've created out

of a real-world data set from IMDb.

So InternetMovieDatabase.com\nis a website

where you can search for TV\nshows, and movies, and actors

and so forth, all using their\ndatabase behind the scenes.

IMDb wonderfully makes their data\n

but TSV files, tab-separated values.

And so what we did is, before class\n

We wrote a Python program\nsimilar to my favorites8.py file

earlier that read in\nall of those TSV files

created some SQL tables\nin an IMDb database

for you in SQLite that has multiple\ntables and multiple columns.

So let's go and wrap our minds around\n

Let me go back to VS Code\nhere, and in just a moment

I'm going to go ahead and copy the\n

And I'm going to go ahead and increase\n

Whenever playing around with a\n

typing .schema is perhaps a good\n

And things just escalated quickly.

There's a lot in this data\nset, because, indeed, there's

going to be tens of hundreds of\n

and also problem set 7, where we'll\n

So what is the schema that\nwe have created for you

from IMDb's actual real-world data?

One, there's a table called shows.

And notice we've just added whitespace\n

to make it a little more\nstylistically readable.

The shows table has an ID\ncolumn, a title column, a year

and the total number of\nepisodes for a given show.

And the types of those columns are\n

So it turns out there's\nactually a few different data

types that are worth being aware of when\n

In fact, in SQLite there's\nfive data types, and only five

fortunately, one of which is, indeed,\n

numeric, which is kind of a\ncatchall for dates and times

things that are numeric\nbut are not just integers

and not just real numbers, for instance.

Real number is what we've generally\n

Text, of course, is\njust text, but notice

that you don't have to\nworry about how big it is.

Like in Python, it will size to fit.

And then there's BLOB, which\nis binary large object, which

is for just raw 0s and 1s, like\nfor files or things like that.

But we'll generally use\nthe other four of these.

And so, indeed, when we\nimported this data for you

we decided that every show would be\n

Every show has, of course, a\ntitle, which should not be null.

Otherwise, why is it in the database?

Every show has a year,\nwhich is numeric according

to that definition a moment ago.

And the total number of episodes for\n

What now is with these primary keys\n

A primary key is the column that\n

In our case, with the\nfavorites, I automatically

gave each of your submissions a unique\n

typed in The Office,\nyour submission still

had a unique identifier, a number\n

with your genres, just\nas we saw a moment ago.

In this version of IMDb,\nthere's also genres.

But they don't come from\nus, they come from IMDb.com.

And so a genre has a show ID, and\n

But these are real-world genres\nwith a bit more filtration.

Notice, though, just like my\nversion, there's a foreign key.

A foreign key is the appearance\nof another table's primary key

So when you have a table\nlike genres, which is somehow

cross referencing the original shows\n

called ID, and those same numbers\nappear in the genres table

under the column called show ID, by\n

It's the same numbers but\nit's foreign in the sense

that the number is being\nused in this table

even though it's officially defined\n

This is what we mean by\nrelational databases.

You have multiple tables with some\n

And those numbers allow you to line\n

that you can reconnect the\nshows with their genres

just like we did with our\nsmaller data set a moment ago.

This logic is extended further.

Notice that the IMDb database we've\n

like TV show stars, the actors therein.

And that table, interestingly,\nhas no mention of people

and no mention of shows, per se.

It only has a column called\nshow ID, which is an integer

and a person ID, which is an integer.

Meanwhile, if we scrolled\ndown to the bottom

you will see a table called people.

And we have decided in IMDb's world\n

will have a unique identifier that's\n

date, which is numeric, and\nthen, again, specifying that ID

is going to be their primary key.

Well, it turns out that TV stars and\n

So using this relational database,\n

We're factoring out commonalities.

And if a person can be\ndifferent things in life

well, we're defining them\nfirst and foremost as people.

And then, notice these two\ntables are almost the same.

The stars table has a show\nID, which is a number

and a person ID, which\nis a number, which

allows us via this middleman table, if\n

Similarly, the writers table allows\n

by just recording those numbers.

So if we go into this data\nset, let's do the following.

Let's do select star\nfrom people semicolon.

So a huge amount of data is coming back.

This is hundreds of thousands of rows\n

So this is real-world data\nnow flying across the screen.

There's a lot of people in the TV show\n

There's a lot of data there.

So my god, if you had to do\nanything manual in this data

set it's probably not going\nto work out very well.

And actually, we're up to, what,\na million people in this data

set, plus, which would mean\nthis probably isn't even

going to open very well in Excel, or\n

SQL probably is the\nbetter approach here.

Let's search for someone\nspecific, like select star

from people, where name equals\n

All right, so there's Steve Carell.

He is person number\n136,797, born in 1962.

And that's as much data as\nwe have on Steve Carell here.

How do we figure out what\nshows, for instance, he's in?

Well, let's see, select\nstar from shows, semicolon.

There's a crazy number of shows\nout there in the IMDb database.

And you can see it here again\nflying across the screen.

Feels like we're going to have to\n

to get at all of Steve Carell's shows.

So how are we going to do that?

Well, god, this is a lot of data here.

And in fact, yeah, we\nhave, what, 15 million

shows plus in this data set, too.

So doing things efficiently is\nnow going to start to matter.

Let me select a specific show.

Select star from shows where title\n

And there presumably shouldn't\nbe typos in this data

because it comes from the\nreal website IMDb.com.

Turns out there's been a lot of\nThe Offices out in the world.

The one that started in 2005\nis the one that we want

presumably the most\npopular with 188 episodes.

Maybe we could do and year\nequals, how about 2005?

All right, so now we've got\nback just the ID of The Office

Let me turn on a timer\nwithin SQLite just

to get a sense of running time now.

Select star from shows, where\ntitle equals The Office

Let's just do titles for now.

All right, so not terribly long.

It found it pretty fast, but it looks\n

0.02 seconds, not bad for just a title.

But just to plant a seed, it\nturns out that we can probably

Let me create something called an\n

in CRUD for creating something.

And I'm going to call this title index.

And I'm going to create\nit on the shows table

specifically on the title column.

And we'll see in a moment what\nthis is going to do for me.

Took a moment, like 0.349 seconds,\n

But now watch, if I select star from\n

previously it took me 0.021 seconds.

Literally no time at all, or so low\n

And I'll do it again just\nto get a sense of things.

Now even though 0.021 seconds, not crazy\n

a lot of users running a real\nwebsite or real mobile app.

Every millisecond we can start to\n

Well, we actually just created\nsomething called an index.

And this is a nice way\nto tie in, now, some

of our week 5 discussion\nof data structures

and our week 3 discussion\nof running times.

An index in a database is\nsome kind of fancy data

structure that allows the database\n

Literally, as you just saw, these\n

And so when I first\nsearched for The Office

it was literally doing linear search,\n

It's not that slow, 0.021 seconds.

But that's relatively slow just\ntheoretically, algorithmically

But if you instead create\nan index using syntax

like this, which I just did, creating an\n

table, that's like giving the\ndatabase a clue in advance saying

hey, I know I'm going to search on\n

Do something with data\nstructures to speed things up.

And so if you think back to our\ndiscussion of data structures

Maybe it's using a trie or a hash\n

structure is generally going to lift\n

So it's just much faster\nto find data, especially

if it's sorting it now\nbased on title, and not

just storing it in one long list.

And in fact, in the world\nof relational databases

the type of structure that's\noften used in a database

is something called a B-tree.

Different use of the letter B, but it\n

It's not binary because\nsome of the nodes

might have more than\ntwo children or fewer

but it's a very wide but\nrelatively shallow tree.

And the upside of that is that if\n

the database can find it more quickly.

And the reason it took half a second,\n

is because SQLite needed to take\nsome non-zero amount of time

to just build up this tree in memory.

And it has algorithms for doing so based\n

But you spend a bit of time\nup front, a third of a second.

Every subsequent query, if I\nkeep doing it again and again

is going to be crazy\nlow, 0.000, maybe 0.001.

But an order of magnitude, a\nfactor of 10 or 100 faster than it

So we have these indexes which\nallow us to get at data faster.

But what if we want to\nactually get data that's

now across these multiple tables?

And how might these indices\nor indexes help further?

Well, it turns out there is\na way that we've seen already

indirectly to join two tables together.

Previously, when I selected\nthe ID of The Office

and then I searched for it in the other\n

I was joining two tables together.

And it turns out there's a\ncouple of ways to do this.

Let's go ahead now and, for instance,\n

Not just The Office\nbut all of them, too.

Unfortunately, if we look at our schema,\n

oh, shows over here has no\nmention of the TV stars in them.

And people have no mention of shows.

We somehow need to use this\ntable here to connect the two.

And this is called a join table, in the\n

it joins the two tables\ntogether logically.

And so if you're savvy enough with SQL,\n

earlier and like recombine\ntables by using these common IDs

Let me go ahead and figure out,\n

So how am I going to do this?

Well, if I select star from people,\n

fortunately, there's only one of them.

So this gives me back his name,\nhis ID, and his birth year.

But it's really only his\nID that I care about.

Because in order to get back his shows,\n

So I need to know his ID number.

So what could I do with this?

Well, remember the schema\nand the stars table.

I've just gotten, from the\npeople table, Steve Carell's ID.

I bet by transitivity I could\nnow use his person ID, his ID

to get back all of his show IDs.

And then once I've got all of his show\n

and get back all of his shows' titles.

So the answer is actually English\n

So let me go ahead and do this.

Let me, again, get Steve\nCarell's ID number, but not star.

It's a wildcard character in SQL.

Let me just select the\nID of Steve Carell.

And that gives me back 136,797.

And it's only giving me back one value.

The thing called ID is just\nthe column heading up above.

Now, suppose I want to\nselect all of the show IDs

that Steve Carell is affiliated with.

Let me select Show ID from stars,\nwhere the person ID in stars

happens to equal Steve Carell's ID.

So again, I'm building up my answer in\n

On the right, in parentheses,\nI'm getting Steve Carell's ID.

On the left, I am now\nselecting all of the show IDs

that have some connection with\n

This answer, too, is not\ngoing to be that illuminating.

It's just a whole bunch of integers\n

But let's take this one step further.

And even though my\ncode is getting long, I

could hit Enter and format\nit nicely, especially

if I were doing this in a code file.

But I'm just doing it\ninteractively for now.

Let's now select all of the\ntitles from the shows table

where the ID of the show is in\nthis following previous query.

So again, the query is getting long.

But notice, it's the\nthird and last step.

Select title from the shows\ntable, where the ID of the show

is in the list of all\nof the show IDs that

came back from the stars table\n

How did we get that person ID?

Well, I selected, in my innermost\n

So now, when I hit Enter, voila.

I get all of Steve Carell's\nTV shows up until now.

And if I want to tidy this up further,\n

Now I've got it all\nalphabetized as before.

So again, with SQL comes\nthe ability to search--

I mean, look how quickly\nwe do this, 0.094 seconds

to search across three different\ntables to get back this answer.

But my data is now all neatly\ndesigned in individual tables

which is going to be important\n

But let me take this one step further.

Let me go ahead and do this.

Let me go ahead and point\nout that with this query

notice that I'm searching on--

let's say I'm searching\non a person ID here.

And at the end here, I'm\nsearching on a name column here.

So let me actually go ahead and do this.

Let me go ahead and see\nif we can't speed this up.

This query at the moment\ntakes 0.092 seconds.

Let's see if we can't speed this\n

a few more of those B-trees\nin the databases memory.

Create an index called person index, and\n

It's taking a moment, taking a moment.

That's almost a full second\nbecause that's a big table.

Let's create another index called\nshow index on the stars table.

Because I want to search\nby the show ID also.

That was part of my big query.

OK, just more than\nabout 2/3 of a second.

Now let's create one last one,\nanother index called name index

but I could call these things\n

Because I'm also searching\non the name column.

So in short, I'm\ncreating indexes on each

of the columns that are somehow\ninvolved in my search query

going from one table to the other.

Now let's go back to the previous\nquery, which, recall, took--

Well, it was roughly\nthis order of magnitude.

We're not seeing the data now.

But let me go ahead and run\nmy original big query once.

And boom, we're down to almost nothing.

So again, creating\nthese indexes in memory

has the effect of rapidly\nspeeding up our computation time.

Now if you've ever used, for instance,\n

here on campus, or Yale's analogue, you\n

This could be one of the reasons why\n

thousands of courses\ntend to be slow, if

and I'm only conjecturing, if the\n

If you're building your\nown web application

and you're finding that users\nare waiting and waiting

and things are spinning and spinning,\n

Well, it could absolutely just be bad\n

Or it might be that you\nhaven't thought about, well

what column should be optimized\nfor searches and filtration

like I've done here in order\nto speed up subsequent queries?

Again, from the outside\nin, we can only conjecture.

But ultimately, this is\njust one of the things that

explains performance problems as well.

All right, let's point out just a\n

and then we'll consider,\nbigger picture, some problems

that might arise in this world.

If these nested, nested queries\nstart to get a little much

there are other ways,\njust so you've seen it

that you can execute\nsimilar logic in SQL.

For instance, if I\nknow in advance that I

want to connect Steve Carell to\n

we can do something more like this.

Select title from the people table,\n

And again, this is not something you'll\n

But just so you've seen other\n

This is an explicit way to say, take\n

table in the other hand,\nand somehow join them

as I keep doing with my fingertips here.

Join them so that the people, the ID\n

with the person ID in the stars table.

But that's not quite everything.

I could also say, join\nfurther on the shows table

where the stars show ID\nequals the shows ID column.

That's saying, go further and join\n

joining the show ID\ncolumn with the ID column.

Again, this starts to get a\nlittle messy to think about.

But now I can just say, where name\n

I can do in one query what previously\n

and get back the same answers.

And I can still add in my order\nby title to get back the result.

And if I do this a little more\n

Let me type this out by adding a\n

I'm going to leave it alone for now.

We can type it on multiple\nlines in other contexts.

And let me do one last thing.

I'm going to show it,\nbut this is not something

you should ingrain just yet either.

Select title from\npeople, stars, and shows.

If you know in advance that you want\n

you can just enumerate them,\none table name after the other.

And then you can say where\npeople.ID equals stars.personID.

And now I'm hitting\nEnter so that it formats

a little more readably on my screen.

And stars.showID equals shows.ID,\n

In short, you specify that you\n

And then you tell the database how to\n

that is, the columns that\nhave those integers in common.

If I hit Enter now, I get\nthe same exact results, ever

more so if I also add\nin an order by title.

That's why I didn't\nwant to do this earlier.

I have to go back through my history\n

the multi-line query this time.

But this is only to say that, even\n

more sophisticated, and we put\nsome of it over here, some of it

over here, some of it over here so as to\n

like putting commas in the data, we\n

that we might want across\nthese several tables.

And using indexes, we can\nsignificantly speed up these processes

so as to handle 10 times as\nmany, a 100 times as many users

on the same actual database.

There is going to be a downside.

And thinking back to our\ndiscussion of algorithms and data

structures in past weeks, what might be\n

Because as of now, I created four\n

the title column, and\nsome other columns, too.

Why wouldn't I just go\nahead and index everything

if it's clearly speeding things up?

Any time you're starting to benefit\n

odds are you're sacrificing\nspace, or vice versa.

And probably indexing absolutely\neverything is a little dumb

because you're going to waste way more\n

So figuring out where the\nright inflection point is

is part of the process of designing and\n

Now unfortunately, a whole lot of\n

and they continue to in the real\n

And in fact, here on\nout, if you're reading

something technical about SQL databases,\n

and passwords leaking out,\nunfortunately, all too often

it is because of what are\ncalled SQL injection attacks.

And just to give you a\nsense now to counterbalance

maybe [INAUDIBLE] enthusiasm\nfor like, oh, that

was neat how we can\ndo things so quickly.

With great power comes\nresponsibility in this world, too.

And so many people introduce\nbugs into their code

by not quite appreciating how it is the\n

Here, for instance, is a\ntypical login screen for Yale.

And here's the analogue for\nHarvard where you're prompted

every day probably, for your\nusername and your password

your email address and\nyour password here.

Suppose, though, that\nbehind this login page

whether Harvard's or Yale's,\nthere's some website.

And that website is using\nSQL underneath the hood

to store all of the\nHarvard or Yale people's

usernames, passwords, ID\nnumbers, courses, transcripts

So there's a SQL database\nunderneath the website.

Well, what might go\nwrong with this process?

Unfortunately, there's\nsome special syntax in SQL

just like there is in C and Python.

For instance, there are\ncomments in SQL, too.

If you do two hyphens, dash,\ndash, that's a comment in SQL.

And if you, the programmer, aren't\n

such that you defend against\npotentially adversarial attacks

you might do something like this.

Suppose that I somewhat\nmaliciously or curiously log in

by typing my username,\nMalan@harvard.edu, and then maybe

a single quote and a dash, dash.

Because I'm trying to suss out\nif there is a vulnerability here

But if I were the owner of the website\n

I might try using potentially\ndangerous characters in my input.

Because single quote is used for\n

single quotes or double quotes.

Dash, dash, I claim now,\nis used for commenting.

But let's now imagine what\nthe code underneath the hood

might be for something like\nYale's login or Harvard's login.

What if it's code that looks like this?

So let me read it from left to right.

Suppose that they are using something\n

and they've got some SQL\ntyped into the website that

says select star from users,\nwhere username equals this

And they're plugging in\nusername and password.

Well, when the user types their\nusername password, hits Enter

I probably want to select\nthat user from my database

to see if the username\nand passwords match.

So the underlying SQL\nmight be, select star

from users, where username\nequals question mark

and password equals question mark.

And if we get back one row,\npresumably Malan@harvard.edu

We should let him proceed\nfrom there on out.

So that's some pseudo code, if\nyou will, for this scenario.

What if, though, this code is not\n

is, and isn't using question marks?

So the question mark syntax\nis a fairly common SQL thing

where the question marks\nare used as placeholders

just like in printf, percent S was.

But this function, db.execute\nfrom CS50's library

and third-party libraries\nas well, is also

doing some good stuff\nwith these question marks

and defending against\nthe following attack.

Suppose that you were not using\na third-party library like ours

and you were just manually constructing\n

You were to do something like this\n

You're comfortable with\nformat strings now.

You've gotten into the habit of using\n

Suppose that you, the\naspiring programmer

is just using techniques\nthat you've been taught.

So you have an f-string\nwith select star from users

where username equals, quote,\n

And password equals, quote,\nunquote, "password" in curly braces.

As of what, two weeks\nago, this was perfectly

legitimate technique in Python\nto plug in values into a string.

But notice if you are using\nsingle quotes yourself

and the user has typed in single\nquotes to their input, what

Where are we going with this if you're\n

into your own prepared string of text?

Worst case, they could insert what is\n

Generally speaking, if you're using\n

to surround the user's\ninput, you'd better

hope that they don't have\nan apostrophe in their name.

Or you better hope that they\ndon't type a single quote as well.

Because what if their single quote\n

and then the rest of\nthis is somehow ignored?

Well, let's consider\nhow this might happen.

This got a little\nblurry here, but let me

plug in here-- wow, that looks awful.

Just change this to white\nso it's more readable.

What happens if the\nuser does this instead?

They type in, like I\ndid into the screenshot

'Malan@harvard.edu,'\nsingle quote, dash, dash.

What has just happened\nlogically, even though we've

only just begun with SQL today?

Well, select star from users, where\n

What's bad about the rest of this?

Dash, dash, I claim,\nmeans a comment, which

means my color coding is going\nto be a little blurry again.

But everything after the\ndash, dash is just ignored.

The logic, then, of\nthe SQL query, then, is

to just say, select\nMalan@harvard.edu from the database

not even checking the password anymore.

Therefore, you will get\nback at least one row.

So length of rows will equal 1, and so\n

logs the user in, gives them\naccess to my my.harvard account

And they've pretended to be me simply\n

dash in the username field.

Again, please don't go\nstart doing this later today

on Harvard, Yale, or other websites.

But it could be as simple as that.

Because the programmer\npracticed what they

were taught, which was just to\nuse curly braces to plug in

But if you don't understand how the\n

and if you don't distrust your users\n

out there there's going\nto be, unfortunately

some adversary who just wants to try\n

This is what's known as\na SQL injection attack

because the user can type something\n

and trick your database into doing\n

like, for instance, logging the user in.

Worst case, they could\neven do something else.

Maybe the user types a semicolon, then\n

You could imagine doing semicolon\nupdate table grades, where

name equals Malan, and set the\ngrade equal to A instead of B

The ability to inject\nSQL into the database

means you can do anything you want with\n

And now, just a quick, little\n

OK, to, like, one of us, two of us.

All right, so let's move\non to one last condition.

There's one other problem\nthat can go awry here.

Oh, and I should explain this.

So this is an allusion to the son,\n

The word drop, table, students, and\n

This is humor that only\nCS people would understand

because it's the mom realizing,\n

Less funny when you explain it, but once\n

So one final threat, now\nthat you are graduating

to the world of proper databases\nand away from CSV files alone.

Things can go wrong\nwhen using databases

and honestly, even using CSV\nfiles if you have multiple users.

And thus far, you and\nI have had the luxury

in almost every program we've written\n

It's just you using your code.

And even if your teaching fellow\nor TA is using it, probably

But the world gets interesting if you\n

on websites, such that now you might\n

to log in at the same time,\nliterally clicking a button

at the same, or nearly the same time.

What happens, then, if\na computer is trying

to handle requests from two\ndifferent people at once

as might happen all\nthe time on a website?

You might get what are\ncalled race conditions.

And this is a problem in computing in\n

with Python, really just any\ntime you have shared data

like a database, as follows.

This apparently is one of the\nmost liked Instagram posts ever.

It is literally just\na picture of an egg.

Has anyone clicked on this egg?

So go search for this photo if you'd\n

The account is world_record_egg.

This is just a screenshot of\n

If you're in the habit\nof using Instagram

or like any social media site, there's\n

or a heart button these days.

And that's actually a\nreally hard problem.

Such a simple idea to count\nthe number of likes something

has, but that means\nsomeone has to click on it.

Your code has to detect the click.

Your code has to update the database,\n

even if multiple people are perhaps\n

And unfortunately, bad things can\n

at the same time on a computer.

So here's some more code, half\n

Suppose that what happens when you,\n

on the like button on\nthe Instagram post.

Suppose that code, like the following,\n

db.execute of select likes from\n

I'm assuming that that\nphotograph has a unique ID.

It's some big integer, whatever\nit was, randomly assigned.

I'm assuming that when\nyou click on the heart

the unique ID is somehow\nsent to Instagram servers

so that their code can call it ID.

And I'm assuming that Instagram\nis using its SQL database

and selecting, from a posts\ntable, the current number of likes

of that egg for that given ID number.

Because I need to know how many likes it\n

and then update the database.

I need to select the data, then\nI need to update the data here.

So in some Python code here,\nlet's store, in a variable called

likes, whatever comes back in the\n

Again, this is new syntax\nspecific to our library

but a common way of getting back\nfirst row and the column called

So at this point in the\nstory, likes is storing

the total number of likes, in\nthe millions or whatever it is

Execute update posts,\nset the number of likes

equal to this value, where the\nID of the post equals this value.

What do I want to update the likes to?

Whatever likes currently is plus\n1, and then plugging in the ID.

I'm checking the value of\nthe likes, and maybe it's 10.

I'm changing 10 to 11 and\nthen updating the table.

But a problem can arise\nif two people have

clicked on that egg at roughly the\n

Well, in the world of\ndatabases and servers

and the Instagrams of the world have\n

So they can support millions,\nbillions even, of users nowadays.

Well, typically code like this\nis not what we'll call atomic.

To be atomic means that it all\nexecutes together or not at all.

Rather, code typically is executed,\n

And if your code is running on a server\n

which is absolutely the case\nfor an app like Instagram

if you and I click on the\nheart at roughly the same time

for efficiency, the computer,\nthe server, owned by Instagram

might execute this line of code for me.

Then it might execute\nthis line of code for you.

Then this line of code for me,\nthen this line of code for you

then this line of code for me,\nthen this line of code for you.

That is to say, our queries might\n

Because it'd be a little obnoxious\n

I'm blocked out while you're\ninteracting with the site.

It'd be a lot nicer for efficiency\nand fairness if somehow they

do a little bit of work for me,\na little bit of work for you

and back and forth, and back and\nforth, equitably on the server.

So that's what typically happens\nby default. These lines of code

And they can happen in alternating\norder with other users.

You can get them combined like this.

Same order top to bottom, but other\n

So suppose that the number of\n

And suppose that Carter and I both click\n

And suppose this line of\ncode gets executed for me

and that gives me a value\nin likes, ultimately, of 10.

Suppose, then, that the computer takes\n

does the same code for\nCarter, and gets back

what value for the\ncurrent number of likes?

Because mine has not been recorded yet.

At this point in the story,\nsomewhere in the computer's memory

there's a likes variable\nfor me, storing 10.

There's a likes variable\nstoring 10 for Carter.

Then this line of code executes for me.

It updates the database to be likes\n

Then Carter's code is executed,\n

Because his value of likes happened\n

And so the metaphor here, that if we\n

actually act out, is something that was\n

systems class, whereby the most similar\n

if you've got a mini\nfridge in your dorm room.

And one of you and your roommates comes\n

oh, we're out of milk, was\nhow the story went in my day.

So you close the refrigerator, and\n

and get in line to buy some milk.

Meanwhile, your roommate comes home.

They, too, inspect the state of your\n

open the door, and realizes,\noh, we're out of milk.

Close the fridge, go\nacross the street, and head

to maybe a different store,\nor the line is long enough

that you don't see each\nother at the store.

So long story short, you both eventually\n

now there's milk from\nyour other roommate

there because you both\nmade a decision on this

based on the state of a variable\n

And you didn't somehow communicate.

Now in the real world, this\nis absolutely solvable.

How would you fix this or avoid\nthis problem in the real world?

Literally, own roommate, own fridge.

AUDIENCE: Text your\nroommate [INAUDIBLE]..

Let them know, so somehow communicate.

And in fact, the terminology\nhere would be multiple threads

can somehow intercommunicate\nby having shared state

like the iMessage thread on your phone.

You could, more dramatically,\nlock the refrigerator somehow

thereby making the milk\npurchasing process atomic.

The fundamental problem is\nthat for efficiency, again

computers tend to\nintermingle logic that needs

to happen when it's happening across\n

You need to make sure that all\nthree of these lines of code

execute for me, and then\nfor Carter, and then for you

if you want to ensure that\nthis count is correct.

And for years, when social media\n

this was a super hard problem.

Twitter used to go down all\nof the time, and tweets

and retweets were a thing\nthat were similarly happening

These are hard problems to solve.

And thankfully, there are solutions.

And we won't get into the weeds\n

but know that there are\nsolutions in the form of things

called locks, which I use that\n

Software locks can allow you to\n

look at it until you're done with it.

There are things called\ntransactions, which

allow you to do the equivalent of\n

out your roommate from accessing\nthat same variable, too

but for slightly less amount of time.

There are solutions to these problems.

So for instance, in Python,\nthe same code now in green

might look a little something like this.

When you know that something\nhas to happen all at once

altogether, you first begin a\n

and then you commit the\ntransaction at the very end.

Here, too, though, there's\ngoing to be a downside.

Typically, the more you use\ntransactions in this way

potentially the higher\nthe probability is

that you're going to box someone out or\n

Because we can't interact\nat the same time.

Or you might make his request\nfail if he tries to update

something that's already been updated.

So you generally want to\nhave as few lines of code

together in between these transactions\n

And you go to CVS and you get\nback really fast so as to not

cause these kind of performance things.

So things indeed\nescalated quickly today.

The original goal was just to solve\n

more effectively than Python.

But as soon as you have these\nmore powerful techniques

a whole new set of problems arises.

Takes practice to get comfortable with.

But ultimately, this is all leading\n

of web programming with HTML,\nCSS, and some JavaScript.

The week after, bringing Python\nand SQL back into the mix.

So that by term's end,\nwe've really now used

all of these different languages\nfor what they're best at.

And over the next few weeks, the goal\n

and comfortable with what each of\n

Let's go ahead and wrap here.

I'll stick around for questions.

This is CS50, and this\nis already week 8.

And if we think back to\nthe past several weeks now

recall that things started pretty\n

in like week 0, when\nwe were using Scratch

because with Scratch we had a\nGUI, a graphical user interface.

So even as we explored variables and\n

you had kind of a fun environment\n

And then in week 1,\nwe sort of took a lot

of that away, when we introduced C, and\n

because now, all of your programs became\n

and gone was the mouse, the\nanimations, the menus, and so forth.

And so now, fast\nforward to week 8, we're

going to bring those kinds of\nuser interface, UI, elements back

in the form of web programming.

And this goes beyond\njust laying out websites.

This will, to this week and next week,\n

stuff that we've been doing\nfor the past several weeks

using Python, using\nSQL, and now introducing

a couple of other languages,\non the so-called client side

on your own Mac, your own PC,\nyour own phone, that's going

to talk to those back-end services.

So indeed, at this end of\nCS50, does everything rather

come together into a user interface\nthat's just super familiar.

All of us are on our phones,\ndesktops, laptops, every day.

And increasingly, even the mobile\napps that you all are using

are implemented, not necessarily\n

if you're familiar with\nthose, but with languages

called HTML, CSS, and JavaScript,\n

But before we do that, let's provide a\n

because indeed, we'll start to look\n

itself works, albeit quickly, so that\n

all of this code is running, how you\n

really, ultimately, after\nCS50, you can learn, by just

poking around other actual websites.

So the internet, we're all on it.

Literally, right now, what\nis it, in your own words?

It's this utility nowadays, that\nwe all rather take for granted.

SPEAKER 1: OK, big\nstorage, and indeed, that's

how the cloud is described, which is\n

for a whole lot of wires\nand cables and hardware.

And the internet, other\nformulations of the term, how else?

AUDIENCE: Bunch of\ndata that we can reach.

SPEAKER 1: OK, a bunch\nof data that we can all

reach, by way of being interconnected\n

And so really, the internet,\ntoo, is a hardware thing.

There's a whole lot of servers out\n

via physical cables, via\ninternet service providers

via wireless connectivity, and the like.

And once you start to have\nnetworks of networks of networks

Indeed, Harvard has its own network\n

and your own home probably\nhas its own network.

But once you start\nconnecting those networks

do you get the interconnected network\n

So there's this whole\nalphabet soup that goes

with the internet, some of\nwhose acronyms and terms

you've probably seen before.

But let's at least peel\nback some of those layers

and consider what some of\nthe building blocks are.

So here's a picture of the internet\n

back in 1969, when it\nwas something called

ARPANET, from the Advanced\nResearch Projects Agency.

And the intent, originally, was just\n

in Utah and California, literally\nservers, or computers, in each

of those areas, somehow\ninterconnected with wires

so that people could\nstart to share data.

A year later, it expanded to\ninclude MIT and Harvard and others.

And now fast forward to\ntoday, you have a huge number

of systems around the world\nthat are on this same network.

And, in fact, if I\njust pull up a web page

here, that's sort of\nconstantly changing

a visualization of the internet as\n

in the abstract, all of these\nlines and interconnections

represent just how interconnected\nthe world is today.

And it just means that there's all the\n

all of the more hardware giving\n

But if we focus, really, on just\n

whether back in 1970, or now in 2021,\n

yes, a server, but a certain type\n

And a router, as the\nname implies, just routes

data left to right, top to\nbottom, from one point to another.

And so there's all these servers here\n

in Comcast's network, Verizon's\nnetwork, your own home network

you have your own routers out\nthere, whose purpose in life

is to take in data and then\ndecide, should I send it this way

or this way, or this way, so\nto speak, assuming there are

multiple options with multiple cables.

You, in your home, probably have just\n

But certainly, if you're a place like\n

there's probably a whole\nbunch of interconnections

that the data can then\ntravel across ultimately.

So how do we get data\namong these routers?

For instance, if you want\nto send an email to someone

at Stanford, in California,\nfrom here, on the East Coast

or if you want to visit\nwww.stanford.edu, how does your laptop

your phone, your desktop, actually\n

Well, essentially, your\nlaptop or phone knows

when it boots up at the beginning of\n

the address of that local router is.

So if you want to send an\nemail from my laptop over here

my laptop is essentially going to\n

And then, from there, I\ndon't know, I don't care

how it gets the rest of the distance.

But hopefully, within some\nsmall number of steps later

Harvard's router is going to\nsend it to maybe Boston's router

is going to send it to\nCalifornia's router is going

to send it to Stanford's router, until\n

And we can depict this, actually,\nhow about a bit playfully.

Thankfully, the course's\nstaff kindly volunteered

to create a visualization for\nthis, using a familiar technology.

So here we have some of our TFs\n

Let me go ahead and full\nscreen this window here.

Give me just a moment to\npull it up on my screen here.

And we'll consider what happens if we\n

from one person or router,\nnamely Phyllis in this case

in the bottom right hand corner,\nup to Brian, in this case

in the top left hand corner.

So each of the staff members\nhere represents exactly one

of these routers on the internet.

It actually took us a\nsignificant number of attempts

to get that ultimately right.

So when, what was it the\nstaff were all passing here?

Here we have just, physically, what\n

So Phyllis started with an\nenvelope, inside of which

was that email, presumably,\non the East Coast

and she wanted to send it to Brian on\n

And so she had all of these different\n

between her and point B, namely Brian.

She could go up, down, in her case, and\n

could go up, down, left, or right,\n

And long story short,\nthere's algorithms that

figure out how you decide\nto send a packet up, down

left, or right, so to speak.

But they do so by taking an input, and\n

And there's at least a couple of\nthings on the outside of this

because all of these routers and,\n

and phones these days,\nspeak something called

TCP/IP, a set of\nacronyms you've probably

seen somewhere on your\nphone, your Mac or PC

in print somewhere, which refers\n

that computers use to\ninter-communicate these days.

A protocol is like a set\nof rules, that you behave.

In healthier times, I might\nextend my hand and someone

like Carter might extend his hand,\n

on a human protocol of like\nliterally physically shaking hands.

Nowadays, we have mask protocols,\nwhereby what you need to do

But that, too, is just a set of rules\n

that's somewhere\nstandardized and documented.

So computers use protocols\nall the time to govern

how they are sending information\nand receiving information.

And TCP and IP are two such protocols\n

What TCP/IP tells someone\nlike Phyllis to do

if she wants to send an email to Brian,\n

But on the outside of that virtual\n

And I'll describe this as destination\n

just like in our human world,\nyou would write the destination

And then she's going to put her own\n

corner, just like you, the\nsender, would put your own source

address in the human world.

But, instead of these addresses\n

Cambridge, Massachusetts 02138, USA,\n

on the internet have unique addresses\n

And an IP address is\njust a numeric identifier

on the internet, that allows\ncomputers, like Phyllis and Brian

to address these envelopes\nto and from each other.

And you've probably seen\nthe format at some point.

Typically, the format of IP\naddresses is something dot something

dot something dot something.

Each of those somethings,\nrepresented here with a hash symbol

is a number from 0 through 255.

And, based on that little\nhint, if each of these hashes

represents a number from 0\nto 255, each of those hashes

is represented with\nhow many bytes or bits?

Eight bits or one byte, which is to\n

an IP address must use\n32 bits or 4 bytes

if we rewind now to some of the\n

And what that means is,\nat least at a glance

it looks like we have 4 billion some\n

Now, unfortunately,\nthere's a huge number

of humans in the world these days,\n

have multiple devices, certainly\n

a laptop, and a phone, and you have\n

all of which need to be addressed.

So there's another type\nof IP address that's

starting to be used more commonly.

There's also version 6\nwhich, instead of 32 bits

uses 128 bits, which gives us a\n

for computers, so we can at least handle\n

So this is to say, what ultimately\nis going on this envelope

is the destination address, that is\n

address, that is Phyllis's IP address,\n

to point B, and if need\nbe, back, by just flipping

the source and the destination.

But on the internet, you presumably know\n

There's web servers, there's chat\n

Like there's all of these different\n

And so, when Brian\nreceives that envelope

how does he know it's an email, versus\n

versus something else altogether.

Well, it turns out that we\ncan look at the other part

of this acronym, the TCP in TCP/IP.

And what TCP allows us\nto do, for instance

is specify a couple of things.

One, the type of service whose\n

it does this with a numeric identifier.

And I'm going to go ahead and write down\n

And I'm going to write that in the\n

So technically, now,\nwhat's on this envelope

is not just the addresses,\nbut also a unique number

that represents what kind of service\n

whether it's email, or web traffic,\nor Skype, or something else.

These numbers are standardized, and here\n

not even in the context of email,\nbut in the context of the web.

Port 80 is typically used\nwhenever an envelope contains

a web page, or a request\ntherefor, or the number 443

when that request is actually\n

know, in URLs, known as HTTPS,\n

More on what the HTTP means later.

If it's email, the number\nmight be 25 or 465, or 587.

These are the kinds of things you\n

But if you've ever had to configure,\nlike, Outlook or even Gmail

to talk to another account,\nyou might very well

have seen these numbers, by typing\n

and then a number, which is only to\n

But they're typically\nnot things you and I

have to care about, because\nservers and computers nowadays

automate much of this process.

But that's all it takes, ultimately, for\n

But what if it's a really big message?

If it's a short email, It might\n

But suppose that Phyllis wants\nto send Brian a picture of a cat

like this, or worse, a video of a cat.

It would be kind of inequitable\nif no one else could do anything

on the internet, just\nbecause Phyllis wants

to send Brian a really big picture,\na really big video of a cat.

It would be nice if we could kind\n

across these routers, so that\nwe can give a little bit of time

to Phyllis, a little bit\nof time to someone else

a little bit of time to someone else,\n

But in terms of fairness, she\ndoesn't monopolize the bandwidth

And this, then, allows us to\ndo one other feature of TCP/IP

which is fragmentation,\nwhere we can temporarily

and Phyllis's computer would\ndo this automatically, fragment

the big packet in question,\nor the big file in question

and then use, not just a single\n

If we do that, though,\nwe're probably going

to need one other piece of information,\n

Like, if you were implementing this,\n

into four parts, like,\nintuitively, what might you

want to put virtually on the\noutside of this envelope now?

SPEAKER 1: The order of them, somehow.

So probably something like part\none of four, part two of four

part three of four, and so forth.

So I'm going to write one more thing\n

I put some kind of\nsequence number, that's

just a little bit of a\nclue to Brian, to know

in what order to\nreassemble these things.

And even more powerfully\nthan that, this actually

gives us this simple primitive of\n

If Brian receives envelopes like these,\n

field, what other feature\ndoes TCP apparently

enable Brian and Phyllis to implement?

But it's not just the\nordering of the packets.

What else might be useful about\nputting numbers on these things

AUDIENCE: How about if you like missed.

SPEAKER 1: If you missed something\nthat was intended to be sent

So short answer, exactly, yes, TCP,\n

that we\'re including, can quote\nunquote "guarantee" delivery.

Because if Brian receives one\nout of four, two out of four

four out of four, but\nnot three out of four

he now knows, predictably, that\n

And so this is why pretty much\nalways, if you receive an email

you either receive the whole\nthing, or nothing at all.

Like sentences and words and\nparagraphs should never really

Or if you download a\nphotograph on the web

it shouldn't just have a\nblank hole in the middle

just because that packet of\ninformation happened to be lost.

TCP, if it is the protocol being used to\n

ensures that it either all gets there,\n

So this is an important property,\nbut, just as a teaser there's

There's something called UDP,\nwhich is an alternative to TCP

that doesn't guarantee delivery.

And just as a taste of why you might\n

maybe you're watching like a streaming\n

You probably don't\nnecessarily want the thing

to buffer and buffer and buffer, just\n

because you're going to\nstart to miss things.

And then you're going to be the\nonly one in the world watching

the game that ended 20 minutes ago, when\n

Similarly for a voice call,\nit would be really annoying

if our voice is constantly buffered.

So UDP might be a good\nprotocol for making sure

that, even if the person on the other\n

It's not pausing and\nresending and resending

because that would really slow down\n

So, in short, IP handles the\naddressing of these packets

and standardizes numbers that every\n

and TCP handles the standardization\nof like what services

can be used, between points A and\n

but presumably, when Phyllis\nsends a message to Brian

she doesn't really know\nand probably shouldn't

care what his IP address is, right?

These days it's, like, I don't\nknow most of the phone numbers

I instead look them up in some way.

And, indeed, when you visit a\nwebsite, what do you type in?

It's typically not something\ndot something dot something dot

something, where each of\nthose somethings is a number.

What do you typically\ntype in to a browser?

Something like Stanford.edu,\nHarvard.edu, Yale.edu, gmail.com

or any other such domain name.

And so, thankfully,\nthere's another system

on the internet, one more acronym for\n

And pretty much every network on the\n

your own home network, somewhere,\nsomehow has a DNS server.

You probably didn't have\nto configure it yourself.

Someone else did, your campus, your\n

But there is some server connected\n

via wires or wirelessly, that just\n

a big spreadsheet, if you\nwill, or, if you prefer

a hash table, that has at least\ntwo columns of keys and values

Where on the left hand\nside is what we'll

call domain name,\nsomething like Harvard.edu

Yale.edu, an IP address on the\nright hand side, that is to say

a DNS server's purpose in life\nis just to translate domain names

And vice versa, if you want\nto go in the other direction

and technically, just to be precise, it\n

And we'll see what those\nare in just a moment.

But again, all of this just\nkind of happens magically

when you turn on your\nphone or your laptop

today, because all of these things\n

So how can we actually start to\n

Well, let's go ahead and poke around,\n

Let's see what we can actually do\n

If we now have the ability to\nmove data from point A to point B

and what can be in that envelope\ncould be, yes, an email

but today, onward, it's really\ngoing to be web content.

There's going to be content\nthat you're requesting

like give me today's home page.

And there's content\nyou're sending, which

would be the contents of\nthat actual home page.

And so, just to go one level deeper,\n

are getting from point A to\npoint B using TCP/IP, let's

put something specific inside of them,\n

but something called HTTP, which\n

You've seen this for\ndecades now, probably

in the form of URLs, so much so that you\n

Your browser just adds\nit for you automatically

and you just type in Harvard.edu,\nor Yale.edu, or the like.

But HTTP is just a final\nprotocol that we'll

talk about here, that just\nstandardizes how web browsers and web

So this is a distinction now\nbetween the internet and the web.

The internet is really like\nthe low-level plumbing

all of the cables, all of a\ntechnology that just moves packets

from left to right, right to left, top\n

to point B. You can do anything you\n

email and web and video and chat\nand gaming, and all of that.

So HTTP, or the web,\nis just one application

that is conceptually on top of,\nbuilt on top of the internet.

Once you take for granted\nthat there is an internet

you can do really\ninteresting things with it

just like in our physical world,\nonce you have electricity

you can just assume you can do really\n

without even knowing\nor caring how it works.

But now that you'll be\nprogramming for the web

it's useful to understand how\nsome of these things indeed work.

So let's take a peek at the\nformat of the things that

These days, it's usually\nactually HTTPS that's

in play, where, again,\nthe S just means secure.

More on that later, but the HTTP is\n

go inside of these envelopes.

And wonderfully, it's just\ntextual information, typically.

There is a simple text format\nthat humans decided on years ago

that goes inside of these\nenvelopes, that tells a browser how

to request information from a server,\n

to that client with information.

So here's, for instance, a canonical\n

What might you see at the end of this?

You might sometimes see a slash.

Browsers nowadays kind of simplify\n

But slash, as we'll see, just\nrepresents like the default

folder, the root of the\nweb server's hard drive

like whatever the base is of it.

It's like C colon backslash on\n

But a URL can have more than that.

It can have slash path,\nwhere path is just a word

or multiple words, that sort of\n

That path could actually be\na specific file, we'll see

like something called file.html.

More on HTML in just a bit, or\nit can even be slash folder

maybe with another slash, or\nmaybe it can be /folder/file.html.

Now these days Safari, and even Chrome\n

are in the habit of trying to hide\n

Ultimately, though, it'll\nbe useful to understand

what URLs you're at, because\nit maps directly to the code

that we're ultimately going to write.

But this is only to say that\nall this stuff in yellow

refers to, presumably, a specific\nfile and/or folder on the web

server, on which you're programming.

Example.com, this is the domain\n

Example.com is the\nso-called domain name.

This whole thing, www.example.com,\n

And what the WW is referring\nto is specifically the name

of a specific server in that domain.

So back in the day, there was\na www.example.com web server.

There might have been a\nmail.example.com mail server.

There might have been a\nchat.example.com chat server.

Nowadays, this hostname, or\nsubdomain, depending on the context

can actually refer to a whole\nbunch of servers, right?

When you go to www.facebook.com,\nthat's not one server

that's thousands of servers nowadays.

So long story short,\nthere's technology that

somehow get your data\nto one of those servers

but this whole thing is what we\n

This thing here, hostname,\nin the context of an email

address it might alternatively\nbe called a subdomain.

This thing here, top\nlevel domain, you probably

know that dot com means commercial,\n

Dot org is similar, dot net.

Some of them are a bit restricted,\n

dot edu is just for accredited\neducational institutions.

But there are hundreds, if\nnot more, top level domains

nowadays, some more popular than others.

CS50's tools, for instance, use CS50.io.

IO sort of connotes input-output.

It actually belongs, though, to\n

whose country code is .io, and you see\n

Indeed, it's something.uk,\nsomething.jp, and the like typically

But some of them have been\nrather co-opted, .tv as well

because they have these\nmeanings in English as well.

Lastly, this is what\nwe'll call the protocol.

That specifies how the server uses\n

to point B. So what is\ninside of this envelope?

Let's now start poking\naround a little bit more.

What is inside of this envelope?

It's essentially, for our\npurposes today, one of two verbs

And if any of you have dabbled\n

you might have seen some\nof these terms before.

But these two verbs describe\njust how to send information

Long story short, more\non this next week

GET means put any user input\nin the URL, POST means hide it

so that things you're searching for,\n

usernames and passwords you're\n

and are therefore visible\nto anyone with access

to your computer and\nyour search history

but rather they're somehow provided\n

But for now, we'll focus\nalmost entirely on GET

which is perhaps the most common\n

And what we're going to do is this.

Let me switch over just\nto a blank screen here.

And if we assume that little\nold me is this laptop here

and I'm connected to the cloud, and\n

want to request the web page\nof, Harvard.edu or Yale.edu

it's really going to\nbe a two-step process.

There's going to be a request,\n

and then, hopefully,\nthe server that hears

that request is going to reply with\n

And other terms that are\nrelevant here, is my laptop

is the so-called client,\nHarvard.edu, Yale.edu, whatever

it is, is the so-called server.

And just like in a restaurant, where\n

the server might bring it to you.

It's, again, that kind of\nbidirectional relationship.

One request, one response, for\neach such web page we request.

All right, so what's inside these\n

Well, this arrow, this line I\njust drew from left to right

representing the request, technically\n

When you visit a web\npage, using your browser

on your phone, laptop, or desktop,\n

and the textual message your Mac or PC\n

looks a little something like this.

The verb GET, the URL, or rather\nthe path that you want to get

slash represents the\ndefault page on the website.

HTTP/1.1 is just some mention of\n

Now we're up to version 2, and\n

And the envelope contains some\n

the fully qualified domain name.

This is because single servers can\n

If you're using Squarespace or Wix or\n

nowadays, you don't get your own\npersonal server, most likely.

You're on the same server as\n

But when your customers,\nyour users' browsers

include a little mention of your\n

name in the envelope,\nSquarespace and Wix just

know to send it to your web page or\n

Dot dot dot, there's\nsome other stuff there.

But that's really the essence\nof what's in these requests.

Hopefully, then, when your browser\n

Well, hopefully, a response\nthat looks like this, HTTP/1.1

so the same version, some\nstatus code, like a number 200

and then literally a short phrase like\n

Then it contains some other\n

And we'll see that this,\ntoo, is standardized.

Text/HTML means here comes some\n

It could instead be image/jpeg\nor Image/png, or video/mp4

there are these different content\n

that uniquely identify types\nof files, that come back

similar in spirit to file\nextensions, but a little more

Then there's some more\nstuff, dot dot dot.

But in general, what you see here, are\n

These keys and values are\notherwise known as HTTP headers.

And your browser has been sending\n

And, indeed, we can see\nthis right now ourselves.

Let me go over, in just a\nsecond, to Chrome on my computer

though you can do this kind of\n

I'll go ahead and visit\nHTTP://Harvard.edu, Enter.

And, voila, I'm at Harvard's\nhome page for today.

But this is what it\nlooks like right now.

Well, I typed in the URL, but\nnotice it changed a little bit.

It actually sent me to\nHTTPS and added the www

even though I didn't type that.

But it turns out we can poke around\n

I'm going to start to use incognito\n

care that people know\nI'm visiting Harvard.edu

but because it throws away\nany history that I just did.

So that every request is going\nto look like a brand new one

and that's just useful\ndiagnostically, because we're always

going to see fresh information.

My browser is not going to remember\n

But I'm going to go\nup to View, developer

developer tools, which is something\n

And there's something\nanalogous for Firefox and Edge

and Safari and other browsers.

Developer tools is going to\nopen up these tabs down here.

I don't really care what's new, so I'm\n

And I'm going to hover over the\nNetwork tab for just a moment.

And now I'm going to go and\nsay HTTP://Harvard.edu, so

I'm going to hit Enter,\nand a whole bunch of stuff

just flew across the screen.

And if I zoom in down here, my God,\n

is downloading, what 17, 18,\n19 megabytes, 20 megabytes

millions of bytes of information,\nover 111 HTTP requests.

In other words, a bit of a\nsimplification, but my browser

unbeknownst to me, sent one\nenvelope initially with the request.

Then the server said,\nOK, by the way, there's

110 other things you need, 112\nother things you need to get.

So my computer went back and forth,\n

Well, inside of Harvard's web\npage is a whole bunch of images

and maybe sound files and\nvideos and other stuff

that all need to be\ndownloaded and to compose

what is ultimately the web page.

But I don't care about like\n100 plus of these things.

Let's focus on the very first one first.

The very first request\nI sent was up here.

And I'm going to click on this\nrow, under the Network tab.

And then I'm going to see a\nbit of diagnostic information.

To an average person using the\n

just as you probably didn't\ncare about it until right now.

But if I scroll down to\nrequest headers, you will see

if I click View source, literally\n

my Mac just sent to Harvard.edu.

Two of the lines are familiar,\nget/http1.1, host:harvard.edu

and then other stuff that, for now,\n

But let's look at the response\nthat came back from the server.

I'm going to scroll up now and\n

There's no 200, there's no word OK.

Curiously, harvard.edu\nhas moved permanently.

Well, there's a whole\nbunch of stuff here

that's not that interesting for us.

But this line, location, is interesting.

This is an HTTP header, a\nstandardized key value pair

that's part of the HTTP\nprotocol, that is, conventions.

And if I highlight just\nthis one, it's telling me

mm-mmm, Harvard is not\nat HTTP://Harvard.edu

Harvard's website is now, and perhaps\n

Probably someone at Harvard wants\n

So they redirected you\nfrom HTTP to HTTPS.

Maybe the marketing people want you to\n

Just to standardize things,\nbut there are technical reasons

to use a hostname, and not\njust the raw domain name.

And all this other stuff is sort\n

now, because a browser that\nreceives a 301 response knows

by design, by the definition of HTTP,\n

And that's why, in my browser, all of\n

because I didn't really know or\ncare about all of those headers.

But that's why and how I\nended up at this URL here.

My browser was told to go\nelsewhere via that new location.

And the browser just\nfollowed those breadcrumbs

if you will, at which point it\n

and files, and so forth, that\ncompose this particular page.

And let me actually go\ninto VS Code, if only

because it's a little more pleasant to\n

without actually using\na full-fledged browser.

So now let's just use\nan equivalent program.

It's called Curl, for\nconnecting to a URL, that's

going to allow me to play with\n

without bothering to download\nall the images and text

and so forth from the website.

It's going to allow me to\ndo something like this.

Let me go ahead and run, for instance,\n

line arguments that says\nsimulate a GET request textually

And let's go to\nHTTP://Harvard.edu Enter.

Now, by way of how Curl, works,\nI'm just seeing the headers.

It didn't bother downloading\nthe whole website.

And you see exactly the same\nthing, 301 moved permanently.

Location is, indeed, this one here.

So that's kind of interesting.

But let's follow it manually now.

Let's now do what it's telling me to do.

Let's go to the location, with\nHTTPS and the www and hit Enter.

And now, what's a good\nsign with this output?

SPEAKER 1: 200 OK, that\nmeans I'm seeing, presumably

if I were using a real browser,\n

Looks like Harvard's version of HTTP\n

It's using HTTP version\n2, which is fine.

But 200 is indeed indicative\nof things being OK.

Well, what if I try\nvisiting some bogus URL

like Harvard.edu, when this file does\n

probably doesn't exist, and hit Enter.

What do you see now, that's perhaps\nfamiliar, in the real world?

All of us have seen\nthis probably endlessly

from time to time, when you\nscrew up by mis-typing a URL

or someone deletes the\nweb page in question.

But all that is is a\nstatus code that a browser

is being sent from the server,\nthat's a little clue as to what

the actual problem is,\nunderneath the hood.

So instead of getting\nback, for instance

something like OK, or moved permanently,\n

Well, it turns out there's\nother types of status codes

that you'll start to see over time,\n

302, 304, 307 are all similar in spirit.

They're related to redirecting the\n

401, 403, unauthorized or forbidden.

If you ever mess up\nyour password, or you

try visiting a URL you're\nnot supposed to look at

you might see one of these\ncodes, indicating that you just

don't have authorization for those.

404 not found, 418, I'm a\nteapot, was an April Fool's joke

by the tech community years ago.

And, unfortunately,\nall of you are probably

on a path now to creating\nHTTP 500 errors, once

next week, we start writing\ncode, because all of us

We're going to have typos, logical\n

just like segfaults were in the world of\n

503 service unavailable, means\nmaybe the server is overloaded

And there's other codes there.

But those are perhaps some\nof the most common ones.

Has anyone, we can get away with\n

has anyone ever visited\nSafetySchool.org?

HTTP://SafetySchool.org,\ndare we do this, Enter.

--so this has been like a\njoke for like 10 or 20 years.

Someone out there has been\npaying for the domain name

safetyschool.org, just for\nthis two second demonstration.

But we can now infer, how did this work?

The person who bought that domain\nname and somehow configured

DNS to point to their web server,\n

what is their web server\npresumably spitting out

whenever a browser requests the page?

Let me increase my terminal window.

Let me do Curl-I-xget\nHTTP://safetyschool.org Enter

and that's all this website does.

There's not even an\nactual website there.

No HTML, no CSS languages\nwe're about to see.

It literally just exists on the\n

In fairness, there are others.

Let me actually do another one here.

Instead of safetyschool.org,\nturns out someone

some years ago, bought\nHarvardSucks.org Enter.

And when we do this, you'll see that,\n

This demo actually\nworked for so many years.

But someone has stopped paying\nfor the Squarespace account

OK, so, fortunately, we\ndid save the YouTube video

And so, just to put this\ninto context, since it's

been quite a few years,\nHarvard and Yale, of course

have this long-standing rivalry.

There is this tradition\nof pranking each other.

And, honestly, hands down, one of the\n

It's about a three-minute retrospective.

It's one of the earliest\nvideos, I dare say, on YouTube

so the quality is\nrepresentative of that.

But let me go ahead and\nfull screen my page here.

And what used to live at\nHarvardSucks.org is this video here.

If we could dim the lights\nfor about three minutes.

- Actually we're going\nall the way to the top.

- We're here to trip up Harvard.

- Pass from the top one, pass it down.

- It's nice to say the ERA sucks.

It's going to have to happen.

- It's actually going to happen.

I can't [BEEP] believe this.

- What do you think of Yale?

- Because they don't have it.

- Probably that's going\nto be legible, very small.

- Says, are we in boats now?

- How many extra are there?

- You guys are from Harvard, right?

- Just make sure everyone has one.

- What do you think of Yale, sir?

- Going to be, do one more time.

SPEAKER 1: All right, so thanks to\n

Let's go ahead here and consider, in\n

down inside of the\nenvelope, because we now

have the ability to get data from,\n

Let's consider for just a moment\n

that we now have this ability to\n

And we have the ability to\nspecify in those envelopes what

it is we want from the website.

We want to get the home page.

We want to get back the HTML.

In fact, we don't yet have the language\n

are written, namely HTML and CSS.

But let's go ahead and take\na five minute break here.

And when we come back, we'll\nlearn those two languages.

So we've got three\nlanguages to look at today.

But two of them are not\nactually programming languages.

What makes something a programming\n

is that there are these constructs via\n

You might have variables, you\nmight have looping constructs.

You have the ability,\nultimately, to express logic.

HTML and CSS aren't so much about\n

and the aesthetics of a page.

And so we're going to create\nthe skeleton of a web page using

this pair of languages, HTML and CSS.

And then toward the\nend of the today, we'll

introduce an actual\nprogramming language

that actually is pretty similar\nin spirit and syntactically

to both C and Python, but that's going\n

just static, things that you look at,\n

And then next week again, in week 9,\n

tie all of this together, so that you\n

talking to a back-end\nserver, and creating

the experience that you and I now take\n

Well, let's go ahead and do this.

Let's quickly whip up something\nin this language called HTML.

I'm going to go ahead and create a\n

The convention is typically to\nend your file names in dot html.

And I'm going to go ahead\nand bang this out real quick.

But then we'll more slowly step\n

So I'm going to say doctype\nhtml open bracket html

and then notice I'm going to do open\n

And I'm leveraging a feature of VS\n

generally, to do a bit of autocomplete.

So you'll see that there's this symmetry\n

but I'm not typing all of these things.

VS Code is automatically generating the\n

Let me go ahead and\nsay, Open the head tag.

I'll say something cute\nlike, Hello, title.

And then down here, I'm going to\n

and say something like Hello, body.

And let me specify at the very top,\n

So at this moment, I have a file in my\n

VS Code as we're using it,\nof course, is cloud-based.

We're using it in a browser,\neven though you can also

download it and run it on a Mac and PC.

So we are in this weird\nsituation where I'm

using the cloud to\ncreate a web page, and I

want that web page to also live in\n

But the thing about VS\nCode, or really any website

that you might use in a browser, by\n

TCP port number 80 or\nTCP port number 443

which is HTTP and HTTPS respectively.

But here I am, sort of\na programmer myself

trying to create my own\nwebsite on an existing website.

So it's a bit of a weird situation.

But that's OK, because\nwhat's nice about TCP

is that you and I can just pick port\n

That is, we can control\nthe environment entirely

by just running our own web server\n

This is a command that we\npreinstalled in VS Code here.

And you'll notice a pop-up just came up.

Your application running\non port 8080 is available.

That's a commonly used TCP port\nnumber, when 80 is already used

and 443 is already used,\nyou can run your own server

on your own port, 8080 in this case.

I've opened that tab in advance, and\n

here I see a so-called directory\n

So I don't see any of my other files.

I don't see anything\nbelonging to VS Code itself.

I only see the file that I've created\n

And so if I click on this file\nnow, I should see Hello, body.

But that's because the\ntitle of a web page

nowadays is typically\nembedded in the tab.

And if I'm full screen in my\nbrowser, there are no tabs.

So let me minimize the window a bit.

And now you can see just in this\n

here, that Hello, body, is\nin the top left hand corner.

And if I zoom in, there's Hello, title.

I have gone ahead and created\nmy own web page in HTML

in a file called Hello.html.

And then I have opened up\na web server of my own

configured it to listen\non TCP port 8080

which just says to the internet, hey,\n

not on the standard port number,\n80 or 443, listen on 8080.

And this means I can develop a website\n

here, which is\nincreasingly common today.

All right, so now let's consider\n

HTML is characterized really by just\n

Most of what I just typed were tags,\n

Here's the same source code that I\n

Let's consider what this is.

The very first line of\ncode here, doctype html

It's the only one that starts with\n

There's no more exclamation\npoints thereafter, for now.

This is the document type declaration,\n

it's just got to be there nowadays.

It's like a little breadcrumb\nat the beginning of a file that

says to the browser, you are about to\n

That line of code has changed\nover time, over the years.

The most recent version of it\nis nice and succinct like this

and it's just a clue to the\nbrowser as to what version of HTML

is being used by you, the programmer.

All right, what comes after that?

Well, after that, and I've\nhighlighted two things in yellow

this is what we're going to\nstart calling an open tag

or a start tag, open bracket HTML\nthen something, close bracket

is the so-called start or open tag.

Then the corresponding close\nor end tag is down here.

You use the same tag number, you\nuse the same angled brackets.

But you do add a slash, and\nyou don't repeat yourself

with any of the things\ncalled attributes

because, what is this thing here?

Lang equals quote unquote\n"en," means the language

of my page is written\nin the English language.

The humans have standardized\ntwo and three letter codes

for every human language, right now.

And so this is just a clue to the\n

and accessibility purposes,\nwhat language the web page

Not the tags, but the words, like\nHello, title and Hello, body

which while minimalist,\nare indeed in English.

So when you close a tag, you close\nthe name of it with the slash

You don't repeat the attribute.

That would just be annoying to\nhave to type everything again.

But notice the pattern here.

But this is another example of\nkey value pairs in computing.

The key is Lang, the\nvalue is E-N for English.

The attribute is called\nLang, the value is

called, it is E-N. So again,\nit's just key value pairs

in just yet another context.

Probably the browser's using a\nhash table underneath the hood

to keep track of this stuff, like a\n

Again, humans keep using the same\n

The nesting is important\nvisually, not to the computer

but to us, the humans,\nbecause it implies

that there's some hierarchy here.

And, indeed, what is inside\nof the HTML tag here?

Well, we have what\nwe'll call the head tag.

The head tag says, hey, browser,\n

And then the body tag\nsays, hey, browser

here comes the body of the page.

The body is like 99% of the user's\n

The head is really just the address\n

like the title that we saw a moment ago.

Just to introduce the vernacular,\n

as an element, has two children,\n

which is to say that head\nand body are now siblings.

So you can use the same kind of\n

when talking about trees, weeks ago.

If we look at the head tag, how\n

I'm seeing one, and,\nindeed, at least if we

ignore all the white space, the\n

there's just one child, a title element.

And an element is the terminology that\n

So this is the title element.

And the title element has one\nchild, which is just pure text

otherwise known as a text node.

Recall, node, from our discussions\nof data structures weeks ago.

If we jump then to the body, which\n

it too has one child, which is just\n

that says, quote unquote "Hello, body.

What's nice about this indentation,\n

is not going to care, is that it\nimplies this kind of structure.

And this is where we connect,\nlike weeks 5 and now weeks 8, here

is the tree structure we began to\n

It's not a binary tree,\neven though this one happens

to have no more than two children.

It's an arbitrary tree that can\n

But if we have a special node\nhere that refers to the document

the root node, so to speak, is\nHTML, drawn with a rectangle

here, just for discussion's sake.

It has two children, head\nand body, also rectangles.

Head has a title child,\nand then it and body

have text nodes, which I've\ndrawn with ovals instead.

Which is only to say that when your\n

downloads a web page,\nopens up that envelope

and sees the contents that\nhave come back from the server

it essentially reads the\ncode that someone wrote

the HTML code, top to\nbottom, left to right

and creates in the browser's\nmemory, in your Mac or your PC

or your phone's memory or RAM,\nthis kind of data structure.

That's what's going on\nunderneath the hood.

And that's why aesthetically,\nit's just nice, as a human

to indent things stylistically,\nbecause it's very clear then

to you, and to other programmers,\n

So that's it for like\nthe fundamentals of HTML.

We'll see a bunch of tags\nand a bunch of examples now.

But HTML is just tags and attributes.

And it's the kind of thing that\n

Eventually, many of them get ingrained.

I constantly check the reference\nguides or stack overflow

if I'm trying to figure out,\nhow do I lay something out.

It's really just these\nbuilding blocks that

allow you to assemble the\nstructure of a web page.

This one is being super simple,\n

Any questions on this\nframework, before we

start to add more tags, more\nvocabulary, if you will?

AUDIENCE: What would happen\nif we put the title tag?

SPEAKER 1: If we put the hello tag\n

So let me actually go to this,\nand say open bracket title

whoops, sometimes you don't want\n

I've gone ahead and changed the file.

Let me go and open up, give me a\n

and go back to the URL that has my page.

And let me go ahead now\nand click on Hello.html.

And in this case, it looks like\nwe don't actually see anything.

So the browser is hiding it.

Technically speaking, browsers\ntend to be pretty generous.

And half the time, when\nyou make mistakes in HTML

it will display, it might display--

not display as you intend it.

It might not display the same on\n

There is a tool, though,\nthat we'll see, that

can help answer this question for you.

For instance, if I go\nto Validator.w3.org

W3 is the World Wide\nWeb Consortium, a group

of people that standardize\nthis kind of stuff

I can click on Validate\nby direct input, and just

copy paste my sample HTML into\nthis box, and click Check.

And I should see,\nhopefully, that indeed, it's

an error, what you proposed that I do.

The browser just did its\nbest to do something

which was to show me nothing at least,\n

But if I revert that change, and\nlet me undo what we just did

let me copy my original code back\n

now you can see, conversely,\nmy code is now correct.

And there's automated\ntools to check that.

But we'll encourage you, for\nproblem sets and projects

to use that particular manual tool.

All right, so let's go ahead\nand enhance this a little bit

by introducing a whole\nbunch of tags, just

to give you a sense of some\nof the building blocks here.

So I'm going to go ahead and create\n

And I'm just going to do a bunch of\n

so I'm not constantly typing all\n

because I want everything\nto be the same here

except I'm going to change my title\n

And inside of the body, I need a\n

And I don't really want\nto come up with some text.

So let me go to some random website\n

which if you're involved in like\n

this is placeholder text, kind of looks\n

Here, though, I have a handy way of\n

in something that looks like Latin.

And I've put those,\nnotice, inside of the body.

Look how long the\nmade-up words here are.

So let me go now into\nmy browser tab here.

Let me reload this page, and you'll\n

Paragraphs.html, which is\nmy new one, and Hello.html.

Let me click on Paragraphs.html,\n

SPEAKER 1: Yeah, it's obviously one\n

So that's interesting, but it's just a\n

It will only do what you say.

And each of these tags tells the\n

and then maybe stop doing something,\n

Hey, browser, here comes\nthe head of my page.

Hey, browser, here comes the\ntitle of my page, Hello, title.

Hey, browser, that's it for the title.

That's it for the head,\nhere comes the body tag.

So it's kind of having this\nconversation between the browser

between the HTML and the browser,\ndoing literally what it says.

So if you want a\nparagraph, you're probably

going to want to use\nthe P tag for paragraph.

And I'm going to go ahead\nand add this to my code.

I'm going to keep things neat,\n

Let me create another paragraph\ntag here, and close it

right after that one,\nindenting again, and I'm

keeping everything nice and orderly.

Let me indent that, and then let me\n

So again, a little tedious, but now I\n

hey, browser, start a paragraph.

Hey, browser, stop that paragraph.

Let me go back to the\nbrowser window here.

Let me hit Command R or\nControl R to reload the page.

And voila, now I have three\ncleaner paragraphs, all right?

So there's a P tag for paragraphs.

So now we have that\nparticular building block.

What if I want to add, for instance,\nsome headings to this page?

Well, that's something\nthat's possible, too.

Let me go ahead and create a\nnew file called Headings.html.

Let me copy and paste\nthat same code as before.

But now, let's preface each\nparagraph with maybe H1.

And I'm going to just\nwrite the word one.

And here I'm going to say H2, two.

And down here I might say H3, three.

So this is another tag,\nanother three tags, H1, H2, H3.

As you might have inferred\nby the file name I chose

this just gives you headings, like in\n

or subsections, or in\nan academic paper, you

have different hierarchies to\nthe text that you're writing.

So now that I've added an H1 tag,\n

two, H3 tag and the word three,\nlet's go back to the browser

reload the page again,\nand voila, once the page

reloads, I'll do it with the\nmanual button, reload the page.

AUDIENCE: Not in headings file.

SPEAKER 1: Right, I'm\nnot in the headings file.

OK, now we see some evidence of this.

Again, it's nonsensical content.

But you can kind of see that\nH1 is apparently big and bold

H2 is slightly less big, but still bold.

H3 is the same but a little smaller.

And it goes all the way down to H6.

After that, you should probably\nreorganize your thoughts.

But there are six\ndifferent hierarchies here

as you might use for chapters, sections,\n

So those are headings, as an\nHTML tag, in our vocabulary.

What's a common thing, too, well, let\n

and get some boilerplate here,\ncreate a file called List.html.

Let's create a simple\nlist inside of my body

and I'll give this a title of List.

And let me fix the title of this\none to be Headings, as well.

So in List.html, suppose I want to have\n

they're like a computer\nscientist's go-to words

just like a mathematician might say xyz.

Foo, bar, baths is in List.html.

Let me go back to my\nbrowser, hit the Back button.

There's List.html, and, hopefully,\n

on each line like a nice little\nlist, but, of course, I do not.

Chrome thinks it might be Arabic.

But that's curious, too,\nbecause the Lang attribute

So Google is trying to override it.

All right, what's the\nobvious explanation

why we're seeing foo, bar, and\nbaths on the same line, and not

AUDIENCE: We didn't tell it.

SPEAKER 1: We didn't tell it to do that.

So we need paragraph tags,\nor maybe something else.

Turns out there is something else.

There is a UL tag, for an\nunordered list in HTML

inside of which you can\nhave LI tags, for list item

inside of which you can put your words.

So there's my foo, there's\nmy bar, there's my baths.

And, again, notice that VS Code\nis finishing my thought for me.

But notice the hierarchy, open\nUL, open LI, close LI, open LI

close LI, open LI, close LI, close UL.

So it's sort of done\nin reverse order here.

Let me go back to my browser, reload\n

a default bulleted list, that\nstill seems to be in Arabic.

What if I want this list to be numbered?

Well, you can probably guess.

If you don't want an unordered list, but\n

SPEAKER 1: OL, sure, so let's try that.

Not always that easy as just\nguessing, but in this case

OL is going to do the trick.

Let me go back to my other browser.

Let me reload the page, and now it's\n

It's a tiny thing, but\nthis is actually useful

if you have a very long\nlist of data, and maybe you

might add some things in the\nmiddle, the beginning, or the end.

It would just be annoying to\nhave to go and renumber it.

The computer is doing it\nfor us by, instead, just

numbering from top to bottom here.

All right, what about\nanother type of layout

not just paragraphs, not just\n

You've got some research\ndata you want to present

some financial data you want to present,\n

How might we go about laying\nout data, a la a table?

Well, let me create a\nfile called Table.html

and I'll just copy paste\nwhere we started earlier.

Let me start to close\nsome of these other files.

And in Table.html, this is\ngoing to be a bit more HTML

but I'm going to go ahead and do this.

Table and close table, tables\ncan have table headings.

So T head is the name of that tag, and\n

So I'm going to add that tag.

And this is a common technique,\nsort of start your thought

finish your thought, and then go\n

What do I want to put in this table?

How about a bunch of names and numbers.

So, for instance, like left\ncolumn name, right column number.

So let's create a table row,\nwith what's called the TR tag.

Let's create a table heading with\n

Let's create another table\nheading called number here.

And all of that, to be\nclear, is in one table row.

Meanwhile, in the table body,\nlet me create another table row

but this time, it's not a heading.

Now I'm in the guts of my table.

Let's do table data, which is synonymous\n

in like an Excel spreadsheet\nor Google spreadsheet.

In this TD, I'm going to\nsay like Carter's name

and then lets grab Carter's number\n

Then let's put me into the mix, and\n

But we'll see that there's a lot\nof shared structure with HTML.

Let me go ahead and do mine,\n

So we're getting to be\na lot of indentation.

I'm using four spaces by default.\n

So long as you're consistent,\nthat's considered good style.

But let me go back to my\nbrowser here, and hit back.

That then brings me to my\ndirectory listing again.

Here's Table.html, and this\nis not that interesting yet.

But you can see that there's\ntwo columns, name and number.

Because it's a table heading, TH,\n

In there, in the table, are two\n

It's a little, oh, I forgot my\nnumber one, sorry about that.

One and one, it's not the\nprettiest table, right?

I feel like I kind of\nwant to separate things

a little more, maybe put\nsome borders or the like.

But with HTML alone, I'm really\nfocusing on the structure alone.

So we'll make this prettier soon.

But for now, this is how you\nmight lay out tabular data.

All right, let me pause here just\n

But, again, the goal right now\nis just to kind of throw at you

some basic building blocks, that, again,\n

But we're going to start\nstylizing these things soon, too.

SPEAKER 1: How do you indent paragraphs?

For that, we'll probably\ngoing to want something

called CSS, Cascading Style Sheets.

So let me come back to\nthat, in just a little bit.

For the stylization of these things,\n

we're going to need a\ndifferent language altogether.

All right, well, let's\nnow create what the web

is full of, which is like\nphotographs and images and the like.

Let me go ahead and create a new file\n

and change the title\nhere to be, say, Image.

And then, in the body of this page,\n

The interesting thing about an\nimage is that it's actually not

going to have a start tag and an end\n

Like, how can you start an image\nand then eventually finish it?

It's either there or it isn't.

So some tags do not have end tags.

So let me do image, IMG,\nsource equals Harvard.jpeg.

And let me go ahead, and,\nin my terminal window

I actually came with a photo of Harvard.

Let me grab this for just a second.

Let me grab Harvard.jpeg and\nput it into my directory

pretend that I downloaded\nthat in advance.

And so I'm referring\nto now a file called

Harvard.jpeg, that apparently is in\n

If this image were on the\ninternet, like Harvard server

I could also say like\nHTTPS://www.Harvard.edu/FolderName

whatever it is, /Harvard.jpeg, but\n

to your own, the Scode environment,\nlike I did before class

by dragging and dropping this\nwhole file, this photo of Harvard

you can just refer to it\nrelatively, so to speak.

This would be the same thing\nas saying ./Harvard.jpeg

go to the current directory and\n

But that's unnecessary to type.

For accessibility purposes, though,\n

it's ideal if we also give this\nan alternative text, something

like Harvard University,\nin the so-called Alt tag

and this is so that\nscreen readers will recite

what it is the photo is,\nfor folks who can't see it.

And if you're just on a slow\nconnection, sometimes you'll

see the text of what\nyou're about to see

before the image itself downloads,\n

So let's now go back to my open browser\n

I now have Harvard.jpeg, which I\n

Let me click on Image.html,\nand here we have

a really big picture of Memorial\n

Suffice it to say I should probably fix\n

But to do that, we're going to probably\n

There are some historical\nattributes that you can still

use to control width and\nheight, and so forth.

But we're going to do it\nthe better way, so to speak

with a language designed for just that.

I also came prepared with,\nlet me grab another file here

let me grab a file called\nHalloween.mp4, which is an MPEG file.

And let me go ahead and change this\n

I'll change my title to be Video.

And let's go ahead and now\nintroduce another tag, a video tag

open bracket video, and then let me go\n

And then inside of the video tag,\n

is going to be specifically\n

I know, is Video/mp4, because I looked\n

And the video tag actually\nhas a few attributes.

I can have this thing autoplay.

I can mute it, so that there's no\n

Most browsers, to prevent ads, don't\n

So if you mute your video, it\nwill autoplay, but presumably not

And let me set the width of this thing\n

But I can make it any size I want.

So I know this just from having\n

Sometimes attributes don't have values.

They're just single words,\nautoplay, loop, muted

and that kind of makes\nsense for any attribute that

Like, it doesn't make sense\nto say muted equals something.

Like it's either muted or not.

The attribute is there or not.

Similarly, for these others, as well.

So let me go back to my other browser\n

There is both my mp4\nand also Video.html

which is the web page that embeds it.

And this is actually a video that was\n

So we included it in this demo here.

This is the video that was on\n

But you can see here that\nan image alone probably

would not have the same effect.

This is actually a movie, a small\nvideo file that's now looping.

Now there's some artifacts here, like\n

I feel like it'd be\nnice to fill the screen.

But again, we'll come back to a language\n

Well, it's not just\nvideos like this, that you

might want to put into a web page.

Let me create another\nfile called iFrame.html.

If you've ever poked around with, if\n

or if you had your own blog or\n

you might have been in the\nhabit of embedding videos

in websites, using like\nembedded YouTube players.

Well, this is possible, too, using\n

And an iFrame is just a tag\nthat is literally iFrame.

It has source equals,\nand then a URL, and if it

happens to be a YouTube video, there's\n

per YouTube's documentation.

So you might do www.youtube.com, embed,\n

So this is essentially what we do, if\n

videos, in the course's website, or\n

If I want to allow full screen,\nI can add this attribute, too

that I know exists, by just\nhaving checked the documentation.

And if I now go back to my browser\n

It's not going to fill\nthe screen, because I

haven't customized the aesthetics yet.

But it does seem to embed a tiny little\n

So we could change the width, change\n

But an iFrame is a way of embedding\n

page, if they allow\nit, so as to create all

the more of an interactive experience\n

All right, well, the web is, of\n

Let's go ahead and create\na file called Link.html.

And if we want to create a web page that\n

else, let's go ahead and do this,\n

Now, in like Facebook, Instagram, a lot\n

in a domain name, or a\nfully qualified domain name

it automatically becomes a link.

That's because those websites have\n

detects something that looks like a\n

HTML itself does not do that for you.

And so if I go back to my web\npage here, click on Link.html

if you type visit\nHarvard.edu period, that's

all you're literally going to see.

But instinctively, even if you've\n

we probably do here\nto solve this problem?

What could we do to solve this problem.

What do I probably want to add.

SPEAKER 1: Yeah, so I want to surround\n

And you wouldn't necessarily\nknow this until someone told you

or you looked it up, but the tag for\n

called the A tag for anchor.

It has an attribute called\nHREF for hyper-reference

which is like a link in\nthe virtual world to a URL.

So let me type in Harvard's\nfull and proper URL here.

Then I'm going to close the tag.

And then I can still say Harvard.edu,\n

But the place they're going to go\n

Now if I go back here\nand reload the page

now it automatically gets underlined.

It happens to be purple by default. Why?

Because we visited\nHarvard.edu a few minutes ago.

So my browser, by default, is indicating\n

But now I have a link\nthat I can click on

and if I hover over it but don't click,\n

there's a little clue as to where\n

And without going too\nfar down a rabbit hole

but to tie together our discussion\nof cybersecurity recently

what if I were to do\nsomething like this.

Right now you have the beginnings\nof a phishing attack of sorts

P-H-I-S-H-I-N-G, whereby you can\n

even an email using HTML, that tells\n

but they're really going to\ngo someplace else altogether.

And that is the essence of\nphishing attacks these days.

If you've ever gotten a bogus\nemail pretending to be from PayPal

or your bank or some\nother website, odds are

they've just written HTML\nthat says whatever they want

but the underlying tags might\ndo something very different.

And so having the instinct to look\n

or be a little suspicious when you're\n

it's this easy to socially\nengineer people, that is

deceive them, by just saying one\nthing and linking to another.

Well, what if I want to link my page\n

Well, if I want to link\nto that photo of Harvard

I can just do HREF = equals quote\n

in my same account, that\nis itself a web page.

So this is how you can create\nrelative links, multi-page web

pages, multi-page websites, yourself.

So if I now reload this\npage, hover over Harvard.edu

you'll see in the bottom left\nhand corner a very long URL.

But that's because I'm in code\nspaces right now, VS Code

and it's appending automatically\nto the end of my current URL

When I click on this, I\ngo immediately to that

file we created earlier, with a\ncrazy, big version of the image.

But that's just a way\nthat one page on a website

can link to another page on a website.

Let's do one other thing here,\nmaking things more responsive

because, in fact, that wasn't a\nparticularly responsive website.

Responsive means responding to the\n

is so important when someone\nmight be on a screen like this

or on a screen like this these days.

There are special tags we can use to\n

So let me create a file\ncalled Responsive.html.

I'm going to copy/paste some starting\n

And let me go ahead and just grab, let\n

from before, just so that we have a\n

And let me go ahead and\ngrab this text here.

And I'm just going to paste\nthis into the body of this page.

So I just have a big paragraph,\n

Let me go back to my browser.

Let me open up this file,\ncalled Responsive.html

to make the point that\nit is not yet responsive.

Let me go ahead and\nclick on Responsive.html.

But here's another trick you can do,\n

You can pretend to be another device.

Let me go to View, developer,\ndeveloper tools again.

Last time we used this to\nuse the Network tab, which

was kind of interesting, because we\n

But notice, we can also click on\nthis icon, in Chrome, at least

that looks like a mobile phone.

I can turn my laptop into what looks\n

I'm going to click the dot dot dot\n

Instead of on the bottom,\nwhere it might be by default

I'm going to move it\nto the right hand side.

So that now on the left,\nyou see what looks more

like the shape of a vertical phone.

And, in fact, if I go\nto my dimensions here

I'll choose something like\niPhone X, so a few years back.

Here's what that same website might\n

that looks pretty damn\nsmall, to be able to read it.

And that's because the\nwebsite has not automatically

responded to the fairly narrow\ndimensions of the iPhone

in question, or Android\ndevice, or whatnot.

So let me go ahead and do this.

Let me go back into my code.

And let me go into the head of\nthe page, and for the first time

This word is now all over\nthe internet, but there

is a metatag that is\ncalled, that allows you

to specify the name of some kind\nof configuration detail here

Viewport is the technical term\nfor the rectangular region

that the human sees in a browser.

It's essentially the body of the\n

And you can specify the\ncontent of the viewport

should have an initial scale of 1.

So it shouldn't be zoomed in or out.

And the width that the\nbrowser should assume

should be equal to the device's width.

These are sort of magical statements\nthat you just have to know

or copy/paste or transcribe, that\njust express, to the browser

assume that the width of the page is the\n

Don't assume the luxury of a\nbig laptop or desktop computer.

Now, making only that change, let\n

here, using Chrome's developer tools.

And now, it's not very effective on this\n

So if I zoom in to 100%, this would be\n

readable than it would\nhave been a moment ago

even though I realized that demo\nwas not necessarily persuasive.

But it's as simple as\ntelling the browser

to resize the thing to\nthe width of the page.

All right, let me pause here to see\n

feels like enough HTML tags.

We'll add just a couple of more in.

But for the most part,\nlike HTML tags are

things you Google and figure out over\n

The basic building blocks\nare tags, attributes.

Some attributes have values.

And that's sort of the\nstructure of HTML in essence.

Questions on any of these, though.

AUDIENCE: Do attributes have an order?

SPEAKER 1: Do attributes have an order?

No, attributes can be in any\norder, from left to right.

I tend to be a little nit-picky,\nand so I alphabetize them

if only because then I can easily\nspot if something's missing

if it's not there alphabetically.

Most people on the internet\ndon't seem to do that.

I mentioned that HTML\nis starting to replace

other languages for user interfaces.

And it's not just HTML alone.

It's HTML with CSS, with JavaScript,\n

That rather has been the\ntrend for portability

and the ability for companies,\nfor individual programmers

to write one version\nof an app and have it

work on Android devices and iPhones\n

It is very time-consuming to\nlearn a language like Java

and write an Android app, learn\nanother language called Swift

and make an iOS app, not to\nmention make them look and behave

the same, not to\nmention fix a bug in one

and then remember to\nfix it in the other.

I mean, this is just very painful\nand time-consuming and costly.

So this standardization on\nHTML, CSS, and JavaScript

even for mobile apps and web apps,\n

because it solves problems like that.

All right, so let's go ahead and now do\n

All of these pages thus\nfar are really just tastes

of static content, content\nthat does not change.

Well, let's go ahead and do this.

Let me introduce one other\nformat of URLs, which looks

a little something like it did before.

So slash path, but it could\nactually be something like this

slash path question\nmark, key equals value.

You might not have noticed,\nor cared to notice

the URLs in your URL bar every day.

But these things are everywhere.

Often when you type into a\nsearch engine like Google

a search query, whatever you\njust typed ends up in the URL.

When you click on a link that\ncontains some information

there might be a question mark,\nand then some keys and values.

There might be an ampersand\nand more keys and values.

Here, again, is that very\ncommon programming paradigm

of just associating keys with values.

Let me actually go to\ngoogle.com, in a browser

here, and let me search for something\n

Enter, notice now that my\nURL changed from google.com

to google.com slash\nsearch question mark

Q equals cats, ampersand\nand then a bunch of stuff

that I don't understand or know.

So let's just delete it for now, and\n

If I zoom out here, years ago\nyou would get pictures of cats.

Now you get videos of the movie.

And then that top query\nthere, is Cats a bad movie.

But we can also, of\ncourse, click on Images.

And there are the\nadorable cat, creepy cats.

All right, this didn't used to\nhappen when we searched for cats.

But anyhow, the point is that the URL\n

And this is such a simple,\nbut such a powerful thing.

This is how humans\nprovide input to servers.

They don't manually create the\nURLs, like I sort of just did.

But when you fill out a form\non the web and you hit Enter

typically the URL suddenly\nchanges to include

whatever you typed in,\nin the URL, assuming

the form is using the verb GET.

If you're typing in a\nusername, a password

a credit card information, because you\n

at your laptop to see literally\neverything you typed in

So there's another verb, POST,\nthat can hide all of that.

And it's just sent a little differently.

But things like this are\ntypically sent via GET

and what that means underneath the\n

making a request like this, Get/search?

Q equals, whatever you typed in, the\n

And hopefully what comes back is a page\n

And what's interesting here now is, if\n

and let me go ahead and create a\n

In Search.html, I'm going to start\n

And in the body of this page, I'm\ngoing to introduce a form tag.

And in this form tag, I'm going\nto have a couple of inputs.

And the types of inputs are going to\n

And this isn't that\ninteresting yet, but let's see

what is happening in the page itself.

Let me go back to my directory listing.

Let me click on Search.html.

I seem to have the beginning\nof my own search engine.

It's just a text box\nand a submit button.

But let's finish my thoughts here.

So let's specifically give\nthis text box a name of Q

which, if you roll back to the late '90s\n

created Google.com, Q represented query,\n

So the name of this\ntext box shall be text

shall be Q. The form is\ngoing to use what method?

Technically it uses GET\nby default, but I'll

be explicit and say method\nequals quote unquote "get.

Stupidly, it's lowercase in HTML, even\n

The action of this form, specifically,\n

But we don't really have time\ntoday to implement Google itself.

So we're just going to send the\n

So I'm creating a form,\nthe action of which

is to send the data to Google's slash\n

It's going to send an input called Q,\n

Let me go back to the\nbrowser, reload the page.

Nothing seems to have changed yet,\n

Right now I'm in Search.html.

If I zoom out and search for\ncats now and click Submit

I'm whisked away to google.com.

But notice that the URL is\nparameterized, with those key value

And I get back a whole\nbunch of cat results.

And I can very easily now\nmake this a little prettier.

Right now, it's not ideal that like\n

And it's a little obnoxious\nthat autocomplete is enabled.

If I don't want to\nsearch for cats anymore

well, according to HTML's documentation,\n

Autocomplete equals off, to turn\noff autocomplete, auto focus

to automatically put the\ncursor inside of that text box.

If I want some explanatory text, I can\n

And now if I go back to\nthis page and reload

now it's a little more user-friendly.

You see query in kind of gray text.

The cursor is already\nthere and blinking.

I don't have to even move my cursor.

I can search for dogs now, and you\n

Hit enter to submit, and\nnow I'm searching for

there we go, adorable dogs, instead.

I've implemented the front end of\n

To implement the back\nend, we're obviously

going to need like a really big\n

We're going to need some code that like\n

We're going to need Python\nfor something like that.

And in fact, that's the direction\nwe're steering next week

when we implement that back end.

But today it's all about this front end.

Or any question, then, about forms,\n

transition to making things look\na little prettier, with CSS?

And then we'll end by making\nthings a little more functional

All right, so let's start to answer\n

came up, by making these pages a\n

Let's go ahead now and introduce to\n

Let me go ahead and create\na file called Home.html

as though I'm making a home\npage for the very first time.

And in this page, I'm going\nto give a title of Home.

And I'm just going to\nhave like three things.

First I'm going to have maybe\na paragraph of text up here

at the top, that says something\nwelcoming for my home page

like my name, John Harvard, for\n

Then in the middle of the page,\n

welcome to my home\npage exclamation point!

And at the bottom of the page, I'm\n

says something like copyright,\nthe copyright symbol, John

Harvard, or something like that.

All right, so it's like a web page\n

This isn't that interesting.

If I open this page called\nHome.html, let me go ahead

and create three quick paragraphs,\n

Inside the middle, I'm going to say\n

And at the bottom,\nwhoops, at the bottom

a little footer that says\nsomething like copyright

a little simple copyright\nsymbol, and John Harvard's name.

All right, now let me reload the page.

It's a very simple, very underwhelming\n

Let's start to now stylize\nthis in an interesting way

so that it's a little more\naesthetically pleasing.

First, these aren't really paragraphs.

They're sort of like areas of the page,\n

There's like the main part of my screen.

And then there's the\nfooter of my screen.

So paragraphs isn't quite\nright, if these aren't really

I might more properly call\nthem divs or divisions

of the page, which is a very commonly\n

this generic rectangular region to it.

It does not do anything aesthetically,\n

It just creates an invisible\nrectangular region, inside of which

you can start to style the text.

Or I can take this one step further.

There's some other tags in HTML,\n

have names that describe the\ntypes of your page, which

is all the more compelling these\ndays for accessibility, too

for screen readers, for search engines,\n

engine can realize that footer\nis probably a little fluffy.

The header might be\na little interesting.

The main part of the page\nis probably the juicy part

that I want users to be able to search\n

So let's start to stylize\nthis page somehow.

Let's introduce a style\nattribute in HTML

inside of which is going to be\ntext like this, font size colon

large, text align colon center.

On Main, I'm going to add a\nstyle attribute and say font size

And then on the footer, I'm going\nto say style equals font size

Well, in blue is the\nlanguage we promised

called CSS, for Cascading Style Sheets.

We're not really seeing the\nCascading Style Sheet of it yet.

But in blue here, notice is\nanother very common paradigm.

It's different syntax\nnow, but how would you

describe what you're\nlooking at here in blue?

This is another example of what\nkind of programming convention?

SPEAKER 1: Yeah, it's just\nmore key value pairs, right?

It'd be nice if the world standardized\n

because we've now seen equal signs\n

But it's just different\nlanguages, different choices.

The key here is font-size,\nthe value is large.

The other key is text-align,\nthe colon, the value is center.

The semicolon just separates\none key value pair from another.

Just like in the URL, the ampersand\ndid, in the context of HTTP.

The designers of CSS\nused semicolons instead.

Strictly speaking, this\nsemicolon isn't necessary.

I tend to include it just for\nsymmetry, but it doesn't matter

because there's nothing after that.

This is a bit of a weird example.

This is the co-mingling of\nCSS inside of JavaScript.

So as of now, you can use the CSS\n

in the value of a style attribute.

We did something a little\nsimilarly last two weeks

a week plus ago, when we included\nsome SQL inside of Python.

So again, languages can kind\nof cross barriers together.

But we're going to clean\nthis up, because this

is going to get messy quickly,\n

of Harvard's or Yale's, or the like.

So let's see what this looks like.

Let me go back to my browser\nwindow here, reload the page.

And it's not that different.

But it's indeed centered, and it's\n

And let me make one refinement.

The copyright symbol\nactually can be expressed

but there's no key on\nmy US keyboard here.

I can actually magically say\nampersand hash 169 semicolon

using what's called an HTML entity.

It turns out there are numeric\n

allow you to specify symbols that\n

but that don't exist on most keyboards.

If I reload the page now, now\nit's a proper copyright symbol.

So minor aesthetic, but it\nintroduces us to these HTML entities.

So even if you've never\nseen CSS before, you

can probably find something\nkind of dumb about what

I did here, like poor design.

It is correct, if my goal was small,\n

looks like a bad design,\nperhaps, even if you've never

SPEAKER 1: Yeah, I've used\nthe same style three times

like copy/paste, or typing the\nexact same thing again and again.

It has rarely been a good thing.

Well, here's where we can take\nadvantage of the design of CSS

because it supports what\nwe might call inheritance

whereby children inherit the properties,\n

And what that means is, I can do this.

Let me get rid of this text align.

Let me get rid of this text align.

I could get rid of the semicolon,\n

And let me add all of that style\n

so that it sort of cascades down to the\n

And let me close my quotes there, too.

Now, if I go back to my browser\nand hit reload, nothing changes.

But it's a little\nbetter designed, right?

Because if I want to change the text\n

I can now reload the page, and\nvoila, now it's over there.

I change it in one place, not\nin three different places.

So that would seem to be\nmarginally better design.

And could we do this\nany more differently?

Well, it's not that elegant that\n

This generally tends to\nbe bad practice, where

you co-mingle your HTML and your\n

might be really good at laying\nout the structure of web pages

and the content and the data, and you\n

or just not care about the aesthetics.

You might work with a\ndesigner, an artist

who's much better at all of\nthese fine tunings aesthetically.

Wouldn't it be nice if you could work\n

And you don't have to\nsomehow like literally

edit the same lines\nof code as each other.

Well, just like we can move\nstuff into header files in C

or packages in Python, we\ncan do the same in CSS.

So I'm actually going\nto go ahead and do this.

Let me get rid of all of\nthese style attributes

and let me now start to practice a\n

Let me instead move it into the\n

This is one of the rare\nexamples where there

are attributes that have the\nsame names of tags as vice versa.

It's not very common,\nbut this one does exist.

Here's a slightly different syntax for\n

If I want to apply CSS properties,\nthat is, key value pairs

to the header of the page, I say\n

and inside of those I say\nfont-size large, text-align center.

Then, if I want to apply some properties\n

I again do font-size, say, medium,\n

Then, lastly, on the\nfooter of the page, I

can assign some properties like\n

And I don't have to do\nanything more in my HTML.

It all just represents\nthe structure of my page.

But, because of this style\ntag in the head of the page

the browser knows in\nadvance that the moment it

encounters a header tag, a\nmain tag, or a footer tag

it should apply those\nproperties, those styles.

If I reload the page, other\nthan it being recentered now

All we're doing is sort of\n

But now everything's\nin the top of the file.

But there's still a bad design here.

What could I now do\nthat would be smarter?

SPEAKER 1: OK, create a\nnew file with just the CSS.

Let's go there in just one second.

But even as we're here,\nthere's still a redundancy

we can probably chip away at.

Yeah, get rid of the text-align center\n

doesn't seem necessary,\nand perhaps someone

else, if I get rid of text-align center,\n

in order to bring it back, but\n

And the page, if I scroll\ndown, looks like this, in HTML.

SPEAKER 1: Yeah, so the body tag.

So let me go ahead and say body.

And then in here, put text-align center.

And that, now, if I reload the\npage, has no visual effect

but it's just better\ndesign, because now I

factored out that kind of commonality.

And so, just to make clear\nwhat we've been doing here

these are all, again, CSS\nproperties, these key value pairs.

And there's different types\nof ways of using them.

And there's this whole taxonomy.

What we've been doing thus far are what\n

where the type is the name of a tag.

And so it turns out there's\nother ways, though, to do this.

And let's head in this direction.

Let's go ahead and maybe write\nour CSS slightly differently

because you know what would be nice.

I bet, after today, once I start\n

or John Harvard's home\npage, I might want

to have centered text on other pages.

And I might want to have large\n

It'd be nice if I could reuse\nthese properties again and again

and kind of create my\nown library, maybe even

ultimately putting it\nin a separate file.

Instead of explicitly applying\ntext-align center to the body

let me create a new\nnoun, or an adjective

rather, for myself, called centered.

It has to start with a\ndot, because what I'm doing

is inventing my own class, so to speak.

This has nothing to do with\nclasses in Java or Python.

Class here is this aesthetic feature.

And, actually, let me rename\nthese, to be dot large

What this is doing for me\nis it's inventing new words

well-named words, that I\ncan now use in this file

or potentially in other web\npages I make, as follows.

I can now say, if I want\nto center the whole body

I can say class equals centered.

On the header tag, I can\nsay class equals large.

On the main tag I can\nsay class equals medium.

On the footer tag, I can\nsay class equals small.

But let me take this one step further.

As you suggested, why\ndon't I go ahead now

and let me actually get rid\nof-- let me grab all of the CSS

Let me get rid of the style tag here,\n

and let me just save all of that same\n

nothing else, no HTML whatsoever.

But let me go back to my\nHome.html page, and this

is one of the most annoyingly named\n

mean what it does, Link HREF\nHome.css rel equals stylesheet.

So ideally we would have used the\n

but this is link in the\nsort of conceptual sense.

We're linking this file to this other\n

using this hyper-reference,\nHome.css, the relationship

of that file to this one\nis that of stylesheet.

A stylesheet is a file\ncontaining a whole bunch

of stylizations, a whole bunch\nof properties, as we just did.

So here, too, it's\nunderwhelming the effect.

If I reload the page, nothing changed.

But now, I not only have\na better design here

because I can now use those same classes\n

my third page, my fourth page, my bio,\n

making on my website here, I\ncan reuse those styles by just

including one line of code, instead of\n

stuff into file after file after file.

And heck, if the rest\nof the world is really

impressed by my centered class, and\n

I could bundle this up, let other\n

and I have my own library, my own CSS\n

Why should you ever invent\na centered class again

if I already did it for you,\nstupid and small as this one is.

But it would be nice\nnow to package this up

in a way that's usable\nby other people as well.

So this is perhaps the best\ndesign, when it comes to CSS.

Use classes where you can, use\n

but don't use the style attribute\n

starts to get messy quickly,\nespecially for large files.

All right, any questions, then, on this.

No, all right, so\nthat's class selectors.

When you specify dot\nsomething, that means

you're selecting all of the tags in the\n

and applying those properties.

So there's a couple of\nothers here, just to give you

a taste now of what's possible.

There's so much more that you can\n

Let me go ahead and open up a few\n

Let me go ahead and open up VS Code.

And let me go ahead and copy\nmy source eight directory.

Give me one second to grab the source\n

so that I can now go into\nmy browser, go into some

of the pre-made examples\nin source eight

and let me open up paragraphs one here.

So here's something,\nit's a little subtle.

But does anyone notice\nhow this is stylized?

This is just some generic\nlorem ipsum text again.

But what's noteworthy\nstylistically, a book might do this.

SPEAKER 1: Yeah, the first\nparagraph's a little bigger.

Who knows, it's just a stylistic\n

The first paragraph is bigger.

Well, we can actually explore\nthis in a couple of ways.

One, I can obviously go into\nVS Code and show you the code.

But, now, that we're using Chrome and\n

View developer, developer\ntools, and now notice

let me turn off the mobile feature,\n

to the bottom, just so\nthat it's fully wide.

We looked at the Network tab before.

We looked at the mobile button before.

Now let me click on Elements.

What's nice about the Elements tab\n

version of the web page's HTML,\n

for you, so that you can now henceforth\n

code, the HTML source code, of\nany web page on the internet.

Notice that my own web page\nhere, it's not that interesting.

There's a bunch of paragraph\ntags of lorem ipsum text.

The very first one, I gave an ID to.

This is something that you,\nas a web designer, can do.

You can give an ID attribute\nto any tag in a page

to give it a unique identifier.

The onus is on you, not to\nreuse the word, anywhere else.

If you reuse it, you've screwed up.

But I chose an ID of\nfirst, just so that I

have some way of referring to the\n

If I look in the head of the\npage, and the style tag here

notice that I have hash first.

So just as I use dot for\nclasses, the world of CSS

uses a hash symbol to\nrepresent IDs, unique IDs.

And what this is telling the browser,\n

F-I-R-S-T, without the hash,\napply font-size larger to it.

And that's why the first paragraph,\n

If I actually go into\nVS Code now, and let

me go into my source eight directory.

Let me open up Paragraphs1.html.

If I want to change the color of that\n

I can do color colon: green.

Let me close the developer\ntools, reload the page.

And now that page is green as well.

You don't have to just use words.

What was the hex code for green in RGB?

Like no red, lots of green, no blue.

So you could do 00 FF 00, using\na hash, which, coincidentally

is the same symbol, but it\nhas nothing to do with IDs.

This is just how Photoshop and\nweb pages represent colors.

Let's go back here and reload.

It's the same, although it's a\n

If I want to change it to red, that\n

and here I can go and reload.

Now it's first paragraph red.

This actually gets\npretty tedious quickly.

Like, if you're a web designer trying\n

it actually might be fun\nto tinker with the website

before you open up your editor\nand you start making changes

So notice what you can\ndo with developer tools

too, in Chrome and other browsers.

When I highlight over this\nparagraph, under the Elements tab

notice that, one, it\ngets highlighted in blue.

If I move my cursor, it\ndoesn't get highlighted.

If I move it, it gets highlighted.

So it's showing me what\nthat tag represents.

But notice over here on\nthe right, you can also

see all of the stylizations\nof that particular element.

The italicized ones here at the\n

That means this is what Google makes\n

But in non-italicized\nhere, you see hash first

which is my code, that I just changed.

And if I want to start tinkering with\n

But notice, if I go back to VS Code, I\n

This is now purely client side.

When I drew that picture\nearlier of the browser going

making a request to the cloud, the\n

coming back, the browser,\nyour Mac, your PC, your phone

has a copy of all the HTML and\nCSS, so you can change it here

And, for instance, you can\ndo this with any website.

Let's go, say, on a field trip\nhere, to how about Stanford.edu.

So here's Stanford's\nwebsite as of today.

Let's go ahead here\nand let's see, there's

their admissions page,\ncampus life, and so forth.

Let me go ahead and view developer\ntools on Stanford's page

developer tools, elements,\nyou can see all of their HTML.

And notice it's collapsed,\nso here is their header.

Here's their main part, and\nI'm using my keyboard shortcuts

to just open and close the tags,\nto dive in deeper and deeper.

Suppose you want to kind\nof mess with Stanford

you can actually like right\nclick on any element of a page

or control click, Inspect, and that's\n

to the tag in the Elements\ntab that shows you that link.

And notice, if I hover over this\n

as an unordered list from left to right.

But it doesn't have to be a\nbulleted list top to bottom.

They've used CSS to change it to be\n

research, health care,\ncampus admission, about.

Well, so much for\nadmission, that's gone.

So now, if I close developer tools,\n

But, of course, what have I really done.

I've just like mutated\nmy own local copy.

So this is not hacking,\neven though this might

be how they do it in TV and the movies.

It's still there if I reload the page.

But it's a wonderfully powerful way\n

different things\nstylistically, figure out

how you want to design\nsomething, and two, just learn

So, for instance, if I right click\n

go to inspect, and let\nme go to the LI tag.

Let me keep going up, up,\nup, up, up to the UL tag.

There's going to be a lot going on here.

But notice, they have applied\nall of these CSS properties

But notice, here, this is\nhow, it's something like this.

And we'd have to read more to learn\n

this is how they probably\ngot rid of the bullets.

And what you can do is just tinker.

Like, all right, well,\nwhat does this do?

All right, didn't really change\n

So now the margin is changed, the\npadding around it has changed.

We can just start turning\nthings on and off, just

to get a sense of how\nthe web page works.

I'm not really learning\nanything here so far.

Let me go to the LI here for, let's\n

So when there's a\ndisplay property in CSS

that's apparently effectively changing\n

if I turn that off, now Stanford's\nlinks all look like this.

And there are those bullets.

So again, just default styles,\nthat they've somehow overridden

and a good web designer\njust knows ultimately

how to do these kinds of things.

All right, how about a couple\nof final building blocks

before we'll take one more break.

And then we'll dive in with\nJavaScript to manipulate this stuff

Let me go ahead and open up,\nhow about Paragraphs2 here.

Let me close this tab, let me go\n

And this one looks\nthe same, except, when

I go ahead and inspect\nthis first paragraph

notice that I was able\nto get rid of the ID

somehow, which is just\nto say, there's many

many ways to solve\nproblems in HTML and CSS

just like there is in C and Python.

Let me look in the head and\nthe style of the page now.

This is what we might call\nanother type of selector

that allows us to specify\nthe paragraph tag

that itself happens to\nbe the first child only.

So you can apply CSS to a very\n

There's also syntax for last\nchild, if just the first one

is supposed to look a little different.

So, here, I've just\ngotten out of the business

of creating my own unique\nidentifier and, instead, I'm

using this type of selector as well.

Let me go into another example\nhere, called Link1.html

and here we have a very simple\n

But notice it's purple\nby default, because we've

Let's see if we can't maybe\nstylize Harvard's links

Let me go into Link version\n2, now, which looks like this.

And now Harvard is very red.

Well, let me right click\non it, click Inspect

and I can start to poke around.

It looks like my HTML is\nnot at all noteworthy.

It's just very simple HTML,\nanchor tag with an HREF.

And we can look at it\nin two different ways.

We can literally look at\nthe style, contents here

or we can look at Chrome's\npretty version of it, over here.

It looks like my style\nsheet, in the style tag

has changed the color to be red, and the\n

but it's another CSS property, to none.

Notice, if I turn that\noff, links on the internet

are underlined by\ndefault, which tends to be

good for familiarity, for\nvisibility, for accessibility.

But, if it's very obvious what\nis text and what is a link

maybe you change text\ndecoration to none.

But maybe, watch this, maybe the\nlink comes, the line comes back

Well, let's look at how\nI did this in style.

Notice that I have stylization, and I\n

here, as tends to be convention in CSS.

Color is red, text decoration is none.

But, whenever an anchor\ntag is hovered over

you can change the text decoration\n

So, again, just little ways of playing\n

once you understand\nthat, really, there's

just different types of selectors.

And you might have to remind\n

But it's just another way of scoping\n

Let's look at version 3 of this\n

If I go to Link3.html, maybe I\nwant to have Harvard links red

Well, let's right click,\nand click Inspect.

And here we might have two links,\nwith a couple of techniques

just to, again, emphasize, you can\n

I gave my Harvard link an ID of\n

In my CSS, if we go to the head\nof the page, I then did this.

The tag with the Harvard ID, a.k.a.

#Harvard, should be red,\n#Yale should be blue

and then any anchor tag should\nhave no text decoration

unless you hover over it, at which\n

And so, if I hover over Harvard,\nit's red underlined, Yale

If I want to get rid of the IDs, I\n

Same effect, but notice,\nI got rid of the IDs now.

How else can I express myself?

Well, let's look at the CSS here.

The anchor tag has no text\ndecoration by default

unless you're hovering over it.

This is what we would\ncall, on our list here

an attribute selector, where you\nselect tags using CSS notation

So this is saying, go ahead\nand find any anchor tag

who's HREF value happens to\nequal this URL, and make it red.

Do the same for Yale, and make it blue.

Now, this might not be ideal, because\n

these equal signs don't\nwork, because if it's

a different Harvard or different Yale\n

So let me look at version\n5 here, of Link.html.

Look at this style, and I\ndid this a little smarter.

And, again, just the kind\nof thing you look up.

Star equals means, change any anchor\n

Harvard.edu to red, and do the same\n

So star here connotes wildcard.

So search for Harvard.edu or\nYale.edu anywhere in the HREF

and if it's there, colorize the link.

And, again, we could do this all\n

to actually achieve the same kind\n

And as projects just\nget larger and larger

you just have more and\nmore decisions to make.

And so you have certain\nconventions you start to adopt.

And, indeed, if I may,\nyou have the introduction

of what are called\nframeworks, ultimately.

If you're a full-time\nweb developer, or you're

working for a company doing the same,\n

For instance, the company might say,\n

Or always use attribute\nselectors, or don't use this.

And it wouldn't be necessarily\nas draconian as that.

But they might have a\nstyle guide of sorts.

But, what many people, and\nmany companies, do nowadays

is they do not come up with all\nof their own CSS properties.

They start with something off the shelf,\n

source framework, that just gives\n

for free, just by using\na third party library.

And one of the most\npopular ones nowadays

is something called\nBootstrap, that CS50 uses

on all of its websites,\nsuper-popular in industry as well.

It's at getbootstrap.com, and this\n

a website that documents\nthe library that they offer.

And there's so much documentation here,\n

It just gives you, out of the\nbox, the CSS with which you

If you've ever noticed\non CS50's website

little colorful warnings at\nthe top of the page, or call

outs, to draw your attention to things.

It's probably a paragraph\ntag or a div tag

and maybe we changed the font color.

We changed the background color.

Or it's a lot of stuff we could\nabsolutely do from scratch

but, you know what,\nwhy would we reinvent

the wheel if we can just use Bootstrap.

So, for instance, let\nme just scroll down.

If you've ever seen on CS50's website\n

let me just zoom in on this.

We are just using HTML like this.

We're using a div tag, which,\nagain, is an invisible division

a rectangular region of the page.

But we're using classes called alert\n

Those are classes that the\nfolks at Bootstrap invented.

They associated certain\ntext colors and background

colors and padding and margin\nand like other aesthetics with

so all we have to do\nis use those classes.

Role equals alert, just makes clear\n

is an alert, that should\nprobably be recited

and whatever's in between\nthe open tag and close tag

is what the human would see.

How do you use something like Bootstrap?

Well, you just read the documentation.

Under Getting Started, there is a\n

So in Table.html, we had code like this.

Let me actually read Bootstrap's\ndocumentation really fast.

I'm going to put this\ninto the head of my page.

And it's quite long, but\nnotice, it's a link tag

which I used earlier for my\nown CSS file, the HREF of which

is this CDN link, content\ndelivery network, that's

referring to a specific version of\n

And the file that I'm including\nis called Bootstrap.min.css.

This is an actual file I\ncan visit with my browser.

If I open this in a separate\ntab, this is the CSS

that Bootstrap has made\nfreely available to us.

That's because it's been\nminimized, just to not

waste space by adding lots\nof white space and comments.

But this contains a whole lot,\nhundreds, of CSS properties

that we can reuse, thanks to\nclasses that they invented.

If I want to use some JavaScript\n

But we'll come back to that before long.

Let me now just make a couple\nof tweaks to this table.

If I go into my browser\nfrom before, this

is what it looked like previously,\nwhere name and number were

bold, but centered, and then\nCarter and David were on the left

and the numbers were to the right.

It's not that pretty, but it'd be nice\n

So if we add Bootstrap into it,\nnotice one thing happens first

No longer are Chrome's\ndefault styles used.

Now Bootstrap's default\nstyles are used, which

is a way of enforcing similarity\nacross Chrome, Edge, Firefox

Notice it went from a\nserif font to a sans serif

font, and something cleaner like this.

It still looks pretty ugly, but let\n

Let me go under their\ncontent tab, for tables.

And if I just kind of\nstart skimming this

these are some good\nlooking tables, right?

Like, there's some underlining\nhere, some bolder font.

If I keep going, ooh,\nthat's getting pretty, too

if I want to have a colorful table,\n

out myself if I want\nsome dark mode here

if I want to have alternating\nhighlights, and so forth.

There's so many different stylizations\n

But I care about making a phone book,\n

So if I read the documentation closely,\n

is add Bootstrap's table\nclass to my table tag

and watch with a simple reload, what\n

Might not be what you want, but, my\n

I just really prettied things up.

And so here, then, is the value of\n

It allows you to actually\ncreate much prettier, much more

user-friendly websites than you might\n

In fact, let's iterate one\nmore time on one other example

before we introduce a bit of that code.

Let me go ahead and open\nup Search.html from before

which, recall, looks like this,\nand Search.html on my browser

was this very simple Google search.

And suppose I want to reinvent\nGoogle.com's UI a bit more.

Here's a screenshot of\nGoogle.com on a typical day.

It's got an about link, a store\n

It's not appearing well\non the screen here

but there's a big text box in\nthe middle, and then two buttons

Google search, and I'm feeling lucky.

Well, could I maybe go about\nimplementing this UI myself

using some HTML, some CSS,\nand maybe Bootstrap's help

just so I don't have to figure out\n

Well, here's my starting point.

In Search.html, let's go and add\n

so that we have access to all of\n

And let me go ahead and\nfigure out how to do this.

Well, just like Stanford's site had\n

but they changed it from being a\n

I bet I can do something\nlike this myself.

So let me go into the body\nof my page and, first

based on Bootstrap's documentation,\nlet me add a div called

a div with a class of container fluid.

Container fluid is\njust a class that comes

with Bootstrap that says, make\nyour web page fluid, that is

So that way it's going to resize nicely.

I'm going to go ahead and\nfix my indentation here.

If you haven't discovered\nthis yet, if you

highlight multiple lines\nin VS Code, you can

hit Tab and indent them all at once.

So now, I have all of\nthat inside of this div.

Now, just like in Stanford's site, let's\n

an LI, called with a class of NAV item,\n

let me go ahead and say, A\nHREF=https://about.google

which is the real URL\nof Google's about page.

And I'll put the about text in there.

Then I'm going to close my LI tag\n

because I'm using Bootstrap.

Bootstrap's documentation,\nif I read it closely

says to add a class to your links,\n

to make it dark, like black or dark\n

All right, so I think I\nhave now an about link

in a navigation part of my screen.

Let me go ahead and\nsave this and reload.

All right, so not exactly what I wanted.

It's a bulleted list, still, so\nI need to override this somehow.

Let me read Bootstrap's\ndocumentation a little more clearly.

And let me pretend to do\nthat, for time's sake.

If I go under content, oops,\nif I go under components

and I go to Navs and\nTabs, long story short

if you want to create a pretty menu\n

from the left to the\nright, just like Stanford

I essentially need HTML like this.

And this is subtle, but\nI left off this class.

I should have added a\nclass called NAV on my UL.

Let me go in here and\nsay add class equals

NAV, and then again, this class\nNAV item, Bootstrap told me to

NAV link text dark,\nBootstrap told me to.

Let me go back to my page here,\n

But at least the About link is\nin the top left hand corner

just like it should be\nin the real google.com.

Now let me whip up a couple\nof more links real fast.

Let me go and do a little\ncopy/paste, though I bet next week

we can avoid this kind of copy/paste.

Let me change this link\nto be Store.google.com.

Let me go ahead and create\nanother one here for Gmail.

So this one's going to go\nto, officially, how about

technically it's www.google.com/gmail.

And let me grab one more of these.

And for Google Images, and I'm\ngoing to paste this, whoops

I'm going to put this here, too.

This is going to be images, and\nthat URL is IMG.hp, is the URL.

All right, let me go ahead\nand reload the browser page.

Now it's coming along, right?

About, store, Gmail, images.

It's not quite what I want.

So I'd have to read the\ndocumentation to figure out

how to maybe nudge one of these\n

And there's a couple of ways to do this.

But one way is if I want Gmail to move\n

else, I can say that add some margin to\n

This is in Bootstrap's documentation, a\n

just automatically\nshove everything apart.

And now, if I reload the page\n

All right, so now we're\nkind of moving along.

Let me go ahead and add the\nbig blue button to sign in.

So here with sign in, let me go\n

so let's go ahead and do one\nmore LI, class equals NAV item.

And then, inside of this LI\ntag, what am I going to do?

Turns out there is a class that can turn\n

for button, and then button\nprimary, makes it blue

the HREF for this one is going\nto be https://accounts.goo

gle.com/service/login, which is\n

The role of this link is that of button.

And then sign in, is going\nto be the text on it.

If I now reload the page, now\nwe're getting even closer

although it looks a little stupid.

Notice that sign in is way\nin the top right hand corner

whereas the real google.com has\n

OK, that's an easy fix, too.

Let me go back into my HTML here.

This, too, is a Bootstrap thing.

They have a class called m-something.

The something is a\nnumber from like 1 to 5

I believe, that adds just\nsome amount of white space.

So if I reload now, OK,\nit's just a little prettier.

Just to demonstrate how I can\ntake this home, let me go ahead

and open up my premade\nversion of this, whereby

I added to this some final flourishes.

If I go to Search2.html, I\ndecided to replace their logo

with just this out of a\ncat, and notice that I

re-implemented essentially google.com.

Here's a text box, here's two\nbuttons, even though they're

a little washed out on the screen.

I even figured out how to get dots\n

And if we view source, you can see\n

If I go to view developer tools, and I\n

and I go into this div, you'll see\n

And I added some classes there to make\n

If I go into the form tag, this\nis the same form tag as before.

But, notice, I used\nbutton tags this time

with button and button light classes.

And then I stylized\nthem in a certain way.

And so in the end result, if I want\n

and click Google search,\nvoila, I've implemented

something that's pretty\ndarn close to Google.com

without even touching raw CSS myself.

And now here's the value,\nthen, of a framework.

You can just start to use\noff the shelf functionality

that someone else created for you.

But if you want to make\nrefinements, you don't really

like the shade of blue that\nBootstrap chose, or the gray button

or you want to curve\nthings a bit more, that's

where you can create\nyour own CSS file, and do

the last mile, sort\nof fine tuning things.

And that tends to be best practice.

Stand on the shoulders of others as\n

And then if you really don't\nlike what the library is doing

then use your own skills and\nunderstanding of HTML and CSS

to refine things a bit further.

But still, after all of that, all of\n

are still static, other\nthan the Google one

which searches on the real Google.com.

Let's take a final 5\nminute break and we'll

give you a sense of what we can next\n

All right, so I think\nit's fair to say, we're

about to see our very last language.

Next week and final\nprojects are ultimately

going to be about\nsynthesizing so many of these.

Thankfully, this language called\nJavaScript is quite similar

syntactically to both C and Python.

And, indeed, if you can imagine\n

you can probably do it in\nsome form in JavaScript.

The most fundamental\ndifference today, though

is that when you have written C\ncode and Python code thus far

you've done it on the server.

You've done it in the\nterminal window environment.

And when you run the code, it's\n

The difference now today\nwith JavaScript is

even though you're going to write\nit in the cloud using VS Code

recall that, when a browser gets\nthe page containing this code

it's going to get a copy of the HTML,\n

So JavaScript, that we see today, is\n

on users' own Macs, PCs, and\nphones, not in the server.

JavaScript can be used on the server,\n

It's an alternative to Python or\n

We are using it today client\nside, which is a key difference.

So in Scratch, let's\ndo this one last time.

If you wanted to create a variable\n

In JavaScript, it's\ngoing to look like this.

You don't specify the type,\nbut you do use the keyword let

and there's a few others as well, that\n

If you want to increment that\nvariable by one, you in JavaScript

could say something like,\ncounter equals counter plus 1

or you can do it more\nsuccinctly, with plus equals

or the plus plus is back in JavaScript.

You can now say counter\nplus plus semicolon again.

In Scratch, if you wanted to\ndo a conditional like this

asking if x less than y, it looks\n

The curly braces here are back, if you\n

But, syntactically, it's pretty much\n

and even for it's else if else.

Unlike Python, it's two\nwords again, else if.

So quite, quite like C,\nnothing new beyond that.

If you want to do something forever\n

In JavaScript, you can do it a few\n

In JavaScript, Booleans are\nlowercase again, just like in C.

If you want to do something\na finite number of times

like repeat three times,\nlooks almost like C as well.

The only difference, really, is using\n

And, again, you'll use let to\ncreate a string, or an INT

or any other type of\nvariable in JavaScript.

The browser will figure out\nwhat type you mean from context.

In C we would have said INT instead.

Ultimately, this language, and that's\n

There's bunches of other\nfeatures, but syntactically it's

going to be that accessible,\nrelatively speaking.

The power of JavaScript\nrunning in the user's browser

is going to be that you can\nchange this thing in memory.

Think about most any website, that's\n

It's typically very\ninteractive and dynamic.

If you're sitting in front of Gmail on\n

open, and someone sends you\nan email, all of a sudden

another row appears in your\ninbox, another row, another row.

Honestly, it could be an HTML table.

Maybe it's a bunch of\ndivs top to bottom.

The point, though, is, you don't\n

R to reload the page to see more email.

It automatically appears\nevery few seconds or minutes.

When you visit Gmail.com,\nyou are downloading not just

HTML and CSS with your\ninitial inbox, presumably.

You're downloading some\nJavaScript code, that

is designed to keep talking every\n

to Gmail servers, and they,\nthen, are using their code

to add another element, another\nelement, another element

to the existing DOM, document object\n

in memory that represents HTML,\n

If you click and drag and drag\nand drag, your browser did not

download the entire world to\nyour Mac or PC by default.

It only downloaded what's in your\n

But when you click and drag, it's\n

some more images, some more\nimages, as you keep dragging, using

JavaScript, again, behind the scenes.

So let's actually use JavaScript\n

We can put the JavaScript\ncode in the head of the page

in the body of the page, or even\n

Here is a new version of\nHello.html, that, during the break

I just added a form to, because it'd\n

say Hello, title, Hello, body, it said,\n

I've got a form that I borrowed\nfrom some of our earlier code

and that form has an input whose ID is\n

But there's no code in this yet.

So let's add a little bit of\nJavaScript code as follows.

Suppose that, when this form is\n

Well, let's do it the\nsomewhat messy way first.

I can add an attribute called\non submit to the form element

and I can say on submit, call the\n

Unfortunately, this\nfunction doesn't yet exist.

But there's another detail here.

When the user clicks submit, normally\n

I don't want to do that today.

I want to just submit the form to\n

and just print to the screen,\nHello, David, or so forth.

So I'm also going to go\nahead and say, return false.

And this is a JavaScript way of telling\n

to submit the form, return false.

Like, no, don't let them\nactually submit the form.

But do call this function called greet.

In the head of my page, I'm going to add\n

implicitly JavaScript,\nand has no relationship

for those of you who took APCS with\n

but no relation, I'm going to\nname a function called Greet.

Apparently in JavaScript, the\nway you create a function is you

literally say the word\nfunction instead of Def.

You don't specify a return type.

And in this function, I could do\n

unquote, how about, Hello, there.

Initially I'm going to keep it simple,\n

which is not a good user interface.

There are better ways to do this.

But we're doing something simple first.

Let me now go ahead and\nload this page again.

It still looks as simple as before,\nwith just a simple text box.

I'll zoom in to make it bigger.

I'm going to type my name,\nbut I think it's going

to be ignored when I click Submit.

And this is, again, this\nis an ugly user interface.

It literally says the whole\ncode space URL of the web page

It's really just meant for simple\n

All right, let's have it\nsay Hello, David, somehow.

Well, if this element on the\npage was given by me a unique ID

it'd be nice if, just like in CSS, I\n

Let me store, in a variable\ncalled name, the result

of calling a special function\ncalled document.queryselector.

This query selector function\nis JavaScript's version

of what we were doing\nin CSS, to select nodes

using hashes or dots or other syntax.

So if I want to select the\nelement whose unique ID is name

I can literally just pass, in\n

That gives me the actual\nnode from the tree.

It gives me one of these rectangles\n

If I actually want to get at\nthe specific value therein

I need to go one step\nfurther and say .value.

So, similar in spirit\nto Python, where we

saw a lot of dot notation, where\nyou can go inside an object

inside of an object,\nthat's what's going on.

Long story short, in JavaScript,\n

called document, that lets you just do\n

One of those functions\nis called query selector.

That function returns to you\nwhatever it is you're selecting.

And dot value means go\ninside of that rectangle

and grab the actual text\nthat the human typed in.

So if I want to now say,\nHello, to that person

the syntax is a little\ndifferent from C and Python.

I can use concatenation, which\nactually does exist in Python

I can go ahead and say hello,\nquote unquote "Hello," plus name.

All right, now, if I go\nback to the browser window

reload the page, to get the latest\n

and click Submit, now\nI see, Hello, David.

Not the best website, but\nit does demonstrate how

I can start to interact with the page.

But let me stipulate that\nthis co-mingling of languages

It's fine to use\nclasses, but using style

equals quote unquote and\na whole bunch of CSS

that was not going to scale well, once\n

Same here, once you\nhave more and more code

you don't want to just put your code\n

Let's get rid of that\non summit attribute

and literally never use it again.

That was for demonstration's sake only.

Let me move the script tag,\nactually, just below the form

but still inside the body, so\nthat the script tag exists only

after the form tag exists, logically.

Just like in Python, your code is\n

Let me define this function\ncalled Greet, and then

let me do this, document.queryselector,\n

It doesn't have a unique ID.

I can just reference it by name, form,\n

And let me call this special\nfunction, add event listener.

This is a function that\nlistens for events.

Now this is actually a term\nof art within programming.

Many different languages\nare governed by events.

And pretty much any user interface is\n

On phones, you have touches, and you\n

and you have pinch, and all\nof these other gestures.

On your Mac or PC you\nhave click, you have drag

you have key down, key up, as\n

This is a non-exhaustive\nlist of all of the events

that you can listen for in the\ncontext of web programming.

And this might be a throwback\nto Scratch, where, recall

Scratch let you broadcast events.

And we had the two puppets sort of\n

In the world of web programming, game\n

these days, they're\njust governed by events.

And you write code that listens\nfor these events happening.

So what do I want to listen for?

Well, I want to add an event\nlistener for the Submit event.

And when that happens, I want to\n

So this is kind of interesting.

Thank you, I have my Greet\nfunction as before, no changes.

But I'm adding one\nline of code down here.

I'm telling the browser to\nuse document.queryselector

Then I'm adding an event listener,\n

And when that happens, I call Greet.

Notice I am not using\nparentheses after Greet.

I don't want to call Greet right away.

I want to tell the browser to call\n

Now let me go ahead and deliberately,\n

here, let me type in my name,\nDavid, submit, and there we go.

All right, but let's now make\nthis slightly better designed.

Right now, I'm defining a\nfunction Greet, which is fine.

But I'm only using it in one place.

And you might recall, we\nstumbled on this in Python

where I was like, why are we creating\n

when we're only using\nit like one line later?

And we introduced what type of\nfunction in Python the other day?

SPEAKER 1: Yeah, so lambda\nfunctions, anonymous functions.

You can actually do this\nin JavaScript as well.

If I want to define a function all\n

Let me cut this onto my\nclipboard, paste it over here.

Let me fix all of the alignment.

And I can actually, now, do this.

The syntax is a little weird.

But using now just these four\nlines of code, I can do this.

I can tell the browser to add an\n

And then when it hears that, call\n

And unlike Python, this function\ncan have multiple lines

which is actually a nice thing.

There's a lot of indentation\nin curly braces going on now.

But you can think of this as just\n

when the form is submitted.

But if I want to block the form\nfrom actually being submitted

I've got to do one other thing.

And you would only know this from being\n

I need to do this\nfunction, prevent default

passing in this E argument, which\nis a variable that represents

the event, more on\nthat another time, that

just allows us to prevent\nwhatever the default

handling of that particular event is.

So long story short, this is\nrepresentative of the type of code

you might write in JavaScript,\nwhereby you can actually interact

with your code, the user's actual form.

And we can do interesting things, too.

Built into browsers nowadays\nis functionality like this.

So here's a very simple example, that\n

Well, it turns out using\nJavaScript, you can control

the CSS of a page programmatically.

I can change the background\nof the body of the page

to red, to green, to blue, just by\n

and then changing CSS properties.

Just to give you a taste of this,\nif I view the page's source

similar code here, I can\nselect the red button by an ID

that I apparently defined\non it, right up here.

I can add an event listener, this\n

And when it's clicked, I\nexecute this one line of code.

And this one line of code\nwe haven't seen before

but you can go into the body of\nthe page, its style property

and you can change its\nbackground color to red.

This is one example of\ntwo different groups

not talking to one another in advance.

In CSS, properties that have two\nwords are usually hyphenated

Unfortunately, in JavaScript, if\n

that's subtraction, which is\nlogically nonsensical here.

So in CSS, you can convert\nbackground-color to, in JavaScript

background Color, where\nyou capitalize the C

and you get rid of the minus sign.

Well, back in the day, there\nused to be a blink tag.

And it's one of the\nfew historical examples

of a tag that was removed from HTML,\n

this is what the web looked like.

There was a lot of this kind of stuff.

There was even a marquee\nthat would move text

from left to right over the screen.

And the web was a very ugly place.

I will admit, my very first web page\n

But how can we bring it back?

Well, this is a version of the\n

I wrote some code in this example, that\n

the CSS of the page to be\nvisible, invisible, visible

invisible, because built into\nJavaScript is support for a clock.

So you can just do something\non some sort of schedule.

Let me go ahead and open up\nthis example, autocomplete.

In Autocomplete.html, I whipped up as\n

but I also grabbed the\ndictionary from problem

set 5 speller, so that if I want\n

this searches that 140,000\nwords, using JavaScript

to create what we know in the\nworld of the web as autocomplete.

When you start searching\nfor something, you

should start to see words\nthat start with that phrase.

And sure enough, if I search\nfor something like banana

here's the three variants of bananas\n

Just JavaScript, when\nit finds matching words

it's just updating the DOM, the\ntree in the computer's memory

to show more and more text, or less.

And for one final example, this is how\n

You have built into browsers today some\n

interfaces, whereby you can ask for\n

For instance, here, I wrote a\n

apparently asking to know my location.

All right, let me go ahead\nand allow it this time

if that's something you're\ncomfortable with on your own device.

It's taking a moment, because sometimes\n

But, hopefully, in just a moment, there\n

and as a final flourish today, for what\n

for your structure, CSS\nfor your style, and now

JavaScript for your logic, which we'll\n

and search Google for\nthose GPS coordinates.

Zoom in here on Google Maps,\nand if we zoom in, in, in

We're not on that street, but\nthere, oh, there it is, actually.

There is the marker it had put for us.

We're indeed here in Memorial Hall.

So all that with JavaScript,\nbut the basic understanding

of the DOM and the\ndocument object model

we'll pick up where\nwe left off next week.

So this is CS50 and this is\nweek nine, and this is it

in terms of programming fundamentals.

Today, we come rather full circle\nwith so many of the languages

that we've been looking at\nover the past several weeks.

And with HTML and CSS\nand JavaScript last week

we're going to add back into\nthe mix, Python and SQL.

And with that, do we have the\nability to program for the web.

And even though this isn't\nthe only user interface out

there, increasingly-- or people\n

and a browser to access applications\nthat people have written

but it's also, increasingly, the way\n

There are languages\ncalled Swift for iOS

there are languages\ncalled Java for Android

but coding applications\nin both of those language

means knowing twice as many language,\n

So we're increasingly seeing,\nfor better or for worse

that the world is starting\nto really standardize

at least for the next some number of\n

coupled with other languages like\n

And so today, we'll tie\nall of those together

and give you the last of the\ntools in your toolkit with which

to tackle final projects to\ngo off into the real world

ultimately, and somehow solve\nproblems with programming.

But we need an additional tool today,\n

This is just a program that\ncomes on certain computers

that you can install\nfor free, happens to be

written in a language called\nJavaScript, but it's a program

that we've been using to\nrun a web server in VSCO.

But you can run it on your own\nMac or PC or anywhere else.

But all this particular\nHTTP server does is

serve up static content\nlike HTML files, CSS files

JavaScript files, maybe images, maybe\n

It has no ability to really interact\n

You can create a web form and serve\n

but if the human types in input into\n

submit it elsewhere to something like\n

it's not actually going to go anywhere\n

process the requests that are coming in.

So today, we're going to introduce\nanother type of server that

comes with Python that allows\nus to not only serve web pages

but also process user input.

And recall that all that input is\n

or more deeply inside of\nthose virtual envelopes.

So here's the canonical URL we talked\n

And I've highlighted the slash to\n

like the default folder\nwhere, presumably, there's

a file called index.html\nor something else in there.

Otherwise, you might have\na more explicit mention

of the actual file named file.html.

You can have folders, as you probably\n

You can have files in\nfolders like this, and these

are all examples of what a programmer\n

So it might not just\nbe a single word, it

might have multiple slashes and multiple\n

But this is just more\ngenerally known as a path.

But there's another term of our,\nthat's essentially equivalent

that we'll introduce today.

This is also synonymously\ncalled a route, which is maybe

a better generic description of what\n

they don't have to\nmap to, that is, refer

to a specific folder\nor a specific file, you

can come up with your\nown routes in a website.

And just make sure that when the\nuser visits that, you give them

If they visit something else, you\n

It doesn't have to map to a very\n

And if you want to get input from\n

like q=cats, you can add a question\n

The key, or the HTTP parameter name\n

and then equal sum value that,\npresumably, the human typed in.

If you have more of these,\nyou can put an ampersand

and then more key equals value pairs\n

The catch, though, is that using the\n

we don't really have the ability to\n

You could have appended question\n

to any of URLs in your home\npage for problem set eight

but it doesn't actually do\nanything useful, necessarily

unless you use some fancy JavaScript.

The server is not going to bother\neven looking in that for you.

But today, we're going to\nintroduce using a bit of Python.

And in fact, we're going to use a web\n

of using HTTP server alone,\nto automatically, for you

look for any key value pairs\nafter the question mark

and then hand them to you in\nthe form of a Python dictionary.

Recall that a dictionary in Python, a\n

That seems like a perfect fit\nfor these kinds of parameters.

And you're not going to have\nto write that code yourself.

It's going to be handed to you by\n

So this will be the\nsecond of two frameworks

really, that we look at in the class.

And a framework is essentially\na bunch of libraries

that someone else wrote\nand a set of conventions

therefore, for doing things.

So those of you who really\nstarted dabbling with Bootstrap

this past week to make your home\n

Well, you're using libraries, code that\n

maybe some of the JavaScript that\n

But it's also a framework in the\n

You have to use Bootstraps\nclasses, and you

have to lay out your divs or\nyour spans or your table tags

in a sort of Bootstrap-friendly way.

And it's not too onerous, but\nyou're following conventions

that a bunch of humans standardized on.

So similarly, in the world of\nPython, is there another framework

we're going to start using today.

And whereas Bootstrap is\nused for CSS and JavaScript

Flask is going to be used for Python.

And it just solves a lot\nof common problems for us.

It's going to make it easier\nfor us to analyze the URLs

and get key value pairs,\nit's going to make it easier

for us to find files or\nimages that the human wants

to see when visiting our website.

It's even going to make it easier\nto send emails automatically

like when someone fills out a form.

You can dynamically, using code,\nsend them an email as well.

So Flask, and with it\nsome related libraries

it's just going to make stuff\nlike that easier for us.

And to do this, all we have to do\n

requirements of this framework.

We're going to have to create a\n

this is where our web app or\napplication is going to live.

If we have any libraries that we want to\n

is to have a very simple text\nfile called requirements.txt

where you list the names\nof those libraries

top to bottom, in that text file,\n

or the import statements that we\n

We're going to have a static\nfolder or static directory, which

means any files you create that\nare not ever going to change

like images, CSS files,\nJavaScript files

they're going to go in this folder.

And then lastly, any\nHTML that you write

web pages you want the\nhuman to see, are going

to go in a folder called templates.

So this is, again, evidence of\nwhat we mean by a framework.

Do you have to make a web app like this?

No, but if you're using\nthis particular framework

this is what people decided\nwould be the human conventions.

If you've heard of other frameworks like\n

there are just different conventions\n

Flask is a very nice\nmicroframework in that that's it.

All you have to do is adhere to\n

to get some code up and running.

All right, so let's go\nahead and make a web app.

Let me go ahead and\nswitch over to VS Code

here, and let me practice\nwhat I'm preaching here

And let's go ahead and create\nan application that very simply

maybe, says hello to the user.

So something that, initially, is not all\n

But we'll build on that\nas we've always done.

So in app.py, what I'm going to do\n

I had on the screen earlier.

From Flask, import Flask, with a capital\n

And I'm also going to\npreemptively import

a couple of functions,\nrender template, and request.

More on those in just a bit.

And then below that, I'm going\nto say, go ahead and do this.

Give me a web-- a\nvariable called app that's

going to be the result of calling\n

this weird incantation here, name.

So we've seen this a few weeks back\n

and we had that if main thing\nat the bottom of the screen.

For now, just know that __name__\n

And so this line here, simple as\n

turn this file into a Flask application.

Flask is a function that just figures\n

The last thing I'm going to do for this\n

I'm going to say that I'm\ngoing to have a function called

index that takes no arguments.

And whenever this\nfunction is called, I want

to return the results of rendering\na template called index.html.

So let's assume there's a file\nsomewhere, haven't created

But render template\nmeans render this file

that is printed to the\nuser's screen, so to speak.

The last thing I'm going to\ndo is I have to tell Flask

when to call this index function.

And so I'm going to tell it to define\n

So let's take a look at\nwhat I just created here.

This is slightly new syntax, and\nit's really the only weirdness

that we'll have today in Python.

This is what's known in Python\nis what's called a decorator.

A decorator is a\nspecial type of function

that modifies, essentially,\nanother function.

For our purposes, just know\nthat on line six this says

hey Python, define a route\nfor slash, the default

page on my website application.

The next two lines, seven\nand eight, say, hey Python

define a function called\nindex, takes no arguments.

And the only thing you should ever do is\n

So really, the next question,\n

Well, let me go ahead and do that next.

Let me create a directory called\ntemplates, practicing, again

So I'm going to create a new\nempty directory called templates

I'm going to go and\nCD into that directory

and then do code of index.html.

So here is going to be my index page.

And I'm going to do a very\nsimple web page, doc type HTML.

I'm just going to borrow\nsome stuff from last week.

HTML language equals English.

I'll then do a head tag, I'll do a meta\n

This makes my site recall responsive.

That is, it just grows and shrink\nto fit the size of the device.

The initial scale for which is going\n

is going to be device width.

So I'm typing this out,\nI have it printed here.

This is stuff I typically copy paste.

But then lastly, I'm going to\nadd in my title, which will just

be hello for the name of this app.

The body of this tag will be--

The body of this page, rather,\nwill just be hello comma world.

So very uninteresting and really a\n

But let's go now and experiment\nwith these two files.

I'm not going to bother\nwith a static folder

right now, because I don't have any\n

No images, no CSS, nothing like that.

And honestly, requirements.txt\nis going to be pretty simple.

I'm going to go requirements.txt and\n

access to the Flask library itself.

All right, but that's the only\n

All right, so now I have two files,\n

But index.html thank you is\ninside of my templates directory

so how do I actually start\na web server last week

I would have said HTTP server.

But HTTP server is not a Python thing.

It has no idea about Flask or\nPython or anything I just wrote.

HTTP server will just\nspit out static files.

So if I ran HTTP server, and\nthen I clicked on app.py

I would literally see my Python code.

It would not get executed because HTTP\n

But today, I'm going to run a\n

So this framework Flask that I\nactually preinstalled in advance

so it wasn't strictly necessary that I\n

yet, comes with a program called Flask,\n

the word run, and when I do that, you'll\n

week whereby you'll see the name--

your URL for your\nunique preview of that.

You might see a pop up saying\nthat your application is running

on TCP port, something or other.

By default, last week,\nwe used port 8080.

Flask, just because, prefers port 5,000.

I'm going to go ahead\nand open up this URL now.

And once it authenticates\nand redirects me

just to make sure I'm allowed to access\n

Voila, there's the extent\nof this application.

If I view source by right-clicking\nor control clicking

there's my HTML that's been spit out.

So really, I've just reinvented\nthe wheel from last week

because there's no dynamism\nnow, nothing at all.

Let me close the source\nand let me zoom out.

Let me zoom in now, and I have\na very unique cryptic URL.

But the point is that\nit ends with nothing.

Or implicitly, it ends with slash.

This is just Chrome\nbeing a little helpful.

It doesn't bother showing you a slash,\n

But let me do something explicit like\n

So there's a key value\npair that I've manually

typed into my URL bar and hit Enter.

Nothing happens, nothing changes.

But the opportunity today is to\n

from that URL and start\ndisplaying it to the user.

So let me go back over here to\nmy terminal window and code.

Let me move that down\nto the bottom there.

And what if I want to\nsay, huh, hello, name.

I ideally want to say something like--

I don't want to hard code\nDavid because then it's never

going to say hello to anyone else.

I want to put like a variable name\n

But it's not an HTML tag, so I\nneed some kind of placeholder.

If I go back to my Python code, I can\n

And I can ask Flask to go\ninto the current request

into its arguments, that is\nin the URL, as they're called

and get whatever the value of\nthe parameter called name is.

That puts that into a variable for me.

And then, in render template--\nthis is one of those functions

that can take more than one argument.

If it takes another\nargument, you can pass

in the name of any variable you want.

So if I want to pass in my name, I\n

So this is the name of a variable\n

This is the actual variable that\nI want to get the value from.

And now lastly, in my index.html,\n

is to do two curly braces and\nthen put the name of the variable

So here's what we mean by a template.

A template is like a blueprint\nin the real world, where

it's plans to make something.

This is the plan to make a web page\n

but there's this placeholder with\ntwo curly braces here and here

that says go ahead and plug in the\n

So in this sense, it's similar\nin spirit to our f strings

or format strings in Python.

The syntax is a little different\njust because reasonable people

disagree, different people,\ndifferent frameworks come up

with different conventions.

The convention in Flask,\nin their templates

is to use two curly braces here.

The hope is that you, the\nprogrammer, will never

want to display two curly\nbraces in your actual web page.

But even if you do,\nthere's a workaround.

So now let me go ahead and go\nback to my browser tab here.

Previously, even though\nI added name equals David

to the end of the URL with a question\n

But now, hopefully, if\nI made these changes

let me go ahead and open\nup my terminal window.

Let me restart Flask so it\nloads my changes by default.

Let me go back to my hello tab and\n

And there we go, hello, David.

I can play around now and I can change\n

And now we have something more dynamic.

So the new pieces here are, in\nPython, we have some code here

that allows us to access,\nprogrammatically, everything

that's after the\nquestion mark in the URL.

And the only thing we have to do that\n

You and I don't have\nto bother figuring out

where is the question mark,\nwhere is the equal sign, where

are the ampersands, potentially.

The framework, Flask,\ndoes all of that for us.

OK, any questions then on\nthese principles thus far?

AUDIENCE: Why do you say the\nquestion mark in the URL?

DAVID: Why do you need a\nquestion mark in the URL?

The short answer is just because that\n

If you're making a GET request\nfrom a browser to a server

the convention, standardized by the\n

after the so-called route or\npath, then a question mark.

And it delineates what's\npart of the root or the path

and what's part of the\nhuman input to the right.

AUDIENCE: Can you go over again why\n

This is this annoying\nthing about Python.

When you pass in parameters,\ntwo functions that have names

you typically say something\nequals something else.

So let me make a slight tweak here.

How about I say name of person here.

This allows me to invent my\nown variable for my template

and assign it the value of name.

I now, though, have to go into my\n

And so this is just stupid because\nit's unnecessarily verbose.

So what typically people do is they\n

itself, even though it looks admittedly\n

The thing to the left\nof the equal sign is

the name of the variable you plan to use\n

is the actual value you're assigning it.

And this is because its general purpose.

I could override this and I could\nsay something like name always

equals Emma, no matter\nwhat that variable is.

And now if I go back to\nmy browser and reload

no matter what's in the URL,\nDavid or Carter, It's always--

Oh, I didn't change my template back.

Let me change that back to be\nname, so that it's name there

But I've hardcoded\nEmma's name, so now we're

only ever going to see Emma no\nmatter whose name is in the URL.

All right, so this is\nbad user interface.

If, in order to get a greeting\nfor the day, you, the user

have to manually change the\nURL, which none of us ever do.

This is not how web pages work.

What is the more normal mechanism\n

and putting it in that\nURL automatically?

How did we do that last week?

AUDIENCE: We have the search\nbar and we [INAUDIBLE] you have

to make something in there [INAUDIBLE].

DAVID: OK, so we did make something in\n

And specifically, what was the tag\n

DAVID: Sorry, a little louder?

DAVID: So the input tag,\ninside of the form tag.

So in short, forms, or of\ncourse, how the web works

and how we typically\nget input from the user

whether it's a button or a text box\n

So let's go ahead and add\nthat into the mix here.

So let's enhance this hello app\n

Let me get rid of this\nname stuff and let me just

have a very simple index.html file\n

the user for some input as follows.

I'm going to go back into my\n

the user's name, this is the page I'm\n

So I'm going to create a form tag.

The method I'm going to use for now\n

Then, inside of that form, I'm\ngoing to have an input tag.

And I'm going to turn off\nautocomplete like we did last week.

I'm going to turn on auto focus, so it\n

I'm going to give the name\nof this input the name, name.

Not to be too confusing, but I'm\n

So it makes sense that the name of the\n

The placeholder I want the\nhuman to see in light gray text

will be Name with a capital N,\n

And then type of this text fiel--

type of this input is going to be text.

Then I'm just going to give myself,\n

And I don't care what\nit says, it's just going

to say the default submit terminology.

Let me go ahead, now, and open\nup my terminal window again.

Let me go to that same URL\nso that I can see-- whoops.

So that was just cached from earlier.

Let me go back to that same\nURL, my GitHub preview.dev URL

And now, I can type in anything I want.

The catch, though, is when I click\n

It does have a default value,\nbut let me go into my index.html

and let me add, just like we\ndid last week for it, Google.

Whereas previously, I said something\n

we're not going to rely\non some third party.

I'm going to implement\nthe so-called backend

and I'm going to have the user\n

not just slash, how about /greet.

I can make it up, whatever I want.

Greet feels like a nice operative word,\n

sent when they click\nSubmit on this form.

All right, so let's go ahead now\nand go back to my browser tab.

Let me go ahead, actually,\nand let me reload Flask

here so that it reloads\nall of my changes.

Let me reload this tab so that I get\n

If I view page source, we\nindeed see that my browser

has downloaded the latest HTML.

So it definitely has changed.

Let's go ahead and type in David.

And when I click Submit\nhere, what's going to happen?

What's going to happen visually,\nfunctionally, however you

want to interpret when I click Submit.

AUDIENCE: [INAUDIBLE] an empty page.

DAVID: OK, the user's going\nto go to an empty page.

Pretty good instinct, because--

no where else, if I mentioned\n/greet, it doesn't seem to exist.

How's the URL going to\nchange, just to be clear?

What's going to appear,\nsuddenly, in the URL?

Specifically in the URL, something's\n

AUDIENCE: The key value pair?

DAVID: The key value pair, right.

That's why our Google\ntrick last week worked.

I sort of recreated a\nform on my own website.

And even though I didn't get around\n

I can still send the information\n

to your question earlier, that\nwhenever you submit a form

it automatically ends up after\na question mark in the URL

So this both of you are\nright, this is going to break.

And all three of you are right,\nin effect, 404 not found.

You can see it in the tab here.

That's the error that has come back.

But what's interesting, and most\nimportant, the URL did change.

And it went to /greet?name=david.

So I just, now, need to add\nsome logic that actually

looks for that so-called route.

So let me go back to my app.py.

Let me define another route for,\nquote unquote, "slash greet.

And then, inside of-- under this,\n

I'll call it greet, but I\ncould call it anything I want.

No arguments, for now,\nfor this, and then

let me go ahead and\ndo this in my app.py.

This time around, I do want\nto get the human's name.

So let me say requeste.args\nget quote unquote "name"

and let me store that in\na variable called name.

Then let me return a\ntemplate, and you know

what, I'm going to give myself\na new template, greet.html.

Because this has a different\npurpose, it's not a form.

I want to say hello to the\nuser in this HTML file

and I want to pass, into it, the\n

All right, so now if I go up and\n

If I go ahead and hit reload or resubmit\n

Let me try, so let's try this.

Let's go ahead and reload the page.

Previously, it was not found.

Now it's worse, and this is\nthe 500 error, internal server

error that I promised next week we will\n

But here we have an\ninternal server error.

Because it's an internal error, this\n

So the route was actually found\n

But if we go into VS Code here and\n

this is actually a bit misleading.

OK, here we have this\nerror here, and this

is where your terminal window\nis going to be helpful.

In your terminal window,\nby default, is typically

going to go helpful\nstuff like a log, L-O-G

of what it is the server\nis seeing from the browser.

For instance, here's what the\nserver just saw in purple.

Get /greet?name=david\nusing HTTP version 1.0.

Here, though, is the status code\nthat the server returned, 500.

Well, here's where we get these\n

that help50 might\nultimately help you with

or here, we might just\nhave a clue at the bottom.

And this is actually pretty\nclear, even though we've never

I just didn't create greet.html, right?

All right, so that must be\nthe last piece of the puzzle.

And again, representative of how you\n

let me go into my terminal window.

After hitting Control C, which\ncancels or interrupts a process

let me go into my templates directory.

If I type ls, I only have index.html.

So let's code up greet.html.

And in this file let's\nquickly do doc type.

Doc type HTML, open bracket\nHTML, language equals English.

Inside of this, I'll have the head tag,\n

The name is viewport,\nthe content of which is--

The content of which is initial scale\n

Quote unquote, title\nis still going to be

I'll call this greet\nbecause this is my template.

And then here, in the body, I'm\ngoing to have hello comma name.

So I could have kept around the old\n

essentially, my second template.

So index.html now is almost the\nsame, but the title is different

greet.html is almost the same,\nbut it does not have a form.

It just has the hello comma name.

So let me now go ahead and\nrerun in the correct directory.

You have to run Flask wherever app.py\n

So let me do Flask run to\nget back to where I was.

Let me go into my other tab.

Cross my fingers this time\nthat, when I go back to slash

and I get index.html's form, now\n

And now we have a full-fledged web\n

slash and /greet, the latter of\n

using a template, spits it out.

But something could go wrong,\nand let's see what happens here.

Suppose I don't type anything in.

Let me go here and just click Submit.

Now, I mean, it looks stupid.

So there's bunches of\nways we could solve this.

I could require that the user\nhave input on the previous page

I could have some kind\nof error check for this.

But there's another mechanism I\ncan use that I'll just show you.

It turns out this GET function,\nin the context of HTTP

and also in general with\nPython dictionaries

you can actually supply a default value.

So if there is no name parameter\n

you can actually give it\na default value like this.

So I'll say world, for instance.

Let me type in nothing\nagain and click Submit.

And hopefully this time,\nI'll do-- oops, sorry.

Let me restart Flask\nto reload the template.

Let me go ahead and type nothing\nthis time, clicking Submit.

Suppose that the reason this--

Suppose I just get rid of name\n

Now I see hello, world,\nand this is a subtlety

that I didn't intend to get into here.

When you have question\nmark name equals nothing

you're passing in\nwhat's called-- whoops.

When you have greet question\nmark name equals something

you actually are giving a value to name.

It is quote unquote\nwith nothing in between.

That is different from\nhaving no value at all.

So allow me to just propose\nthat the error here, we

would want to require\nthis in a different way.

And probably the most\nrobust way to do this

would be to go in here, in my HTML, and\n

Now, if I go back to my form\nafter restarting Flask here

and I go ahead and click reload\non my form and type in nothing

and click Submit, now the\nbrowser is going to yell at me.

But just as a teaser\nfor something we'll be

doing in the next problem set\nin terms of error checking

you should never, ever, ever rely on\n

Because we know, from last week, that\n

and let me poke around the HTML here.

Let me go into the body, the form.

OK, you say required,\nI say not required.

You can just delete what's\nin the dom, in the browser

and now I can go ahead\nand submit this form.

And it appears to be broken.

Not a big deal with a silly little\n

But if you're trying to\nrequire that humans actually

provide input that is necessary for\n

you don't want to trust that the HTML\n

All right, any questions,\nthen, on this particular app

before we add another feature here?

AUDIENCE: Do you guys [INAUDIBLE].

DAVID: Sorry, little louder.

DAVID: Would it be a problem if what?

AUDIENCE: You have to [INAUDIBLE].

What you should really do is something\n

where I'm going to start\nerror checking things.

So let me wave my hands at\nthat and propose that we'll

solve this better in just a bit.

But it's not bad to do\nwhat I just did here, it's

only going to handle one of the\n

All right, so even though\nthis is new to most of us

here, consider index.html, my first\n

What might be arguably badly designed?

Even though this might\nbe the first time you've

ever touched web programming like this.

What's bad or dumb about this\n

And there's a reason, too, that I bored\n

AUDIENCE: [INAUDIBLE] you said,\n

DAVID: Yeah, there's so much repetition.

I mean, it was deliberately tedious\n

The doc type, the HTML tag,\nthe head tag, the title tag.

And little things did change\nalong the way, like the title

and certainly, the content of the body.

But so much of this, I\nmean, almost all of the page

is a copy of itself in multiple files.

And God forbid we have a third template,\n

This is going to get very\ntedious very quickly.

And suppose you want to\nchange something in one place

you're going to have to change it now in\n

So just like in\nprogramming more generally

we have this ability to\nfactor out commonalities.

So do you in the context\nof web programming

and specifically\ntemplating, have the ability

to factor out all of\nthose commonalities.

The syntax is going to\nbe a little curious

but it functionally is\npretty straightforward.

Let me go ahead and copy\nthe contents of index.html.

Let me go into my templates\ndirectory and code a file that

by default, is called layout.html.

And let me go ahead, and per\nyour answer, copy all of those

commonalities into\nthis file now instead.

So here I have a file\ncalled layout.html.

I don't want to give every page the same\n

I'm going to call everything hello.

But in the body of the page,\nwhat I'm going to do here is just

have a placeholder for actual\ncontents that do change.

So in this layout, I'm\ngoing to go ahead in here

and just put in the body of my\npage, how about this syntax?

Block body, and then percent\nsign close curly brace.

And then I'm going to do end block.

So a curious syntax here, but\nthis is more template syntax.

The other template syntax we saw\n

That's for just plugging in values.

There's this other syntax with Flask\n

brace, a percent sign, and then some\n

And this one's a little weird\nbecause there's literally

nothing between the close curly\nand the open curly brace here.

But let's see what this can do for us.

Let me now go into my index.html, which\n

from, and let me focus on\nwhat is minimally different.

The only thing that's really different\n

So let me go ahead and just cut\nthat form out to my clipboard.

Let me change the first\nline of index.html

to say this file is going\nto extend layout.html

and notice I'm using\nthe curly braces again.

And this file is going to\nhave its own body block

inside of which is just\nthe HTML that I actually

want to make specific to this page.

And I'll keep my indentation\nnice and neat here.

And let's consider what I've done.

This is starting to look\nweird fast, and this is now

a mix of HTML with templating code.

Index.html, first line now says, hey,\n

This next line, three through\n10, says, hey, Flask, here

is what I consider my body block to be.

Plug this into the layout placeholder.

Therefore, so if I now go back\nto layout.html, and layout.html

it's almost all HTML by contrast.

But there is this placeholder, and\n

If I want to put a\ndefault value, I could

put a default value there just in case\n

But in general, that's\nnot going to be relevant.

So this is just a placeholder,\n

plug in the page-specific\ncontent right here.

So if I go now into greet.html,\nthis one's even easier.

I'm going to cut this content\nand get rid of everything else.

Greet.html 2 is going to extend\n

and then I'm going to have my body block\n

And then I'm going to go\nahead and end that block here.

These are not HTML tags,\nthis is not HTML syntax.

Technically, the syntax we keep\nseeing with the curly braces

and these now curly braces with percent\n

J-I-N-J-A, which is a language,\nthat some humans invented

for this purpose of templating.

And the people who\ninvented Flask decided

we're not going to come\nup with our own syntax

we're going to use these other\n

So again, there starts to be\nat this point in the course

and really in computing, a lot of\n

So Flask is using this syntax, but\n

All right, so now\nindex.html is half HTML

half templating code, Jinja syntax.

Greet.html is almost all\nJinja syntax, no tags even

but because they both\nextend layout.html

now I think I've improved\nthe design of this thing.

If I go back to app.py, none\nof this really needs to change.

I don't change my templates\nto mention layout.html

that's already implicit in the fact\n

So now if I go ahead and\nopen my terminal window

go back to the same folder\nas app.py and do Flask run

all right, my application\nis running on port 5000.

Let me now go back to the /route\nin my browser and hit Enter

And just as a little check, let\nme view the source of the page

And there's all of the code.

No mention of Jinja, no curly\nbraces, no percent signs.

It's not quite pretty printed in\nthe same way, but that's fine.

Because now, we're starting to\ndynamically generate websites.

And by that, I mean this isn't\n

If it's indented in the\nsource code version

doesn't matter what the\nbrowser really sees.

Let me now go ahead and type\nin my name, click Submit.

I should see, yep, hello, David.

Let me go ahead and view\nthe source of this page.

And we'll see almost the same\n

So this is, now, web programming\nin the literal sense.

I did not hard code a page that says\n

I hardcoded a page that has a\ntemplate with a placeholder

and now I'm using actual\nlogic, some code in app.py

to actually tell the server\nwhat to send to the browser.

All right, any questions,\nthen, on where we're at here?

This is now a web application.

Simple though it is, it's\nno longer just a web site.

AUDIENCE: Is what we did just better\n

DAVID: It better for\ndesign or for memory?

It's definitely better\nfor design because, truly

if we had a third page,\nfourth page, I would really

start just resorting to copy paste.

And as you saw with home page,\noften, in the head of your page

you might want to include some CSS\n

You might want to have\nother information up there.

If you had to upgrade the version of\n

so you want to change\none of those lines

you would literally have to go into\n

Theoretically, the server, because\n

it can theoretically do some\noptimizations underneath the hood.

Flask is probably doing that, but\n

We're using it in\ndevelopment mode, which

means it's typically\nreloading things each time.

Other questions on this application?

All right, so let me ask a question,\n

What about the implications for privacy?

Why is this maybe not the best design\n

AUDIENCE: For some reason,\nyou wanted your name.

So these private people\ncould just look at the URL.

I mean, if you have a\nnosy sibling or roommate

and they have access to\nyour laptop and they just

go trolling through your\nautocomplete or your history

like, literally what you typed into\n

Not a big deal if it's your name, but\n

card or anything else\nthat's mildly sensitive

you probably don't want it\nending up in the URL at all

even if you're in\nincognito mode or whatnot.

You just don't want to expose yourself\n

So perhaps, we can do better than that.

And fortunately, this one\nis actually an easy change.

Let me go into my\nindex.html where my form is.

And in my form, I can just change\nthe method from GET to POST.

It's still going to send key\nvalue pairs to the server

but it's not going to\nput them in the URL.

The upside of which is that we\ncan assuage this privacy concern

but I'm going to have to\nmake one other change too.

Because now, if I go ahead and run\n

and I now reload the form to make\n

You should be in the habit\nof going to View, Developer

View Source, or Developer\nTools just to make sure

that what you're seeing in your\nbrowser is what you intend.

And yes, I do see what I wanted.

Let me go ahead and type\nin David and click Submit.

Now I get a different error.

This one is HTTP 405,\nmethod not allowed.

Well, in my Flask application, I've\n

One of which is for slash,\nthen that worked fine.

One of which is for /greet,\nand that used to work fine.

But apparently, what Flask is doing\n

So if I want to change this route to\n

quote unquote "POST" inside\nof this parameter here.

So that now, I can actually\nsupport POST, not just GET.

And if I now restart Flask, so Flask\n

Let me go back one screen\nto the form, reload

the page just to make\nsure I have the latest

even though nothing there has changed.

Type David and click Submit now,\nnow I should see hello, world.

Notice that I'm at the greet route,\n

All right, so that's an\ninteresting takeaway.

It's a simple change, but whereas GET\n

But it still works so long\nas you tweak the backend

to look as a POST request, which\n

It's not going to be as simple\nas looking at the URL itself.

Why shouldn't we just always use POST?

Why not use POST everywhere?

Right, because it's obnoxious to\n

if you're leaving these little\n

can poke around and see\nwhat you've been doing.

AUDIENCE: You're supposed\nto duplicate [INAUDIBLE]..

I mean, if you get rid of GET\n

your history, your autocomplete,\ngets pretty less useful.

Because none of the information is\n

go through the menu and hit Enter.

You'd have to re-fill out the form.

And there's this other\nsymptom that you can see here.

Let me zoom out and let\nme just reload this page.

Notice that you'll get\nthis warning, and it'll

look different in Safari and Firefox\n

So your browser might remember what\n

but just while you're on the page.

And this is in contrast to GET,\nwhere the state is information.

Like, key value pairs is\nembedded in the URL itself.

And if you looked at an\nemail I sent earlier today

I deliberately linked\nto https://www.google.c

om/search?q=what+time+is+it.

This is, by definition, a GET\nrequest when you click on it.

Because it's going to grab the\ninformation, the key value pair

from the URL, send it to Google\n

And the reason I sent this\nvia email earlier was I

wanted people to very quickly be able\n

And so I can sort automate the process\n

but that you induce when\nyou click that link.

If Google did not support GET, they\n

is send you all to this\nURL which, unfortunately

I would have had to add to my\n

So it's just bad for usability.

So there, too, we might have design\n

but also the design when it comes\nto the user experience, or UX

as a computer scientist would call it.

Just in terms of what you want\nto optimize for, ultimately.

So GET and POST both have their roles.

It depends on what kind of\nfunctionality you want to provide

and what kind of sensitivity\nthere might be around it.

All right, any questions, then, on\n

Super simple, just gets someone's\nname and prints it back out.

But we now have all\nthe plumbing with which

to create really most anything we want.

All right, let's go ahead\nand take a five minute break.

And when we come back, we'll add to\n

And recall that the last\nthing we just changed

was the route to use\nPOST instead of GET.

So gone is my name and\nany value in the URL.

But there was a subtle bug or change\n

I did type David into the\nform and I did click Submit

and yet here it is\nsaying hello comma world.

So that seems to be\nbroken all of a sudden

even though we added support for POST.

But something must be wrong.

Logically, it must be the case here.

Intuitively, that if I'm seeing\n

It must be that it's\nnot seeing a key called

name in request.args, which is this.

Gives you access to\neverything after the URL.

That's because there's this\nother thing we should know about

which is not just\nrequest.args but request.form.

These are horribly named, but\nrequest.args is for GET requests

request.form is for POST requests.

Otherwise, they're pretty\nmuch functionally the same.

But the onus is on you,\nthe user or the programmer

to make sure you're using the right one.

So I think if we want\nto get rid of the world

and actually see what\nI, the human, typed in

I think I can just change\nrequest.args to request.form.

Still dot get, still\nquote unquote "name

and now, if I go ahead and rerun\nFlask in my terminal window

go back to my browser, go\nback to-- and actually

I won't even go back to the form.

I will literally just reload,\nCommand R or Control R

and what this warning is\nsaying is it's going to submit

the same information to the website.

When I click Continue, now I\nshould see hello comma David.

So again, you, too, are\ngoing to encounter, probably

all these little subtleties.

But if you focus on, really, the\nfirst principles of last week

like what it HTTP, how\ndoes it get request work

how does a POST request\nwork now, you should

have a lot of the mental\nbuilding blocks with which

to solve problems like these.

And let me give you one other mental\n

This framework called Flask is just an\n

that all implement the same\nparadigm, the same way of thinking

and the same way of\nprogramming applications.

And that's known as MVC,\nmodel view controller.

And here's a very simple diagram\n

and I have been implementing thus far.

And actually, this is more than\n

In app.py is what a programmer\n

That's the code you're\nwriting, this are called

business logic that makes all of the\n

what values to show, and so forth.

In layout.html, index.html, greet.html\n

that is the visualizations\nthat the human actually

Those things are dumb, they pretty\n

All of the hard work is done in app.py.

So controller, AKA app.py, is where\n

And in your view is where your HTML and\n

the curly braces, the curly braces\n

We haven't added an M\nto MVC yet model, that's

going to refer to things\nlike CSV files or databases.

The model, where do you keep\nactual data, typically long term.

So we'll come back to\nthat, but this picture

where you have one of these-- each of\n

another is representative of\nhow a lot of frameworks work.

What we're teaching today, this week,\n

It's not really specific to Flask,\n

It really is a very\ncommon paradigm that you

could implement in Java, C sharp, or\n

All right, so let's now\npivot back to VS Code here.

Let me stop running\nFlask, and let me go ahead

and create a new folder altogether\n

And let me go ahead and create\na folder called FroshIMS

representing freshman intramural\n

And now I'm going to code an app.py.

And in anticipation, I'm going to\n

This one in the FroshIMS folder.

And then in my templates directory,\n

and I'm just going to\nget myself started here.

I'm just copying my layout\nfrom earlier because most

of my interesting work, this time, is\n

So what is it we're creating?

So literally, the very first\nthing I wrote as a web application

20 years ago, was a site that\nliterally looked like this.

So I was like a sophomore\nor junior at the time.

I'd taken CS50 and a\nfollow-on class only.

I had no idea how to do web programming.

Neither of those two courses taught\n

So I taught myself, at the\ntime, a language called Perl.

And I learned a little something about\n

can't even say googled enough,\nbecause Google didn't come out

Read enough online to figure out how to\n

on campus, first years,\ncould actually register

via a website for intramural sports.

Back in my day, you would\nliterally fill out a piece of paper

and then walk it across the yard to\n

slide it under the dorm\nof the Proctor or RA

and thus you were\nregistered for sports so.

There was an internet,\njust wasn't really being

used much on campus or more generally.

So background images\nthat repeat infinitely

was in vogue, apparently, at the time.

All of this was like images\nthat I had to hand make

because we did not have the features\n

So it was really just HTML, and it was\n

And it was really just\nthe same building blocks

that we hear already today now have.

So we'll get rid of all of\nthe imagery and focus more

on the functionality and the\naesthetics, but let's see

if we can whip up a web\napplication via which someone could

register for one such intramural sport.

So in app.py, me go ahead and\nimport some familiar things now.

From Flask, let's import\ncapital Flask, which

is that function we need to kick\n

Render templates, so we have the\n

those templates, and request\nso that we have the ability

to get at input from the human.

Let me go ahead and create\nthe application itself

using this magical incantation here.

And then let's go ahead and define a\n

I'm going to define a\nfunction called index.

But just to be clear, this\nfunction could be anything.

Foo, bar, baz, anything else.

But I tend to name\nthem in a manner that's

consistent with what\nthe route is called.

But you could call it\nanything you want, it's

just the function that will get\n

Now, let me go ahead here\nand just get things started.

Return, render template of index.html.

Just keep it simple, nothing more.

So there's nothing really\nFroshIM specific about this here

I just want to make sure I'm\ndoing everything correctly.

Meanwhile, I've got my layout.

OK, let me go ahead, and in my\ntemplates directory, code a file

And let's just do extends\nlayout.html at the top

just so that we get\nbenefit from that template.

And down here, I'm just\ngoing to say to do.

Just so that I have something\ngoing on visually to make sure

In my FroshIMS directory,\nlet me do Flask run.

Let me now go back to my previous URL,\n

But now, I'm serving\nup the FroshIM site.

That's because I\nscrewed up accidentally.

What did I do wrong in index.html?

This file extends layout.html, but--

AUDIENCE: You left out the block tag?

I forgot to tell Flask what\nto plug into that layout.

So I just need to say block body, and\n

or whatever I want to\neventually get around to.

OK, so now it looks ugly, more cryptic.

But this is, again, the\nessence of doing templating.

Let me now restart Flask up\nhere, let me go back to the page.

Crossing my fingers this\ntime, and there we go.

So it's not the application\nI want, but at least I

know I have some of the\nplumbing there by default.

All right, so if I want the\nuser to be able to register

for one of these sports,\nlet's enhance, now

index.html to actually\nhave a form that's

maybe got a dropdown menu for all of\n

So let me go into this template here.

And instead of to do, let's\ngo ahead and give myself

how about an H1 tag that just says\n

How about a form tag\nthat's going to use POST

just because it's not really necessary\n

The action for that, how\nabout we plan to create

a register route so that we're sending\n

So we'll have to come back to that.

In here, let me go ahead and create,\n

How about a name equals\nname, because I'm

going to ask the student for their\n

And the type of this box will be text.

So this is pretty much\nidentical to before.

But if you've not seen this\nyet, let's create a select menu

a so-called dropdown menu in HTML.

And maybe the first option\nI want to be in there

is going to be, oh, how\nabout the current three

sports for the fall, which are\nbasketball, and another option

is going to be soccer,\nand a third option is

going to be ultimate frisbee for\n

So I've got those three options.

I haven't implemented my route yet,\n

to go back now and check\nif my form has reloaded.

So let me go ahead and\nstop and start Flask.

You'll see there's ways to\nautomate the process of restarting

the server that we'll do for\nyou for problem set nine

so you don't have to\nkeep stopping Flask.

Let me reload my index route\nand OK, it's not that pretty.

But it now has at least\nsome functionality

where I can type in my name\nand then type in the sport.

Now, I might be biasing\npeople toward basketball.

Like UX wise, user experience\nwise, it's obnoxious to precheck

basketball but not the others.

So there's some little\ntweaks we can make there.

Let me go back into index.html.

Let me create an empty option up here\n

going to have the name of any sports.

But it's just going to have a\nword I want the human to see

so I'm actually going to disable this\n

But I'm going to say sport up here.

And there's different ways to do this,\n

Creating a placeholder\nsports so that the user

sees something in the dropdown.

Let me go ahead and restart\nFlask, reload the page

and now it's just going\nto be marginally better.

Now you see sport that's\nchecked by default

but you have to check one of\nthese other ones ultimately.

All right, so that's pretty good.

So let me now type in David.

I'll register for ultimate frisbee.

OK, I definitely forgot something.

All right, so input type equals submit.

All right, let's put that in.

Submit could be a little prettier.

Recall that we can change some of\n

The value of this button\nshould be register, maybe

just to make things a little prettier.

Let me now reload the page and register.

All right, so now we really have\n

that I created some years ago to let\n

So let's go, now, and create maybe\n

And in here, if we want to\nallow the user to register

let's do a little bit of error checking\n

What could the user do wrong?

Because assume that they will.

One, they might not type their name.

Two, they might not choose a sport.

So they might just submit an empty form.

So that's two things we\ncould check for, just

so that we're not scoring bogus\n

So let's create another\nroute called greet, /greet.

And then in this route, let's\ncreate a function called greet

but can be called anything we want.

And then let's go ahead, and in\n

and validate the submission.

So a little comment to myself here.

How about if there is not a\nrequest.form GET name value

so that is if that\nfunction returns nothing

like quote unquote, or the\nspecial word none in Python.

Or request.form.get"sport" not\nin quote unquote, what were they?

Basketball, the other one was soccer,\n

Getting a little long, but notice\n

If the user did not\ngive us a name, that is

if this function returns\nthe equivalent of false

which is, quote unquote, or literally\n

Or if the sport the user provided is\n

or ultimate frisbee, which I've defined\n

and just yell at the user in some way.

Let's return render\ntemplate of failure.html.

And that's just going to be some\n

Otherwise, if they get\nthis far, let's go ahead

and confirm registration\nby just returning-- whoops

returning render template quote\nunquote "success" dot HTML.

All right, so a couple\nquick things to do.

Let me first go in and in\nmy templates directory

let's create this failure.html file.

And this is just meant to\nbe a message to the user

that they fail to provide\nthe information correctly.

So let me go ahead and in failure.html.

So let me extend layout.html and in\n

I'll just yell at them like that so\n

And then let me create one other\nfile called success.html, that

similarly is mostly just Jinja syntax.

And I'm just going to say for\nnow, even though they're not

technically registered in any\ndatabase, you are registered.

That's what we mean by success.

All right, so let me go ahead,\nand back in my FroshIMS

Let me go back to the form and reload.

All right, so now let me\nnot cooperate and just

immediately click Register impatiently.

Register-- oh, I'm\nconfusing our two examples.

All right, I spotted the error.

There's where I am, what did\nI actually invent over here?

AUDIENCE: Register, not greet.

I had last example on my mind,\nso the route should be register.

Ironically, the function could be greet,\n

But to keep ourselves sane, let's\n

Let me go ahead now and\nstart Flask as intended.

Let me reload the form just\nto make sure all is working.

Now, let me not cooperate and be\na bad user, clicking register--

OK, other unintended mistake.

But this one we've seen before.

Notice that by default,\nroute only support GET.

So if I want to\nspecifically support POST

I have to pass in, by a methods\n

methods that could be\nGET comma POST, but if I

don't have no need for a GET in\n

All right, now let's\ndo this one last time.

Reload the form to make sure\neverything's OK, click Register

and you are not registered.

All right, let me go ahead and\nat least give them my name.

Fine, I'm going to go ahead and be\n

What should I-- what\ndid I mean to do here?

All right, so let's figure this out.

How to debug something like this,\n

How can we go about\ntroubleshooting this?

Turn this into the teachable moment.

All right, well first,\nsome safety checks.

Let me go ahead and view page\nsource, a good rule of thumb.

Look at the HTML that you\nactually sent to the user.

So here, I have an\ninput with a name name.

So that's what I\nintended, that looks OK.

Ah, I see it already, even\nthough you, if you've never

used a select menu, you might\nnot know what, apparently

is missing from here that I\ndid have for my text input.

Just intuitively, logically.

What's going through my\nhead, embarrassingly

is, all right, if my form thinks\n

how did I create a situation in which\n

Well, name, I don't think\nit's going to be blank

because I explicitly gave\nthis text field a name name

and that did work last time.

I've now given a second input\nin the form of the select menu.

But what seems to be missing here\nthat I'm assuming exists here?

It's just a dumb mistake I made.

What might be missing here?

If request.form gives you all of\nthe inputs that the user might

have typed in, let me\ngo into my actual code

here in my form and name equals sport.

I just didn't give a name to that input.

So it exists, and the\nbrowser doesn't care.

It's still going to\ndisplay the form to you

it just hasn't given it a unique name\n

So now, if I'm not going\nto put my foot in my mouth

I think that's what I did wrong.

And again, my process\nfor figuring that out

was looking at my code,\nthinking through logically

is this right, is this right?

No, I was missing the name there.

So let's run Flask,\nlet's reload the form

just to make sure it's all defaults\n

in ultimate frisbee, crossing\nmy fingers extra hard this time.

I did not intend to\nscrew up in that way

but that's exactly the right\nkind of thought process

to diagnose issues like this.

Go back to the basics, go back to what\n

and just rule things in and out.

There's only a finite number of\n

AUDIENCE: Are you [INAUDIBLE].

DAVID: Excuse-- say a little louder?

AUDIENCE: I don't understand why\nname equals sport [INAUDIBLE]..

DAVID: Why did name equal\nsport address the problem?

Well, let's first go back to the HTML.

Previously, it was just the reality that\n

But names, or more\ngenerally, key value pairs

is how information is sent\nfrom a form to the server.

So if there's no name, there's no key to\n

It would be like nothing equals ultimate\n

The browser is just\nnot going to send it.

However, in app.py, I was naively\n

there would be a name called\nquote unquote "sport.

It could have been anything,\nbut I was assuming it was sport.

But I never told the form that.

And if I really wanted to dig in,\n

Let me go back to the\nway it was a moment ago.

Let me get rid of the name\nof the sport dropdown menu.

Let me rerun Flask down here\nand reload the form itself

after it finishes being served.

View Developer Tools, and then let me\n

we played around with\na little bit last week.

And we also played around with Curl,\n

Here's another-- here's\nwhat I would have

done if I still wasn't seeing the error\n

I would have typed in my name as before,\n

I would have clicked register.

And now, I would have\nlooked at the HTTP request.

And I would click on Register here.

And just like we did last week, I\n

And there's a whole lot of stuff\nthat we can typically ignore.

But here, let me zoom\nin, way at the bottom

what Chrome's developer\ntools are doing for me

it's showing me all of the\nform data that was submitted.

So this really would have\nbeen my telltale clue.

I'm just not sending the sport,\neven if the human typed it in.

And logically, because\nI've done this before

that must mean I didn't\ngive the thing a name.

Like good programmers, web developers\n

They're not writing bug-free code.

That's not the point to get to.

The point to get to is\nbeing a good diagnostician

I would say, in these cases.

AUDIENCE: What if you want to\n

DAVID: I'm sorry, a little bit louder?

AUDIENCE: If you want to\nedit in CSS or anything

in HTML, once you have to fix\nthe template, how do you that?

DAVID: So how would you edit\nCSS if you have these templates?

That process we'll\nactually see before long.

It's almost going to be the exact same.

Just to give you a teaser for this,\n

but we'll give you some distribution\n

You can absolutely still\ndo something like this.

Link href equals quote\nunquote "styles" dot

CSS rel equals style sheet, that's one\n

The only difference today, using Flask,\n

by convention, should go\nin your static folder.

So the change you would\nmake in your layout

would be to say that styles dot\nCSS is in your static folder.

And then, if I go into\nmy FroshIMS directory

I can create a static folder.

I can CD into it,\nnothing's there by default.

But if I now code a\nfile called styles.css

I could now do something like this body.

And in here, I could say background\n

Let me go ahead now and restart\nFlask in the FroshIMS directory.

Cross my fingers because\nI'm doing this on the fly.

Go back to my form and reload.

Voila, now we've tied together\nlast week's stuff as well.

If I answered the right question?

AUDIENCE: [INAUDIBLE] change\none page and not the other.

DAVID: If you want to change one page\n

In that case, you might want to have\n

You could use different classes in one\n

There's different ways to do that.

You could even have a\nplaceholder in your layout

that allows you to plug in\nthe URL of a specific style

sheet in your individual files.

But that starts to get\nmore complicated quickly.

So in short, you can absolutely do it.

But typically, I would\nsay most websites try not

to use different style Sheets per page.

They reuse the styles\nas much as they can.

All right, let me go ahead\nand revert this real quick.

And let's start to add a little\nbit more functionality here.

I'm going to go ahead and just\n

to not complicate things just yet.

And let's go ahead and just play\n

In my form here, the dropdown\nmenu is perfectly fine.

But suppose that I wanted to\nchange it to checkboxes instead.

Maybe I want students to be able to\n

Well, it might make sense to\nclean this up in a couple of ways.

Before we even get into the checkboxes,\n

Notice that I've hardcoded basketball,\n

And if you recall, in app.py, I also\n

And any time you see copy paste\nor the equivalent thereof

feels like we could do better.

So what if I instead do this.

What if I instead give myself\na global variable of Sports

I'll capitalize the word\njust to connote that it's

meant to be constant even though\n

The first sport will be basketball.

The third will be ultimate frisbee.

Now I have one convenient\nplace to store all of my sports

if it changes next semester\nor next year or whatnot.

But notice what I could do to.

I could now do something like this.

Let me pass into my\nindex template a variable

called sports that's equal to\nthat global variable sports.

Let me go into my index now,\nand this is really, now

going to hint at the power of\n

Let me go ahead and get rid of all\n

and let me show you some slightly\n

We've not seen this end for syntax.

There's like end block syntax,\nbut it's as simple as that.

So you have a start and an end to your\n

Option curly brace\nsport close curly brace.

Let me go back into my\nterminal window, do Flask run.

And if I didn't mess up\nhere, let me go back to this.

The red's going to go away\nbecause I deleted my CSS.

And now I still have a sport\ndropdown and all of those sports

I can make one more improvement now.

I don't need to mention these\nsame sports manually in app.py.

I can now just say if the\nuser's inputed sport is not

in my global variable, sports,\nand ask the same question.

And this is really\nhandy because if there's

another sport, for instance, that\ngets added, like say football

all I have to do is\nchange my global variable.

And if I reload the form now\nand look in the dropdown, boom

now I have support for a fourth sport.

And I can keep adding and adding there.

So here's where templating starts\nto get really powerful in that

now, in this template, I'm using\nJinja's for loop syntax, which

is almost identical to\nPython here, except you

need the curly brace and the percent\n

But it's the same idea as in Python.

Iterating over something with a for loop\n

And this is like every\nwebsite out there.

When you visit your inbox and you\n

Google has not hardcoded\nyour emails manually.

They have grabbed them from a database.

They have some kind\nof for loop like this

and are just outputting table row after\n

All right, so now, let's go\nahead and change this, maybe

to, oh, how about little\ncheckboxes or radio buttons.

So let me go ahead and do this.

Instead of a select menu, I'm going to\n

For each of these sports let me go\n

but let me go ahead and\noutput an input tag

the name for which is quote\nunquote "sport," the type of which

is checkbox, the value of which is\n

quote unquote, and then afterward\n

So you see a word next to the checkbox.

And we'll look at the result\nof this in just a moment.

So it's actually a little simpler\n

because now watch what\nhappens if I reload my form.

Different user interface,\nand it's not as pretty

but it's going to allow users to sign\n

Now I can click on basketball\nand football and soccer

or some other combination thereof.

If I view the page's source, this\n

I didn't have to type out four\n

And these things all have\nthe same name, but that's OK.

It turns out with Flask, if it sees\n

it's going to hand them back to you as\n

All right, but suppose we don't want\n

Let me go ahead and change this\ncheckbox to radio button, which

a radio button is mutually exclusive.

So you can only sign up for one.

So now, once I reload\nthe page, there we go.

And because I've given each of these\n

sport," that\'s what makes\nthem mutually exclusive.

The browser knows all four of\nthese things are types of sports

therefore I'm only going to let\nyou select one of these things.

And that's simply because\nthey all have the same name.

Again, if I view page source, notice\n

name equals sport, name equals\n

that each one is going to have.

All right, any questions,\nthen, on this approach?

Well, let me go ahead and\nopen a version of this

that I made in advance that's going\n

So thus far, we're\nnot quite at the point

of where this website was, which\n

like in a database, everyone\nwho had registered for sports.

Now, we're literally telling\nstudents you are registered

or you are not registered,\nbut we're literally

doing nothing with this information.

So how might we go\nabout implementing this?

Well, let me go ahead\nand close these tabs

and let me go into what I call version\n

And let me go into my source\nnine directory, FroshIMS3

and let me go ahead and open up app.py.

So this is a premade version.

I've gotten rid of\nfootball, in this case.

But I've added one\nthing at the very top.

What's, in English, does\nthis represent on line seven?

What would you describe\nwhat that thing is?

AUDIENCE: It's an empty dictionary.

DAVID: Yeah, it's an\nempty dictionary, right?

Registrants is apparently\na variable on the left.

It's being assigned an empty\ndictionary on the right.

And a dictionary, again,\nis just key value pairs.

Here, again, is where dictionaries\n

Because this is going to allow me\n

for ultimate frisbee, Carter\nregistered for soccer

Emma registered for something else.

You can associate keys with\nvalues, names with sports

assuming a model where you can only\n

And so let's see what the\nlogic is that handles this.

Here in my register route\nin the code I've premade

notice that I'm validating\nthe user's name.

Slightly differently from\nbefore but same idea.

I'm using request.form.get\nto get the human's name.

If not name, so if the\nhuman did not type a name

I'm going to output error.html.

But notice I've started to make\n

I'm telling the user, apparently,\n

I'm apparently passing\nto my error template

instead of just failure.html,\na specific message.

So let's go down this rabbit hole.

Let me actually go into\ntemplates/error.hml, and sure enough

here's a new file I created here, that\n

a grumpy cat as part of the error\n

In my block body I've got an H1 tag\n

I then have a paragraph\ntag that plugs in whatever

the error message is that the\ncontroller, app.py, is passing in.

And then just for fun, I have a\n

that there was, in fact, an error.

I do similarly\nrequest.form.get of sport

and I store it in a\nvariable called sport.

If there's no such sport, that is the\n

then I'm going to render\nerror.html two, but I'm

going to give a different\nmessage, missing sport.

Else, if the sport they did type in\n

I'm going to render error.html,\nbut complain differently

you gave me an invalid sport somehow.

As if a hacker went into\nthe HTML of the page

changed it to add their\nown sport like volleyball.

Even though it's not offered,\nthey submitted volleyball.

But that's OK, I'm rejecting it, even\n

tried to send it to me by\nchanging the dom locally.

And then really, the magic is just this.

I remember that this\nperson has registered

by indexing into the\nregistrant dictionary

using the name the human typed in as the\n

Well, I added one final route here.

I have a /registrants route with a\n

a template called registrants.html.

But it takes as input that\nglobal variable just like before.

So let's go down this rabbit hole let me\n

It looks a little crazy big,\nbut it extends the layout.

I've got an H1 tag that says\nregistrants, big and bold.

Then I've got a table\nthat we saw last week.

This has a table head that just\nsays name sport for two columns.

Then it has a table body where in,\n

I'm saying, for each name\nin the registrants variable

output a table row, start tag,\nand end tag, inside of which

two table datas, two\ncells, table data for name

table data for registrants bracket name.

So it's very similar to Python syntax.

It essentially is Python syntax, albeit\n

So the net effect here is what?

Let me open up my terminal\nwindow, run Flask run.

Let me now go into the\nform that I premade here.

Let me go ahead and type in David.

Let me choose, oh, no sport.

And there is the grumpy cat.

So missing sport, though,\nspecifically was outputed.

Let me go ahead and say no name.

All right, and let me\nmaliciously, now, do this.

I'll type my name, sure, but let\n

Let me maliciously go down in ultimate\n

Change that and change\nthis to volleyball.

So now, I can register for\nany sport I want to create.

Let me click register,\nbut invalid sports.

So again, that speaks to\nthe power and the need

for checking things on backend\nand not trusting users.

It is that easy to hack websites\n

All right, finally, let's\njust do this for real.

David is going to register\nfor ultimate frisbee.

And now, the output is not\nvery pretty, but notice

I'm at the registrants route.

And if I zoom out, I have an HTML table.

Two columns, name and sport,\nDavid and ultimate frisbee.

Let me go back to the form, letting me\n

and registered for basketball.

Now we see two rows in this table,\n

And if we do this one\nmore time, maybe Emma

comes along and registers\nfor soccer register.

All of this information is being\nstored in this dictionary, now.

All right, so that's great.

Now we have a database, albeit in\n

But why is this, maybe, not\nthe best implementation?

AUDIENCE: You are storing [INAUDIBLE].

So we're only storing this\ndictionary in the computer's memory

and that's great until I hit\nControl C and kill Flask

Or the server reboots, or maybe\nI close my laptop or whatever.

If the server stops running,\nmemory is going to be lost.

It's thrown away when you lose\npower or stop the program.

So maybe this isn't the best approach.

Maybe it would be better\nto use a CSV file.

And in fact, some 20 years ago,\nthat's literally what I did.

I stored everything in a CSV file.

But let's skip that step,\nbecause we already saw last week

or a couple of weeks ago\nnow, how we can use SQLite.

Let's see if we can't\nmarry in some SQL here

to store an actual\ndatabase for the program.

Let me go back here and\nlet me open up, say

version four of this, which\nis almost the same but it

adds a bit more functionality.

Let me close these tabs and let me\n

So notice it's almost\nthe same, but at the top

I'm creating a database connection\n

So that's a database\nI created in advance.

So let's go down that rabbit hole.

Let me make my terminal window bigger.

Let me run SQLite 3 of FroshIMS.db.

and let's just infer what\nI designed this to be.

I have a table called registrants,\n

An ID column that's an integer, a name\n

and a sport column that's\nalso text, cannot be null

and the primary key is just ID.

So that I have a unique\nID for every registration.

Let's see if there's\nanyone in there yet.

Select star from registrants.

OK, there's no one in there.

No one is yet registered for sports.

So let's go back to the\ncode and continue on.

In my code now, I've got\nthe same global variable

for validation and\ngeneration of my HTML.

Looks like my index route is the same.

It's dynamically generating\nthe menu of sports.

Interestingly, we'll come back to this.

There's a deregister route\nthat's going to allow someone

to deregister themselves if\nthey want to exit the sport

Here's my new and\nimproved register route.

Still works on POST, so\nsome mild privacy there.

I'm validating the\nsubmission as follows.

I'm getting the user's inputted\nname, the user's inputted sport

and if it is not a name or\nthe sport is not in sports

I'm going to render failure.html.

There's no cat in this version.

Otherwise, recall how we\nco-mingled SQL and Python before.

We're using CS50's SQL\nlibrary, but that just

makes it a little easier to execute\n

Insert into registrants\nname comma sport.

What two values, the name and the\n

And then lastly, and this is a new\n

explicitly now, Flask\nalso gives you access

to a redirect function, which is how\n

and all these other sites we\nplayed around with last week

we're all implemented redirecting\n

This Flask function\nredirect comes from my just

having imported it at the\nvery top of this file.

It handles the HTTP 301 or 302 or 307\n

All right, so that's it for\nregistering via this route.

Let's look at what the\nregistrant's route is.

Here, we have a new\nroute for /registrants.

And instead of just iterating\nover a dictionary like before

we're getting back, let's\nsee, db.execute of select star

So that's literally the programmatic\n

That gives me back a\nlist of dictionaries

each of which represents\none row in the table.

Then, I'm going to render\nregister and start HTML

passing in literally\nthat list of dictionaries

just like using CS50's\nlibrary in the past.

So let's go and look\nat these-- that form.

If I go into templates and\nopen up registrants.html

oh, OK, it's just a table like before.

And actually, let me change this\nsyntactically for consistency.

We have a Jinja for loop that\niterates over each registrant

and for each of them,\noutputs a table row.

Oh, but this is interesting.

Instead of just having two columns\n

notice that I'm also\noutputting a full-fledged form.

All right, this is\nstarting to get juicy.

So let's actually go back\nto my terminal window

run Flask, and actually see what\nthis example looks like now.

In the home page, it\nlooks exactly the same.

But let me now register for something.

David for ultimate frisbee, register.

David registering for\nultimate frisbee, register.

So good thing I have deregister.

So this is what it should now look like.

I have a page at the route called\n

columns, name and sport,\nDavid, ultimate frisbee.

But oh, wait, a third column.

Because if I view the page source,\n

For every row in this table, I'm also\n

But before we see how that works,\n

So Carter will give you basketball.

Now, let me go back and let's\nregister Emma for soccer.

Before we look at that HTML, let's\n

Let's go into SQLite FroshIMS.

Let me go into FroshIMS, and let me\n

And now do select star from registrants.

And whereas, previously, when I executed\n

So now we see exactly what's\ngoing on underneath the hood.

So let's look at this\nform now-- this page now.

If I want to unregister, deregister\n

Clicking one of those\nbuttons will indeed

delete the row from the database.

But how do we go about linking a web\n

This is the last piece of the puzzle.

Up until now, everything's been\nwith forms and also with URLs.

But what if the user is\nnot typing anything in

they're just clicking a button?

Let me go ahead and\nsniff the traffic, which

you could be in the habit of doing now.

Any time you're curious how a website\n

And Carter, shall we\nderegister you from basketball?

Let's deregister Carter and\nlet's see what just happened.

If I look at the deregister\nrequest, notice that it's a POST.

The status code that\neventually came back as 302

but let's look at the request itself.

All the headers there we'll ignore.

The only thing that\nbutton submits, cleverly

is an ID parameter, a key equaling two.

What does two presumably\nrepresent or map to?

Where did this two come from?

It doesn't say Carter, it\ndoesn't say basketball?

AUDIENCE: The second\nperson who registered.

DAVID: The second\nperson that registered.

So those primary keys that we started\n

ago, why it's useful to be able to\n

here is just one of the reasons why.

If it suffices for me just to\nsend the ID number of the person

I want to delete from the database,\n

If I go into app.py and I look at my\n

I first go into the form, and I get\n

If there was, in fact, an ID, and\nthe form wasn't somehow empty

I execute this line of code.

Delete from registrants where\nID equals question mark

and then I plug-in that number,\ndeleting Carter and only Carter.

And I'm not using his name, because\n

two people named Emma or David?

You don't want to delete both of them.

That's why these unique\nIDs are so, so important.

And here's another reason why.

You don't want to store\nsome things in URLs.

Suppose we went to this\nURL, deregister?ID=3.

Suppose I, maliciously,\nemailed this URL to Emma.

It doesn't matter so much\nwhat the beginning is

but supposed I emailed her this URL,\n

And it uses GET instead of POST.

What did I just trick her into doing?

What's going to happen\nif Emma clicks this?

DAVID: You would trick her\ninto deregistering herself.

Because if she's logged\ninto this FroshIMS website

and the URL contains her ID just\nbecause I'm being malicious

and she clicked on it and\nthe website is using GET

unfortunately, GET URLs\nare, again, stateful.

They have state information in the URLs.

And in this case, it's enough\nto delete the user and boom

she would have accidentally\nderegistered herself.

And this is pretty innocuous.

Suppose that this was\nher bank account trying

to make a withdrawal or a deposit.

Suppose that this were some\nother website, a Facebook URL

trying to trick her into\nposting something automatically.

Here, too, is another\nconsideration when you

should use POST versus GET,\nbecause GET requests can

be plugged into emails sent via Slack\n

And unless there's a\nprompt saying, are you sure

you want to deregister\nyourself, you might blindly

trick the user into being\nvulnerable to what's

called a cross-site request forgery.

A fancy way of saying you\ntrick them into clicking a link

that they shouldn't have, because\n

All right, any question, then,\non these building blocks?

AUDIENCE: What do the first\nthing in the instance of the SQL

[INAUDIBLE] where they\nhave three slashes?

DAVID: When three columns, you mean?

AUDIENCE: No, three forward slashes.

DAVID: The three forward slashes.

AUDIENCE: Yeah, so I\nthink it's in [INAUDIBLE]..

DAVID: Sorry, it's in where?

AUDIENCE: It's in [INAUDIBLE] scroll up.

DAVID: Sorry, the other direction?

So please scroll a little bit more.

DAVID: Keep scrolling more?

This is a URI, it's typical syntax\n

protocol, so to speak, which means\n

:// is just like you and I see in URLs.

The third slash, essentially,\nmeans current folder.

So it's a weird curiosity,\nbut it's typical

whenever you're referring to a\nlocal file and not one that's

That's a bit of an oversimplification,\n

Sorry for not clicking earlier.

All right, let's do one\nother iteration of FroshIMS

here just to show what I was\n

was not only storing these\nthings in CSV files, as I recall.

I was also automatically\ngenerating an email

to the proctor in charge of\nthe intramural sports program

so that they would have sort of a\n

and they could easily\nreply to them as well.

Let me go into FroshIMS version\nfive, which I precreated here

and let me go ahead and open\nup, say, app.py this time.

And this is some code\nthat I wrote in advance.

And it looks a little scary at first\n

I have now added the Flask\nmail library to the picture

by adding Flask mail to\nrequirements.txt and running a command

to automatically install email\nsupport for Flask as well.

And this is a little bit\ncryptic, but it's honestly mostly

copy paste from the documentation.

What I'm doing here is\nI'm configuring my Flask

application with a few configuration\nvariables, if you will.

This is the syntax for that.\n

comes with Flask that is automatically\n

on line nine, and I just had to fill\n

values for the default\nsender address that I

want to send email as, the default\n

the port number, the TCP port,\nthat we talked about last week.

The mail server, I'm going to use\nGmail's smtp.gmail.com server.

Use TLS, this means use encryption.

Mail username, this is going\nto grab it from my environment.

So for security purposes, I didn't\n

and password into the code.

So I'm actually storing those in what\n

You'll see more of these\nin problem set nine

and it's a very common\nconvention on a server

in the real world to store sensitive\n

so that it can be accessed\nwhen your website is running

but not in your source code.

It's way too easy if\nyou put credentials

sensitive stuff in your source\ncode, to post it to GitHub

or to screenshot it accidentally,\n

So for today's purposes, know that the\n

are called environment variables.

And this is like an out-of-band, a\n

pairs in the computer's memory\nby running a certain command

but that never show up\nin your actual code.

Otherwise, there would be so\nmany usernames and passwords

accidentally visible on the internet.

So I've installed this in advance.

Let me see if I can do this correctly.

Let me go over to another\ntab in just a moment.

And here, I have on my second\nscreen here, John Harvards inbox.

It's currently empty, and I'm\ngoing to go ahead and register

for some sport as John\nHarvard here, hopefully.

So let me go ahead and run\nFlask run on this version five.

Let me go ahead and\nreload the main screen.

Let me reload the main screen here.

This time, clearly, I'm\nasking for name and email.

So name will be John Harvard.

He'll register for, how about soccer.

And if I did this correctly, not\n

seeing you are registered, but when he\n

crossing his fingers that this\n

and I promise it did right before class.

I don't think there's\na mistake this time.

Let me try something\nover here real quick

but I don't think this is broken.

It wouldn't have said\nsuccess if it were.

I just tried submitting again, so I\n

Oh, I'm really sad right now.

DAVID: I could check\nspam, but then it's--

not sure we want to show spam here on\n

Wow, that was a risky click I worried.

All right, so you are registered\nis the email that I sent out

and it doesn't have any\nactual information in it.

But back in the day it\nwould have, because I

included the student's\nname and their dorm

and all of the other fields of\ninformation that we asked for.

So let's just take a quick look\nat how that code might work.

I did have to configure Gmail\nin a certain way to allow

what they call, less\nsecure apps using SMTP

which is the protocol\nused for outbound email.

But besides setting these things, let's\n

It's actually pretty straightforward.

In my register route, I validated\n

I then confirmed the registration\ndown here, nothing new there.

All I did was use two new lines of code.

And it's this easy to automate\nthe sending of emails.

I apparently have done\nit too many times

which is why it ended up in spam.

I created a variable called message.

I used a message function that\nI must have imported higher up

Here's, apparently, the subject\nline as the first argument.

And the second argument is the\nnamed parameter recipients

which takes a list of emails that\n

So in brackets, I just\nput the one user's email

and then mail.send that message.

So let's scroll back up to see what\n

Yep, mail is this, which\nI have as a variable

because I followed the\ndocumentation for this library.

You simply configure your current app\n

And if you look up here\nnow, on line seven

here's the new library\nfrom Flask mail I imported.

Capital Mail, capital Message, so that\n

So such a simple thing whether you\n

you want to do password resets.

It can be this easy to\nactually generate emails

provided you have the requisite\naccess and software installed.

And just to make clear that\nI did add something here

let me open up my requirements.txt\nfile, and indeed, I

have both Flask and\nFlask-mail ready to go.

But I ran the command in\nadvance to actually do that.

All right, any questions,\nthen, on these examples here?

So what other pieces might actually\n

It turns out that a key\ncomponent of most any web

application nowadays that\nwe haven't touched on yet

but it'll be one of our final flourishes\n

And a session is actually\na feature that derives

from all of the basics we talked\nabout today and last week

and a session is the technical term for\n

When you go to amazon.com and you start\n

they follow you from\npage to page to page.

Heck if you close your browser,\ncome back to the next day

they're typically still your shopping\n

because they want your business.

They don't want you to have to\nstart from scratch the next day.

Similarly, when you log\ninto any website these days

even if it's not an e-commerce thing\n

you and I are not in\nthe habit of logging

into every darn page\nwe visit on a website.

Typically, you log in once, and then\n

you stay logged into that website.

So somehow, the website is\nremembering that you have logged in.

And that is being implemented\nby way of this thing called

a session, and perhaps\na more familiar term

that you might know as, and\nworry about, called cookies.

Let's go ahead and take one\nmore five minute break here.

And when we come back, we'll\nlook at cookies, sessions

So the promise now is that\nwe're going to implement

this notion of a session, which is going\n

them logged in and even implement\nthings like a shopping cart.

And the overarching goal here\nis to build an application that

is, quote unquote, "stateful.

Again, state refers to information,\n

And in this context, the curiosity\nis that HTTP is technically

Once you visit a URL,\nhttp://something, hit Enter

web page is downloaded to\nyour browser, like that's it.

You can unplug from the internet,\nyou can turn off your Wi-Fi

but you still have the web page locally.

And yet we somehow want to make\nsure that the next time you

click on a link on that website,\nit doesn't forget who you are.

Or the next thing you add\nto your shopping cart

it doesn't forget what\nwas already there.

So we somehow want to\nmake HTTP stateful

and we can actually do this using the\n

So concretely, here's a form you might\n

And I say rarely because most of\n

you just stay logged in, pretty\nmuch endlessly, in your browser.

And that's because Google\nhas made the conscious choice

to give you a very long session\ntime, maybe a day, a week

a month, a year, because\nthey don't really

want to add friction to using their tool\n

By contrast, there's other\napplications on campus

including some of the CS50 zone,\n

Because we want to make\nsure that it's indeed you

accessing the site, and not a roommate\n

So once you do fill out this\nform, how does Google subsequently

know that you are you, and\nwhen you reload the page even

or open a second tab for\nyour same Gmail account

how do they know that you're still\n

Well, let's look underneath\nthe hood of what's going on.

When you log into Gmail,\nessentially, you initially

see a form like this\nusing a GET request.

And the website responds\nlike we saw last week

with some kind of HTTP response.

Hopefully 200 OK with the form.

Meanwhile, the website might\nalso respond with an HTTP header

that, last week we didn't care\nabout, this week, we now do.

Whenever you visit a website,\nit is very commonly the case

that the website is putting\na cookie on your computer.

And you may generally know\nthat cookies can be bad

and they track you in some way, and\n

Without cookies, you could not implement\n

Unfortunately, they can also\nbe used for ill purposes

like tracking you on every website and\n

So with good comes some bad.

But the basic primitive for\nus, the computer scientist

boils down to just HTTP headers.

A cookie is typically a big number,\n

that a server tells your browser\nto store in memory, or even

So you can think of it like a file that\n

And the promise that HTTP\nmakes is that if a server sets

a cookie on your computer,\nyou will represent

that same cookie or that same\nvalue on every subsequent request.

So when you visit the\nwebsite like Gmail

they plop a cookie on your computer\nlike this with some session

equals value, some long random value.

One, two, three, A, B,\nC, something like that.

And when you then visit another page\n

you send the opposite header, not\n

and you send the exact same value.

It's similar to going to a\nclub or an amusement park

where you pay once, you\ngo through the gates once

you get checked by\nsecurity once, and then

they very often take like a little stamp\n

And then for you, efficiency-wise,\n

or later in the evening, you\ncan just present your hand.

You've been stamped, presumably.

They've already-- you've\nalready paid, you've

already been searched or whatnot.

And so it's this sort\nof fast track ticket

back into the club, back into the park.

That's essentially what a\ncookie is doing for you, whereby

it's a way of reminding the\nwebsite we've already done this

you already asked me for\nmy username and password.

This is my path to now come and go.

Now, unlike this hand stamp, which\n

or duplicated or kept\non over multiple days

these cookies are really big, seemingly\n

So statistically, there's\nno way someone else

is just going to guess your cookie\n

very low probability, statistically.

But this is all it boils down to is this\n

to send these values back\nand forth in this way.

So when we actually\ntranslate this, now, to code

let's do something like\na simple login app.

Let me go into a folder I made\nin advance today called login.

And let me code up app.py and\nlet's take a look in here.

A couple of new things up top.

If I want to have the ability to\n

and implement sessions, I'm going\n

So this is another feature you\nget for free by using a framework

and not having to implement\nall this yourself.

And from the Flask\nsession library, I'm going

to import Session, capital S. Why?

I'm going to configure\nthe session as follows.

Long story short, there's different\nways to implement sessions.

The server can store these\ncookies in a database, in a file

in memory, in RAM, in other places too.

We are telling it to store these\n

So in fact, whenever you use sessions\n

you'll actually see a folder\n

inside of which are the\ncookies, essentially

for any users or friends\nor yourself who've been

visiting your particular application.

So I'm setting it to\nuse the file system

and I don't want them to be\npermanent because I want

when you close your browser,\nthe session to go away.

They could be made to be\npermanent and last much longer.

Then I tell my app to support sessions.

Let's see what this application actually\n

Let me go over to my terminal window,\n

Give it a second to kick back in.

Let me go ahead and open my URL.

So this website simply has a login form.

There's no password,\nthough I could certainly

add that and check for that too.

So I'm going to log in as\nmyself, David, and click Login.

And now notice I'm currently\nat the /login route.

If I try to go to the\ndefault route, just

slash, which is where most\nwebsites live by default

notice that I magically\nget redirected to log in.

So somehow, my code knows, hey, if\n

Let me type in my name,\nDavid, and click Login.

And now notice I am back at slash.

Chrome is sort of annoyingly hiding\n

And now notice it says you\nare logged in as David.

What's cool is notice if I reload\nthe page, it still knows that.

If I create a second tab and go to\n

I could keep doing\nthis in multiple tabs

it's still going to remember me on both\n

Especially when I click Log Out,\n

All right, so let's see how this works.

And it's some basic building blocks.

Under my /route, notice I have this.

If there is no name in the session,\nredirect the user to /login.

So these two lines\ntogether are what implement

that automatic redirection using\nHTTP 301 or 302 automatically.

It's handled for me\nwith these two lines.

All right, let's go\ndown that rabbit hole.

let me look in my templates\nfolder for my login demo and look

All right, so what's going on here?

I extend layout.html,\nI have a block body

and then I've got some other syntax.

So we haven't seen this yet,\nbut it's more Jinja stuff, which

again, is almost identical to Python.

If there's a name in\nthe session variable

then literally say you are logged in\n

And then notice this, I've got a simple\n

Else, if there is no\nname in the session

then it apparently says you are not\n

link to /login and then end diff.

So again, Jinja does\nnot rely on indentation.

Recall the HTML and CSS don't\nreally care about indentation

But in code with Jinja,\nyou need these end tags

end block, end for, end\nif, to make super obvious

that you're done with that thought.

So session is just this\nmagic variable that we now

have access to because we've\nincluded these two lines of code

and these that handle that whole\n

with a different, unique identifier.

If I made my code space\npublic and I let all of you

visit the exact same URL, all of\n

You could all type your\nown names individually

all log in at the same URL\nusing different sessions.

And in fact, I would then see,\nif I go into my terminal window

here and my login directory, notice the\n

And if I CD into that and type ls,\n

or actually, I think I\nstarted the server twice.

I would ultimately have one\nfile for every one of you.

And that's what's\nbeautiful about sessions

is it creates the illusion\nof per user storage.

Inside of my session is my name,\n

And the same is going to apply to\n

Let's see how login works here.

My login route supports both GET and\n

And notice this, this login route\n

If the user got to this\nroute via POST, my inference

is that they must have submitted a form.

Because that's how I'm going to\n

And if they did submit\nthe form via POST

I'm going to store, in\nthe session, at the name

key, whatever the human's name is.

And then, I'm going to\nredirect them back to slash.

Otherwise, I'm going to\nshow them the login form.

If I go to this login\nform, which lives at

literally, slash login, by default,\n

And so that's why I see the form.

The form, very cleverly,\nsubmits to itself

like the one route/login submits\nto its same self, /login

but it uses POST when\nyou submit the form.

And this is a nice way of having one\n

When I'm just there visiting /login\n

But if I submit the form, then this\n

and this just avoids my having to have\n

I can just have one route that\nhandles both GET and POST.

Well, it's as simple as this.

Change whatever name\nis in the session to be

none, which is Python's version of null,\n

Because now, in index.html, I will\n

And so I'll tell the user\ninstead, you are not logged in.

I want to say as simple as\nthis is, though I realize

this is a bunch of steps involved.

This is the essence of every\nwebsite on the internet that

has usernames and passwords.

And we skip the password name step for\n

but this is how every website out\n

And how this works,\nultimately, is that as soon

as you use in Python lines\nlike this and lines like this

Flask takes care of stamping the\n

and whenever Flask sees the same\ncookie coming back from a user

it grabs the appropriate\nfile from that folder

loads it into the\nsession global variable

so that your code is now unique\nto that user and their name.

Let's do one other\nexample with sessions here

that'll show how we might use\nthese, now, for shopping carts.

Let me go into the store example here.

Let me go ahead and\nrun this thing first.

If I run store in my same\ntab and go back over here

we'll see a very ugly\ne-commerce site that

just sells seven different books here.

But each of these books has a button\n

All right, well where are\nthese books coming from?

Let me go into my terminal window again.

Let me go into this example,\nwhich is called store

and let me open up about\nindex dot ht-- whoops.

Let's open up index,\nhow about, books.html

is the default one, not index this time.

So if I look here, notice that\nthat route that we just saw

uses a for loop in Jinja to iterate\n

and it outputs, in an H2\ntag, the title of the book

and then another one of these forms.

Let's go ahead and open up app.py,\n

what's ticking all of this off.

Notice that this file is\nimporting session support.

It's configuring sessions\ndown here, but it's also

connecting to a store.db file.

And notice this, in my /route,\nI'm selecting star from books

which is going to give me\na list of dictionaries

each of which represents a row of books.

And I'm going to pass that list of\n

is why this for loop\nworks the way it does.

Let's look at this actual database.

Let me increase my terminal window\n

It's a book-- it's a table called\n

Let's do select star\nfrom books semicolon.

There are the seven books,\neach of which has a unique ID.

And you might see where this is going.

If I go to the UI and I look\nat each of these buttons

for add to cart, just like Amazon might\n

And what's magical here,\njust like deregister

even though I didn't\nhighlight it at the time

there's another type\nof input that allows

you to specify a value without the\n

Instead of type equals\ntext or type equals submit

type equals hidden will put the value in\n

So that's how I'm saying that\nthe idea of this book is one

the idea of this book is two, the idea\n

And each of these forms,\nthen, will submit, apparently

to /cart using POST and that would\n

Let me click on one or two of these.

Let's add the first book, add to cart.

Notice my route change to /cart.

All right, let's go back and\nlet's add the book number two.

And let's skip ahead to the\nseventh book, Deathly Hallows

and now we have all three books here.

So what does the cart route do at /cart?

If I go back to my terminal window,\n

there's a lot going on\nhere, but let's see.

So the /cart route\nsupports both GET or POST

which is a nice way to\nconsolidate things into one URL.

All right, this is interesting.

If there is not a, quote\nunquote, "cart" key in session

we haven't technically seen this syntax.

But long story short, these lines\n

It makes sure that there's a cart\n

and it's by default going\nto be an empty list.

That just means you have\nan empty shopping cart.

But if the user visits this route via\n

they didn't muck with the form in any\n

they gave me a valid ID, then\nI'm going to use this syntax.

If session bracket cart is a list--

recall from a couple of weeks\nago that dot append just

adds something to the list.

So I'm going to add the ID to the\n

Otherwise, if the user is at /cart\n

Select star from books where ID is in.

And this might be syntax\nyou recall from Pset six.

It lets you look for\nmultiple IDs all at once

because if I have a list of session--

list of IDs in my cart, I can\nget all of those books at once.

So long story short,\nwhat has happened here?

I am storing, in the cart, the books\n

My browser is sending the same\nhand stamp again and again

which is how this website knows that\n

and not you or not Carter or not Emma.

Indeed, if all of us visited the\n

and allowed that, then we would\nall have our own illusions

And each of those carts,\nin practice, would just

be stored in this Flask\nsession directory on the server

so that the server\ncan keep track of each

of us using, again, these\ncookie values that are being

sent back and forth via these headers.

I know that's a lot,\nbut again, it's just

the new Python way of\njust leveraging those HTTP

headers from last week in a clever way.

Any questions before we look\nat one final set of examples?

AUDIENCE: [INAUDIBLE] understand how\n

How does it use [INAUDIBLE],,\nhow do you change [INAUDIBLE]??

Because in order to use a GET\nrequest dot [INAUDIBLE] equals

there has to be an\nexchange in [INAUDIBLE]..

DAVID: So I think you're\nasking about using the GET

and POST in the same function.

So this is just a nice\naesthetic, if you will.

If I had to have separate\nroutes for GET and POST, I mean

it literally might mean I need\ntwice as many routes in my file.

And it just starts to\nget a little annoying.

And these days, too, in\nterms of user experience

this is maybe only appeals to the\n

You don't want to have\nlots of words in the URL

it's nice if the URLs are nice and\n

So it's nice if I can centralize all of\n

only, and not in multiple routes,\none for GET, one for POST.

It's a little nitpicky of me,\nbut this is commonly done here.

So what this code here means is\nthat this route, this function

henceforth will support both\nGET requests and POST requests.

But then I need to distinguish between\n

Because if it's a GET request,\nI want to show the cart.

If it's a POST request, I\nwant to update the cart.

And the simplest way to do that\n

In the request variable that we\nimported from Flask up above

you can check what is the\ncurrent type of request.

Is it a GET, is it a POST, or\nis it something else altogether?

If it's a POST, that must mean, because\n

that the user clicked\nthe Add to Cart button.

Otherwise, if it's not POST, it's\n

Then, I just want to show the\nuser the contents of the cart

and I use these lines instead.

So it's just one way of avoiding having\n

You can combine them so long\nas you have a check like this.

If I really wanted to be pedantic, I\n

This would be more symmetric,\nbut it's not really necessary

because I know there's\nonly two possibilities.

All right, let's do one\nfinal set of examples here

that's going to tie the\nlast of these features

together to something\nthat you probably see

quite often in real-world applications.

And that, for better\nor for worse, is now

going to involve tying back in\nsome JavaScript from last week.

The goal at hand of\nthese examples is not

to necessarily master how you yourself\n

code, the JavaScript code, but just\n

these different languages work.

So that for final\nprojects, especially if you

do want to add JavaScript functionality,\n

you at least have the bare\nbones of a mental model for how

you can tie these languages together.

Even though our focus, generally,\n

than on JavaScript from last week.

Let me go ahead and open up an example\n

And let me go into my URL here and\n

like by default. This has just a simple\n

Let's take a look at the HTML\nthat just got sent to my browser.

All right, there's not\nmuch going on here at all.

So there's a form whose\naction is /search.

It's going to submit via GET.

It's going to use a q parameter, just\n

So this actually looks like the\nGoogle form we did last week.

So let's see what goes on here.

Let me search for something like cat.

all right, so this is actually\na somewhat familiar file.

What I've gone ahead and done is I've\n

from a couple of weeks ago\nwhen we first introduced SQL

and I loaded them into this\ndemo so that you can search

by keyword for any word you want.

If we were to do this again, we\n

that contain D-O-G, dog, as a\nsubstring somewhere and so forth.

So this is a traditional\nway of doing this.

Just like in Google, it uses\n/search?q=cat, q=dog, and so forth.

Well, let's just take a\nquick look at app.py here.

Let me go into my zero example\nhere, show zero, and open up

app.py and see what's going on.

Here's the form, that's\nhow we started today.

And here is the /search route.

Well, what's going on here?

This gets a little interesting.

So I first select a whole\nbunch of shows by doing this.

Select star from shows, where\ntitle like question mark.

And then I'm using some\npercent signs from SQL

on both the left and the\nright, and I'm plugging

in whatever the user's input was for q.

If I didn't use like and\nI used equal instead

I could get rid of these curly\nbrace, these percent signs

but then it would have to be a show\n

to it being like cat or like dog.

This whole line returns to me a\n

represents a show in the database.

And then, I'm passing all of those\n

So let's just follow that\nbreadcrumb, let's open up shows dot--

All right, so this is\nwhere templating gets cool.

So I just passed back hundreds\nof results, potentially

but the only thing I'm\noutputting is an unordered list

and using a Jinja for\nloop and li tag containing

the titles of each of those shows.

And just to prove that this\nis indeed a familiar data set

and I actually simplified it a bit,\n

I threw away all the other stuff like\n

and I just have, for instance,\nselect star from shows

limit 10, just so we can see 10 of them.

There's 10 of the shows\nfrom that database.

So that's all that's\nin the database itself.

So it would look like this is a\npretty vanilla web application.

It uses GET, it submits\nit to the server

the server spits out a response,\nand that response, then

looks like this, which is a huge\n

But everything else\ncomes from a layout.html.

All the stuff at the\ntop and at the bottom.

All right, so these days, though, we're\n

And you start typing something\nand you don't have to hit Submit

you don't have to click a button,\n

Web applications, nowadays,\nare much more dynamic.

So let's take a look at this\nversion one of this thing.

Let me go into shows one\nand close my previous tabs

And it's almost the same thing, but\n

I'm reloading the form,\nthere's no button now.

So gone is the need for a submit button.

I want to implement autocomplete now.

So let's go ahead and\ntype in C. OK, there's

every show that starts\nwith C. A, there's

every show that has C-A in it, rather.

T, there's every show with C-A-T in it.

I can start it again and do dog,\n

And notice my URL never changed,\nthere's no /search route

With every keystroke, it is\nsearching again and again and again.

That's a nice UX, user experience,\nbecause it's immediate.

This is what users are\nused to these days.

But if I look at the source code\n

there's just an empty UL by default but\n

So let's see what's going on here.

This JavaScript code\nis doing the following.

Let me zoom in a little bit more.

This JavaScript code is first\nselecting, with query selector

which you used this past week,\n

so that's just getting the text box.

Then it's adding an event listener\n

We didn't talk about this\nlast week, but literally

when you provide any\nkind of input by typing

by pasting, by any other\nuser interface mechanism

it triggers an event called input.

So similar to key press or key up.

I then have a function, no worries\n

Then what do I do inside of this?

All right, so this is\nnew, and this is the part

that let's just focus on the\nideas and not the syntax.

JavaScript, nowadays,\ncomes with a function

called fetch that allows you to\n

without reloading the whole page.

You can sort of secretly\ndo it inside of the page.

slash search question mark q equals\n

When I get back a response, I want\n

and store it in a variable called shows.

And I'm deliberately bouncing\naround, ignoring special words

like await and await here, but for\n

A response came back from the\n

storing it in a variable called shows.

I'm using query selector to select\n

and I'm changing its inner HTML\nto be equal to the shows that

Here's where, again, developer\ntools are quite powerful.

Let me go ahead and reload this\npage to get rid of everything.

And let me now open up inspect.

Let me go to the Network tab and\n

between my browser and server.

I'm going to search for C. Notice that\n

So I didn't even finish my cat\n

A bunch of response headers, but let's\n

This is literally the response from the\n

No UL, no HTML, no\ntitle, no body, nothing.

And we can actually simulate this.

Let me manually go to\nthat same URL, q=c, Enter.

We are just going to get back--

slash search q equals c, we are\n

which if I view source, it's\nnot even a complete web page.

The browser is trying to show it to me\n

but it's really just partial HTML.

But that's perfect,\nbecause this is literally

what I essentially want my\nPython code to copy paste

into the otherwise empty UL tag.

And that's what this JavaScript\ncode then, here, is doing.

Once it gets back that response from the\n

to plug all of those li's\ninto the UL after the fact.

Again, changing the so-called dom.

But there's a slightly better way\n

Because if you've got a hundred shows or\n

Why do I need to send all\nof these stupid HTML tags?

Why don't I just create those\nwhen I'm ready to create them?

Well, here's the final flourish.

Whenever making a web\napplication nowadays

where client and server keep talking\n

Gmail does this, literally\nevery cool application

nowadays you load the\npage once and then it

keeps on interacting\nwith you without you

reloading or having to change the URL.

Let's actually use a format called\n

is to say there's just a\nbetter, more efficient, better

designed way to send that same data.

I'm going to go into shows\ntwo now and do Flask run.

And I'm going to go\nback to my page here.

The user interface is exactly the same,\n

Here's C, C-A, C-A-T, and so forth.

But let's see what's coming back now.

If I go to /search?q=cat, Enter, notice\n

But the fact that it's so\ncompact is actually a good thing.

This is actually going to-- let\n

This is what's called\nJavaScript Object Notation.

In JavaScript, an angle-- a square\n

In JavaScript, a curly bracket says\n

Yes, sort of recall that you can now\n

notation using colons like this.

So long story short, cryptic\nas this is to you and me

and not very human friendly,\nit's very machine friendly.

Because for every\ntitle in that database

I get back its ID and its title, its\n

And this is a very generic format that\n

interface, might return to you.

And this is how APIs, nowadays, work.

You get back very raw textual\ndata in this format, JSON format

and then you can write code that\nactually programmatically turns

that JSON data into any language\nyou want, for instance, HTML.

So here's the third and final\nversion of this program.

I then, when I get input,\ncall this function.

I fetch slash search q equals whatever\n

I then wait for the response,\nbut instead of getting text

I'm calling this other function that\n

called JSON, that just parses that.

It turns it into a dictionary for me,\n

and stores it in a\nvariable called shows.

And this is where you start to see the\n

Let me initialize a variable called\n

using single quotes, but I\ncould also use double quotes.

This is JavaScript syntax for a loop.

Let me iterate over every\nID in the show's list

that I just got back in the server,\nthat big chunk of JSON data.

Let me create a variable called\n

the title of the show at that ID.

But for reasons we'll\ncome back to, let me

replace a couple of scary characters.

Then let me dynamically add to this\n

And then very lastly,\nafter this for loop

let me update the ULs in our HTML to\n

So in short, don't worry\ntoo much about the syntax

because you won't need to use\nthis unless you start playing

with more advanced features quite soon.

But what we're doing is,\nwith JavaScript, we're

creating a bigger and bigger\nand bigger string of HTML

containing all of the open brackets,\n

but we're just grabbing the\nraw data from the server.

And so in fact in\nproblem set nine, you're

going to use a real world third\n

interface, for which you sign up.

The data you're going to get\nback from that API is not

going to be show titles, but\nactually stock quotes and stocks

ticker symbols and the prices of last--

at which stocks were\nlast bought or sold

and you're going to get that\ndata back in JSON format.

And you're going to write a bit of\n

to the requisite HTML on the page.

So the final result here is\nliterally the kind of autocomplete

that you and I see and\ntake for granted every day

and that's ultimately how it works.

HTML and CSS are used to present\nthe data, your so-called view.

Python might be used to send or\n

And then lastly, JavaScript\nis going to be used

to make things dynamic and interactive.

So I know that's a whole\nbunch of building blocks

but the whole point of problem set\n

set the stage for hopefully a\nvery successful final project.

Why don't we go ahead and\nwrap up there, and we'll see

you one last time next week for emoji.

Can't find what you're looking for?
Get subtitles in any language from opensubtitles.com, and translate them here.