CS50 Video Player
    • 🧁

    • 🍬

    • 🥭

    • 🍿
    • 0:00:00Introduction
    • 0:01:17Python
    • 0:03:42Syntax
    • 0:18:19Types
    • 0:20:48CS50 Library
    • 0:22:55Compilation and Interpretation
    • 0:26:55blur.py
    • 0:33:00dictionary.py
    • 0:45:17hello.py
    • 0:49:57calculator.py
    • 0:55:25Exceptions
    • 1:00:49Floating Point Imprecision
    • 1:02:17points.py
    • 1:05:49agree.py
    • 1:13:00meow.py
    • 1:21:44mario.py
    • 1:38:23Documentation
    • 1:41:45scores.py
    • 1:45:59uppercase.py
    • 1:49:56Command-line Arguments
    • 1:54:10Exit Status
    • 1:56:34numbers.py
    • 1:57:40names.py
    • 1:58:49Dictionaries
    • 2:05:33CSV Files
    • 2:16:20Speech Synthesis
    • 2:18:04Facial Recognition
    • 2:20:53Speech Recognition
    • 2:22:31QR Codes
    • 2:23:46This was CS50
    • 0:00:00[MUSIC PLAYING]
    • 0:01:17DAVID J. MALAN: All right, this is CS50, and this is already week 6.
    • 0:01:21And this is the week in which you learn yet another language.
    • 0:01:24But the goal is not just to teach you another language,
    • 0:01:26for languages sake, as we transition today
    • 0:01:29and in the coming weeks from C, where we've spent the past several weeks, now
    • 0:01:32to Python.
    • 0:01:33The goal ultimately is to teach you all how to teach yourselves new languages,
    • 0:01:37so that by the end of this course, it's not in your mind,
    • 0:01:40the fact that you learned how to program in C
    • 0:01:42or learned some weeks back how to program in Scratch,
    • 0:01:44but really how you learned how to program fundamentally,
    • 0:01:48in a paradigm known as procedural programming,
    • 0:01:50as well as with some taste today, and in the weeks to come,
    • 0:01:53of other aspects of programming languages,
    • 0:01:55like object-oriented programming, and more.
    • 0:01:58So recall, though, back in week zero, Hello, world
    • 0:02:00looked a little something like this.
    • 0:02:01And the world was quite simple.
    • 0:02:03All you had to do was drag and drop these puzzle pieces.
    • 0:02:05But there were still functions and conditionals and loops and variables
    • 0:02:08and all of those kinds of primitives.
    • 0:02:11We then transitioned, of course, to a much more arcane language that
    • 0:02:14looked a little something like this.
    • 0:02:15And even now, some weeks later, you might still
    • 0:02:17be struggling with some of the syntax or getting annoying bugs
    • 0:02:20when you try to compile your code, and it just doesn't work.
    • 0:02:22But there, too, the past few weeks, we've
    • 0:02:24been focusing on functions and loops and variables, conditionals, and really
    • 0:02:28all of those same ideas.
    • 0:02:29And so what we begin to do today is to, one, simplify the language
    • 0:02:33we're using, transitioning from C now to Python, this now being the equivalent
    • 0:02:38program in Python, and look at its relative simplicity,
    • 0:02:42but also transitioning to look at how you
    • 0:02:43can implement these same kinds of features,
    • 0:02:45just using a different language.
    • 0:02:47So we're going to see a lot of code today.
    • 0:02:49And you won't have nearly as much practice with Python as you did with C.
    • 0:02:53But that's because so many of the ideas are still going to be with us.
    • 0:02:56And, really, it's going to be a process of figuring out, all right,
    • 0:02:58I want to do a loop.
    • 0:02:59I know how to do it in C. How do I do this in Python?
    • 0:03:01How do I do the same with conditionals?
    • 0:03:02How do I declare variables, and the like,
    • 0:03:04and moving forward, not just in CS50, but in life in general,
    • 0:03:07if you continue programming and learn some other language after the class,
    • 0:03:10if in 5-10 years, there's a new, more popular language that you pick up,
    • 0:03:14it's just going to be a matter of googling and looking
    • 0:03:16at websites like Stack Overflow and the like,
    • 0:03:18to look at just basic building blocks of programming languages,
    • 0:03:21because you already speak, after these past 6 plus weeks,
    • 0:03:24you already speak programming itself fundamentally.
    • 0:03:27All right, so let's do a few quick comparisons, left and right, of what
    • 0:03:31something might have looked like in Scratch,
    • 0:03:32and what it then looked like in C, but now,
    • 0:03:34as of today, what it's going to look like in Python.
    • 0:03:36Then we'll turn our attention to the command line,
    • 0:03:38ultimately, in order to implement some actual programs.
    • 0:03:42So in Scratch, we had functions like this, say Hello,
    • 0:03:45world, a verb or an action.
    • 0:03:47In C it looked a little something like this,
    • 0:03:49and a bit of a cryptic mess the first week, you had the printf,
    • 0:03:53you had the double quotes.
    • 0:03:54You had the semicolon, the parentheses.
    • 0:03:55So there's a lot more syntax just to do the same thing.
    • 0:03:58We're not going to get rid of all of that syntax now, but as of today,
    • 0:04:01in Python, that same statement is going to look a little something like this.
    • 0:04:05And just to perhaps call out the obvious, what
    • 0:04:07is different or, now, simpler in Python versus C, even
    • 0:04:12in this simple example here?
    • 0:04:13Yeah.
    • 0:04:14AUDIENCE: Now print, instead of printf would be, something like that.
    • 0:04:17DAVID J. MALAN: Good, so it's now print instead of printf.
    • 0:04:19And there's also no semicolon.
    • 0:04:21And there's one other subtlety, over here.
    • 0:04:23AUDIENCE: No new line.
    • 0:04:24DAVID J. MALAN: Yeah, so no new line, and that
    • 0:04:25doesn't mean it's not going to be printed.
    • 0:04:27It just turns out that one of the differences we'll see
    • 0:04:29is that, with print, you get the new line for free.
    • 0:04:31It automatically gets outputted by default, being sort of a common case.
    • 0:04:34But you can override it, we'll see, ultimately, too.
    • 0:04:37How about in Scratch?
    • 0:04:38We had multiple functions like this, that not only said something
    • 0:04:42on the screen, but also asked a question,
    • 0:04:43thereby being another function that returned a value, called answer.
    • 0:04:47In C we saw code that looked a little something
    • 0:04:49like this, whereby that first line declares a variable called answer,
    • 0:04:53sets it equal to the return value of getString,
    • 0:04:55one of the functions from the CS50 library,
    • 0:04:57and then the same double quotes and parentheses and semicolon.
    • 0:05:00Then we had this format code in C that allowed us, with %S,
    • 0:05:05to actually print out that same value.
    • 0:05:07In Python, this, too, is going to look a little bit simpler.
    • 0:05:10Instead, we're going to have answer equals getString,
    • 0:05:13quote unquote "What's your name," and then print,
    • 0:05:16with a plus sign and a little bit of new syntax.
    • 0:05:18But let's see if we can't just infer from this example what
    • 0:05:21it is that's going on.
    • 0:05:22Well, first missing on the left is what?
    • 0:05:25To the left of the equal sign, there's no what this time?
    • 0:05:28Feel free to just call it out.
    • 0:05:29AUDIENCE: Type.
    • 0:05:30DAVID J. MALAN: So there's no type.
    • 0:05:31There's no type, like the word string, which
    • 0:05:33even though that was a type in CS50, every other variable in C
    • 0:05:38did we use Int or string or float, or Bool or something else.
    • 0:05:41In Python, there are still going to be data types,
    • 0:05:43today onward, but you, the programmer, don't
    • 0:05:45have to bother telling the computer what types you're using.
    • 0:05:49The computer is going to be smart enough,
    • 0:05:50the language, really, is going to be smart enough, to just figure it out
    • 0:05:53from context.
    • 0:05:54Meanwhile, on the right hand side, getString
    • 0:05:56is going to be a function we'll use today
    • 0:05:57and this week, which comes from a Python version of the CS50 library.
    • 0:06:01But we'll also start to take off those training wheels, so that you'll
    • 0:06:04see how to do things without any CS50 library moving forward,
    • 0:06:07using a different function instead.
    • 0:06:09As before, no semicolon, but the rest of the syntax is pretty much the same
    • 0:06:12here.
    • 0:06:13This starts, of course, to get a little bit different, though.
    • 0:06:16We're using print instead of printf.
    • 0:06:17But now, even though this looks a little cryptic,
    • 0:06:20perhaps, if you've never programmed before CS50,
    • 0:06:23what might that plus be doing, just based on inference here.
    • 0:06:27What do you think?
    • 0:06:27AUDIENCE: Adding answer to the string Hello.
    • 0:06:31DAVID J. MALAN: Yeah, so adding answer to the string Hello,
    • 0:06:34and adding, so to speak, not mathematically,
    • 0:06:37but in the form of joining them together, much like we
    • 0:06:39saw the joined block in Scratch, or concatenation was the term of art
    • 0:06:43there.
    • 0:06:43This plus sign appends, if you will, whatever's
    • 0:06:46in answer to whatever is quoted here.
    • 0:06:48And I deliberately left a space there, so that grammatically it
    • 0:06:51looks nice, after the comma as well.
    • 0:06:53Now there's another way to do this.
    • 0:06:54And it, too, is going to look cryptic at first glance.
    • 0:06:57But it just gets easier and more convenient over time.
    • 0:06:59You can also change this second line to be this, instead.
    • 0:07:04So what's going on here.
    • 0:07:05This is actually a relatively new feature of Python in the past couple
    • 0:07:08of years, where now what you're seeing is, yes,
    • 0:07:11a string, between these same double quotes,
    • 0:07:13but this is what Python would call a format string, or Fstring.
    • 0:07:17And it literally starts with the letter F, which admittedly looks, I think,
    • 0:07:20a little weird.
    • 0:07:20But that just indicates that Python should
    • 0:07:24assume that anything inside of curly braces inside of the string
    • 0:07:29should be interpolated, so to speak, which is a fancy term saying,
    • 0:07:32substitute the value of any variables therein.
    • 0:07:36And it can do some other things as well.
    • 0:07:38So answer is a variable, declared, of course, on this first line.
    • 0:07:42This Fstring, then, says to Python, print out Hello comma space, and then
    • 0:07:46the value of Answer.
    • 0:07:47If, by contrast, you omitted the curly braces,
    • 0:07:52just take a guess, what would happen?
    • 0:07:54What would the symptom of that bug be, if you accidentally
    • 0:07:56forgot the curly braces, but maybe still had the F there?
    • 0:08:00AUDIENCE: It would print below it, too.
    • 0:08:01DAVID J. MALAN: Yeah, it would literally print Hello, comma answer, because it's
    • 0:08:04going to take you literally.
    • 0:08:05So the curly braces just kind of allow you to plug things in.
    • 0:08:07And, again, it looks a little more cryptic,
    • 0:08:09but it's just going to save us time over time.
    • 0:08:11And if any of you programmed in Java in high school, for instance,
    • 0:08:14you saw plus in that context, too, for concatenation.
    • 0:08:16This just kind of makes your code a little tighter, a little more succinct.
    • 0:08:19So it's a convenient feature now in Python.
    • 0:08:21All right, this was an example in Scratch of a variable,
    • 0:08:24setting a variable like counter equal to 0.
    • 0:08:26In C it looked like this, where you specify the type, the name,
    • 0:08:30and then the value, with a semicolon.
    • 0:08:32In Python, it's going to look like this.
    • 0:08:35And I'll state the obvious here.
    • 0:08:36You don't need to mention the type, just like before with string.
    • 0:08:39And you don't need a semicolon.
    • 0:08:41So it's a little simpler.
    • 0:08:42If you want a variable, just write it and set it equal to some value.
    • 0:08:45But the single equal sign still behaves the same as in C.
    • 0:08:48Suppose we wanted to increment counter by one.
    • 0:08:50In Scratch, we use this puzzle piece here.
    • 0:08:52In C, we could do this, actually, in a few different ways.
    • 0:08:55There was this way, if counter already exists,
    • 0:08:57you just say counter equals counter plus 1.
    • 0:08:59There was the slightly less verbose way, where you could say, oops, sorry.
    • 0:09:04Let me do the first sentence first.
    • 0:09:06In Python, that same thing, as you might guess,
    • 0:09:08is actually going to be almost the same, you just throw away the semicolon.
    • 0:09:12And the mathematics are ultimately the same, copying from right to left,
    • 0:09:15via the assignment operator.
    • 0:09:17Now, recall, in C, that we had this shorthand
    • 0:09:19notation, which did the same thing.
    • 0:09:22In Python, you can similarly do the same thing, just no need for the semicolon.
    • 0:09:26The only step backwards we're taking, if you
    • 0:09:29were a big fan of counter plus plus, that doesn't exist in Python,
    • 0:09:33nor minus minus.
    • 0:09:34You just can't do it.
    • 0:09:35You have to do the plus equals 1 or plus/minus or minus equals 1
    • 0:09:40to achieve that same result. All right, how about in Python 2?
    • 0:09:43Here in Scratch, recall, was a conditional,
    • 0:09:46asking a silly question like is x less than y, and if so, just say as much.
    • 0:09:49In C, that looked a little something like this, printf and if
    • 0:09:53with the parentheses, the curly braces, the semicolon, and all of that.
    • 0:09:57In Python, this is going to get a little more pleasant to type, too.
    • 0:10:00It's going to be just this.
    • 0:10:03And if someone wants to call out some of the obvious changes here,
    • 0:10:06what has been simplified now in Python for a conditional, it would seem?
    • 0:10:10Yeah, what's missing, or changed?
    • 0:10:11AUDIENCE: Braces.
    • 0:10:12DAVID J. MALAN: So no curly braces.
    • 0:10:13AUDIENCE: Colon is back.
    • 0:10:14DAVID J. MALAN: I'm sorry?
    • 0:10:15AUDIENCE: Using the colon instead.
    • 0:10:16DAVID J. MALAN: And we're using the colon instead.
    • 0:10:18So I got rid of the curly braces in Python.
    • 0:10:20But I'm using a colon instead.
    • 0:10:22And even though this is a single line of code,
    • 0:10:24so long as you indent subsequent lines along with the printf,
    • 0:10:28that's going to imply that everything, if the if condition is true,
    • 0:10:32should be executed below it, until you start to un-indent and start writing
    • 0:10:36a different line of code altogether.
    • 0:10:38So indentation in Python is important.
    • 0:10:41So this is among the reasons we've emphasized axes like style,
    • 0:10:45just how well styled your code is.
    • 0:10:46And honestly, we've seen, certainly, in office hours,
    • 0:10:49and you've seen in your own code, sort of a tendency sometimes
    • 0:10:52to be a little lax when it comes to indentation, right?
    • 0:10:55If you're one of those folks who likes to indent everything
    • 0:10:57on the left hand side of the window, yeah, it might compile and run.
    • 0:11:01But it's not particularly readable by you or anyone else.
    • 0:11:04Python actually addresses this by just requiring indentation,
    • 0:11:08when logically needed.
    • 0:11:09So Python is going to force you to start inventing properly now, if that's been,
    • 0:11:14perhaps, a tendency otherwise.
    • 0:11:16What else is missing?
    • 0:11:17Well, we have no semicolon here.
    • 0:11:19Of course, it's print instead of printf.
    • 0:11:21But otherwise, those seem to be the primary differences.
    • 0:11:23What about something larger in Scratch?
    • 0:11:25If an if-else block, like this, you can perhaps
    • 0:11:28guess what it's going to look like.
    • 0:11:30In C it looks like this, curly braces semicolons, and so forth.
    • 0:11:33In Python, it's going to now look like this, almost the same,
    • 0:11:37but indentation is important.
    • 0:11:38The colons are important.
    • 0:11:39And there's one other difference that's now again visible here,
    • 0:11:42but we didn't call it out a second ago.
    • 0:11:44What else is different in Python versus C for these conditionals?
    • 0:11:47Yeah.
    • 0:11:48AUDIENCE: You don't have any parentheses around the condition.
    • 0:11:51DAVID J. MALAN: Perfect.
    • 0:11:51We don't have any parentheses around the condition,
    • 0:11:54the Boolean expression itself.
    • 0:11:55And why not?
    • 0:11:56Well, it's just simpler to type.
    • 0:11:57It's less to type.
    • 0:11:58You can still use parentheses.
    • 0:12:00And, in fact, you might want to or need to,
    • 0:12:02if you want to combine thoughts and do this and that, or this or that.
    • 0:12:07But by default, you no longer need or should have those parentheses.
    • 0:12:10Just say what you mean.
    • 0:12:12Lastly, with conditionals, we had something like this,
    • 0:12:14an if else if else statement.
    • 0:12:16In C, it looked a little something like this.
    • 0:12:18In Python, it's going to get really tighter now.
    • 0:12:20It's just if, and this is the curiosity, elif x greater than y.
    • 0:12:25So it's not else if, it's literally one keyword, elif, and the colons
    • 0:12:31remain now on each of the three lines.
    • 0:12:33But the indentation is important.
    • 0:12:34And if we did want to do multiple things,
    • 0:12:36we could just indent below each of these conditionals, as well.
    • 0:12:40All right, let me pause there first, to see
    • 0:12:42if there's any questions on these syntactic differences.
    • 0:12:44Yeah.
    • 0:12:45AUDIENCE: My thought is maybe like, it's good,
    • 0:12:47though, does it matter if there's this in between thing like that, but
    • 0:12:51and why.
    • 0:12:52DAVID J. MALAN: In between, between what and what?
    • 0:12:55AUDIENCE: So like the left-hand side and like the right side spaces?
    • 0:12:58DAVID J. MALAN: Ah, good question, is Python sensitive
    • 0:13:01to spaces and where they go?
    • 0:13:03Sometimes no, sometimes yes, is the short answer.
    • 0:13:06Stylistically, though, you should be practicing what we're preaching here,
    • 0:13:10whereby you do have spaces to the left and right of binary operators,
    • 0:13:14that they're called, something like less than
    • 0:13:16or greater than is a binary operator, because there's
    • 0:13:18two operands to the left and to the right of them.
    • 0:13:20And in fact, in Python, more so than the world of C,
    • 0:13:23there's actually formal style conventions.
    • 0:13:26Not only within CS50 have we had a style guide on the course's website,
    • 0:13:30for instance, that just dictates how you should write your code so that it looks
    • 0:13:34like everyone else's.
    • 0:13:34In the Python community, they take this one step further,
    • 0:13:37and there's an actual standard whereby you don't have to adhere to it,
    • 0:13:41but generally speaking, in the real world, someone would reprimand you,
    • 0:13:44would reject your code, if you're trying to contribute it to another project,
    • 0:13:47if you don't adhere to these standards.
    • 0:13:48So while you could be lax with some of this white space,
    • 0:13:51do make things readable.
    • 0:13:52And that's Python theme, for the code to be as readable as possible.
    • 0:13:56All right, so let's take a look at a couple of other constructs
    • 0:13:59before transitioning to some actual code.
    • 0:14:01This, of course, in Scratch was a loop, meowing forever.
    • 0:14:04In C, the closest we could get was doing something while true, because true
    • 0:14:08never changes.
    • 0:14:09So it's sort of a simple way of just saying do this forever.
    • 0:14:12In Python, it's pretty much the same thing,
    • 0:14:14but a couple of small differences here.
    • 0:14:16The parentheses are gone.
    • 0:14:18The colon is there.
    • 0:14:19The indentation is there.
    • 0:14:20No semicolon, and there's one other subtle difference.
    • 0:14:24What do you see?
    • 0:14:24AUDIENCE: True is capitalized?
    • 0:14:25DAVID J. MALAN: True is capitalized, just because.
    • 0:14:28Both true and false are Boolean values in Python.
    • 0:14:30But you've got to start capitalizing them, just because.
    • 0:14:33All right, how about a loop like this, where
    • 0:14:35you repeat something a finite number of times, like meowing three times.
    • 0:14:38In C, we could do this a few different ways.
    • 0:14:41There's this very mechanical way, where you initialize a variable like i
    • 0:14:44to zero.
    • 0:14:45You then use a while loop and check if i is less than 3,
    • 0:14:49the total number of times you want to meow.
    • 0:14:51Then you print what you want to print.
    • 0:14:52You increment i using this syntax, or the longer, more verbose syntax,
    • 0:14:56with plus equals or whatnot.
    • 0:14:57And then you do it again and again and again.
    • 0:15:00In Python, you can do it functionally the same way, same idea,
    • 0:15:04slightly different syntax.
    • 0:15:05You just don't bother saying what type of variable you want.
    • 0:15:08Python will infer from the fact that there's a 0 right there.
    • 0:15:11You don't need the parentheses.
    • 0:15:12You do need the colon.
    • 0:15:13You do need the indentation.
    • 0:15:14You can't do the i plus plus, but you can do this other technique,
    • 0:15:17as we could have done in C, as well.
    • 0:15:20How else might we do this, though, too?
    • 0:15:22Well. it turns out in C, we could do something
    • 0:15:24like this, which, again, sort of cryptic at first glance,
    • 0:15:28became perhaps more familiar, where you have initialization,
    • 0:15:31a conditional, and then an update that you do after each iteration.
    • 0:15:34In Python, there isn't really an analog.
    • 0:15:37There is no analog in Python, where you have
    • 0:15:40the parentheses and the multiple semicolons in the same line.
    • 0:15:43Instead, there is a for loop, but it's meant to read a little more
    • 0:15:47like English, for i in 0, 1, and 2.
    • 0:15:50So we'll see in a bit, these square brackets represent an array, now
    • 0:15:54to be called a list in Python.
    • 0:15:57So lists in Python are more like link lists than they are arrays.
    • 0:16:01More on that soon.
    • 0:16:02So this just means for i and the following list of three values.
    • 0:16:06And on each iteration of this loop, Python automatically, for you,
    • 0:16:09it first sets i to zero.
    • 0:16:11Then it sets i to one.
    • 0:16:12Then it sets i to two, so that you effectively do things three times.
    • 0:16:17But this doesn't necessarily scale, as I've drawn it on the board.
    • 0:16:21Suppose you took this at face value as the way
    • 0:16:25you iterate some number of times in Python, using a for loop.
    • 0:16:28At what point does this approach perhaps get bad, or bad design?
    • 0:16:33Let me give folks just a moment to think.
    • 0:16:35Yeah, in back.
    • 0:16:36AUDIENCE: If you don't know how many times, last time, you know,
    • 0:16:39you've got the link in there.
    • 0:16:41DAVID J. MALAN: Sure, if you don't know how many times you
    • 0:16:43want to loop or iterate, you can't really create a hard-coded list
    • 0:16:47like that, of 0, 1, 2.
    • 0:16:48Other thoughts?
    • 0:16:50AUDIENCE: So you want to say raise a large number of allowances.
    • 0:16:52DAVID J. MALAN: Yeah, if you're iterating a large number of times,
    • 0:16:55this list is going to get longer and longer,
    • 0:16:57and you're just kind of stupidly going to be typing out
    • 0:16:59like comma 3, comma 4, comma 5, comma dot dot dot, comma 99, comma 100.
    • 0:17:03I mean, your code would start to look atrocious, eventually.
    • 0:17:06So there is a better way.
    • 0:17:07In Python, there is a function, or technically a type,
    • 0:17:10called range, that essentially magically gives you back a range of values
    • 0:17:14from 0 on up to, but not through a value.
    • 0:17:17So the effect of this line of code, for i in the following range,
    • 0:17:21essentially hands you back a list of three values,
    • 0:17:24thereby letting you do something three times.
    • 0:17:26And if you want to do something 99 times instead, you, of course,
    • 0:17:29just change the 3 to a 99.
    • 0:17:30Question.
    • 0:17:31AUDIENCE: Is there a way to start the beginning point of that range
    • 0:17:35at a number or an integer that's higher than zero, or is there never a really
    • 0:17:39any point to do so?
    • 0:17:40DAVID J. MALAN: A really good question, can
    • 0:17:41you start counting at a higher number.
    • 0:17:43So not 0, which is the implied default, but something larger than that.
    • 0:17:46Yes, so it turns out the range function takes multiple arguments, not just one
    • 0:17:51but maybe two or even three, that allows you to customize this behavior.
    • 0:17:54So you can customize where it begins.
    • 0:17:56You can customize the increment.
    • 0:17:57By default, it's one, but if you want to do
    • 0:17:59every two values, for like evens or odds, you could do that as well,
    • 0:18:02and a few other things.
    • 0:18:03And before long, we'll take a look at some Python documentation
    • 0:18:05that will become your authoritative source for answers like that.
    • 0:18:08Like, what can this function do.
    • 0:18:10Other questions on this thus far?
    • 0:18:15Seeing none, so what else might we compare and contrast here.
    • 0:18:19Well, in the world of C, recall that we had a whole bunch of built-in data
    • 0:18:24types, like these here, Bool and char and double and float, and so forth,
    • 0:18:28string, which happened to come from the CS50 library.
    • 0:18:31But the language C itself certainly understood the idea of strings,
    • 0:18:35because the backslash 0, the support for %S and printf, that's all native,
    • 0:18:40built into C, not a CS50 simplification.
    • 0:18:43All we did, and revealed, as of a couple of weeks
    • 0:18:45ago, is that string, this data type, is just
    • 0:18:48a synonym for a typedef for char star, which is part of the language natively.
    • 0:18:52In Python now, this list actually gets a little shorter, at least
    • 0:18:55for these common primitive data types.
    • 0:18:57Still going to have bulls, we're going to have floats, and Ints,
    • 0:19:00and we're going to have strings, but we're going to call them STRs.
    • 0:19:02And this is not a CS50 thing from the library,
    • 0:19:04STR, S-T-R, is, in fact, a data type in Python,
    • 0:19:08that's going to do a lot more than strings did for us automatically in C.
    • 0:19:12Ints and floats, meanwhile, don't need the corresponding longs and doubles,
    • 0:19:17because, in fact, among the problems Python solves for us,
    • 0:19:19too, Ints can get as big as you want.
    • 0:19:22Integer overflow is no longer going to be an issue.
    • 0:19:25Per week 1, the language solves that for us.
    • 0:19:27Floating point imprecision, unfortunately,
    • 0:19:29is still a problem that remains.
    • 0:19:31But there are libraries, code that other people have written, as we briefly
    • 0:19:34discussed in weeks past, that allow you to do
    • 0:19:37scientific or financial computing, using libraries that build
    • 0:19:40on top of these data types, as well.
    • 0:19:42So there's other data types, too, in Python, which we'll see actually
    • 0:19:45gives us a whole bunch of more power and capability,
    • 0:19:48things called ranges, like we just saw, lists,
    • 0:19:51like I called out verbally, with the square brackets,
    • 0:19:54things called tuples, for things like x comma y,
    • 0:19:56or latitude, longitude, dictionaries, or Dicts,
    • 0:20:00which allow you to store keys and values, much like our hash tables
    • 0:20:03from last time, and then sets in the mathematical sense, where they filter
    • 0:20:06out duplicates for you, and you can just put a whole bunch of numbers,
    • 0:20:09a whole bunch of words or whatnot, and the language, via this data type,
    • 0:20:13will filter out duplicates for you.
    • 0:20:16Now there's going to be a few functions we give you this week and beyond,
    • 0:20:19training wheels that we're then going to very quickly take off,
    • 0:20:22just because, as we'll see today, they just simplify the process of getting
    • 0:20:26user input correctly, without accidentally writing buggy code,
    • 0:20:29just when you're trying to get Hello, World, or something similar, to work.
    • 0:20:32And we'll give you functions, not like, not as long as this list in C,
    • 0:20:36but a subset of these, get float, get Int,
    • 0:20:38and get string, that'll automate the process of getting
    • 0:20:41user input in a way that's more resilient against potential bugs.
    • 0:20:45But we'll see what those bugs might be.
    • 0:20:47And the way we're going to do this is similar in spirit to C.
    • 0:20:50Instead of doing include, CS50.h, like we did in C,
    • 0:20:54you're going to now start saying import CS50.
    • 0:20:57Python supports, similar to C, libraries,
    • 0:21:00but there aren't header files anymore.
    • 0:21:02You just use the name of the library in Python.
    • 0:21:05And if you want to import CS50's functions, you just say import CS50.
    • 0:21:08Or, if you want to be more precise, and not just import the whole thing, which
    • 0:21:12could be slow, if you've got a really big library with a lot of functionality
    • 0:21:15in it, you can be more precise and say from CS50, import get float.
    • 0:21:19From CS50 import get Int, from CSM 50 import get string,
    • 0:21:23or you can just separate them by commas and import 3
    • 0:21:26and only 3 things from a particular library, like ours.
    • 0:21:30But starting today and onward, we're going
    • 0:21:32to start making much more heavy use of libraries, code
    • 0:21:35that other people wrote, so that we're no longer reinventing the wheel.
    • 0:21:38We're not making our own linked lists, our own trees, our own dictionaries.
    • 0:21:41We're going to start standing on the shoulders of others,
    • 0:21:44so that you can get real work done, so to speak, faster,
    • 0:21:47by building your software on top of others' code as well.
    • 0:21:51All right, so that's it for the syntactic tour of the language,
    • 0:21:55and the sort of core features.
    • 0:21:56Soon we'll transition to application thereof.
    • 0:21:58But let me pause here to see if there's any questions on syntax or primitives
    • 0:22:04or otherwise, or otherwise.
    • 0:22:10Oh, yes, in back.
    • 0:22:12AUDIENCE: Why don't Python have the increment operators.
    • 0:22:16DAVID J. MALAN: I'm sorry, say it again, why doesn't
    • 0:22:18Python have what kind of operators?
    • 0:22:19AUDIENCE: Why doesn't Python have the increment operator?
    • 0:22:22DAVID J. MALAN: Sorry, someone coughed when you said something operators.
    • 0:22:25AUDIENCE: The increment.
    • 0:22:26DAVID J. MALAN: Oh, the increment operator?
    • 0:22:28I'd have to check the history, honestly.
    • 0:22:30Python has tended to be a fairly minimus language.
    • 0:22:32And if you can do something one way, the community, arguably,
    • 0:22:36has tended to not give you multiple ways to do the same thing syntactically.
    • 0:22:40There's probably a better answer.
    • 0:22:41And I'll see if I can dig in and post something online, to follow up on that.
    • 0:22:45All right, so before we transition to now writing some actual code,
    • 0:22:49let me go ahead and consider exactly how we're going to write code.
    • 0:22:54In the world of C, recall that it's generally been a 2-step process.
    • 0:22:58We create a file called like Hello.c, and then, step one, make Hello, step 2,
    • 0:23:04./Hello.
    • 0:23:05Or, if you think back to week two, when we sort of peeled back
    • 0:23:08the layer of what Hello, of what make was doing,
    • 0:23:11you could more verbosely type out the name of the actual compiler,
    • 0:23:14Clang in our case, command line arguments like dash Oh, Hello,
    • 0:23:17to specify what name you want to create.
    • 0:23:19And then you can specify the file name.
    • 0:23:21And then you can specify what libraries you want to link in.
    • 0:23:25So that was a very verbose approach.
    • 0:23:26But it was always a two-step approach.
    • 0:23:28And so, even as you've been doing recent problem sets,
    • 0:23:31odds are you've realized that, any time you want to make a change to your code,
    • 0:23:35or make a change to your code and try and test your code again,
    • 0:23:39you're constantly doing those two steps.
    • 0:23:42Moving forward in Python, it's going to become simpler,
    • 0:23:45and it's going to be just this.
    • 0:23:47The file name is going to change, but that might go without saying.
    • 0:23:50It's going to be something like Hello.py, P-Y, instead of Hello.c.
    • 0:23:55And that's just a convention, using a different file extension.
    • 0:23:57But there's no compilation step per se.
    • 0:24:00You jump right to the execution of your code.
    • 0:24:04And so Python, it turns out, is the name, not only of the language
    • 0:24:07we're going to start using, it's also the name of a program on a Mac, a PC,
    • 0:24:12assuming it's been pre-installed, that interprets the language for you.
    • 0:24:16This is to say that Python is generally described as being interpreted,
    • 0:24:20not compiled.
    • 0:24:21And by that, I mean you get to skip, from the programmer's perspective,
    • 0:24:25that compilation step.
    • 0:24:26There is no manual step in the world of Python, typically, of writing your code
    • 0:24:30and then compiling it to zeros and ones, and then running the zeros and ones.
    • 0:24:34Instead, these kind of two steps get collapsed
    • 0:24:36into the illusion of one, whereby you, instead, are able to just run the code,
    • 0:24:42and let the computer figure out how to actually convert it
    • 0:24:46to something the computer understands.
    • 0:24:48And the way we do that is via this old process, input and output.
    • 0:24:51But now, when you have source code, it's going
    • 0:24:53to be passed into an interpreter, not a compiler.
    • 0:24:56And the best analog of this is just to perhaps point out
    • 0:24:59that, in the human world, if you speak, or don't speak,
    • 0:25:01multiple human languages, it can be a pretty slow process from going
    • 0:25:05from one language to another.
    • 0:25:07For instance, here are step-by-step instructions for finding someone
    • 0:25:10in a phone book, unfortunately, in Spanish.
    • 0:25:12Unfortunately, if you don't speak or read Spanish.
    • 0:25:15You could figure this out.
    • 0:25:16You could run this algorithm, but you're going to have to do some googling,
    • 0:25:19or you're going to have to open up literal dictionary from Spanish
    • 0:25:22to English and convert this.
    • 0:25:23And the catch with translating any language, human or computer
    • 0:25:27or otherwise, is that you're going to pay a price, typically some time.
    • 0:25:30And so converting this in Spanish to this in English
    • 0:25:33is just going to take you longer than if this were already
    • 0:25:36in your native language.
    • 0:25:38And that's going to be one of the subtleties with the world of Python.
    • 0:25:41Yes, it's a feature that you can just run the code without having
    • 0:25:45to bother compiling it manually first.
    • 0:25:47But we might pay a price.
    • 0:25:49And things might be a little slower.
    • 0:25:50Now, there's ways to chip away at that.
    • 0:25:52But we'll see an example thereof.
    • 0:25:53In fact, let me transition now to just a couple of examples
    • 0:25:56that demonstrate how Python is not only easier for many people
    • 0:26:00to use, perhaps yourselves too, because it throws away
    • 0:26:03a lot of the annoying syntax, it shortens the number of lines
    • 0:26:06you have to write, and also it comes with so many darn libraries,
    • 0:26:09you can just do so much more without having to write the code yourself.
    • 0:26:14So, as an example of this, let me switch over here
    • 0:26:17to this image from problem set 4, which is the Weeks Bridge down by the Charles
    • 0:26:24River here in Cambridge.
    • 0:26:25And this is the original photo, pretty clear,
    • 0:26:27and it's even higher res if we looked at the original version of the photo.
    • 0:26:30But there have been no filters, a la Instagram, applied to this photo.
    • 0:26:33Recall, for problem set four, you had to implement a few filters.
    • 0:26:36And among them might have been blur.
    • 0:26:38And blur was probably among the more challenging of the ones,
    • 0:26:41because you had to iterate over all of the pixels,
    • 0:26:44you had to take into account what's above, what's below, to the left,
    • 0:26:47to the right.
    • 0:26:47I mean, there was a lot of math and arithmetic.
    • 0:26:49And if you ultimately got it, it was probably a great sense of satisfaction.
    • 0:26:52But that was probably several hours later.
    • 0:26:54In a language like Python, where there might
    • 0:26:57be libraries that had been written by others, on whose shoulders
    • 0:27:01you can stand, we could perhaps do something like this.
    • 0:27:03Let me go ahead and run a program, or write a program, called Blur.py here.
    • 0:27:08And in Blur.py, in VS Code, let me just do this.
    • 0:27:12Let me import from a library, not the CS50 library,
    • 0:27:15but the Pillow library, so to speak, a keyword called image
    • 0:27:19and another one called image filter, then let me go ahead
    • 0:27:23and say, let me open the current version of this image, which
    • 0:27:26is called Bridge.bmp.
    • 0:27:27So the before version of the image will be
    • 0:27:30the result of calling image.open quote unquote "Bridge.bmp,"
    • 0:27:34and then, let me create an after version.
    • 0:27:37So you'll see before and after.
    • 0:27:38After equals the before version .filter of image filter.
    • 0:27:45And there is, if I read the documentation,
    • 0:27:46I'll see that there's something called a box blur, that
    • 0:27:49allows you to blur in box format, like one pixel above,
    • 0:27:52below, left, and right.
    • 0:27:53So I'll do one pixel there.
    • 0:27:55And then, after that's done, let me go ahead and save the file
    • 0:27:57as something like Out.bmp.
    • 0:28:01That's it.
    • 0:28:02Assuming this library works as described,
    • 0:28:04I am opening the file in Python, using line 3.
    • 0:28:08And this is somewhat new syntax.
    • 0:28:09In the world of Python, we're going to start making use of the dot operator
    • 0:28:13more, because in the world of Python, you have
    • 0:28:15what's called object-oriented programming, or OOP, as a term of art.
    • 0:28:19And what this means is that you still have functions,
    • 0:28:22you still have variables, but sometimes those functions
    • 0:28:24are embedded inside of the variables, or, more specifically,
    • 0:28:28inside of the data types themselves.
    • 0:28:30Think back to C. When you wanted to convert something to uppercase,
    • 0:28:34there was a to upper function that takes as input an argument that's a char.
    • 0:28:38And you can pass in any char you want, and it will uppercase it for you
    • 0:28:41and give you back a value.
    • 0:28:42Well, you know what, if that's such a common paradigm, where
    • 0:28:46upper-casing chars is a useful thing, what the world of Python does
    • 0:28:49is it embeds into the string data type, or char if you will,
    • 0:28:54the ability just to uppercase any char by treating the char, or the string,
    • 0:28:59as though it's a struct in C. Recall that structs
    • 0:29:02encapsulate multiple types of values.
    • 0:29:04In object-oriented programming, in a language like Python,
    • 0:29:07you can encapsulate not just values, but also functionality.
    • 0:29:11Functions can now be inside of structs.
    • 0:29:13But we're not going to call them structs anymore.
    • 0:29:15We're going to call them objects.
    • 0:29:17But that's just a different vernacular.
    • 0:29:19So what am I doing here?
    • 0:29:20Inside of the image library, there's a function called open,
    • 0:29:23and it takes an argument, the name of the file, to open.
    • 0:29:26Once I have a variable called before, that is a struct, or technically
    • 0:29:30an object, inside of which is now, because it
    • 0:29:33was returned from this function, a function
    • 0:29:36called filter, that takes an argument.
    • 0:29:38The argument here happens to be image.boxblur1,
    • 0:29:41which itself is a function.
    • 0:29:42But it just returns the filter to use.
    • 0:29:44And then, after, dot save does what you might think.
    • 0:29:46It just saves the file.
    • 0:29:48So instead of using fopen and fwrite, you just say dot save,
    • 0:29:51and that does all of that messy work for you.
    • 0:29:54So it's just, what, four lines of code total?
    • 0:29:57Let me go ahead and go down to my terminal window.
    • 0:30:00Let me go ahead and show you with LS that, at the moment,
    • 0:30:03whoops, sorry, let me not bother showing that,
    • 0:30:05because I have other examples to come.
    • 0:30:07I'm going to go ahead and do Python of Blur.py, nope, sorry, wrong place.
    • 0:30:14I did need to make a command.
    • 0:30:15There we go.
    • 0:30:16OK, let me go ahead and type LS inside of my filter directory, which
    • 0:30:19is among the sample code online today.
    • 0:30:21There's only one file called Bridge.bmp, dammit,
    • 0:30:24I'm trying to get these things ready at the same time.
    • 0:30:27Let me rewind.
    • 0:30:28Let me move this code into place.
    • 0:30:32All right, I've gone ahead and moved this file, Blur.py,
    • 0:30:34into a folder called filter, inside of which
    • 0:30:37there's another file called Bridge.bmp, which we can confer with LS.
    • 0:30:42Let me now go ahead and run Python, which
    • 0:30:44is my interpreter, and also the name of the language,
    • 0:30:46and run Python on this file.
    • 0:30:48So much like running the Spanish algorithm
    • 0:30:51through Google Translate, or something like that,
    • 0:30:53as input, to get back the English output,
    • 0:30:55this is going to translate the Python language to something
    • 0:30:59this computer, or this cloud-based environment,
    • 0:31:01understands, and then run the corresponding code, top to bottom,
    • 0:31:05left to right.
    • 0:31:05I'm going to go ahead and Enter.
    • 0:31:07No error message is generally a good thing.
    • 0:31:08If I type LS you'll now see out.bmp.
    • 0:31:11Let me go ahead and open that.
    • 0:31:13And, you know what, just to make clear what's really happening,
    • 0:31:15let me blur it even further.
    • 0:31:17Let's make a box that's not just one pixel around, but 10.
    • 0:31:20So let's make that change.
    • 0:31:21And let me just go ahead and rerun it with Python of Blur.py.
    • 0:31:24I still have Out.bmp.
    • 0:31:27Let me go ahead and open Out.bmp and show you first the before,
    • 0:31:32which looks like this.
    • 0:31:33That's the original.
    • 0:31:34And now, crossing my fingers, four lines of code later,
    • 0:31:37the result of blurring it, as well.
    • 0:31:39So the library is doing all of the same kind of legwork
    • 0:31:42that you all did for the assignment, but it's
    • 0:31:44encapsulated it all into a single library, that you can then use instead.
    • 0:31:48Those of you who might have been feeling more comfortable,
    • 0:31:50might have done a little something like this.
    • 0:31:52Let me go ahead and open up one other file, called Edges.py.
    • 0:31:56And in Edges.py, I'm again going to import from the Pillow library
    • 0:32:00the image keyword, and the image filter.
    • 0:32:03Then I'm going to go ahead and create a before image, that's
    • 0:32:05a result of calling image.open of the same thing, Bridge.bmp,
    • 0:32:09then I'm going to go ahead and run a filter on that, called image, whoops,
    • 0:32:16image filter.find edges, which is like a content, if you will,
    • 0:32:21defined inside of this library for us.
    • 0:32:23And then I'm going to do after.save quote unquote
    • 0:32:25"Out.bmp," using the same file name.
    • 0:32:28I'm now going to run Python of Edges.py, after, sorry, user error.
    • 0:32:36We'll see what syntax error means soon.
    • 0:32:38Let me go ahead and run the code now, Edges.py.
    • 0:32:41Let me now open that new file, Out.bmp.
    • 0:32:44And before we had this, and now, especially if what will look familiar
    • 0:32:49if we did the more comfortable version of P set 4,
    • 0:32:52we now get this, after just four lines of code.
    • 0:32:55So again, suggesting the power of using a language that's better
    • 0:32:58optimized for the tool at hand.
    • 0:32:59And at the risk of really making folks sad, let's go ahead
    • 0:33:02and re-implement, if we could, problem set five, real quickly here.
    • 0:33:06Let me go ahead and open another version of this code,
    • 0:33:11wherein I have a C version, just from problem
    • 0:33:14set five, wherein you implemented a spell checker,
    • 0:33:16loading 100,000 plus words into memory.
    • 0:33:18And then you kept track of just how much time and memory it took.
    • 0:33:22And that probably took a while, implementing
    • 0:33:24all of those functions in Dictionary.c.
    • 0:33:26Let me instead now go into a new file, called Dictionary.py.
    • 0:33:32And let me stipulate, for the sake of discussion,
    • 0:33:35that we already wrote in advance, Speller.py,
    • 0:33:37which corresponds to Speller.c.
    • 0:33:39You didn't write either of those.
    • 0:33:41Recall for problem set five, we gave you Speller.c.
    • 0:33:43Assume that we're going to give you Speller.py.
    • 0:33:45So the onus on us right now is only to implement Speller, Dictionary.py.
    • 0:33:52All right, so I'm going to go ahead and define a few functions.
    • 0:33:54And we're going to see now the syntax for defining functions in Python.
    • 0:33:58I want to go ahead and define first, a hash table, which
    • 0:34:02was the very first thing you defined in Dictionary.c.
    • 0:34:04I'm going to go ahead, then, and say words gets this, give me a dictionary,
    • 0:34:09otherwise known as a hash table.
    • 0:34:11All right, now let me define a function called
    • 0:34:13check, which was the first function you might have implemented.
    • 0:34:16Check is going to take a word, and you'll see in Python,
    • 0:34:19the syntax is a little different.
    • 0:34:20You don't specify the return type.
    • 0:34:21You use the word Def instead to define.
    • 0:34:24You still specify the name of the function and any arguments thereto.
    • 0:34:28But you omit any mention of types.
    • 0:34:31But you do use a colon and indent.
    • 0:34:33So how do I check if a word is in my dictionary, or in my hash table?
    • 0:34:37Well, in Python, I can just say, if word in words,
    • 0:34:41go ahead and return true, else go ahead and return false, done,
    • 0:34:46with the check function.
    • 0:34:47All right, now I want to do like load.
    • 0:34:49That was the heavy lift, where you had to load the big file into memory.
    • 0:34:52So let me define a function called load.
    • 0:34:54It takes a string, the name of a file to load.
    • 0:34:56So I'll call that Dictionary, just like in C, but no data type.
    • 0:34:59Let me go ahead and open a file by using an open function in Python,
    • 0:35:04by opening that Dictionary in read mode.
    • 0:35:06So this is a little similar to fopen, a function in C you might recall.
    • 0:35:10Then let me iterate over every line in the file.
    • 0:35:12In Python, this is pretty pleasant, for line in file colon indent.
    • 0:35:17How, now, do I get at the current word, and then strip off the new line,
    • 0:35:22because in this file of words, 140,000 words,
    • 0:35:25there's word backslash n, word backslash n, all right?
    • 0:35:28Well, let me go ahead and get a word from the current line,
    • 0:35:31but strip off, from the right end of the string, the new line, which
    • 0:35:34the Rstrip function in Python does for me.
    • 0:35:37Then let me go ahead and add to my dictionary, or hash table, that word,
    • 0:35:42done.
    • 0:35:43Let me go ahead and close the file for good measure.
    • 0:35:45And then let me go ahead and return true, because all was well.
    • 0:35:48That's it for the load function in Python.
    • 0:35:50How about the size function?
    • 0:35:51This did not take any arguments, it just returns the size of the hash table
    • 0:35:54or dictionary in Python.
    • 0:35:55I can do that by returning the length of the dictionary in question.
    • 0:35:59And then lastly, gone from the world of Python is malloc and free.
    • 0:36:04Memory is managed for you.
    • 0:36:06So no matter what I do, there's nothing to unload.
    • 0:36:08The computer will do that for me.
    • 0:36:10So I give you, in these functions, problem set five in Python.
    • 0:36:14So, I'm sorry, we made you write it in C first.
    • 0:36:17But the implication now is that, what are you getting for free,
    • 0:36:20in a language like Python?
    • 0:36:21Well, encapsulated in this one line of code
    • 0:36:24is much of what you wrote for problem set five, implementing
    • 0:36:28your array for all of your letters of the alphabet or more,
    • 0:36:31all of the linked lists that you implemented to create chains,
    • 0:36:34to store all of those words.
    • 0:36:35All of that is happening.
    • 0:36:37It's just someone else in the world wrote that code for you.
    • 0:36:40And you can now use it by way of a dictionary.
    • 0:36:43And actually, I can change this a little bit,
    • 0:36:45because add is technically not the right function to use here.
    • 0:36:48I'm actually treating the dictionary as something simpler, a set.
    • 0:36:51So I'm going to make one tweak, set recall was another data type in Python.
    • 0:36:55But set just allows it to handle duplicates,
    • 0:36:57and it allows me to just throw things into it by literally
    • 0:37:00using a function as simple as add.
    • 0:37:02And I'm going to make one other tweak here,
    • 0:37:05because, when I'm checking a word, it's possible it might be given
    • 0:37:09to me in uppercase or capitalized.
    • 0:37:12It's not going to necessarily come in in the same lowercase format
    • 0:37:15that my dictionary did.
    • 0:37:17I can force every word to lowercase by using word.lower.
    • 0:37:22And I don't have to do it character for character,
    • 0:37:24I can do the whole darn string at once, by just saying word.lower.
    • 0:37:29All right, let me go ahead and open up a terminal window here.
    • 0:37:32And let me go into, first, my C version, on the left.
    • 0:37:36And actually I'm going to go ahead and split my terminal window into two.
    • 0:37:39And on the right, I'm going to go into a version that I essentially just wrote.
    • 0:37:44But it's also available online, if you want to play along afterward.
    • 0:37:46I'm going to go ahead and make speller in C on the left,
    • 0:37:50and note that it takes a moment to compile.
    • 0:37:52Then I'm going to be ready to run speller of dictionaries,
    • 0:37:56let's do like the Sherlock Holmes text, which is pretty big.
    • 0:37:59And then over here, let me get ready to run Python of speller
    • 0:38:03on texts/homes.txt2.
    • 0:38:07So the syntax is a little different at the command prompt.
    • 0:38:10I just, on the left, have to compile the code, with make,
    • 0:38:12and then run it with ./speller.
    • 0:38:14On the right, I don't need to compile it.
    • 0:38:16But I do need to use the interpreter.
    • 0:38:17So even though the lines are wrapping a little bit here,
    • 0:38:20let me go ahead and run it on the right.
    • 0:38:22And I'm going to count how long it takes, verbally,
    • 0:38:24for demonstration sake.
    • 0:38:25One Mississippi, two Mississippi, three Mississippi, OK,
    • 0:38:28so it's like three seconds, give or take.
    • 0:38:31Now running it in Python, keeping in mind,
    • 0:38:33I spent way fewer hours implementing a spell checker in Python
    • 0:38:37than you might have in problem set five.
    • 0:38:38But what's the trade-off going to be, and what kinds of design decisions
    • 0:38:42do we all now need to be making consciously?
    • 0:38:43Here we go, on the right, in Python.
    • 0:38:46One Mississippi, two Mississippi, three Mississippi, four Mississippi,
    • 0:38:50five Mississippi, six Mississippi, seven Mississippi, eight Mississippi,
    • 0:38:54nine Mississippi, 10 Mississippi, 11 Mississippi,
    • 0:38:57all right, so 10 or 11 seconds.
    • 0:38:59So which one is better?
    • 0:39:01Let's go to the group here, which of these programs is the better one?
    • 0:39:06How might you answer that question, based on demonstration alone?
    • 0:39:10What do you think?
    • 0:39:11AUDIENCE: I think Python's better for the programmer,
    • 0:39:13more comfortable for the programmer, but C is better for the user.
    • 0:39:17DAVID J. MALAN: OK, so Python, to summarize,
    • 0:39:19is better for the programmer, because it was way faster to write,
    • 0:39:23but C is maybe better for the computer, because it's much faster to run.
    • 0:39:26I think that's a reasonable formulation.
    • 0:39:28Other opinions?
    • 0:39:29Yeah.
    • 0:39:30AUDIENCE: I think it depends on the size of the project
    • 0:39:32that you're dealing with.
    • 0:39:33So if it's going to be something that's relatively quick,
    • 0:39:36I might not care that it takes 10 seconds to do it.
    • 0:39:38And it could be way faster to do it with Python.
    • 0:39:40Whereas with C, if I'm dealing with something like a massive data
    • 0:39:44set or something huge, then that time is going to really build up on,
    • 0:39:48it might be worth it to put in the upfront effort and just load it into C,
    • 0:39:52so the process continually will run faster over a longer period of time.
    • 0:39:56DAVID J. MALAN: Absolutely, a really good answer.
    • 0:39:57And let me summarize, is it depends on the workload, if you will.
    • 0:40:00If you have a very large data set, you might
    • 0:40:04want to optimize your code to be as fast and performant as it can be,
    • 0:40:07especially if you're running that code again and again.
    • 0:40:09Maybe you're a company like Google.
    • 0:40:10People are searching a huge database all the time.
    • 0:40:13You really want to squeeze every bit of performance
    • 0:40:15as you can out of the computer.
    • 0:40:17You might want to have someone smart take a language like C
    • 0:40:19and write it at a very low level.
    • 0:40:21It's going to be painful.
    • 0:40:22They're going to have bugs.
    • 0:40:23They're going to have to deal with memory management and the like.
    • 0:40:26But if and when it works correctly, it's going to be much faster, it would seem.
    • 0:40:29By contrast, if you have a data set that's big,
    • 0:40:32and 140,000 words is not small, but you don't
    • 0:40:35want to spend like 5 hours, 10 hours, a week of your time,
    • 0:40:38building a spell checker or a dictionary,
    • 0:40:41you can instead leverage a different language with different libraries
    • 0:40:43and build on top of it, in order to prioritize the human time instead.
    • 0:40:48Other thoughts?
    • 0:40:50AUDIENCE: Would you, because with Python,
    • 0:40:52doesn't it also like convert the words, or like
    • 0:40:56convert the words, for a lesson?
    • 0:40:58When we convert that into the same version again,
    • 0:41:00do we just take that into view?
    • 0:41:04DAVID J. MALAN: That's a perfect segue to exactly the next point we
    • 0:41:06wanted to make, which was, is there something in between?
    • 0:41:09And indeed there is.
    • 0:41:10I'm oversimplifying what this language is actually doing.
    • 0:41:12It's not as stark a difference as saying, like, hey,
    • 0:41:15Python is four times slower than C. Like that's not the right takeaway.
    • 0:41:18There are absolutely ways that engineers can optimize languages,
    • 0:41:21as they have already done for Python.
    • 0:41:23And in fact, I've configured my settings in such a way
    • 0:41:25that I've kind of dramatized just how big the difference is.
    • 0:41:28It is going to be slower, Python, typically,
    • 0:41:30than the equivalent C program.
    • 0:41:31But it doesn't have to be as big of a gap
    • 0:41:33as it is here, because, indeed, among the features you can turn on in Python
    • 0:41:37is to save some intermediate results.
    • 0:41:40Technically speaking, yes, Python is interpreting
    • 0:41:43Dictionary.py and these other files, translating them
    • 0:41:46from one language to another.
    • 0:41:48But that doesn't mean it has to do that every darn time you run the program.
    • 0:41:51As you propose, you can save, or cache, C-A-C-H-E, the results of that process.
    • 0:41:57So that the second time and the third time are actually notably faster.
    • 0:42:00And, in fact, Python itself, the interpreter, the most popular version
    • 0:42:03thereof, itself is actually implemented in C.
    • 0:42:05So you can make sure that your interpreter is as fast as possible.
    • 0:42:09And what then is maybe the high level takeaway?
    • 0:42:11Yes, if you are going to try to squeeze every bit of performance
    • 0:42:14out of your code, and maybe code is constrained.
    • 0:42:17Maybe you have very small devices.
    • 0:42:19Maybe it's like a watch nowadays.
    • 0:42:20Or maybe it's a sensor that's installed in some small format in an appliance,
    • 0:42:26or in infrastructure, where you don't have much battery life
    • 0:42:29and you don't have much size, you might want
    • 0:42:31to minimize just how much work is being done.
    • 0:42:33And so the faster the code runs, and the better it's going to be,
    • 0:42:36if it's implemented something low level.
    • 0:42:38So C is still very commonly used for certain types of applications.
    • 0:42:42But, again, if you just want to solve real world problems,
    • 0:42:45and get real work done, and your time is just as, if not more, valuable
    • 0:42:49than the device you're running it on, long term,
    • 0:42:52you know what, Python is among the most popular languages as well.
    • 0:42:55And frankly, if I were implementing a spell checker moving forward,
    • 0:42:58I'm probably starting with Python.
    • 0:42:59And I'm not going to waste time implementing
    • 0:43:01all of that low-level stuff, because the whole point of using newer,
    • 0:43:04modern languages is to use abstractions that other people have created for you.
    • 0:43:09And by abstraction, I mean something like the dictionary function,
    • 0:43:12that just gives you a dictionary, or hash table,
    • 0:43:15or the equivalent version that I used, which in this case was a set.
    • 0:43:19All right, any questions, then, on Python thus far?
    • 0:43:25No, all right.
    • 0:43:26Oh, yeah, in the middle.
    • 0:43:27AUDIENCE: Could you compile the Python code,
    • 0:43:29or is there some, I'd imagine that with the audience that can happen,
    • 0:43:34but it feels like if you can just come up with a Python compiler,
    • 0:43:38that would give you the best of both worlds.
    • 0:43:40DAVID J. MALAN: Really good question or observation,
    • 0:43:42could you just compile Python code?
    • 0:43:43Yes, absolutely, this idea of compiling code or interpreting code
    • 0:43:47is not native to the language itself.
    • 0:43:49It tends to be native to the conventions that we humans use.
    • 0:43:52So you could actually write an interpreter for C
    • 0:43:54that would read it top to bottom, left to right, converting it to, on the fly,
    • 0:43:57something the computer understands, but historically that's not been the case.
    • 0:44:01C is generally a compiled language.
    • 0:44:03But it doesn't have to be.
    • 0:44:04What Python nowadays is actually doing is what you described earlier.
    • 0:44:08It technically is, sort of unbeknownst to us,
    • 0:44:10compiling the code, technically not into 0's and 1's, technically
    • 0:44:13into something called byte code, which is this intermediate step that
    • 0:44:17just doesn't take as much time as it would to recompile the whole thing.
    • 0:44:21And this is an area of research for computer scientists working
    • 0:44:24in programming languages, to improve these kinds of paradigms.
    • 0:44:26Why?
    • 0:44:27Well, honestly, for you and I, the programmer, it's just much easier to,
    • 0:44:30one, run the code and not worry about the stupid second step
    • 0:44:33of compiling it all the time.
    • 0:44:35Why?
    • 0:44:35It's literally half as many steps for me, the human.
    • 0:44:38And that's a nice thing to optimize for.
    • 0:44:40And ultimately, too, you might want all of the fancy features that
    • 0:44:44come with these other languages.
    • 0:44:45So you should really just be fine-tuning how
    • 0:44:47you can enable these features, as opposed to shying away from them here.
    • 0:44:51And, in fact, the only time I personally ever use C
    • 0:44:54is from like September to October of every year, during CS50.
    • 0:44:57Almost every other month do I reach for Python,
    • 0:45:00or another language called JavaScript, to actually get real work done,
    • 0:45:03which is not to impugn C. It's just that those other languages tend to be better
    • 0:45:07fits for the amount of time I have to allocate, and the types of problems
    • 0:45:11that I want to solve.
    • 0:45:11All right, let's go ahead and take a five minute break here.
    • 0:45:14And when we come back, we'll start writing some programs from Scratch.
    • 0:45:17All right.
    • 0:45:18So let's go ahead and start writing some code from the beginning
    • 0:45:21here, whereby we start small with some simple examples,
    • 0:45:24and then we'll build our way up to more sophisticated examples in Python.
    • 0:45:28But what we'll do along the way is first,
    • 0:45:29look side by side at what the C code looked
    • 0:45:31like way back in week 1 or 2 or 3 and so forth,
    • 0:45:34and then write the corresponding Python code at right.
    • 0:45:36And then we'll transition just to focusing on Python itself.
    • 0:45:39What I've done in advance today is I've downloaded some of the code
    • 0:45:42from the course's website, my source 6 directory, which
    • 0:45:44contains all of the pre-written C code from weeks past.
    • 0:45:47But it'll also have copies of the Python code
    • 0:45:49we'll write here together and look at.
    • 0:45:51So first, here is Hello.c back from week 0.
    • 0:45:55And this was version 0 of it.
    • 0:45:57I'm going to go ahead and do this.
    • 0:45:58I'm going to go ahead and split my code window up here.
    • 0:46:02I'm going to go ahead and create a new file called Hello.py.
    • 0:46:05And this isn't something you'll typically have to do,
    • 0:46:07laying your code out side by side.
    • 0:46:08But I've just clicked the little icon in VS Code
    • 0:46:10that looks like two columns, that splits my code editor into two places,
    • 0:46:14so that we can, in fact, see things, for now, side by side,
    • 0:46:17with my terminal window down below.
    • 0:46:18All right, now I'm going to go ahead and write the corresponding Python
    • 0:46:21program on the right, which, recall, was just print, quote
    • 0:46:24unquote, "Hello, world," and that's it.
    • 0:46:27Now down in my terminal window, I'm going
    • 0:46:29to go ahead and run Python of Hello.py, Enter, and voila,
    • 0:46:33we've got Hello.py working.
    • 0:46:34So again, I'm not going to play any further with the C code.
    • 0:46:36It's there just to jog your memory left and right.
    • 0:46:38So let's now look at a second version of Hello, world
    • 0:46:41from that first week, whereby if I go and get Hello1.c,
    • 0:46:44I'm going to drag that over to the right.
    • 0:46:46Whoops, I'm going to go ahead and drag that over to the left here.
    • 0:46:48And now, on the right, let's modify Hello.py
    • 0:46:51to look a little more like this second version in C, all right?
    • 0:46:55I want to get an answer from the user as a return value,
    • 0:46:59but I also want to get some input from them.
    • 0:47:01So from CS50, I'm going to import the function called getString for now.
    • 0:47:05We're going to get rid of that eventually,
    • 0:47:07but for now, it's a helpful training wheel.
    • 0:47:08And then down here, I'm going to say, answer
    • 0:47:11equals getString quote unquote, "What's your name"?
    • 0:47:14Question mark, space.
    • 0:47:15But no semicolon, no data type.
    • 0:47:17And then I'm going to go ahead and print, just
    • 0:47:19like the first example on the slide, Hello, comma space plus answer.
    • 0:47:25And now let me go ahead and run this.
    • 0:47:26Python, of Hello.py, all right, it's asking me what's my name.
    • 0:47:29David.
    • 0:47:30Hello comma David.
    • 0:47:31But it's worth calling attention to the fact that I've also simplified further.
    • 0:47:36It's not just that the individual functions are simpler.
    • 0:47:38What is also now glaringly omitted from my Python code at right,
    • 0:47:42both in this version, and the previous version.
    • 0:47:44What did I not bother implementing?
    • 0:47:46AUDIENCE: The main code.
    • 0:47:47DAVID J. MALAN: Yeah, so I didn't even need to implement main.
    • 0:47:49We'll revisit the main function, because having a main function
    • 0:47:53actually does solve problems sometimes.
    • 0:47:54But it's no longer required.
    • 0:47:56In C you have to have that to kick-start the entire process of actually running
    • 0:47:59your code.
    • 0:48:00And in fact, if you were missing main, as you might have experienced
    • 0:48:03if you accidentally compiled Helpers.c instead of the file
    • 0:48:06that contained main, you would have seen a compiler error.
    • 0:48:08In Python it's not necessary.
    • 0:48:09In Python you can just jump right in, start programming, and boom,
    • 0:48:12you're good to go.
    • 0:48:13Especially if it's a small program like this,
    • 0:48:15you don't need the added overhead or complexity of a main function.
    • 0:48:18So that's one other difference here.
    • 0:48:19All right, there are a few other ways we could say Hello, world.
    • 0:48:23Recall that I could use a format string.
    • 0:48:26So I could put this whole thing in quotes, I could use this f prefix.
    • 0:48:30And then let me go ahead and run Python of Hello.py again.
    • 0:48:33You can perhaps see where we're going with this.
    • 0:48:35Let me type my name, David, and here we go.
    • 0:48:37OK, that's the mistake that someone identified earlier,
    • 0:48:39you need the curly braces.
    • 0:48:41Otherwise no variables are interpolated, that is substituted,
    • 0:48:44with their actual values.
    • 0:48:46So if I go back in and add those curly braces to the F string,
    • 0:48:50now let me run Python of Hello.py, type in my name, and there we go.
    • 0:48:54We're back in business.
    • 0:48:55Which one's better?
    • 0:48:56I mean, it depends.
    • 0:48:57But generally speaking, making shorter, more concise code
    • 0:49:00tends to be a good thing.
    • 0:49:01So stylistically, the F string is probably a reasonable instinct to have.
    • 0:49:06All right, well, what more can we do besides this?
    • 0:49:09Well, let me go ahead here and let's get rid of the training wheel
    • 0:49:12altogether, actually.
    • 0:49:13So same C code at left.
    • 0:49:15Let me get rid of the CS50 library, which we will ultimately,
    • 0:49:18in a couple of weeks, anyway.
    • 0:49:19I can't use getString, but I can use a function
    • 0:49:22that comes with Python called input.
    • 0:49:24And, in fact, this is actually a one-for-one substitution, pretty much.
    • 0:49:28There's really no downside to using input instead of getString.
    • 0:49:31We implement getString just for consistency
    • 0:49:33with what you saw in C. Python of Hello.py, what's your name, David.
    • 0:49:37Still actually works the same.
    • 0:49:39So gone are the CS50 specific training wheels.
    • 0:49:41But we're going to bring them back shortly, just
    • 0:49:43to deal with integers or floats or other values,
    • 0:49:45too, because it's going to make our lives a little simpler,
    • 0:49:47with error checking.
    • 0:49:48All right, any questions, before we now pivot to revisiting other examples
    • 0:49:52from week 1, but now in Python?
    • 0:49:56All right, let me go ahead and open up now.
    • 0:49:58Let's say Calculator0.c, which was one of the first examples we did involving
    • 0:50:03math and operators like that, as well as functions like getInt,
    • 0:50:06let me go ahead and create a new file now called Calculator.py,
    • 0:50:11at right, so that I have my C code at left still,
    • 0:50:15and my Python code at right.
    • 0:50:16All right, let me go dive into a translation of this code into Python.
    • 0:50:20I am going to use getInt from the CS50 library.
    • 0:50:23So let me import that.
    • 0:50:24I'm going to go ahead now and get an Int from the user.
    • 0:50:27So x equals getInt, and I'll ask them for an x value,
    • 0:50:31just like we did weeks ago.
    • 0:50:32No need to specify a semicolon, though, or an Int for the x.
    • 0:50:37It will just figure it out.
    • 0:50:38Y is going to get another Int via y colon,
    • 0:50:42and then down here, I'm going to go ahead and say print of x plus y.
    • 0:50:46So this is already a bit new.
    • 0:50:48Recall, the C version required that I use this format string, as well
    • 0:50:53as printf itself.
    • 0:50:54Python is just a little more user-friendly.
    • 0:50:56If all you want to do is print out a value, like x plus y, just print it.
    • 0:50:59Don't futz with any percent signs or format codes.
    • 0:51:02It's not printf, it's indeed just print now.
    • 0:51:05All right, let me go ahead and run Python of Calculator.py,
    • 0:51:08Enter, just do a quick sample, 1 plus 2 indeed equals 3.
    • 0:51:13As an aside, suppose I had taken a different approach
    • 0:51:16to importing the whole CS50 library, functionally, it's the same.
    • 0:51:19You're not to notice any performance impact here.
    • 0:51:21It's a small library.
    • 0:51:22But notice what does not work now, whereas it did work
    • 0:51:25in C. Python of Calculator.py, Enter, we see our first traceback deliberately
    • 0:51:31here.
    • 0:51:31So a traceback is just a term of art that
    • 0:51:33says, here is a trace back through all of the functions
    • 0:51:37that just got executed.
    • 0:51:38In the world of C, you might call this a stack
    • 0:51:40trace, stack being the operative word.
    • 0:51:42Recall that when we talked about the stack and the heap,
    • 0:51:45the stack, like a stack of trays, was all of the functions that
    • 0:51:48might get called, one after the other.
    • 0:51:49We had main, we had swap, then swap went away, and then main finished, recall.
    • 0:51:54So here's a trace back of all of the functions or code that got executed.
    • 0:51:58There's not really any functions other than my file itself.
    • 0:52:00Otherwise there'd be more detail.
    • 0:52:02But even though it's a little cryptic, we can perhaps infer from the output
    • 0:52:05here, name error, so something related to the name of something, name, getInt
    • 0:52:09is not defined.
    • 0:52:10And this of course, happens on line 3 over there.
    • 0:52:14All right, so why is that?
    • 0:52:15Well, Python essentially allows us to namespace
    • 0:52:19our functions that come from libraries.
    • 0:52:21There was a problem in C. If you were using the CS50 library,
    • 0:52:25and thus had access to getInt, getString,
    • 0:52:27and so forth, you could not use another library
    • 0:52:29that had the same function names.
    • 0:52:31They would collide, and the compiler would not
    • 0:52:33know how to link them together correctly.
    • 0:52:36In Python, and other languages like JavaScript, and in Java,
    • 0:52:41you have support for effectively what would be called namespaces.
    • 0:52:45You can isolate variables and function names to their own namespace,
    • 0:52:50like their own container in memory.
    • 0:52:52And what this means is, if you import all of CS50,
    • 0:52:55you have to say that the getInt you want is inside the CS50 library.
    • 0:52:59So just like with the image blurring, and the image edges
    • 0:53:03before, where I had to specify image dot and image filter dot, similarly here,
    • 0:53:08am I specifying with a dot operator, albeit a little differently, that I
    • 0:53:11want CS50.getInt in both places.
    • 0:53:14And now if I rerun Python of Calculator.py, 1 and 2,
    • 0:53:18now we're back in business.
    • 0:53:19Which one is better?
    • 0:53:20Generally speaking, it depends on just how many functions
    • 0:53:24you're using from the library.
    • 0:53:26If you're using a whole bunch of functions, just import the whole thing.
    • 0:53:29If you're only using maybe one or two, import them line by line.
    • 0:53:33All right, so let's go ahead and make a little tweak here.
    • 0:53:35Let's get rid of this library and take this training wheel off,
    • 0:53:38too, as quickly as we introduced it, though for the problems set six
    • 0:53:41you'll be able to use all of these same functions.
    • 0:53:44Suppose I get rid of this, and I just use the input function,
    • 0:53:48just like I did by replacing getString earlier.
    • 0:53:51Let me go ahead now and run this version of the code.
    • 0:53:54Python of Calculator.py, OK, how about 1 plus 2 equals 3.
    • 0:54:00Huh.
    • 0:54:02All right, obviously wrong, incorrect.
    • 0:54:05Can anyone explain what just happened, based on instincts?
    • 0:54:09What just happened here.
    • 0:54:10Yeah.
    • 0:54:11AUDIENCE: You want an answer?
    • 0:54:12DAVID J. MALAN: Sure, yeah.
    • 0:54:13AUDIENCE: Say you have a number of strings that don't have Ints,
    • 0:54:17so you would part with them and say, printing one, two, better.
    • 0:54:21DAVID J. MALAN: Exactly, Python is interpreting, or treating,
    • 0:54:24both x and y as strings, which is actually
    • 0:54:26what the input function returns by default.
    • 0:54:29And so plus is now being interpreted as concatenation, as we defined it
    • 0:54:32earlier.
    • 0:54:32So x plus y isn't x plus y mathematically,
    • 0:54:35but in terms of string joining, just like in Scratch.
    • 0:54:38So that's why we're getting 12, or really one two,
    • 0:54:41which isn't itself a number.
    • 0:54:43It, too, is another string.
    • 0:54:44So we somehow need to convert things.
    • 0:54:45And we didn't have this ability quite as easily in C.
    • 0:54:49We did have like the A to i function, ASCII to integer,
    • 0:54:52which did allow you to do this.
    • 0:54:54The analog in Python is actually just to do a cast, a typecast, using Int.
    • 0:54:59So just like in C, you can use the keyword Int,
    • 0:55:02but you use it a little differently.
    • 0:55:04Notice that I'm not doing parenthesis Int close parenthesis before the value.
    • 0:55:09I'm using Int as a function.
    • 0:55:11So indeed, in Python, Int is a function.
    • 0:55:13Float is a function, that you can pass values into,
    • 0:55:16to do this kind of conversion.
    • 0:55:18So now, if I run Python of Calculator.py, 1 and 2,
    • 0:55:22now we're back in business, and getting the answer of 3.
    • 0:55:25But there's kind of a catch here.
    • 0:55:27There's always going to be a trade-off.
    • 0:55:28Like that sounds amazing that it just works in this way.
    • 0:55:30We can throw away the CS50 library already.
    • 0:55:32But what if the user accidentally types, or maliciously types in,
    • 0:55:37like a cat, instead of a number.
    • 0:55:39Damn, well, there's one of these trace backs.
    • 0:55:40Like, now my program has crashed.
    • 0:55:42This is similar in spirit to the kinds of segfaults
    • 0:55:45that you might have had in C.
    • 0:55:46But they're not segfaults per se.
    • 0:55:47It doesn't necessarily relate to memory.
    • 0:55:49This time it relates to actual runtime values, not being as expected.
    • 0:55:55So this time it's not a name error, it's a value error,
    • 0:55:58invalid literal for Int with base 10 quote unquote "cat."
    • 0:56:02So, again, it's written for sort of a programmer, more than sort
    • 0:56:06of a typical person, because it's pretty arcane, the language here.
    • 0:56:09But let's try to interpret it.
    • 0:56:10Invalid literal, a literal is just something someone typed for Int, which
    • 0:56:14is the function name, with base 10.
    • 0:56:16It's just defaulting to decimal numbers.
    • 0:56:18Cat is apparently not a decimal number.
    • 0:56:20It doesn't look like it, therefore it can't be treated like it.
    • 0:56:23Therefore, there's a value error.
    • 0:56:24So what can we do?
    • 0:56:26Unfortunately, you would have to somehow catch this error.
    • 0:56:30And the only way to do that in Python really
    • 0:56:32is by way of another feature that C did not have,
    • 0:56:34namely, what are called exceptions.
    • 0:56:37An exception is exactly what just happened, name error, value error.
    • 0:56:42They are things that can go wrong when your Python code is running,
    • 0:56:45that aren't necessarily going to be detected until you run your code.
    • 0:56:50So in Python, and in JavaScript, and in Java, and other more modern languages,
    • 0:56:56there's this ability to actually try to do something,
    • 0:56:59except if something goes wrong.
    • 0:57:01And in fact, I'm going to introduce a bit of syntax
    • 0:57:03here, even though we won't have to use this much just yet.
    • 0:57:05Instead of just blindly converting x to an Int, let me go ahead
    • 0:57:09and try to do that.
    • 0:57:11And if there's an exception, go ahead and say something
    • 0:57:15like print, that is not an Int.
    • 0:57:22And then I'm going to do something like exit, right there.
    • 0:57:25And let me go ahead and do this here.
    • 0:57:27Let me try to get y, except if there's an exception.
    • 0:57:31Then let me go ahead and say, again, that is not an Int exclamation point.
    • 0:57:35And then I'm going to exit from there to, otherwise I'll
    • 0:57:38go ahead and print x plus y.
    • 0:57:39If I run Python of Calculator.py now, whoops, oh,
    • 0:57:46forgot my close quote, sorry.
    • 0:57:48All right, so close quote, Python of Calculator.py, 1 and 2 still work.
    • 0:57:54But if I try to type in something wrong like cat, now
    • 0:57:57it actually detects the error.
    • 0:57:59So what is the CS50 library in Python doing?
    • 0:58:01It's actually doing that try and accept for you, because suffice it to say,
    • 0:58:05otherwise your programs for something simple, like a calculator,
    • 0:58:08start to get longer and longer.
    • 0:58:09So we factored that kind of logic out to the CS50 getInt
    • 0:58:13function and get float function.
    • 0:58:14But underneath the hood, they're essentially doing this, try except,
    • 0:58:18but they're being a little more precise.
    • 0:58:20They're detecting a specific error, and they are doing it in a loop,
    • 0:58:24so that these functions will get executed again and again.
    • 0:58:27In fact, the best way to do this is to say except if there's a value error,
    • 0:58:30then print that error message out to the user.
    • 0:58:34And again, let's not get too into the weeds here with this feature.
    • 0:58:36We've already put into the CS50 library.
    • 0:58:38But that's why, for instance, we bootstrap things,
    • 0:58:41by just using these functions out of the box.
    • 0:58:44All right, let's do something more with our calculator here.
    • 0:58:47How about this.
    • 0:58:49In the world of C, we had another version
    • 0:58:51of this code, which actually did some division by way of--
    • 0:58:56which actually did division of numbers, not just the addition herein.
    • 0:59:01So let me go ahead and close the C version, and let's focus only on Python
    • 0:59:05now, doing some of these same lines of codes.
    • 0:59:07But I'm going to go ahead and just assume
    • 0:59:09that the user is going to cooperate and use proper input.
    • 0:59:12So from CS50, import getInt, that will deal with any errors for me.
    • 0:59:16X gets getInt, ask the user for an Int x, y equals getInt,
    • 0:59:23ask the user for an Int y.
    • 0:59:25And then, let's go ahead and do this.
    • 0:59:27Let's declare a variable called z, set it equal to x divided by y.
    • 0:59:31Then let's go ahead and print z.
    • 0:59:32Still no need for a format string, I can just print out the variable's value.
    • 0:59:37Let me go ahead and run Python of Calculator.py.
    • 0:59:39Let me do 1, 10, and I get 0.1.
    • 0:59:43What did I get in C, though, if you think back.
    • 0:59:49What would we have happened in C?
    • 0:59:52AUDIENCE: Zero?
    • 0:59:53DAVID J. MALAN: Yeah, we would have gotten zero in C.
    • 0:59:55But why, in C, when you divide one Int by another,
    • 0:59:57and those Ints are like 1 and 10 respectively?
    • 0:59:59AUDIENCE: It'll give you an integer back.
    • 1:00:01DAVID J. MALAN: It will give you what?
    • 1:00:03AUDIENCE: An integer back.
    • 1:00:04DAVID J. MALAN: It will give you an integer back, and, unfortunately, 0.1,
    • 1:00:07the integer part of it is indeed zero.
    • 1:00:09So this was an example of truncation.
    • 1:00:11So truncation was an issue in C. But it would
    • 1:00:14seem as though this is no longer a problem in Python,
    • 1:00:17insofar as the division operator actually handles that for us.
    • 1:00:21As an aside, if you want the old behavior, because it actually
    • 1:00:24is sometimes useful for rounding or flooring values,
    • 1:00:27you can actually use two slashes.
    • 1:00:29And now you get the C behavior.
    • 1:00:31So that now 1 divided by 10 is zero.
    • 1:00:33So you don't give up that capability, but at least it
    • 1:00:36does a more sensible default.
    • 1:00:37Most people, especially new programmers, when dividing one value by another,
    • 1:00:41would want to get 0.1, not 0, for reasons
    • 1:00:44that indeed we had to explain weeks ago.
    • 1:00:46But what about another problem we had with the world of floats before,
    • 1:00:49whereby there is imprecision?
    • 1:00:52Let me go ahead and, somewhat cryptically, print out the value of z
    • 1:00:54as follows.
    • 1:00:55I'm going to format it using an f-string.
    • 1:00:58And I'm going to go ahead and format, not just z, because this is essentially
    • 1:01:02the same thing.
    • 1:01:03Notice this, if I do Python of Calculator.py, 1 and 10,
    • 1:01:06I get, by default, just one significant digit.
    • 1:01:09But if I use this syntax in Python, which we won't have to use often,
    • 1:01:13I can actually do in C like I did before,
    • 1:01:1650 significant digits after the decimal point.
    • 1:01:19So now let me rerun Python of Calculator.py 1 and 10,
    • 1:01:24and let's see if floating point imprecision is still with us.
    • 1:01:26Unfortunately, it is.
    • 1:01:28And you can see as much here, the f-string, the format string,
    • 1:01:30is just showing us now 50 digits instead of the default one.
    • 1:01:33So we've not solved all problems.
    • 1:01:36But we have solved at least some.
    • 1:01:38All right, before we pivot away from a mere calculator, any questions
    • 1:01:41now on syntax or concepts or the like?
    • 1:01:45Yeah.
    • 1:01:46AUDIENCE: Do you think the double slash you get
    • 1:01:49has merit, how do you comment on that?
    • 1:01:51DAVID J. MALAN: How do you what?
    • 1:01:53Oh, how do you comment.
    • 1:01:54Really good question, if you're using double slash for division
    • 1:01:57with flooring or truncation, like I described,
    • 1:01:59how do you do a comment in Python.
    • 1:02:01This is a comment.
    • 1:02:03And the convention is actually to use a complete sentence,
    • 1:02:05like with a capital T here.
    • 1:02:07You don't need a period unless there's multiple sentences.
    • 1:02:09And technically, it should be above the line of code by convention.
    • 1:02:12So you would use a hash symbol instead.
    • 1:02:15Good question.
    • 1:02:16I haven't seen those yet.
    • 1:02:17All right, let's go ahead and make something else here, how about.
    • 1:02:20Let me go ahead and open up, for instance,
    • 1:02:23an example called Points1.c, which we saw a few weeks back.
    • 1:02:29And let me go ahead on the other side and create a file called Points.py.
    • 1:02:33This was a program, recall, that asked the user how many points they
    • 1:02:36lost on the first assignment.
    • 1:02:39And then it went ahead and just printed out
    • 1:02:41whether they lost fewer points than me, because I lost two,
    • 1:02:43if you recall the photo, more points than me, or the same points as me.
    • 1:02:47Let me go ahead and zoom out so we can see a bit more of this.
    • 1:02:49And let me now, on the top right here, go about implementing this in Python.
    • 1:02:54So I want to first prompt the user for some number of points.
    • 1:02:56So from CS50 let's import getInt, so it handles the error-checking.
    • 1:03:00Let's then do points equals getInt, and ask
    • 1:03:03the user, how many points did you lose, question mark.
    • 1:03:07Then let's go ahead and say, if points less than two, which was my value,
    • 1:03:11print, you lost fewer points than me.
    • 1:03:15Otherwise, if it's else if points greater than 2, go ahead and print,
    • 1:03:23you lost more points than me.
    • 1:03:27Else let's go ahead and handle the final scenario, which is you
    • 1:03:30lost the same number of points as me.
    • 1:03:34Before I run this, does anyone want to point out a mistake I've already made?
    • 1:03:39Yeah.
    • 1:03:39AUDIENCE: Else if has to be elif.
    • 1:03:41DAVID J. MALAN: Yeah, so else if in C is actually now elif in Python.
    • 1:03:44It's a single word.
    • 1:03:45So let me change this to elif, and now cross my fingers, Python of Points.py,
    • 1:03:49suppose you lost three points on some assignment.
    • 1:03:53You lost more points than my two.
    • 1:03:55If you only lost one point, you lost fewer points than me.
    • 1:03:57So the logic is the same.
    • 1:03:58But notice the code is much tighter.
    • 1:04:01In 10 total lines, we did in what was 24 lines, because we've
    • 1:04:04thrown away a lot of the syntax.
    • 1:04:06The curly braces are no longer necessary.
    • 1:04:08The parentheses are gone, the semicolons.
    • 1:04:10So this is why it just tends to be more pleasant pretty quickly,
    • 1:04:13using a language like this.
    • 1:04:16All right, let's do one other example here.
    • 1:04:18In C, recall that we were able to determine the parity of some number,
    • 1:04:23if something is even or odd.
    • 1:04:24Well, in Python, let me go ahead and create a file called Parity.py,
    • 1:04:29and let's look for a moment at the C version at left.
    • 1:04:32Here was the code in C that we used to determine the parity of a number.
    • 1:04:36And, really, the key takeaway from all these lines
    • 1:04:39was just the remainder operator.
    • 1:04:41And that one is still with us.
    • 1:04:42So this is a simple demonstration, just to make that point,
    • 1:04:44if in Python, I want to determine whether a number is even or odd.
    • 1:04:48Well, let's go ahead and from CS50, import getInt, then let's go ahead
    • 1:04:53and get a number like n from the user, using getInt, and ask them for n.
    • 1:04:58And then let's go ahead and say, if n percent sign 2 equals 0,
    • 1:05:04then let's go ahead and print quote unquote "Even."
    • 1:05:08Else let's go ahead and print out Odd, but before I run this,
    • 1:05:13anyone want to instinctively, even though we've not talked about this,
    • 1:05:16point out a mistake here?
    • 1:05:19What I did wrong?
    • 1:05:19AUDIENCE: Double equals.
    • 1:05:20DAVID J. MALAN: Yeah, so double equals.
    • 1:05:22Again, so even though some of the stuff is changing, some of the same ideas
    • 1:05:25are the same.
    • 1:05:26So this, too, should be a double equal sign,
    • 1:05:28because I'm comparing for equality here.
    • 1:05:30And why is this the right math?
    • 1:05:32Well, if you divide a number by 2, it's either
    • 1:05:34going to have 0 or 1 as a remainder.
    • 1:05:36And that's going to determine if it's even or odd for us.
    • 1:05:39So let's run Python of Parity.py, type in a number like 50,
    • 1:05:42and hopefully we get, indeed, even.
    • 1:05:44So again, same idea, but now we're down to eight lines
    • 1:05:46of code instead of the 20.
    • 1:05:48Well, let's now do something a little more interactive
    • 1:05:50and a little representative of tools that actually ask the user questions.
    • 1:05:54In C, recall that we had this agreement program, Agree.c.
    • 1:06:00And then let's go ahead and implement a corresponding version in Python,
    • 1:06:04in a file called Agree.py.
    • 1:06:05And let's look at the C version first.
    • 1:06:08On the left, we used get char here.
    • 1:06:10And then we used the double vertical bars
    • 1:06:13to check if C is equal to capital Y or lowercase y.
    • 1:06:16And then we did the same thing for n for no.
    • 1:06:18And so let's go over here and let's do from CS50, import get--
    • 1:06:24OK, get char is not a thing.
    • 1:06:26And this here is another difference with Python.
    • 1:06:29There is no data type for individual characters.
    • 1:06:32You have strings, STRs, and, honestly, those
    • 1:06:34are fine, because if you have a STR that's
    • 1:06:36just one character, for all intents and purposes,
    • 1:06:38it is just a single character.
    • 1:06:40So it's just a simplification.
    • 1:06:41You don't have to think as much.
    • 1:06:43You don't have to worry about double quotes, single quotes.
    • 1:06:45In fact, in Python, you can use double quotes or single quotes,
    • 1:06:49so long as you're consistent.
    • 1:06:50So long as you're consistent, the single quotes
    • 1:06:52do not mean something different, like they do in C.
    • 1:06:55So I'm going to go ahead and use getString here,
    • 1:06:58although, strictly speaking, I could just use the input function,
    • 1:07:01as we saw before.
    • 1:07:02I'm going to get a string from the user that asks them this, getString,
    • 1:07:07quote unquote, "Do you agree," like a little checkbox or interactive prompt,
    • 1:07:10where you have to say yes or no, you want to agree to the following terms,
    • 1:07:13or whatnot.
    • 1:07:14And then let's translate the conditionals to Python, now, too.
    • 1:07:18So if S equals equals quote-unquote "Y," or S equals equals lowercase y,
    • 1:07:25let's go ahead and print out agreed, just like in C, elif S equals
    • 1:07:32equals N or S equals equals little n.
    • 1:07:35Let's go ahead, then, and print out not agreed.
    • 1:07:38And you can already see, perhaps, one of the differences here, too.
    • 1:07:40Is Python a little more English-like, in that
    • 1:07:43you just literally use the English word or, instead of the two vertical bars.
    • 1:07:47But it's ultimately doing the same thing.
    • 1:07:50Can we simplify this code a bit, though.
    • 1:07:53This would be a little annoying if we wanted
    • 1:07:55to add support, not just for big Y and little y,
    • 1:07:57but Yes or big Yes or little yes or big Y, lowercase e, capital S, right?
    • 1:08:04There's a lot of permutations of Y-E-S or just y,
    • 1:08:07that we ideally should tolerate.
    • 1:08:08Otherwise, the user is going to have to type exactly what we want,
    • 1:08:11which isn't very user-friendly.
    • 1:08:12Any intuition for how we could logically,
    • 1:08:15even if you don't know how to do it in code, make this better?
    • 1:08:18Yeah.
    • 1:08:18AUDIENCE: Write way over the list, and then up,
    • 1:08:21it's like the things in the list.
    • 1:08:22DAVID J. MALAN: Nice, yeah, we saw an example of a list before, just 0, 1, 2.
    • 1:08:27Why don't we take that same idea and ask a similar question.
    • 1:08:29If S is in the following list of values, Y or little y,
    • 1:08:34or heck, let me add to the list now, yes, or maybe all capital YES.
    • 1:08:38And it's going to get a little annoying, admittedly,
    • 1:08:40but this is still better than the alternative, with all the or's.
    • 1:08:43I could do things like this, and so forth.
    • 1:08:45There's a whole bunch more permutations.
    • 1:08:47But let's leave this alone, and let me just go into here
    • 1:08:50and change this to, if S is in the following list of N or little n or no,
    • 1:08:57and I won't do as, let's just not worry about the weird capitalizations
    • 1:09:00there, for now.
    • 1:09:01Let's go ahead and run this.
    • 1:09:02Python of Agree.py, do I agree?
    • 1:09:05Y. OK, how about yes?
    • 1:09:08All right, how about big Yes.
    • 1:09:10OK, that does not seem to work.
    • 1:09:11Notice it did not say agreed, and it did not say not agreed.
    • 1:09:14It didn't detect it.
    • 1:09:15So how can I do this?
    • 1:09:17Well, you know what I could do, what I don't really
    • 1:09:20need the uppercase and lowercase.
    • 1:09:22Let me tighten this list up a little bit.
    • 1:09:24And why don't I just force S to be lowercase.
    • 1:09:27S.lower, recall, whether it's one character or more,
    • 1:09:31is a function built into STRs now, strings in Python,
    • 1:09:34that forces the whole thing to lowercase.
    • 1:09:35So now, watch what I can do.
    • 1:09:37Python of Agree.py, little y, that works, big Y, that works.
    • 1:09:42Big Yes, that works, big Y, little e, big S, that also works.
    • 1:09:47So we've now handled, in one fell swoop, a whole bunch more logic.
    • 1:09:50And you know what, we can tighten this up a bit.
    • 1:09:52Here's an opportunity, in Python, for slightly better design.
    • 1:09:56What have I done in here that's a little redundant?
    • 1:10:00Does anyone see an opportunity to eliminate a redundancy,
    • 1:10:04doing something more times than you need.
    • 1:10:06Is a stretch here, no.
    • 1:10:08Yep.
    • 1:10:08AUDIENCE: You can do S dot lower, above.
    • 1:10:11DAVID J. MALAN: We could move the S dot lower above.
    • 1:10:13Notice that I'm using S dot lower twice.
    • 1:10:15But it's going to give me the same answer both times.
    • 1:10:17So I could do a couple of things here.
    • 1:10:20I could, first of all, get rid of this lower, and get rid of this lower,
    • 1:10:24and then above this, maybe I could do something like this, S equal--
    • 1:10:28I can't just do this, because that throws the value away.
    • 1:10:31It does the math, but it doesn't convert the string itself.
    • 1:10:34It's going to return a value.
    • 1:10:35So I have to say S equals s.lower.
    • 1:10:38I could do that.
    • 1:10:39Or, honestly, I can chain these things together.
    • 1:10:41And this is not something we saw in C. If getString returns a string,
    • 1:10:46and strings have functions like lower in them,
    • 1:10:49you can chain these functions together, like this, and do dot this,
    • 1:10:52dot that, dot this other thing.
    • 1:10:53And eventually you want to stop, because it's going to become crazy long.
    • 1:10:56But this is reasonable, still fits on the screen.
    • 1:10:58It's pretty tight.
    • 1:10:59It does in one place what I was doing in two.
    • 1:11:01So I think that's OK.
    • 1:11:03Let me go ahead and do Python of Agree.py one last time.
    • 1:11:05Let's try it one last time.
    • 1:11:07And it's still working as intended.
    • 1:11:10Also if I tried those other inputs as well.
    • 1:11:12Yeah, question.
    • 1:11:13AUDIENCE: Could you add on like a for uppercase as well, for like upper,
    • 1:11:19and then cover all the functions where it's lowercase, for all the functions
    • 1:11:22where it's uppercase as well, or could you not just do this again.
    • 1:11:29DAVID J. MALAN: Let me summarize.
    • 1:11:30Could we handle uppercase and lowercase together in some form?
    • 1:11:33I'm actually doing that already.
    • 1:11:35I just have to pick a lane.
    • 1:11:36I have to either be all lowercase in my logic or all uppercase,
    • 1:11:39and not worry about what the human types in,
    • 1:11:41because no matter what the human types in, I'm
    • 1:11:43forcing their input to lowercase.
    • 1:11:44And then I am using a lowercase list of values.
    • 1:11:48If I want to flip that, fine.
    • 1:11:49I just have to be self-consistent.
    • 1:11:51But I'm handling that already.
    • 1:11:52Yeah.
    • 1:11:53AUDIENCE: Are strings no longer an array of characters?
    • 1:11:56DAVID J. MALAN: A really good loaded questions
    • 1:11:58are strings no longer an array of characters?
    • 1:12:02Conceptually, yes, underneath the hood, no.
    • 1:12:04They're a little more sophisticated than that,
    • 1:12:06because with strings, you have a few changes.
    • 1:12:08Not only do they have functions built into them,
    • 1:12:10because strings are now what we call objects,
    • 1:12:12in what's called object-oriented programming.
    • 1:12:14And we're going to keep seeing examples of this dot operator.
    • 1:12:17They are also immutable, so to speak, I-M-M-U-T-A-B-L-E.
    • 1:12:21Immutable means they cannot be changed, which means, unlike C,
    • 1:12:25you can't go into a string and change its individual characters.
    • 1:12:28You can make a copy of the string that makes a change,
    • 1:12:31but you can't change the original string itself.
    • 1:12:33This is both a little annoying, maybe, sometimes.
    • 1:12:35But it's also pretty protective, because you can't do screw-ups
    • 1:12:38like I did weeks ago, when I was trying to copy S and call it T.
    • 1:12:41And then one affected the other.
    • 1:12:43Python, underneath the hood, is handling all of the memory management
    • 1:12:47and the pointers and all of that.
    • 1:12:48There are no pointers in Python.
    • 1:12:51So If that wasn't clear, all of that pain, if you will, all of that power,
    • 1:12:55is now handled by the language itself, not by us, the programmers.
    • 1:13:00All right, so let's introduce maybe some loops,
    • 1:13:02like we've been in the habit of doing.
    • 1:13:04Let me open up Meow.c, which was an example in C, just meowing
    • 1:13:08a bunch of times textually.
    • 1:13:09Let me create a file called Meow.py here on the right.
    • 1:13:12And notice on the left, this was correct code in C,
    • 1:13:15but it was kind of poorly designed.
    • 1:13:16Why?
    • 1:13:17Because it was a missed opportunity for a loop.
    • 1:13:19Why say something three times when you can say it just once?
    • 1:13:22So in Python, let me do it the poorly designed way first.
    • 1:13:25Let me print out meow.
    • 1:13:27And, like I generally should not, let me copy, paste it three times,
    • 1:13:31run Python of Meow.py, and it works.
    • 1:13:33OK, but not good practice.
    • 1:13:35So let me go ahead and improve this a little bit.
    • 1:13:37And there's a few ways to do this.
    • 1:13:38If I wanted to do this three times, I could instead do something like this.
    • 1:13:44For i in range of 3, recall that that was the better version,
    • 1:13:48rather than arbitrarily enumerate numbers yourself, let me go ahead
    • 1:13:51and print out quote unquote "Meow."
    • 1:13:53Now if I run Python of Meow, still seems to work.
    • 1:13:56So it's a little tighter, and, my God, like,
    • 1:13:57programs can't really get much shorter than this.
    • 1:13:59We're down to two lines of code, no main function, no gratuitous syntax.
    • 1:14:04Let's now improve the design further, like we
    • 1:14:06did in C, by introducing a function called
    • 1:14:09meow, that actually does the meowing.
    • 1:14:11So this was our first abstraction, recall,
    • 1:14:13both in Scratch and in C. Let me focus now entirely on the Python version
    • 1:14:18here.
    • 1:14:18Let me go ahead and first define a function.
    • 1:14:26Let me first go ahead and do this, for i in range of 3,
    • 1:14:30let's assume for the moment that there's a meow function,
    • 1:14:33that I'm just going to call.
    • 1:14:34Let's now go ahead and define, using the Def key word, which we saw briefly
    • 1:14:38with the speller demonstration, a function
    • 1:14:41called meow that takes no arguments.
    • 1:14:42And all it does for now is print meow.
    • 1:14:45Let me now go ahead and run Python of Meow.py Enter, huh, one
    • 1:14:50of those trace backs.
    • 1:14:51So this is another name error.
    • 1:14:54And, again, name meow is not defined.
    • 1:14:57What's your instinct here, even though we've not
    • 1:14:59tripped over this yet in Python?
    • 1:15:00Where does your mind go here?
    • 1:15:03Yeah.
    • 1:15:03AUDIENCE: Does it read top to bottom, left to right?
    • 1:15:06I'm guessing we could find a new case.
    • 1:15:09DAVID J. MALAN: Perfect, as smart, as smarter as Python seems to be,
    • 1:15:13it still makes certain assumptions.
    • 1:15:14And if it hasn't seen a keyword yet, it just doesn't exist.
    • 1:15:18So if you want it to exist, we have to be a little clever here.
    • 1:15:21I could just put it, flip it around, like this.
    • 1:15:24But this honestly isn't particularly good design.
    • 1:15:26Why?
    • 1:15:26Because now, if you, the reader of your code, whether you
    • 1:15:30wrote it or someone else, you kind of have to go fishing now.
    • 1:15:32Like where does this program begin?
    • 1:15:34And even though, yes, it's obvious that it begins on line four, logically,
    • 1:15:38like, if the file were longer, you're going to be annoyed
    • 1:15:40and fishing visually for the right lines of code.
    • 1:15:43So let's reintroduce main.
    • 1:15:44And indeed, this would be a common paradigm.
    • 1:15:46When you want to start having abstractions in your own functions,
    • 1:15:49just put your own code in main, so that, one, you can leave it up top, and two,
    • 1:15:53you can solve the problem we just encountered.
    • 1:15:55So let me define a function called main that has that same loop,
    • 1:15:58meowing three times.
    • 1:16:00But now watch what happens.
    • 1:16:02Let me go into my terminal and run Python of Meow.py, Enter.
    • 1:16:07Nothing.
    • 1:16:10All right, investigate this.
    • 1:16:14What could explain this symptom.
    • 1:16:16I have not told you the answer yet.
    • 1:16:18So all you have is your instinct, assuming
    • 1:16:19you've never touched Python before.
    • 1:16:21What might explain this symptom, where nothing is meowing?
    • 1:16:26Yeah?
    • 1:16:27AUDIENCE: Didn't run the main function.
    • 1:16:28DAVID J. MALAN: Yeah, I didn't run the main function.
    • 1:16:31So in C, this is functionality you get for free.
    • 1:16:33You have to have a main function.
    • 1:16:34But, heck, so long as you make it, it will be called for you.
    • 1:16:37In Python, this is just a convention, to create a main function,
    • 1:16:41borrowing a very common name for it.
    • 1:16:43But if you want to call that main function, you have to do it.
    • 1:16:46So this looks a little weird, admittedly,
    • 1:16:48that you have to call your own main function now,
    • 1:16:50and it has to be at the bottom of the file,
    • 1:16:51because only once the interpreter gets to the bottom of the file,
    • 1:16:55have all of your functions been defined, higher up.
    • 1:16:58But this solves both problems.
    • 1:16:59It keeps your code, that's the main part of your code,
    • 1:17:02at the very top of the file.
    • 1:17:03So it's just obvious to you, and a TF, or any reader in the future,
    • 1:17:06where the program logically starts.
    • 1:17:09But it also ensures that main is not called until everything else, main
    • 1:17:13included, has been defined.
    • 1:17:15So this is another perfect example of we're
    • 1:17:17learning a new language for the first time.
    • 1:17:19You're not going to have heard all of the answers before.
    • 1:17:21Just apply some logic, as to, like, all right, what could explain this symptom.
    • 1:17:24Start to infer how the language does or doesn't work.
    • 1:17:28If I now go and run this, Python of Meow.py, now we're back in business.
    • 1:17:32And just so you have seen it, there is a quote
    • 1:17:35unquote "better" way of doing this, that solves different problems that we
    • 1:17:38are not going to encounter, certainly in these initial days.
    • 1:17:42Typically, you would see in online tutorials or books,
    • 1:17:45something that looks like this, where you actually have a weird conditional
    • 1:17:49with multiple underscores.
    • 1:17:50That's functionally the same thing, but it solves problems with libraries,
    • 1:17:54if we ourselves were implementing a library or something similar in spirit.
    • 1:17:57But we're going to keep things simpler and just write main at the bottom,
    • 1:18:00because we're not going to encounter that problem just yet.
    • 1:18:03All right, let's make one change to this, just to show how it's done.
    • 1:18:06In C, the last version of meow also took command line argument, sorry, also
    • 1:18:11took arguments to the function meow.
    • 1:18:13So suppose that I want to factor this out.
    • 1:18:16And I want to just call meow as a better abstraction, where I just
    • 1:18:19say meow this number of times.
    • 1:18:21And I figure out how many times by just, like, putting in number 3
    • 1:18:24or using getInt or something like that, to figure out
    • 1:18:26how many times to say meow.
    • 1:18:28Well, now, I have to define inside my meow function, in input,
    • 1:18:31let's call it n, and then use that, as by doing this, for i in range of n,
    • 1:18:38let me go ahead and print out meow that many times.
    • 1:18:41So again, the only thing that's different in C
    • 1:18:43is we don't bother specifying return types for any of these functions,
    • 1:18:47and we don't bother specifying the type of our arguments or our variables.
    • 1:18:52So same ideas, simpler in some sense.
    • 1:18:54We're just throwing away keystrokes.
    • 1:18:56All right, let me run this one final time, Python of Meow.py,
    • 1:18:59and we still have the same program.
    • 1:19:02All right, let me pause here.
    • 1:19:04Any questions?
    • 1:19:04And I know this is going fast.
    • 1:19:06But hopefully, the C code is still somewhat familiar.
    • 1:19:11Yeah.
    • 1:19:11AUDIENCE: Is there any difference between global and local variables.
    • 1:19:17DAVID J. MALAN: Good question.
    • 1:19:18Is there any difference between global and local variables?
    • 1:19:21Short answer, yes, and we would run into that same problem,
    • 1:19:23if we declare a variable in one function,
    • 1:19:25another function is not going to have access to it.
    • 1:19:27We can solve that by putting variables globally.
    • 1:19:30But we don't have all of the features we had in C,
    • 1:19:32like there's no such thing as a constant in Python.
    • 1:19:35The mentality in the Python community is,
    • 1:19:36if you don't want some value to change, don't touch it.
    • 1:19:39Like just don't screw up.
    • 1:19:40So there's trade-offs here, too.
    • 1:19:42Some languages are stronger or more defensive than that.
    • 1:19:45But that, too, is part of the mindset with this particular language.
    • 1:19:48[SIREN]
    • 1:19:49DAVID J. MALAN: Yeah.
    • 1:19:50AUDIENCE: There is really only one green line, in the--
    • 1:19:52DAVID J. MALAN: Oh, sorry, where's--
    • 1:19:54say it louder.
    • 1:19:55AUDIENCE: There has only been one green line printed at a time.
    • 1:19:58DAVID J. MALAN: That is an amazing segue.
    • 1:20:00Let's come to that in just a moment, because we're
    • 1:20:01going to recreate also that Mario example, where
    • 1:20:03we had like the question marks for the coins and the vertical bars.
    • 1:20:06So let's come back to that in a second.
    • 1:20:08And your question?
    • 1:20:09AUDIENCE: If strings are immutable, and every time you like make a copy.
    • 1:20:13DAVID J. MALAN: Correct, strings are immutable.
    • 1:20:15Any time you seem to be modifying it, as with the lower function,
    • 1:20:19you're getting back a copy.
    • 1:20:20So it's taking a little more memory somewhere.
    • 1:20:22But you don't have to deal with it Python's doing that for you.
    • 1:20:26AUDIENCE: So you don't free anything.
    • 1:20:28DAVID J. MALAN: Say it again?
    • 1:20:30You don't need what?
    • 1:20:31AUDIENCE: You don't free like taking leave on stuff.
    • 1:20:34DAVID J. MALAN: You don't free anything.
    • 1:20:36So if you weren't a big fan, over the past couple of weeks,
    • 1:20:38of malloc or free or memory or addresses, or all
    • 1:20:42of those low level implementation details,
    • 1:20:44Python is the language for you, because all of that
    • 1:20:47is handled for you automatically.
    • 1:20:49Java does the same.
    • 1:20:50JavaScript does the same.
    • 1:20:51Yeah.
    • 1:20:52AUDIENCE: Each up for the variable, you put it before the name, use of the body
    • 1:20:58before the name, correct?
    • 1:20:59Well, if there isn't a main function in Python, how do you define those words?
    • 1:21:03DAVID J. MALAN: How do you define a global variable
    • 1:21:05if there's no main function in Python?
    • 1:21:07Global variables, by definition, always need to be outside of main, as well.
    • 1:21:11So that's not a problem.
    • 1:21:12If I wanted to have a function that's outside of,
    • 1:21:15and, therefore, global to all of these, like global--
    • 1:21:19actually, don't use the word global, that's a special word in Python--
    • 1:21:22variable equals Foo, F-O-O, just as an arbitrary string
    • 1:21:27value that a computer scientist would typically use, that is now global.
    • 1:21:31There are some caveats, though, as to how you access that.
    • 1:21:34But let's come back to that another time.
    • 1:21:36But that problem is solvable, too.
    • 1:21:38All right.
    • 1:21:38So let's go ahead and do this.
    • 1:21:39To come back to the question about the print command, let me go ahead
    • 1:21:43and create a file now called Mario.py.
    • 1:21:45Won't bother showing the C code anymore.
    • 1:21:47We'll focus just on the new language here.
    • 1:21:49But recall that, in Python, in Mario, we wanted to first do something like this.
    • 1:21:54This was a random screen from the side scroller version 1
    • 1:21:57of Super Mario Brothers.
    • 1:21:58And we just want to print like three hashes to represent those three blocks.
    • 1:22:02Well, in Python, we could do something like this,
    • 1:22:04print, oh, sorry, for i in the range of 3, go ahead and print out quote unquote
    • 1:22:11"hash."
    • 1:22:11And I think this is pretty straightforward.
    • 1:22:13Python of Mario.py, we get our three hashes.
    • 1:22:16You could imagine parameterizing this now, though,
    • 1:22:18and getting actual user input.
    • 1:22:20So let's do that.
    • 1:22:21Let me go up here and let me go and say from CS50, import getInt,
    • 1:22:27and then let's get the input from the user.
    • 1:22:31So it actually is a value n, like, all right,
    • 1:22:33getInt the height of the column of bricks that you want to do.
    • 1:22:38And then, let's go ahead and print out n hashes instead of three.
    • 1:22:42So let me run this.
    • 1:22:43Let's print out like five hashes.
    • 1:22:45OK, one, two, three, four, five, that seems to work, too.
    • 1:22:47And it's going to work for any positive value.
    • 1:22:49But it's not going to work for, how about negative 1?
    • 1:22:53That just doesn't do anything.
    • 1:22:54But that seems OK.
    • 1:22:55But also recall that it's not going to work if the user types in something
    • 1:22:58weird, like, oh, sorry, it is going to work if the user types in something
    • 1:23:03weird like cat, why?
    • 1:23:05We're using CS50's getInt function, which is
    • 1:23:08handling all of those headaches for us.
    • 1:23:11But, what if the user indeed types a negative number?
    • 1:23:15We're tolerating that.
    • 1:23:16So that was the bug I wanted to highlight.
    • 1:23:17It would be nice to re-prompt them and re-prompt them.
    • 1:23:20And in C, what was the programming construct we
    • 1:23:22used when we wanted to ask the user a question.
    • 1:23:25And then, if they didn't cooperate, prompt them again, prompt them again.
    • 1:23:29What was that?
    • 1:23:29Yeah.
    • 1:23:30AUDIENCE: Do while loop.
    • 1:23:30DAVID J. MALAN: Yeah, do while loop, right?
    • 1:23:32That was useful, because it's almost the same as a while loop.
    • 1:23:34But instead of checking a condition, and then doing something,
    • 1:23:38you do something and then check a condition,
    • 1:23:39which makes sense with user input, because what are you
    • 1:23:42even going to check if the user hasn't done anything yet?
    • 1:23:44You need that inverted logic.
    • 1:23:46Unfortunately in Python, there is no do while loop.
    • 1:23:50There is a for loop.
    • 1:23:51There is a while loop.
    • 1:23:52And frankly, those are enough to recreate this idea.
    • 1:23:55And the way to do this in Python, the Pythonic way, which
    • 1:23:59is another term of art in the community, is to say this.
    • 1:24:02Deliberately induce an infinite loop, while True, with capital T for true.
    • 1:24:06And then do what you got to do, like get an Int from a user,
    • 1:24:09asking them for the height of this thing.
    • 1:24:12And then, if that is what you want, like a number greater than zero, go ahead
    • 1:24:18and break out of the loop.
    • 1:24:20So this is how, in Python, you could recreate the idea of a do while loop.
    • 1:24:25You deliberately induce an infinite loop.
    • 1:24:27So something's going to happen at least once.
    • 1:24:29Then, if you get the answer you want, you break out of it,
    • 1:24:32effectively achieving the same logic.
    • 1:24:34So this is the Pythonic way of doing a do while loop.
    • 1:24:37Let me go ahead and run Python of Mario.py, type in 3 this time.
    • 1:24:41And now I get back just the 3 hashes as well.
    • 1:24:44What if, though, I wanted to get rid of, how about ultimately
    • 1:24:50that CS50 library function, and also encapsulate this in a function.
    • 1:24:55Well, let's go ahead and tweak this a little bit.
    • 1:24:57Let me go ahead and remove this temporarily.
    • 1:24:59Give myself a main function, so I don't make the same mistake
    • 1:25:01as I did initially earlier.
    • 1:25:03And let me give myself a function called get height that takes no arguments.
    • 1:25:07And inside of that function is going to be that same code.
    • 1:25:10But I don't want to break in this case, I want to return n.
    • 1:25:14So, recall, that if you return from a function, you're done,
    • 1:25:17you're going to exit from right at that point.
    • 1:25:19So this would be fine.
    • 1:25:20You can just say return n inside of the loop,
    • 1:25:22or, if you would prefer to break out, you
    • 1:25:25could do something like this instead.
    • 1:25:26Break, and then down here, you could return, down here,
    • 1:25:32you could return n as well.
    • 1:25:34And let me make one point here before we go back up to main.
    • 1:25:37This is a little different from C. And this one's subtle.
    • 1:25:41What have I done here that in C would have been a bug, but is apparently not,
    • 1:25:47I claim, in Python.
    • 1:25:50It's super subtle, this one.
    • 1:25:52Yeah.
    • 1:25:52AUDIENCE: So aren't we like defining mostly object,
    • 1:25:55like we're using it first, defining an object?
    • 1:25:59[INAUDIBLE]
    • 1:26:04DAVID J. MALAN: So similar, it's not quite that we're using it first.
    • 1:26:07So it's OK not to declare a variable with like the data type.
    • 1:26:10We've addressed that before, but on line 9, we're assigning n a value, it seems.
    • 1:26:15And then we return n on line 12.
    • 1:26:18But notice the indentation.
    • 1:26:20In the world of C, if we had declared a variable inside of a loop, on line 9,
    • 1:26:25it would have been scoped to that loop, which
    • 1:26:28means as soon as you get out of that loop, like further down in the program,
    • 1:26:31n would not exist.
    • 1:26:33It would be local to the curly braces therein.
    • 1:26:36Here, logically, curly braces are gone, but the indentation
    • 1:26:39makes clear that n is still inside of this loop, between lines 8 through 11.
    • 1:26:44But n is actually still in scope in Python.
    • 1:26:47The moment you create a variable in Python, for better or for worse,
    • 1:26:50It is available everywhere within that function, even outside
    • 1:26:53of the loop in which you defined it.
    • 1:26:55So this logic is actually OK in Python.
    • 1:26:59In C, recall, to solve this same problem,
    • 1:27:02we would have had to do something a little hackish like this,
    • 1:27:04like define n up here on line 8, so that it exists, now, on line 10,
    • 1:27:09and so that it exists on line 13.
    • 1:27:12That is no longer an issue or need, in Python.
    • 1:27:15Once you create a variable, even if it's nested,
    • 1:27:17nested, nested inside of some loops or conditionals,
    • 1:27:19it still exists within the function itself.
    • 1:27:23All right, any questions then on this, before we now run this and then get
    • 1:27:27rid of the CS50 library again?
    • 1:27:31OK, so let me go ahead and get the height from the user.
    • 1:27:34Let's go ahead and create a variable in main called height.
    • 1:27:36Let's call this get height function.
    • 1:27:38And then let's use that height value, instead of something hardcoded there.
    • 1:27:43And let me see if this all works now.
    • 1:27:45Python of Mario.py.
    • 1:27:46Hopefully, I haven't messed up, but I did.
    • 1:27:49But this is an easy fix now.
    • 1:27:51Yeah.
    • 1:27:51AUDIENCE: Got to call main.
    • 1:27:53DAVID J. MALAN: I got to call main.
    • 1:27:54So again, I deleted that earlier.
    • 1:27:55But let me bring it back.
    • 1:27:56So I'm actually calling main.
    • 1:27:58Let me rerun Python of Mario.py, there we go, height 3.
    • 1:28:02Now it seems to be working.
    • 1:28:03So let's do one last thing with Mario, just
    • 1:28:05to tie together that idea now of exceptions from before.
    • 1:28:08Again, exceptions are a feature of Python,
    • 1:28:11whereby you can try to do something.
    • 1:28:13And if there's a problem, you can handle it in any way you see fit.
    • 1:28:16Previously, I handled it by just yelling at the user that that's not an Int.
    • 1:28:20But let's actually use this to re-implement CS50's own getInt
    • 1:28:23function.
    • 1:28:24Let me throw away CS50's getInt function.
    • 1:28:27And now let me go ahead and replace getInt with input.
    • 1:28:32But it's not sufficient to just use input.
    • 1:28:35What do I have to add to this line of code on line 8?
    • 1:28:39If I want to get back an Int?
    • 1:28:40AUDIENCE: The Int function.
    • 1:28:41DAVID J. MALAN: Yeah, I have to cast it to an Int
    • 1:28:43by calling the Int function around that value,
    • 1:28:46or I could do it on a separate line, just to be clear.
    • 1:28:48I could also do n equals Int of n.
    • 1:28:52That would work too, but it's sort of an unnecessary extra line.
    • 1:28:55This is not sufficient, because that does not change the value.
    • 1:28:57It creates the value.
    • 1:28:58But then it throws it away.
    • 1:29:00We need to assign it.
    • 1:29:01So the conventional way to do this would probably be in one line,
    • 1:29:03just to keep things nice and tight.
    • 1:29:05So that works fine now.
    • 1:29:06If I run Python of Mario.py, I can still type in 3, and all as well.
    • 1:29:11I can still type in negative 1, because that is an Int that I am handling.
    • 1:29:15What I'm not yet handling is weird input like cat
    • 1:29:18or some string that is not a base 10 number.
    • 1:29:21So here, again, is my traceback.
    • 1:29:23And notice that here, let me scroll up a little bit,
    • 1:29:27here we can actually see more detail in the traceback.
    • 1:29:31Notice that, just like in C, or just like in the debugger in VS Code,
    • 1:29:36you can see a few things.
    • 1:29:38You can see mention of module, that just means your file, main, which
    • 1:29:41is my main function, and get height.
    • 1:29:43So notice, it's kind of backwards.
    • 1:29:44It's top to bottom instead of bottom up, as we drew it
    • 1:29:46on the board the other day, and as we envisioned
    • 1:29:48stacks of trays in the cafeteria.
    • 1:29:50But this is your stack, of functions that
    • 1:29:52have been called, from top to bottom.
    • 1:29:54Get height is the most recent, main is the very first,
    • 1:29:57value error is the problem.
    • 1:29:59So let's try to do, let's try to do this literally, except if there's an error.
    • 1:30:03So what do I want to do?
    • 1:30:04I'm going to go in here, and I'm going to say, try to do the following.
    • 1:30:09Whoops, try to do the following, except if there's a value error, value error,
    • 1:30:17then go ahead and say something, well, like before, print,
    • 1:30:20that's not an integer exclamation point.
    • 1:30:23But the difference this time is because I'm in a loop, the user
    • 1:30:26is going to have a chance to recover from this issue.
    • 1:30:29So if I run Mario.py, 3 still works as before.
    • 1:30:32If I run Mario.py and type in cat, I detect it now,
    • 1:30:35and because I'm still in that loop, and because the program hasn't crashed,
    • 1:30:39because I've caught, so to speak, the value error, using this line of code
    • 1:30:43here, that's the way in Python to detect these kinds of errors,
    • 1:30:46that would otherwise end up being on the user's own screen.
    • 1:30:49If I type in cat, dog, that doesn't work.
    • 1:30:51If I type in, though, 2, I get my two hashes, because that's, indeed, an Int.
    • 1:30:56Are any questions on this, and we're not going
    • 1:30:58to spend too much time on exceptions, but just wanted
    • 1:31:00to show you what's involved with getting rid of those training wheels.
    • 1:31:03Yeah.
    • 1:31:04AUDIENCE: Then the hash marks in line.
    • 1:31:05DAVID J. MALAN: OK, so let's do this.
    • 1:31:07That actually comes to the earlier question
    • 1:31:09about printing the hashes on the same line,
    • 1:31:11or maybe something like this, where we have the little bricks
    • 1:31:13in the sky, or little question marks.
    • 1:31:15Let's recreate this idea, because the problem with print,
    • 1:31:17as was noted earlier, is you're automatically printing out new lines.
    • 1:31:20But what if we don't want that.
    • 1:31:22Well, let's change this program entirely.
    • 1:31:24Let me throw away all the functions.
    • 1:31:26Let's just go to a simpler world, where we're just doing this.
    • 1:31:29So let me start fresh in Mario.py.
    • 1:31:30I'm not going to bother with exceptions or functions.
    • 1:31:33Let's just do a very simple program, to create this idea, for i in range of 4
    • 1:31:39this time, because there are four of these things in the sky.
    • 1:31:42Let's go ahead and just print out a question mark
    • 1:31:45to represent each of those bricks.
    • 1:31:47Odds are you know this not going to end well, because these are unfortunately,
    • 1:31:51as you've predicted, on separate lines.
    • 1:31:54So it turns out that the print function actually
    • 1:31:57takes in multiple arguments, not just the thing you want to print,
    • 1:32:00but also some additional arguments, that allow you to specify
    • 1:32:03what the default line ending should be.
    • 1:32:06But what's interesting about this is that, if you
    • 1:32:09want to change the line ending to be something like,
    • 1:32:12quote unquote, "that is nothing," instead of backslash n,
    • 1:32:16this is not sufficient, because in Python, you
    • 1:32:19can have two types of arguments, or parameters.
    • 1:32:21Some arguments are positional, which is the fancy way of saying it's
    • 1:32:25a comma separated list of arguments.
    • 1:32:26And that's what we did all the time in C. Something comma, something
    • 1:32:29comma, something, we did it in printf all the time,
    • 1:32:31and in other functions that took multiple arguments.
    • 1:32:33In Python, you have, not only positional arguments,
    • 1:32:37where you just separate them by commas, to give one or two or three or more
    • 1:32:41arguments.
    • 1:32:42There are also named arguments, which looks weird but is
    • 1:32:46helpful for reasons like this.
    • 1:32:48If you read the documentation, you will see
    • 1:32:50that there is a named argument that Python accepts, called end.
    • 1:32:54And if you set that equal to something, that
    • 1:32:57will be used as the end of every line, instead
    • 1:33:00of the default, which the documentation will also say
    • 1:33:02is quote unquote backslash n.
    • 1:33:04So this line here has no effect on my logic at the moment.
    • 1:33:09But if I change it to just quote unquote, essentially overriding
    • 1:33:13the default new line character, and now run Mario again, now I get all four
    • 1:33:18on the same line.
    • 1:33:19There's a bit of a bug, though.
    • 1:33:20My prompt is not meant to be on the same line.
    • 1:33:23So I can fix that by just printing nothing.
    • 1:33:25But, really, it's not nothing, because you get the new line for free.
    • 1:33:28So let me run Python of Mario.py again, and now we
    • 1:33:32have what I intended in the first place, which was a little something that
    • 1:33:36looked like this.
    • 1:33:37And this is just one example of an argument that has a name.
    • 1:33:40But this is a common paradigm in Python 2,
    • 1:33:43to not just separate things by commas, but to be very specific,
    • 1:33:46because the print function might take 5, 10, even 20 different arguments.
    • 1:33:50And my God, if you had to enumerate like 10 or 20 commas,
    • 1:33:54you're going to screw up.
    • 1:33:55You're going to get things in the wrong order.
    • 1:33:57Named arguments allow you to be resilient against that.
    • 1:34:00So you only specify arguments by name, and it
    • 1:34:02doesn't matter what order they are in.
    • 1:34:06All right, any questions, then, on this, and the overriding of new line.
    • 1:34:10And to be clear, you can do something like, very weird,
    • 1:34:14but logically expected, like this, by just changing the line ending, too.
    • 1:34:19But the right way to solve the Mario problem
    • 1:34:21would be just to override it to be nothing like this.
    • 1:34:25All right, how about this for cool.
    • 1:34:27And this is why a lot of people like Python.
    • 1:34:29Suppose you don't really like loops.
    • 1:34:30You don't really like three-line programs,
    • 1:34:31because that was kind of three times longer than it needs to be.
    • 1:34:34What if you just printed out a question mark four times?
    • 1:34:39Python, whoops, Python of Mario.py, that also works.
    • 1:34:43So it turns out that, just like the plus operator in Python
    • 1:34:46can join things together, the multiply operator is not
    • 1:34:50arithmetic in this case.
    • 1:34:51It actually means, take this and concatenate it four times over.
    • 1:34:56So that's a way of just distilling into one line what
    • 1:34:59would have otherwise taken multiple lines in C, fewer, but still multiple
    • 1:35:02lines in Python, but is really now rather succinct in Python,
    • 1:35:07by doing that instead.
    • 1:35:08Let's do one last Mario example, which looked a little something like this.
    • 1:35:11If this is another part of the Mario interface,
    • 1:35:14this is like a grid of like 3 by 3 bricks, for instance.
    • 1:35:16So two dimensions now, just not just vertical, not horizontal, but now both.
    • 1:35:20Let's print out something like that, using hashes.
    • 1:35:23Well, how about, how do I do this.
    • 1:35:26So how about for i in range of 3.
    • 1:35:29Then I could do for j in range of 3, just because j comes after I
    • 1:35:34and that's reasonable for counting.
    • 1:35:35I could now print out a hash symbol, well, let's see what this does.
    • 1:35:41Python of Mario.py, OK, that's just one crazy long column.
    • 1:35:47What do I need to fix and where here, to make this look like this?
    • 1:35:51So 3 by 3 bricks, instead of one long column.
    • 1:35:55Any instincts?
    • 1:35:56AUDIENCE: Why don't we create a line and then we'll skip it.
    • 1:36:00DAVID J. MALAN: OK, so after printing 3, we want to skip a line.
    • 1:36:03So maybe like print out a blank line here.
    • 1:36:05OK, let's try that.
    • 1:36:06I like that instinct, right, print 3, new line, print 3, new line.
    • 1:36:09Let's go ahead and run Python of Mario.py.
    • 1:36:12OK, it's more visible, what I'm doing, but still wrong.
    • 1:36:16What can I, what's the remaining fix, though?
    • 1:36:19Yeah.
    • 1:36:19AUDIENCE: So right behind the two.
    • 1:36:22DAVID J. MALAN: Yeah, I'm getting an extra new line here,
    • 1:36:25which I don't want while I'm on this row.
    • 1:36:27So let me do n equals quote unquote, and now, together, your solutions might
    • 1:36:31take us the whole way there.
    • 1:36:33Python of Mario.py, voila, now we've got it, in two dimensions.
    • 1:36:37And even this, we can tighten up.
    • 1:36:38Like, we could just use the little trick we learned.
    • 1:36:41So we could just say, print a hash times 3 times,
    • 1:36:45and we can get rid of one of those loops altogether.
    • 1:36:47All it's doing is, whoops, all it's doing is automating that process.
    • 1:36:50But, no, I don't want to do that.
    • 1:36:53What do I, how do I fix this here.
    • 1:36:54I don't think I want this anymore, right?
    • 1:36:56Because that's giving me an extra new line.
    • 1:36:58So now this program is really tightened up.
    • 1:37:01Same thing, two lines of code.
    • 1:37:03But we're now implementing this same two dimensional structure here.
    • 1:37:07All right, any questions here on these?
    • 1:37:10Yeah.
    • 1:37:10AUDIENCE: Is there any practical reason why when we write n, n is, I mean,
    • 1:37:16the print function, you don't put any spaces in it.
    • 1:37:19DAVID J. MALAN: If I print n, any spaces.
    • 1:37:22Say that once more.
    • 1:37:23AUDIENCE: Whenever we write n, for example,
    • 1:37:25the print function is, you know, in order
    • 1:37:28to stop it from going to a new line, it seems like any spaces,
    • 1:37:33we did like n equals and then too close.
    • 1:37:37There were no spaces.
    • 1:37:38Did you do that on purpose?
    • 1:37:40DAVID J. MALAN: Oh.
    • 1:37:42yes, good question.
    • 1:37:43I see what you're saying.
    • 1:37:44So in a previous version, let me rewind in time, when we had this,
    • 1:37:48I did not put spaces.
    • 1:37:49The convention in Python is not to do that.
    • 1:37:51Why?
    • 1:37:52It just starts to add too much space.
    • 1:37:54And this is a little inconsistent, because, earlier,
    • 1:37:56when we talked about like pluses or spaces
    • 1:37:58around the less than or equal signs, I did say add it.
    • 1:38:00Here it's actually clearer and recommended
    • 1:38:03to keep them tighter together.
    • 1:38:04Otherwise it just becomes harder to read where the gaps are.
    • 1:38:07Good observation.
    • 1:38:08All right, let's do, how about, another five minute break.
    • 1:38:14Let's do that.
    • 1:38:14And then we're going to dive into some more sophisticated problems,
    • 1:38:17and then ultimately build with some audio and visual examples, as well.
    • 1:38:21See you in five.
    • 1:38:23All right, so almost all of the examples we just did
    • 1:38:28were recreations of what we did in week 1.
    • 1:38:30And recall that week 1 was like our most syntax-heavy week.
    • 1:38:33It was when we were first learning how to program in C. But after week 1,
    • 1:38:36we began to focus a bit more on ideas, like arrays,
    • 1:38:39and other higher-level constructs.
    • 1:38:41And we'll do that again here, condensing some of those first early weeks
    • 1:38:44into a fewer set of examples in Python.
    • 1:38:47And we'll culminate by actually taking Python out for a spin,
    • 1:38:50and doing things that would be way harder to do,
    • 1:38:52and way more time-consuming to do in C, even more so than the speller example.
    • 1:38:56But how do you go about figuring out what functions exist,
    • 1:38:59if you didn't hear it in class, you don't see it online,
    • 1:39:02but you want to see it officially, you can go to the Python documentation,
    • 1:39:06docs.python.org here.
    • 1:39:08And I will disclaim that, honestly, the Python documentation is not
    • 1:39:11terribly user-friendly.
    • 1:39:12Google will often be your friend, so googling something
    • 1:39:15you're interested in, to find your way to the appropriate page on Python.org,
    • 1:39:19or StackOverflow.com is another popular website.
    • 1:39:22As always, though, the line should be googling
    • 1:39:24things like, how do I convert a string to lowercase.
    • 1:39:27Like that's reasonable to Google.
    • 1:39:29Or how to convert to uppercase or how implement function in Python.
    • 1:39:33But googling, of course, things like how to implement problem set 6 in CS50,
    • 1:39:37of course, crosses the line.
    • 1:39:39But moving forward, and really with programming in general, like Google
    • 1:39:42and Stack Overflow are your friends, but the line
    • 1:39:44is between the reasonable and the unreasonable.
    • 1:39:46So let me officially use the Python documentation search, just
    • 1:39:49to search for something like the lowercase function.
    • 1:39:52Like, I know I can lowercase things in Python.
    • 1:39:54I don't quite remember how.
    • 1:39:55So let me just search for the word lower.
    • 1:39:57You're going to get, often, an overwhelming number of results,
    • 1:40:00because Python is a pretty big language, with lots of functionality.
    • 1:40:03And you're going to want to look for familiar patterns.
    • 1:40:05For whatever reason, string.lower, which is probably
    • 1:40:09more popular or more commonly used than these other ones, is third on the list.
    • 1:40:12But it's purple, because I clicked it a moment ago, when looking for it.
    • 1:40:15So str.lower is probably what I want, because I
    • 1:40:18am interested at the moment in lower casing strings.
    • 1:40:21When I click on that, this is an example of what Python's documentation tends
    • 1:40:25to look like.
    • 1:40:25It's in this general format.
    • 1:40:27Here's my str.lower function.
    • 1:40:29This returns a copy of the string, with all
    • 1:40:31of the cased characters converted to lowercase,
    • 1:40:33and the lower-casing algorithm, dot dot dot.
    • 1:40:35So that doesn't give me much.
    • 1:40:37It doesn't give me sample code.
    • 1:40:38But it does say what the function does.
    • 1:40:40And if we keep looking, you'll see mention of Lstrip, which is left strip.
    • 1:40:43I used its analog, Rstrip before, right strip, which allows you to remove,
    • 1:40:48that is strip, from the end of a string, something like white space,
    • 1:40:51like a new line, or even something else.
    • 1:40:52And if you scroll through string, this web page here.
    • 1:40:56And we're halfway down the page already.
    • 1:40:58If you see my scroll bar, tiny on the right,
    • 1:41:00there's a huge amount of functionality built into string objects, here.
    • 1:41:05And this is just testament to just how rich the language itself is.
    • 1:41:08But it's also reason to reassure that the goal, when
    • 1:41:12playing around with some new language and learning it,
    • 1:41:14is not to learn it exhaustively.
    • 1:41:16Just like in English or any human language,
    • 1:41:18there's always going to be vocab words you don't know,
    • 1:41:20ways of presenting the same information in some language.
    • 1:41:23That's going to be the case with Python.
    • 1:41:25And what we'll do today and this week in problem set 6 is really
    • 1:41:28get your footing with this language.
    • 1:41:30But you won't know all of Python, just like you won't know all of C.
    • 1:41:33And, honestly, you won't know all of any of these languages on your own,
    • 1:41:36unless you're, perhaps, using them full time professionally,
    • 1:41:38and even then, there's more libraries than one might even retain themselves.
    • 1:41:42So let's actually now pivot to a few other ideas,
    • 1:41:45that we'll implement in Python, in a moment.
    • 1:41:47Let me switch back over to VS Code here.
    • 1:41:50And let me whip up, say, a recreation of our scores example from week two,
    • 1:41:55where we averaged like three scores together.
    • 1:41:57And that was an opportunity in week 2 to play with arrays,
    • 1:42:00to realize how constrained arrays are.
    • 1:42:02They can't grow or shrink.
    • 1:42:03You have to decide in advance.
    • 1:42:05But let's see what's different here in Python.
    • 1:42:07So let me do Scores.py, and let me give myself an array in Python
    • 1:42:11called scores, sorry, let me give myself a variable in Python called scores.
    • 1:42:15Set it equal to a list of three scores, which
    • 1:42:17are the same ones we've used before, 72, 73, 33, in this context
    • 1:42:22meant to be scores, not ASCII values.
    • 1:42:24And then let's just do the average of these.
    • 1:42:26So average will be another variable.
    • 1:42:28And it turns out I can do, well, how did I sum these before?
    • 1:42:32I probably had a for loop to add one, then I knew how long they were.
    • 1:42:36Turns out in Python, you can just say sum of scores
    • 1:42:39divided by the length of scores.
    • 1:42:41That's going to give me my average.
    • 1:42:43So sum is a function that takes a list, in this case, as input,
    • 1:42:46and it just does the sum for you, with a for loop or whatever
    • 1:42:49underneath the hood.
    • 1:42:49Len gives you the length of the list, how many things are in it.
    • 1:42:53So I can dynamically figure that out.
    • 1:42:55Now let me go ahead and print out, using print, the word average, and then,
    • 1:43:00in curly braces, the actual average, close quote.
    • 1:43:03All right, so let's run this code, Python of Scores.py.
    • 1:43:05And there is my average, in this case, 59.33333 and so forth,
    • 1:43:11based on the math.
    • 1:43:12Well, let's actually, now, change this a little bit
    • 1:43:14and make it a little more interesting, and actually get input from the user
    • 1:43:17rather than hard coding this.
    • 1:43:19Let me go back up here and use from CS50 import getInt,
    • 1:43:22because I don't want to deal with all the exceptions and the loops.
    • 1:43:25Like, I just want to use someone else's function here.
    • 1:43:27Let me give myself an empty list called scores.
    • 1:43:31And this is not something we were able to do in C, right?
    • 1:43:34Because in C, if you tried to make an empty array,
    • 1:43:36well, that's pretty stupid, because you can't add things to it.
    • 1:43:39It's a fixed size.
    • 1:43:40So it wouldn't even let you do that.
    • 1:43:42But I can just create an empty list in Python,
    • 1:43:45because lists, unlike arrays, are really lengthless.
    • 1:43:48They'll grow and shrink.
    • 1:43:49But you and I are not dealing with all the pointers underneath the hood.
    • 1:43:52Python's doing that for us.
    • 1:43:54So now, let's go ahead and get a whole bunch of scores from the user.
    • 1:43:58How about three of them in total.
    • 1:43:59So for i in range of 3, let's go ahead and grab a score from the user,
    • 1:44:05using getInt, asking them for score.
    • 1:44:07And then let's go ahead and append, to the scores list, that particular score.
    • 1:44:14So it turns out that a list, and I could read the Python
    • 1:44:17documentation to confirm as much, lists have a function built into them,
    • 1:44:21and functions built into objects are generally known as methods,
    • 1:44:25if you've heard that term before.
    • 1:44:26Same idea, but whereas a function kind of stands on its own,
    • 1:44:29a method is a function built into an object, like a list here.
    • 1:44:33That's going to achieve the same result. Strictly speaking,
    • 1:44:35I don't need the variable.
    • 1:44:37Just like in C, I could tighten this up and do something like this as well.
    • 1:44:40But, I don't know, I kind of like it this way.
    • 1:44:42It's more clear, to me, at least, that what I'm doing here, getting the score
    • 1:44:45and then appending it to the list.
    • 1:44:47Now the rest of the code can stay the same.
    • 1:44:49Python of Scores.py, score will be 72, 73, 33.
    • 1:44:54And I get back the math.
    • 1:44:55But now the program's a little more dynamic, which is nice.
    • 1:44:58But there's other syntax I could use here.
    • 1:45:00Just so you've seen it, Python does have some neat syntactic tricks,
    • 1:45:04whereby, if you don't want to do scores.append,
    • 1:45:06you can actually say scores plus equals this score.
    • 1:45:11So you can actually concatenate lists together in Python 2.
    • 1:45:15Just as we used plus to join two strings together,
    • 1:45:18you can use plus to join two lists together.
    • 1:45:21The catch is, you need to put the one score I'm
    • 1:45:24adding here in a list of its own, which is kind of silly.
    • 1:45:26But it's necessary, so that this thing and this thing are both lists.
    • 1:45:31To do this more verbosely, which most programmers wouldn't
    • 1:45:33do, but just for clarity, this is the same thing
    • 1:45:36as saying scores plus this score.
    • 1:45:38So now maybe it's a little more clear that scores and brackets score
    • 1:45:42plural, sorry, singular, are both lists themselves, being concatenated
    • 1:45:47or joined together.
    • 1:45:48So two different ways, not sure one is better than the other.
    • 1:45:51This way is pretty common, but .append is also quite reasonable as well.
    • 1:45:57All right, how about another example from week two.
    • 1:46:00This one was called uppercase.
    • 1:46:03So let me do this in Uppercase.py, though, this time.
    • 1:46:06And let me import from CS50, get string again.
    • 1:46:10And let me go ahead and say, before will be my first variable.
    • 1:46:14Let me get a string from the user, asking them for a before string.
    • 1:46:17And then let me go ahead and say, after, just to demonstrate some changes,
    • 1:46:22upper-casing to this string.
    • 1:46:25Let me change my line ending to be that, using our new trick.
    • 1:46:27And this is where things get cool in Python, relatively speaking.
    • 1:46:31If I want to iterate over all of the characters in a string,
    • 1:46:35and print them out in uppercase, one way to do that would be this.
    • 1:46:38For c in the before string, go ahead and print out C.uppercase, sorry, C.upper,
    • 1:46:46but don't end the line yet, because I want to keep these all on the same line
    • 1:46:49until I'm all done.
    • 1:46:50So what am I doing?
    • 1:46:51Python of Uppercase.py, let me type in Hello in all lowercase.
    • 1:46:54I've just upper-cased the whole string.
    • 1:46:57How?
    • 1:46:57I first get string, calling it before.
    • 1:47:00I then just print out some fluffy text that says after colon,
    • 1:47:02and I get rid of the line ending, just so I can kind of line these up.
    • 1:47:04Notice I hit the spacebar a couple of times
    • 1:47:06just so letters line up to be pretty.
    • 1:47:08For c and before, this is new.
    • 1:47:10This is powerful in C, sorry, in Python, whereby
    • 1:47:14you don't have to do like Int i equals 0 and i less than this,
    • 1:47:17you could just say, for c in the string in question, for c and before.
    • 1:47:22And then here is just upper-casing that specific character,
    • 1:47:25and making sure we don't output a new line too soon.
    • 1:47:27But this is actually more work than I need to do.
    • 1:47:29Based on what we've seen thus far, like from our agreement example,
    • 1:47:34can I tighten this up further?
    • 1:47:35Can I collapse lines 5 and 6, maybe even 7, all together?
    • 1:47:40If the goal of this program is just to uppercase the before string,
    • 1:47:46how might I do this?
    • 1:47:49Yeah, in back.
    • 1:47:50AUDIENCE: Would it be str.upper?
    • 1:47:52DAVID J. MALAN: Str.upper, yeah, so I could do something
    • 1:47:54like this, after gets before.upper.
    • 1:47:57So it's not stir literally dot upper, stir
    • 1:47:59just represents the string in question.
    • 1:48:01So it would be before.upper, but right idea otherwise.
    • 1:48:04And so let me go ahead and just tweak my print statement a little bit.
    • 1:48:08Let me just go ahead and print out the after variable here, after creating it.
    • 1:48:12So this line is the same, I'm getting a string called before.
    • 1:48:15I'm creating another variable called after, and, as you propose,
    • 1:48:18I'm calling upper on the whole string, not one character at a time.
    • 1:48:21Why?
    • 1:48:22Because it's allowed.
    • 1:48:23And, again, in Python, there aren't technically characters individually.
    • 1:48:27There's only strings, anyway.
    • 1:48:28So I might as well do them all at once.
    • 1:48:30So if I rerun the code now, Python of Uppercase.py.
    • 1:48:34Now I'll type in Hello in all lowercase, and, oh, so close,
    • 1:48:39I think I can get rid of this override, because I'm
    • 1:48:42printing the whole thing out at once, not character by character.
    • 1:48:45So now if I type in Hello before, now I have an even tighter version
    • 1:48:49of the program here.
    • 1:48:52All right, any questions, then, on lists or on strings,
    • 1:48:55and what this kind of function, upper, represents, with its docs.
    • 1:49:01No?
    • 1:49:01All right, so a couple other building blocks before we start.
    • 1:49:04Oh.
    • 1:49:05Where was that?
    • 1:49:06AUDIENCE: To the right.
    • 1:49:08DAVID J. MALAN: To the right, right.
    • 1:49:10Yes, thank you.
    • 1:49:11AUDIENCE: Could you write, very close to variable string, and then print upper,
    • 1:49:17you start creating a variable upper.
    • 1:49:19DAVID J. MALAN: Yes, do I have to create this variable, upper?
    • 1:49:21No, I don't.
    • 1:49:22I could actually tighten this up, and, if you really
    • 1:49:24want to see something neat, inside of the curly braces,
    • 1:49:28you don't have to just put the names of variables.
    • 1:49:31You can put a small amount of logic, so long
    • 1:49:33as it doesn't start to look stupid and kind of overwhelmingly complex, such
    • 1:49:36that it's sort of bad design at that point.
    • 1:49:38I can tighten this up like this.
    • 1:49:40And now we're in Python of Uppercase.py, writing Hello again.
    • 1:49:44And that, too, works.
    • 1:49:45But I would be careful about this.
    • 1:49:47You want to resist the temptation of having like a long line of code that's
    • 1:49:50inside the curly braces, because it's just going to be harder to read.
    • 1:49:53But, absolutely, you could indeed do that, too.
    • 1:49:55All right, how about command line arguments, which was one thing
    • 1:49:58we introduced in week two also, so that we could actually have the ability
    • 1:50:03to take input from the user, whoops.
    • 1:50:06So we could actually take input from the user at the command line,
    • 1:50:10so as to take literally command line arguments.
    • 1:50:13These are a little different, but it follows the same paradigm.
    • 1:50:16There's no main by default. And there's no Def main int
    • 1:50:19arg c char, or we called it string, argv by default. There's none of this.
    • 1:50:26So if you want access to the argument vector, argv, you import it.
    • 1:50:30And it turns out, there's another module in Python, or library in Python
    • 1:50:35called CIS, and you can import from the system this thing called argv.
    • 1:50:39So same idea, different place.
    • 1:50:41Now I'm going to go ahead and do this.
    • 1:50:42Let's write a program that just requires that the user types in two, a word,
    • 1:50:47after the program's name, or none at all.
    • 1:50:50So if the length of argv equals 2, let's go ahead and print out, how about,
    • 1:50:56Hello comma argv bracket 1 close quote, else if they don't type two words
    • 1:51:05total at the prompt, let's just say the default's, like we did weeks ago,
    • 1:51:08Hello, world.
    • 1:51:09So the only thing that's new here is we're importing argv from CIS,
    • 1:51:12and we're using this fancy f-string format, which kind of to your point,
    • 1:51:15too, it's putting more complex logic in the curly braces.
    • 1:51:18But that's OK.
    • 1:51:19In this case, it's a list called argv, and we're getting bracket 1 from it.
    • 1:51:23Let's do Python of Argv.py, Enter, Hello, world.
    • 1:51:27What if I do Argv.py David at the command line.
    • 1:51:31Now I get Hello, David.
    • 1:51:32So there's one curiosity here.
    • 1:51:34Python is not included in argv, whereas in C, dot
    • 1:51:39slash whatever was the first thing.
    • 1:51:41If the analog in Python is that the name of your Python program
    • 1:51:45is the first thing, in bracket 0, which is why David is in bracket 1,
    • 1:51:49the word Python does not appear in the argv list, just to be clear.
    • 1:51:55But otherwise, the idea of these arguments
    • 1:51:57is exactly the same as before.
    • 1:52:00And in fact, what you can do, which is kind of cool,
    • 1:52:02is, because argv is a list, you can do things like this.
    • 1:52:05For arg in argv, go ahead and print out each argument.
    • 1:52:10So instead of using a for loop and i and all
    • 1:52:12of this, if I do Python of argv Enter, it just writes the program's name.
    • 1:52:17If I do Python of argv Foo, it puts Argv.py and Foo.
    • 1:52:21If I do, sorry, if I do Foo and bar, those words all print out.
    • 1:52:26If I do Foobar baz, those print out too.
    • 1:52:28And Foo and bar or baz are like a mathematician's x and y and z
    • 1:52:31for computer scientists, when you just need some placeholder words.
    • 1:52:35So this is just nice.
    • 1:52:36It reads a little more like English, and a for loop is just much more concise,
    • 1:52:40allows you to iterate very quickly when you want something like that.
    • 1:52:43Suppose I only wanted the real words that the human typed
    • 1:52:46after the program's name.
    • 1:52:47Like, suppose I want to ignore Argv.py.
    • 1:52:50I mean I could do something hackish like this.
    • 1:52:53If arg equals Argv.py, I could just ignore,
    • 1:52:59you know, let's invert the logic.
    • 1:53:00I could do this, for instance.
    • 1:53:02So if the arg does not equal the program name,
    • 1:53:05then go ahead and print out the word.
    • 1:53:07So I get Foobar and baz only.
    • 1:53:09Or, this is what's kind of neat about Python 2, let me undo that.
    • 1:53:14And let me just take a slice of the array of the list instead.
    • 1:53:18So it turns out, if argv is a list, I can actually say,
    • 1:53:22you know what, go into that list, start at element 1, instead of 0,
    • 1:53:27and then go all the way to the end.
    • 1:53:29And we have not seen this syntax in C. But this
    • 1:53:31is a way of slicing a list in Python.
    • 1:53:34So now watch what happens.
    • 1:53:35If I run Python of Argv.py, Foo bar baz Enter,
    • 1:53:40I get only a subset of the list, starting at position 1,
    • 1:53:44going all of the way to the end.
    • 1:53:46And you can even do kind of the opposite.
    • 1:53:48If, for whatever reason, you want to ignore the last element,
    • 1:53:51you can say colon, we could say colon negative 1,
    • 1:53:57and use a negative number, which we've not seen before,
    • 1:53:59which slices off the end of the list, as well.
    • 1:54:02So there's some syntactic tricks that tend to be powerful in Python 2,
    • 1:54:06even if at first glance, you might not need them for typical things.
    • 1:54:10All right, let's do one other example with exit,
    • 1:54:12and then we'll start actually applying some algorithms,
    • 1:54:15to make things interesting.
    • 1:54:16So in one last program here, let's do Exit.py, just to do one more mechanic,
    • 1:54:20before we introduce some algorithms.
    • 1:54:22And let's do this.
    • 1:54:24Let's import from CIS, import argv.
    • 1:54:28Let's now do this.
    • 1:54:30Let's make sure the user gives me one command line argument.
    • 1:54:33So if the length of argv does not equal 2 in total, then let's go ahead
    • 1:54:39and print out something like missing command line argument,
    • 1:54:42just to explain what the problem is.
    • 1:54:44And then let's do this.
    • 1:54:47We can exit.
    • 1:54:48But I'm going to use a better version of exit here.
    • 1:54:50Let me import two functions from CIS.
    • 1:54:52Turns out the better way to do this is with CIS.exit, because I can then exit
    • 1:54:57specifically 2, with this exit code.
    • 1:54:59Otherwise, down here, I'm going to go ahead and print out,
    • 1:55:02something like Hello, comma argv bracket 1, same as before.
    • 1:55:06And then I'm going to exit with zero.
    • 1:55:08So, again, this was a subtle thing we introduced
    • 1:55:10in week two, where you can actually have your programs exit,
    • 1:55:12with some number, where 0 signifies success,
    • 1:55:15and anything else signifies error.
    • 1:55:17This is just the same idea in Python.
    • 1:55:19So if I, for instance, just run the program like this, oops, I screwed up.
    • 1:55:23I meant to say exit here and exit here.
    • 1:55:26Let me do that again.
    • 1:55:27If I run this like this, I'm missing a command line argument.
    • 1:55:30So let me rerun it with like my name at the prompt.
    • 1:55:33So I have exactly two command line arguments, the file name and my name,
    • 1:55:37Hello comma David.
    • 1:55:38And if I do David Malan, it's not going to work either,
    • 1:55:40because now argv does not equal 2.
    • 1:55:42But the difference here is that we're exiting with 1,
    • 1:55:44so that special programs can detect an error, or 0 in the event of success.
    • 1:55:49And now there's one other way to do this, too.
    • 1:55:52Suppose that you're importing a lot of functions,
    • 1:55:54and you don't really want to make a mess of things
    • 1:55:56and just have all of these function names available,
    • 1:55:59without it being clear where they came from.
    • 1:56:01Let's just import all of CIS.
    • 1:56:03And let's just change our syntax, kind of like I proposed for CS50,
    • 1:56:07where we just prepend to all of these library functions,
    • 1:56:09CIS, just to be super-explicit where they came from,
    • 1:56:13and if there's another exit or argv value
    • 1:56:18that we want to import from a library, this is one way to avoid collision.
    • 1:56:21So if I do it one last time here, missing command line argument.
    • 1:56:25But David still actually worked.
    • 1:56:27All right, only to demonstrate how we can implement that same idea.
    • 1:56:30Let's now do something more powerful, like a search algorithm,
    • 1:56:33like binary search.
    • 1:56:34I'm going to go ahead and open up a file called Numbers.py,
    • 1:56:36and let's just do some searching or linear search, rather,
    • 1:56:40on a list of numbers.
    • 1:56:42Let's go ahead and do this.
    • 1:56:44How about import CIS as before.
    • 1:56:47Let me give myself a list of numbers, like 4, 6, 8, 2, 7, 5, 0,
    • 1:56:52so just a bunch of integers.
    • 1:56:54And then let's do this.
    • 1:56:56If you recall from week three, we searched for the number 0
    • 1:56:59at the end of the lockers on stage.
    • 1:57:01So let's just ask that question in Python.
    • 1:57:04No need for a loop or anything like that.
    • 1:57:05If 0 is in the numbers, go ahead and print out found.
    • 1:57:09And then let's just exit successfully, with 0, else, if we get down here,
    • 1:57:13let's just say print not found.
    • 1:57:15And then we'll CIS exit with 1.
    • 1:57:19So this is where Python starts to get powerful again.
    • 1:57:21Here's your list.
    • 1:57:23Here is your loop, that's doing all of the checking for you.
    • 1:57:25Underneath the hood, Python is going to use linear search.
    • 1:57:28You don't have to implement it yourself.
    • 1:57:29No while loop, no for loop, you just ask a question.
    • 1:57:32If 0 is in numbers, then do the following.
    • 1:57:36So that's one feature we now get with Python,
    • 1:57:38and get to throw away a lot of that code.
    • 1:57:40We can do it with strings, too.
    • 1:57:41Let me open a file called Names.py instead,
    • 1:57:44and do something that was even more involved in C,
    • 1:57:46because we needed Str Comp and the for loop, and so forth.
    • 1:57:50Let me import CIS for this file.
    • 1:57:52Let's give myself a bunch of names like we did in C.
    • 1:57:54And those were Bill and Charlie and Fred and George and Ginny,
    • 1:58:01and two more, Percy, and lastly Ron.
    • 1:58:05And recall, at the time, we looked for Ron.
    • 1:58:07And so we had to iterate through the whole thing,
    • 1:58:09doing Str Comp and i plus plus and all of that.
    • 1:58:11Now just ask the question, if Ron is in names, then let's go ahead
    • 1:58:18and, whoops, let me hide that.
    • 1:58:20I hit the command too soon.
    • 1:58:22Let me go ahead and say print, found, as before.
    • 1:58:26CIS exit 1, just to indicate success, and then down here,
    • 1:58:29if we get to this point, we can say not found.
    • 1:58:32And then we'll just CIS exit 1 instead.
    • 1:58:36So, again, this just does linear search for us by default, Python of Names.py,
    • 1:58:40we found Ron, because, indeed, he's there, and at the end of the list.
    • 1:58:44But we don't need to deal with all of the mechanics of it.
    • 1:58:48All right, let's take things one step further.
    • 1:58:50In week three, we also implemented the idea
    • 1:58:52of a phone book, that actually associated keys with values.
    • 1:58:56But remember, the phone book in C, was kind of a hack, right?
    • 1:59:00Because we first had two arrays, one with names, one with numbers.
    • 1:59:03Then we introduced structs, and so we gave you a person structure.
    • 1:59:07And then we had an array of persons.
    • 1:59:10You can do this in Python, using objects and things called classes.
    • 1:59:15But we can also just use a general purpose dictionary,
    • 1:59:17because just like in P set 5, you can associate keys with values, using
    • 1:59:21a hash table, using a try.
    • 1:59:23Well, similarly, can Python just do this for us.
    • 1:59:26From CS50, let's import get string.
    • 1:59:29And now let's give myself a dictionary of people,
    • 1:59:32D-I-C-T () open paren closed paren gives you a dictionary.
    • 1:59:36Or you can simplify the syntax, actually,
    • 1:59:39and a dictionary again is just keys and values, words and definitions.
    • 1:59:42You can also just use curly braces instead.
    • 1:59:45That gives me an empty dictionary.
    • 1:59:47But if I know what I want to put in it by default, let's put Carter in there,
    • 1:59:50with a number of plus 1-617-495-1000, just like last time, and put myself,
    • 1:59:57David, with plus 1-949-468-2750.
    • 2:00:03And it came to my attention, tragically, after class that day,
    • 2:00:06that we had a bug in our little Easter egg.
    • 2:00:08If today, you would like to call me or text me, at that number,
    • 2:00:11we have fixed the code that underlies that little Easter egg.
    • 2:00:14Spoiler ahead.
    • 2:00:15All right, so this now gives me a variable
    • 2:00:17called people, that's associating keys with values.
    • 2:00:21There is some new syntax here in Python, not just the curly braces,
    • 2:00:25but the colons, and the quotes on the left and the right.
    • 2:00:28This is a way, in Python, of associating keys
    • 2:00:31with values, words with definitions, anything with anything else.
    • 2:00:35And it's going to be a super-common paradigm, including in week seven,
    • 2:00:38when we look at CSS and HTML and web programming, keys and values
    • 2:00:42are like this omnipresent idea in computer science and programming,
    • 2:00:45because it's just a really useful way of associating one thing with another.
    • 2:00:49So, at this point in the story, we have a dictionary, a hash table,
    • 2:00:52if you will, of people, associating names with phone numbers,
    • 2:00:56just like a real world phone book.
    • 2:00:57So let's write a program that gets a string from the user and asks them
    • 2:01:01whose number they would like to look up.
    • 2:01:03Then, let's go ahead and say, if that name is in the people dictionary,
    • 2:01:09go ahead and print out that person's number,
    • 2:01:12by going into the people dictionary and going
    • 2:01:14to that specific name, within there, using an f-string for the whole thing.
    • 2:01:19So this is similar in spirit to before.
    • 2:01:21Linear search and dictionary lookups will just happen automatically for you
    • 2:01:26in Python, by just asking the question, if name and people.
    • 2:01:29And this line is just going to print out,
    • 2:01:31whoever is in the people dictionary, at that name.
    • 2:01:35So I'm using square brackets, because here's the interesting thing in Python,
    • 2:01:40just like you can index into an array, or a list in Python,
    • 2:01:43using numbers, 0, 1, 2, you can very conveniently index
    • 2:01:48into a dictionary in Python, using square brackets, as well.
    • 2:01:53And just to make clear what's going on here, let me go
    • 2:01:56and create a temporary variable, person equals people bracket name.
    • 2:02:00And then let's just, or, sorry, let's say, number equals people bracket name.
    • 2:02:05And that will just print out the number in question.
    • 2:02:07In C, and previously in Python, anything with square brackets like this
    • 2:02:11would have been go to a location in a list or an array, using a number.
    • 2:02:16But that can actually be a string, like a word the human has typed.
    • 2:02:20And this is what's amazing about dictionaries,
    • 2:02:22it's not like a big line, a big linear thing.
    • 2:02:25It's this table, that you can look up in one column the name,
    • 2:02:28and get back in the other column the number.
    • 2:02:31So let's go ahead and run Python of Phonebook.py,
    • 2:02:33found, not that, oh, wait.
    • 2:02:38That's not what's supposed to happen at all.
    • 2:02:41I think I'm in the wrong play.
    • 2:02:43Phonebook.py.
    • 2:02:47What's going on?
    • 2:02:49Print found.
    • 2:02:51I am confused.
    • 2:02:53OK, let's run this again.
    • 2:02:55Python of Phonebook.py, what the--
    • 2:02:59OK, stand by.
    • 2:03:07[KEYS CLICKING]
    • 2:03:17What the heck?
    • 2:03:19What am I not understanding here?
    • 2:03:24OK, Roxanne, Carter, do you see what I'm doing wrong?
    • 2:03:27AUDIENCE: I don't.
    • 2:03:29DAVID J. MALAN: What the--
    • 2:03:31[LAUGHTER]
    • 2:03:33Say again?
    • 2:03:34SPEAKER 47: When you found the test results, it was doing both commands.
    • 2:03:38DAVID J. MALAN: Oh, yeah, found, OK, we're going to do this.
    • 2:03:43One sec.
    • 2:03:45[KEYS CLICKING]
    • 2:03:52Whoa, OK.
    • 2:03:55All this is coming out of the video.
    • 2:03:57So.
    • 2:03:58[LAUGHTER]
    • 2:03:59[APPLAUSE]
    • 2:04:01Thanks.
    • 2:04:05All right.
    • 2:04:06I will try to figure out what was going wrong.
    • 2:04:08The best I can tell, it was running the wrong program.
    • 2:04:10I don't quite understand why.
    • 2:04:12So we will diagnose this later.
    • 2:04:14I just put the file into a temporary directory, for now, to run it.
    • 2:04:16So let me go ahead and just run this, Python of Phonebook.py,
    • 2:04:22type in, for instance, my name.
    • 2:04:24And there's my corresponding number.
    • 2:04:26Have no idea what was just happening.
    • 2:04:27But I will get to the bottom of it and update you,
    • 2:04:30if we can put our finger on it.
    • 2:04:31So this was just an example, now, of implementing a phone book.
    • 2:04:34Let's now consider what we can do that's a little more
    • 2:04:37powerful, in these examples, like a phone book that
    • 2:04:40actually keeps this information around.
    • 2:04:42Thus far, these simple phone book examples throw the information away.
    • 2:04:45But using CSV files, comma separated values,
    • 2:04:48maybe we could actually keep around the names and numbers,
    • 2:04:51so that, like on your phone, you can actually
    • 2:04:53keep your contacts around long-term.
    • 2:04:55So I'm going to go ahead now and do a slightly different example.
    • 2:04:59And let me just hide this detail, so it's not confusing.
    • 2:05:03Whoops, I'm going to change my prompt temporarily.
    • 2:05:06So let me go ahead now and refine this example as follows.
    • 2:05:10I'm going to go into Phonebook.py, and I'm
    • 2:05:13going to import a whole library called CSV.
    • 2:05:16And this is a powerful one, because Python
    • 2:05:18comes with a library that just handles CSV files for you.
    • 2:05:21A CSV file is just a file with comma separated values.
    • 2:05:25And, in fact, to demonstrate this, let me check on one thing
    • 2:05:29here, just to make this a little more real.
    • 2:05:32To demonstrate this, let's go ahead and do this.
    • 2:05:39Let me import the CSV library from CS50.
    • 2:05:41Let me import getString.
    • 2:05:43Let me then open a file, using the open function,
    • 2:05:47open a file called Phonebook.csv, in append format,
    • 2:05:52in contrast with read format and write format.
    • 2:05:54Write just blows it away if it exists, append adds to the bottom of it.
    • 2:05:58So I keep this phone book around, just like you might
    • 2:06:00keep adding contacts to your phone.
    • 2:06:02Now let me go ahead and get a couple of values from the user.
    • 2:06:05Let me say getString and ask the user for a name.
    • 2:06:08Then let me getString again, and ask the user for their number.
    • 2:06:14And now, let me go ahead and do this.
    • 2:06:16And this is new, and this is Python-specific.
    • 2:06:18And you would only know this by following a tutorial,
    • 2:06:20or reading the documentation.
    • 2:06:22Let me give myself a variable called writer,
    • 2:06:24and ask the CSV library for a writer to that file.
    • 2:06:29Then, let me go ahead and use that writer variable,
    • 2:06:33use a function or a method inside of it, called write row,
    • 2:06:36to write out a list containing that person's name and number.
    • 2:06:41Notice the square brackets inside the parentheses,
    • 2:06:44because I'm just printing a list to that particular row in the file.
    • 2:06:49And then I'm just going to close the file.
    • 2:06:51So what is the effect of all of this?
    • 2:06:52Well, let me go ahead and run this version of Phonebook.py,
    • 2:06:55and I'm prompted for a name.
    • 2:06:56Let's do Carter's first, plus 1-617-495-1000, and then,
    • 2:07:05let's go ahead and LS.
    • 2:07:07Notice in my current directory, there's two files now, Phonebook.py,
    • 2:07:10which I wrote, and apparently Phonebook.csv.
    • 2:07:14CSV just stands for comma separated values.
    • 2:07:16And it's like a very simple way of storing data in a spreadsheet,
    • 2:07:20if you will, where the comma represents the separation between your columns.
    • 2:07:23There's only two columns here, name and number.
    • 2:07:26But, because I'm writing to this file in append mode,
    • 2:07:29let me run it one more time, Python of Phonebook.py,
    • 2:07:33and let me go ahead and do David and plus 1-949-468-2750, Enter.
    • 2:07:41And notice what happened in the CSV file.
    • 2:07:43It automatically updated, because I'm now persisting
    • 2:07:46this data to the file in question.
    • 2:07:49So if I wanted to now read this file in, I
    • 2:07:51could actually go ahead and do linear search on the data,
    • 2:07:55using a read function to actually read from the CSV.
    • 2:07:58But, for now, we'll just leave it a little simply as write.
    • 2:08:01And let me make one refinement here.
    • 2:08:03It turns out that, if you're in the habit of re-opening a file,
    • 2:08:07you don't have to even close it explicitly.
    • 2:08:09You can instead do this.
    • 2:08:10You can instead say, with the opening of a file called Phonebook.csv
    • 2:08:16in append mode, calling the thing file, go ahead and do all of these lines
    • 2:08:21here.
    • 2:08:22So the with keyword is a new thing in Python.
    • 2:08:24And it's used in a few different ways, but one of the ways it's used
    • 2:08:27is to tighten up code here.
    • 2:08:28And I'm going to move my variables to the outside,
    • 2:08:30because they don't need to be inside of the with statement,
    • 2:08:32where the file is open.
    • 2:08:33This just has the effect of ensuring that you, the programmer,
    • 2:08:36don't screw up, and accidentally don't close your file.
    • 2:08:38In fact, you might recall, from C, Valgrind
    • 2:08:40might have complained at you, if you had a file that, you didn't close a file,
    • 2:08:45you might have had a memory leak as a result. The with keyword
    • 2:08:47takes care of all of that for you, as well.
    • 2:08:51How about let's do, want to do this.
    • 2:08:54How about, let's do one other thing.
    • 2:08:57Let's do this.
    • 2:08:59Let me go ahead and propose, that on your phone or laptop
    • 2:09:02here, or online, go to this URL here, where you'll find a Google form.
    • 2:09:07And just to show that these CSVs are actually kind of omnipresent,
    • 2:09:10and if you've ever like used a Google Form
    • 2:09:11or managed a student group, or something where you've
    • 2:09:13collected data via Google Forms, you can actually
    • 2:09:15export all of that data via CSV files.
    • 2:09:18So go ahead to this URL here.
    • 2:09:21And those of you watching on demand later,
    • 2:09:22will find that the form is no longer working,
    • 2:09:24since we're only doing this live.
    • 2:09:26But that will lead to a Google Form that's
    • 2:09:27going to let everyone input their answer to a question,
    • 2:09:30like what house do you want to end up into,
    • 2:09:33sort of an approximation of the sorting hat in Harry Potter.
    • 2:09:36And via this form, will we then have the ability to export,
    • 2:09:40we'll see, a CSV file.
    • 2:09:43So let's give you a moment to do that.
    • 2:09:47In just a moment, I'll share my version of the screen, which
    • 2:09:50is going to let me actually open the file, the form itself.
    • 2:09:54And in just a moment, I'll switch over.
    • 2:09:59OK, so this is now my version of the form
    • 2:10:01here, where we have 200 plus responses to a simple question of the form, what
    • 2:10:04house do you belong in, Gryffindor, Hufflepuff, Ravenclaw, or Slytherin.
    • 2:10:08If I go over to responses, I'll see all of the responses in the GUI form here.
    • 2:10:12So graphical user interface, and we could flip through this.
    • 2:10:15And it looks like, interestingly, 40% of Harvard students
    • 2:10:20want to be in Gryffindor, 22% in Slytherin, and everyone else
    • 2:10:24in between the others.
    • 2:10:25But you might have noticed, if ever using a Google Form,
    • 2:10:27this Google Spreadsheets link.
    • 2:10:28So I'm going to go ahead and click that.
    • 2:10:30And that's going to automatically open, in this case, Google Spreadsheets.
    • 2:10:32But you can do the same thing with Office 365 as well.
    • 2:10:35And now you see the raw data as a spreadsheet.
    • 2:10:38But in Google Spreadsheets, if I go to File and then I go to Download,
    • 2:10:42notice I can download this as an Excel file, a PDF, and also
    • 2:10:46a CSV, comma separated values.
    • 2:10:48So let me go ahead and do that.
    • 2:10:50That gives me a file in my Downloads folder on my computer.
    • 2:10:53I'm going to now go back to my code editor here.
    • 2:10:57And what I'm going to go ahead and do is upload
    • 2:11:00this file, from my Downloads folder to VS Code,
    • 2:11:04so that we can actually see it within here.
    • 2:11:06And now you can see this open file.
    • 2:11:08And I'm going to shorten its name, just so it's a little easier to read.
    • 2:11:11I'm going to rename this using the MV command, to just Hogwarts.csv.
    • 2:11:15And then we can see, in the file, that there's two columns, timestamp column
    • 2:11:19house, where you have a whole bunch of time stamps
    • 2:11:21when people filled out the form, with someone very early in class.
    • 2:11:24And then everyone else just a moment ago.
    • 2:11:25And the second value, after each comma, is the name of the house.
    • 2:11:29Well, let me go ahead here and implement a program
    • 2:11:32in a file called Hogwarts.py, that processes this data.
    • 2:11:36So in Hogwarts.py, let's just write a program
    • 2:11:38that now reads a CSV, in this case not a phone book,
    • 2:11:41but everyone's sorting hat information.
    • 2:11:43And I'm going to go ahead and Import CSV.
    • 2:11:45And suppose I want to answer a reasonable question, ignoring
    • 2:11:48the fact that Google's GUI or graphical user interface, can do this for me.
    • 2:11:52I just want to count up who's going to be in which house.
    • 2:11:55So let me give myself a dictionary called houses, that's initially empty,
    • 2:11:59with curly braces.
    • 2:12:00And let me pre-create a few keys.
    • 2:12:02Let me say Gryffindor is going to be initialized to 0,
    • 2:12:07Hufflepuff will be initialized to 0 as well, Ravenclaw
    • 2:12:11will be initialized to 0.
    • 2:12:13And finally, Slytherin will be initialized to 0.
    • 2:12:16So here's another example of a dictionary, or a hash table,
    • 2:12:19just being a very general-purpose piece of data.
    • 2:12:22You can have keys and values.
    • 2:12:23The keys, in this case, are the houses.
    • 2:12:25The values are initially zero, but I'm going to use this,
    • 2:12:28instead of like four separate variables, to keep track of everyone's answer
    • 2:12:33to this form.
    • 2:12:34So I'm going to do this.
    • 2:12:35With opening Hogwarts.csv, in read mode, not append, I don't want to change it.
    • 2:12:43I just want to read it, as file as my variable name.
    • 2:12:46Let's go ahead and create a reader this time,
    • 2:12:49that is using the reader function in the CSV library, by opening that file.
    • 2:12:54I'm going to go ahead and ignore the first line of the file,
    • 2:12:57because, recall, that the first line is just timestamp and house.
    • 2:13:00I want to get the real data.
    • 2:13:01So this next function is just a little trick
    • 2:13:03for ignoring the first line of the file.
    • 2:13:06Then let's do this.
    • 2:13:07For every other row in the reader, that is line by line,
    • 2:13:12get the current person's house, which is in row bracket 1.
    • 2:13:15This is what the CSV reader library is doing for us.
    • 2:13:18It's handling all of the reading of this file.
    • 2:13:20It figures out where the comma is, and, for every row in the file,
    • 2:13:23it hands you back a list of size 2.
    • 2:13:26In bracket 0 is the time stamp, in bracket 1 is the house name.
    • 2:13:31So, in my code, I can say house equals row bracket 1.
    • 2:13:34I don't care about the time stamp for this program.
    • 2:13:36And then let's go into my dictionary called houses, plural, index
    • 2:13:41into it at the house location, by its name, and increment that 0 to 1.
    • 2:13:47And now, at the end of this block of code,
    • 2:13:50that has the effect of iterating over every line of the file,
    • 2:13:53updating my dictionary in four different places,
    • 2:13:55based on whether someone typed Gryffindor or Slytherin or anything
    • 2:13:59else.
    • 2:13:59And notice that I'm using the name of the house to index into my dictionary,
    • 2:14:03to essentially go up to this little cheat sheet and change the 0 to a 1,
    • 2:14:07the 1 to a 2, the 2 to a 3, instead of having
    • 2:14:10like four separate variables, which would just
    • 2:14:12be much more annoying to maintain.
    • 2:14:14Down at the bottom, let's just print out the results.
    • 2:14:16For each house in those houses, iterating over
    • 2:14:19the keys they're in by default in Python,
    • 2:14:21let's go ahead and print out an f-string that says,
    • 2:14:24the current house has the current count.
    • 2:14:29And count will be the result of indexing into houses, for that given house.
    • 2:14:35And let me close my quote.
    • 2:14:36So let's run this to summarize the data, Hogwarts.py, 140 of you
    • 2:14:41answered Gryffindor, 54 Hufflepuff, 72 Ravenclaw, and 80 of you Slytherin.
    • 2:14:46And that's just my now way of code, and this is, oh,
    • 2:14:48my God, so much easier than C, to actually analyze data in this way.
    • 2:14:52And one of the reasons that Python is so popular for data science and analytics,
    • 2:14:55more generally, is that it's actually really easy to manipulate data, and run
    • 2:14:59analytics like this.
    • 2:15:00And let me clean this up slightly.
    • 2:15:02It's a little annoying that I just have to know and trust
    • 2:15:05that the house name is in bracket 1 and timestamp is in bracket 0.
    • 2:15:10Let's clean this up.
    • 2:15:11There's something called a Dictionary Reader in the CSV library
    • 2:15:16that I can use instead.
    • 2:15:17Capital D, capital R, this means I can throw away this next thing,
    • 2:15:22because what a dictionary reader does is it
    • 2:15:24still returns to me every row from the file, one after the other,
    • 2:15:28but it doesn't just give me a list of size 2 representing each row.
    • 2:15:32It gives me a dictionary.
    • 2:15:33And it uses, as the keys in that dictionary, timestamp and house,
    • 2:15:39for every row in the file, which is just to say
    • 2:15:41it makes my code a little more readable, because instead
    • 2:15:43of doing this little trickery, bracket 1,
    • 2:15:46I can say quote unquote "Bracket House" with a capital H,
    • 2:15:49because it's capitalized in the Google Form itself.
    • 2:15:52So the code now is just minorly different,
    • 2:15:54but it's way more resilient, especially if I'm using Google Spreadsheets,
    • 2:15:57and I'm moving the columns around or doing something like that,
    • 2:16:00where the numbers might get messed up.
    • 2:16:01Now I can run this on Hogwarts.py again, and I get the same answers.
    • 2:16:05But I now don't have to worry about where those individual columns are.
    • 2:16:09All right, any questions on those capabilities there.
    • 2:16:14And that's a teaser of sorts, for some of the manipulation
    • 2:16:17we'll do in P set 6.
    • 2:16:19All right, so some final examples and flair, to intrigue
    • 2:16:23with what you can do with Python.
    • 2:16:24I'm going to actually switch over to a terminal window on my own Mac,
    • 2:16:28so that I can actually use audio a little more effectively.
    • 2:16:31So here's just a terminal window on Mac OS.
    • 2:16:33I before class have preinstalled some additional Python libraries,
    • 2:16:37that won't really work in VS Code in the cloud,
    • 2:16:40because they require audio that the browser won't necessarily support.
    • 2:16:43But I'm going to go ahead and write an example here
    • 2:16:45that involves writing a speech-based program, that actually does something
    • 2:16:49with speech.
    • 2:16:50And I'm going to go ahead and import a library,
    • 2:16:52that, again, I pre-installed, called Python text to speech,
    • 2:16:55and I'm going to go ahead and, per its documentation,
    • 2:16:58give myself a speech engine, by using that library's init function,
    • 2:17:02for initialize.
    • 2:17:04I'm then going to use this engine's save function
    • 2:17:06to do something fun, like Hello, world.
    • 2:17:09And then I'm going to go ahead and tell this engine to run and wait,
    • 2:17:12while it says those words.
    • 2:17:13All right, I'm going to save this file.
    • 2:17:15I'm not using VS Code at the moment.
    • 2:17:16I'm using another popular program that we used in CS50 back in my day,
    • 2:17:20called Vim, which is a command line program that's
    • 2:17:22just in this black and white window.
    • 2:17:24Let me go ahead now and run Python of Speech.py, and--
    • 2:17:28COMPUTER: Hello, world.
    • 2:17:30DAVID J. MALAN: All right, so it's a little computerized,
    • 2:17:33but it is speech that has been synthesized from this example.
    • 2:17:36Let's change it a little bit to be more interesting.
    • 2:17:38Let's do something like this.
    • 2:17:39Let's ask the user for their name, like what's your name question mark.
    • 2:17:43And then, let's use the little F string, and say, not Hello, world,
    • 2:17:47but Hello to that person's name.
    • 2:17:50Let me save my file, run Python of Speech.py, Enter.
    • 2:17:54David.
    • 2:17:55COMPUTER: Hello, David.
    • 2:17:57DAVID J. MALAN: All right, so we pronounce my name OK,
    • 2:17:59might struggle with different names, depending on the phonetics.
    • 2:18:02But that one seemed to be OK.
    • 2:18:03Let's do something else with Python, using similarly,
    • 2:18:05just a few lines of code.
    • 2:18:07Let me go into today's examples.
    • 2:18:12And I'm going to go into a folder called Detect, whoops, a folder called
    • 2:18:18Faces.py.
    • 2:18:19Sorry, Faces.
    • 2:18:20And in this folder, that I've written in advance,
    • 2:18:23are a few files, Detect.py, Recognize.py,
    • 2:18:25and two full of photos, Office.jpeg and Toby.jpeg.
    • 2:18:30If you're familiar with the show, here, for instance,
    • 2:18:32is the cast photo from The Office here.
    • 2:18:34So here's a photo as input.
    • 2:18:36Suppose I want to do something very Facebook-style,
    • 2:18:38where I want to analyze all of the faces,
    • 2:18:40or detect all of the faces in there.
    • 2:18:42Well, let me go ahead and show you a program
    • 2:18:44I wrote in advance, that's not terribly long.
    • 2:18:47Much of it is actually comments.
    • 2:18:49But let's see what I'm doing.
    • 2:18:50I'm importing the Pillow library, again, to get access to images.
    • 2:18:54I'm importing a library called face recognition, which I downloaded
    • 2:18:57and installed in advance.
    • 2:18:58But it does what it says.
    • 2:19:00According to its documentation, you go into that library
    • 2:19:02and you call a function called load image
    • 2:19:04file, to load something like Office.jpeg,
    • 2:19:07and then you can use the line of code like this.
    • 2:19:10Call a function called face locations, passing the images input,
    • 2:19:14and you get back a list of all of the faces in the image.
    • 2:19:17And then down here, a for loop, that iterates over all of those
    • 2:19:20face locations.
    • 2:19:22And inside of this loop, I just do a bit of trickery.
    • 2:19:24I figure out the top, right, bottom, and left corners of those locations.
    • 2:19:29And then, using these lines of code here,
    • 2:19:31I'm using that image library, to just draw a box, essentially.
    • 2:19:34And the code looks cryptic.
    • 2:19:35Honestly, I would have to look this up to write it again.
    • 2:19:38But per the documentation, this just draws a nice little box
    • 2:19:40around the image.
    • 2:19:41So let me go ahead and zoom out here, and run this now on Office.jpeg.
    • 2:19:48All right, it's analyzing, analyzing, and you can see in the sidebar here,
    • 2:19:53here's the original.
    • 2:19:54And here is every face that my, what, 10 lines of Python code
    • 2:19:59found, within that file.
    • 2:20:00What's a face?
    • 2:20:01Presumably the library is looking for something,
    • 2:20:04maybe without a mask, that has two eyes, a nose, and a mouth,
    • 2:20:07in some kind of arrangement, some kind of pattern.
    • 2:20:09So it would seem pretty reliable, at least on these fairly easy-to-read
    • 2:20:12faces here.
    • 2:20:13What if we want to look for someone specific,
    • 2:20:15for instance, someone that's always getting picked on.
    • 2:20:17Well, we could do something like this.
    • 2:20:18Recognize.py, which is taking two files as input, that image and the image
    • 2:20:23of one person in particular.
    • 2:20:24And if you're trying to find Toby in a crowd,
    • 2:20:26here I conflated the program, sorry, this is the version that
    • 2:20:29draws a box around the given face.
    • 2:20:31Here we have Toby as identified.
    • 2:20:33Why?
    • 2:20:34Because that program, Recognize.py, has a few more lines of code,
    • 2:20:38but long story short, it additionally loads as input Toby.jpeg,
    • 2:20:42in order to recognize that specific face.
    • 2:20:45And that specific face is a completely different photo,
    • 2:20:48but it looks similar enough to the person, that it all worked out OK.
    • 2:20:52Let's do one other that's a little sensitive to microphones.
    • 2:20:55Let me go into, how about my listen folder here, which is available
    • 2:21:00online, too.
    • 2:21:01And let's just run Python of Listen0.py.
    • 2:21:04I'm going to type in like David.
    • 2:21:07Oh, sorry, no, I'm going to--
    • 2:21:10Hello, world.
    • 2:21:16Oh, no, that's the wrong version.
    • 2:21:17[CHUCKLES] OK, I looked like an idiot.
    • 2:21:19OK, hello, there we go.
    • 2:21:21Hello to you, too.
    • 2:21:22And if I say goodbye, I'm talking to my laptop like an idiot, OK.
    • 2:21:26Now it's detecting what I'm saying here.
    • 2:21:28So this first version of the program is just using some relatively simple, if
    • 2:21:32elif elif, and it's just asking for input, forcing it to lowercase.
    • 2:21:36And that was my mistake with the first example.
    • 2:21:38And then, I'm just checking, is Hello in the user's words?
    • 2:21:41Is how are you in the user's words?
    • 2:21:42Didn't see that, but it's there.
    • 2:21:44Is goodbye in the user's words?
    • 2:21:45Now let's do a cooler version, using a library, just by looking at the effect.
    • 2:21:49Python of Listen1.py.
    • 2:21:51Hello, world.
    • 2:21:55Huh.
    • 2:21:56Let's do version 2 of this, that uses an audio speech-to-text library.
    • 2:22:04Hello, world.
    • 2:22:07OK, so now it's artificial intelligence.
    • 2:22:09Now let's do something a little more interesting.
    • 2:22:11The third version of this program that actually analyzes the words that are
    • 2:22:15said.
    • 2:22:16Hello, world, my name is David.
    • 2:22:18How are you?
    • 2:22:22OK, so that time, it not only analyzed what I said,
    • 2:22:26but it plucked my name out of it.
    • 2:22:27Let's do two final examples.
    • 2:22:30This one will generate a QR code.
    • 2:22:33Let me go ahead and write a program called
    • 2:22:35QR.py, that very simply does this.
    • 2:22:39Let me import a library called OS.
    • 2:22:40Let me import a library called QR code.
    • 2:22:43Let me grab an image here, that's QRcode.make.
    • 2:22:48And let me give you the URL of like a lecture video on YouTube, or something
    • 2:22:51like that, with this ID.
    • 2:22:55Let me just type this, so I don't get it wrong.
    • 2:22:59OK, so if I now use this URL here, of a video on YouTube, making
    • 2:23:05sure I haven't made any typos, I'm now going
    • 2:23:07to go ahead and do two lines of code in Python.
    • 2:23:09I'm going to first save that as a file called QR.png, which is
    • 2:23:13a two dimensional barcode, a QR code.
    • 2:23:15And, indeed, I'm going to use this format.
    • 2:23:17And I'm going to use the OS.system library to open QR.png automatically.
    • 2:23:23And if you'd like to take out your phone at this point,
    • 2:23:26you can see the result of my barcode, that's just been dynamically generated.
    • 2:23:32Hopefully from afar that will scan.
    • 2:23:37[UPROAR]
    • 2:23:40And I think that's an appropriate line to end on.
    • 2:23:42So that's it for CS50.
    • 2:23:43We will see you next time.
    • 2:23:46[APPLAUSE]
    • 2:23:47[MUSIC PLAYING]
  • CS50.ai
Shortcuts
Before using a shortcut, click at least once on the video itself (to give it "focus") after closing this window.
Play/Pause spacebar or k
Rewind 10 seconds left arrow or j
Fast forward 10 seconds right arrow or l
Previous frame (while paused) ,
Next frame (while paused) .
Decrease playback rate <
Increase playback rate >
Toggle captions on/off c
Toggle mute m
Toggle full screen f or double-click video