CS50 Video Player
    • 🧁

    • 🍮

    • 🍉

    • 🍿
    • 0:00:00Introduction
    • 0:01:15Python
    • 0:04:54Speller
    • 0:10:05Filter
    • 0:13:38Functions
    • 0:33:22Data Types
    • 0:35:45Calculator
    • 0:41:14Conditionals
    • 0:43:53Compare
    • 0:52:37Object-Oriented Programming
    • 0:57:35copy.py
    • 1:00:58Loops
    • 1:09:34Meow
    • 1:19:32Truncation
    • 1:23:40Exceptions
    • 1:32:05Mario
    • 1:39:19Lists
    • 1:48:02Dictionaries
    • 1:56:14sys
    • 2:00:46csv
    • 2:06:30pip
    • 0:00:00[MUSIC PLAYING]
    • 0:01:15DAVID J. MALAN: All right, this is CS50.
    • 0:01:19And this is week 6, wherein we transition away from that programming
    • 0:01:22language called C to another programming language called Python.
    • 0:01:26And, whereas a language like C, as you've probably come to appreciate,
    • 0:01:29for better or for worse, is very low level--
    • 0:01:31like, if you want the computer to do something,
    • 0:01:33you have to do most everything yourself, including asking for memory,
    • 0:01:37giving memory back.
    • 0:01:38Python is actually representative of a type of programming language
    • 0:01:41that's generally referred to as a higher-level language, which
    • 0:01:44does a lot of that lower-level stuff for you.
    • 0:01:46In other words, you don't have to manage your own memory.
    • 0:01:48You can iterate over things much more quickly
    • 0:01:51than using a traditional for loop as in C. And so, in short,
    • 0:01:54a language like Python is just easier and more pleasant, daresay, more fun
    • 0:01:58to use.
    • 0:01:59Moreover, it has even more of an ecosystem
    • 0:02:01of libraries, libraries being code that other people wrote that you can use.
    • 0:02:04And, as we'll see today, it's so much easier to get real work done
    • 0:02:08and really focus on the problems that are of interest to you.
    • 0:02:11What today is also going to be about is teaching yourself a new language.
    • 0:02:15And, indeed, the way we're going to approach this lecture
    • 0:02:18and the coming weeks problem set and beyond
    • 0:02:19is to give you all of the right tools and techniques via which
    • 0:02:22to learn a new language in the confines of CS50
    • 0:02:25initially but, after this course, on your own
    • 0:02:28because even if you don't go off and major in computer science,
    • 0:02:31odds are you'll have some occasion for programming in the future,
    • 0:02:34be it for academically, professionally, or for fun.
    • 0:02:36And so odds are a lot of the languages we're talking about today
    • 0:02:40are not going to be nearly as useful in a few years and few years out.
    • 0:02:44But the fundamentals, the ideas underlying them will be the same.
    • 0:02:48And so the goal today is to pick up new ideas and syntax along the way.
    • 0:02:51So recall that where we began was this in week 0, like hello, world.
    • 0:02:55Everything was so cute and easy to do.
    • 0:02:56It sort of escalated quickly when we got to see
    • 0:02:59where all of a sudden hello, world became a little something like this.
    • 0:03:02But, to my point about Python being higher level
    • 0:03:05and just doing more work for you, today, in Python,
    • 0:03:08if you want to implement hello, world, it's
    • 0:03:10going to be reduced to a single one line.
    • 0:03:12And we'll see this in all sorts of contexts.
    • 0:03:15The catch, though, is that if you want to run Python programs,
    • 0:03:17that process today is going to change a little bit.
    • 0:03:20Recall that, in C, we've had this technique for a while now where you have
    • 0:03:23to make your program, and then you can run it with ./whatever the name
    • 0:03:26of the program is.
    • 0:03:27Technically, we reveal that that's short for a longer form command where
    • 0:03:30Clang is the actual compiler.
    • 0:03:32But, today, the command is going to be simpler and fewer in quantity
    • 0:03:36and that this is the command, henceforth, via which we'll run
    • 0:03:39a program in a language like Python.
    • 0:03:41And, in particular, there's a few things that have changed here.
    • 0:03:44Obviously the file extension is different.
    • 0:03:46Instead of c, it's going to be .py or py for Python.
    • 0:03:49But, notice too, it's only one step instead of two.
    • 0:03:52And that's because, as we'll see, Python is generally
    • 0:03:55described as an interpreted language where a C is generally
    • 0:03:58described as a compiled language.
    • 0:04:00And that's not a characteristic.
    • 0:04:02That's intrinsic to the language just by convention.
    • 0:04:04Most everyone in the world, when writing C code,
    • 0:04:07compiles it thereafter from source code to machine code, the 0's
    • 0:04:11and 1's that your computer, your CPU ultimately understands.
    • 0:04:15But Python and other languages like it are a little more user-friendly
    • 0:04:19in that you don't need to write your code, compile your code, run your code,
    • 0:04:23change your code, compile your code, run your code.
    • 0:04:25You can actually skip the compilation step
    • 0:04:27and just use a program that coincidentally is called Python itself.
    • 0:04:32But, whereas Clang, for instance, was a compiler that
    • 0:04:35converted source code to machine code, Python, in this case,
    • 0:04:38is an interpreter, which, for now, you can
    • 0:04:40think of as just running your code top to bottom, left to right,
    • 0:04:43and looking at each line of code and figuring out
    • 0:04:46what to do with it without actually compiling it to 0's and 1's first.
    • 0:04:50So it's a little more user-friendly, half as many steps.
    • 0:04:53And so that too is a good thing.
    • 0:04:54Well, let's actually see this in context for a moment in VS Code.
    • 0:04:57Let me go over to the very first program we
    • 0:04:59wrote in C, which was this one here in a file called hello.c, or, in this case,
    • 0:05:04hello0.c.
    • 0:05:05And what I want to do here is create a new program that's
    • 0:05:08the distillation of this in Python.
    • 0:05:10So let me do code of hello.py, in this case.
    • 0:05:13Notice, that it's opened a second tab as always.
    • 0:05:15But what I'm going to do a bit of today is open two files side by side
    • 0:05:19just so we can see exactly what's going on.
    • 0:05:21So if I drag this tab over here, you'll see
    • 0:05:24that it'll split the screen in this nice, convenient way.
    • 0:05:27So now I have two files open.
    • 0:05:29But, in this file, I'm just going to do print, quote, unquote,
    • 0:05:31"Hello comma world", and that's it.
    • 0:05:35Well, what am I next going to do?
    • 0:05:36Well, in order to run this code at right, I don't need to compile it.
    • 0:05:40I just need to interpret it by running a program called Python on a file
    • 0:05:44called hello.py, crossing my fingers, as always.
    • 0:05:46And, voila, now I have written my first program in Python, so kind of neat.
    • 0:05:51And, so far at least, it's now one line of code instead of six.
    • 0:05:54There's no curly braces.
    • 0:05:56There's no includes.
    • 0:05:57There's no int, main, and void.
    • 0:05:58There's just a lot of less-- there's a lot less clutter in there.
    • 0:06:01But the idea's ultimately the same.
    • 0:06:03But what's exciting about Python and just
    • 0:06:05to motivate why we're introducing a higher-level language here on out,
    • 0:06:09you can just get a lot more interesting work done quickly too.
    • 0:06:12So, for instance, let me go ahead and do this.
    • 0:06:15Let me go ahead and open up in my own pset5 directory files
    • 0:06:20that I brought in advance, which was a solution to problem set 5's spell
    • 0:06:24checker whereby recall that you made a program called speller,
    • 0:06:27but that compiled a file along with it called dictionary.c,
    • 0:06:31which you had to implement the functions within.
    • 0:06:34So if I go ahead and run this program, recall,
    • 0:06:36on maybe one of the bigger files, like the Sherlock Holmes text and hit
    • 0:06:41Enter, that's going to churn through all of the seeming misspellings
    • 0:06:44therein and tell me that time in total took 1.17
    • 0:06:47seconds to spell check that whole file.
    • 0:06:50Well, that's pretty darn fast.
    • 0:06:52But consider how many hours, days, week it
    • 0:06:55took to actually implement that spell checker, the contents of dictionary.
    • 0:06:58Let me propose that what I'm going to do here
    • 0:07:00is open up a new file called dictionary.py.
    • 0:07:04And I'm going to propose to implement four functions,
    • 0:07:07but in Python instead of in C.
    • 0:07:10And those functions are going to be check, load, size,
    • 0:07:13and unload, and let's see how quickly I can churn out problem set
    • 0:07:165 using a language like Python instead of C. I'm going to go ahead
    • 0:07:19and open a file called dictionary.py.
    • 0:07:21And, in the first line of code, I'm going
    • 0:07:22to give myself a variable called words.
    • 0:07:24And I'm going to set that equal to a function
    • 0:07:26called set, which, just like in math, gives me
    • 0:07:28a container for a set of values, so no duplicates, for instance.
    • 0:07:32You can think of it sort of like an array, sort of like a list,
    • 0:07:35but less well defined in this case.
    • 0:07:37It's just going to be a set of words.
    • 0:07:39Now, I'm going to go ahead and define a function in Python called check.
    • 0:07:42Just like in C, it's going to take one word as input.
    • 0:07:45And the way I'm going to implement this check function in Python
    • 0:07:47is quite simply is this. return word.lower in words.
    • 0:07:53All right, that's it for the check function in Python.
    • 0:07:55Now, I'm going to go ahead and define another function called
    • 0:07:58load, which, just like in C, takes a dictionary as input.
    • 0:08:00And then I'm going to implement that as follows.
    • 0:08:02With open dictionary as file colon.
    • 0:08:07And then, below that, words.update file.read .splitlines,
    • 0:08:14and that's it for that.
    • 0:08:15And then I'm going to go ahead and return true, capital T. Below that,
    • 0:08:18I'm going to define a size function whose purpose in life is just like in C,
    • 0:08:22to return the size of this here dictionary.
    • 0:08:24So I'm going to return the length of that words variable
    • 0:08:27that I created on my first line.
    • 0:08:29And then down here I'm going to define, lastly, a function called unload.
    • 0:08:33But, as I mentioned earlier, because Python manages your memory for you,
    • 0:08:36you don't need to go and free anything like that.
    • 0:08:39So, you know what, I'm just going to say return true, and I'm done.
    • 0:08:42This then is problem set 5 written in Python.
    • 0:08:46So a bit of a flex, to be fair, because I had the cheat sheet in front of me
    • 0:08:50with all the answers.
    • 0:08:51And it might've taken me, though, a few minutes to actually implement
    • 0:08:53this instead of indeed a few hours or, again, a few days.
    • 0:08:57And what's in here should not necessarily be obvious.
    • 0:08:59These are some somewhat cryptic lines of code vis-a-vis what
    • 0:09:02we've been doing in C. But, by the end of today, by the end of this week,
    • 0:09:05by the end of the course, after which you've seen more Python,
    • 0:09:08you'll be able to read and understand what's going on here.
    • 0:09:11And, in fact, the way I myself wrote this code some time ago was I opened up
    • 0:09:15in one file dictionary.c, and then I opened up another file, dictionary.py,
    • 0:09:20and I essentially translated the left to the right
    • 0:09:23by googling, as needed, the syntax in Python or looking back at my own notes.
    • 0:09:27But that, too, is going to be how we, today and this coming week,
    • 0:09:30introduce you to this new language by showing you
    • 0:09:32how it is similar to and sometimes different
    • 0:09:34from a language you already know.
    • 0:09:36And so the hard part is done.
    • 0:09:38Now that you know a fairly low level and challenging language like C,
    • 0:09:41even though it's been just a few weeks, you
    • 0:09:43can really bootstrap yourself to knowing and understanding
    • 0:09:46new languages, present and future, by just
    • 0:09:50recognizing similarities and patterns.
    • 0:09:52And, along the way, there's undoubtedly going
    • 0:09:54to be new features that you encounter in Python, in future languages.
    • 0:09:57But no big deal, you're just going to be filling in some gaps in your knowledge
    • 0:10:00at that point, instead of starting from scratch.
    • 0:10:03I guess, pun intended.
    • 0:10:04Well, let's do one other sort of revelation here.
    • 0:10:07Recall that in problem set 4, you had to implement
    • 0:10:10a few filters like that of blurring.
    • 0:10:12And maybe you were feeling more comfortable,
    • 0:10:14and you did a bit of edge detection.
    • 0:10:15Let me propose that I could do exactly that in some Python code too.
    • 0:10:19So let me go ahead and open up a new file, for instance, called blur.py.
    • 0:10:24Let me go ahead and use a library that comes with Python that we've already
    • 0:10:29installed.
    • 0:10:29It's called the Python image library, so from PIL import Image comma ImageFilter.
    • 0:10:36Then, on my next line, I'm going to create a variable called before.
    • 0:10:39I'm going to set that equal to the return value of a function
    • 0:10:42called Image.open.
    • 0:10:43And I'm going to open a file that you've seen before, bridge.bmp.
    • 0:10:47My next line of code, I'm going to create a variable called after
    • 0:10:50to represent after the filtration of this image and set that equal
    • 0:10:54to the before variable .filter, passing in as an argument ImageFilter.BoxBlur
    • 0:11:01open parenthesis 1 close paren.
    • 0:11:04And then, lastly, I'm going to do after.save.
    • 0:11:06And I'm going to save this file as out.bmp.
    • 0:11:09Now, of course, I'm relying on the fact that there is a file called bridge.bmp.
    • 0:11:14So I'm going to grab a copy of that from problem set 4,
    • 0:11:18and that file is going to be a nice, pretty picture of the Weeks Bridge down
    • 0:11:24by the river.
    • 0:11:25And, in fact, if I open that up with code of bridge.bmp,
    • 0:11:28this here is the original version of that there bridge.
    • 0:11:32So let's run my four lines of blur.py code on this.
    • 0:11:37And, just to make it a little more obvious on the screen
    • 0:11:39here, instead of just looking at one pixel around every pixel to blur things,
    • 0:11:43I'm going to be a little dramatic and use 10 pixels just
    • 0:11:46to make it even blurrier as to appear nicely on the screen.
    • 0:11:49I'm going to go ahead and run Python of blur.py.
    • 0:11:52And, when I hit Enter, those four lines of code will be interpreted,
    • 0:11:56so to speak, top to bottom, left to right.
    • 0:11:58Nothing seems to happen.
    • 0:11:59But if I type ls now, I should see, indeed, a file called out.bmp as well.
    • 0:12:05Let me go ahead and open that, out.bmp.
    • 0:12:08And, whereas the before version was this,
    • 0:12:11the after version is now this in just four lines of code.
    • 0:12:15And, for those of you who were indeed feeling
    • 0:12:17more comfortable with that same problem set,
    • 0:12:20let me propose to implement the edge-detection algorithm that you
    • 0:12:23might recall.
    • 0:12:23And let me create a different file for that, so code of edge.py.
    • 0:12:28And, inside of edge.py, I'm going to go ahead and do the same thing as before
    • 0:12:33from the Python image library.
    • 0:12:35Import an image feature and an image filter feature.
    • 0:12:39Then give myself a variable again before equals Image.open,
    • 0:12:43quote unquote, bridge.bmp.
    • 0:12:45Then a variable called after as before equals before.filter,
    • 0:12:50passing in this time ImageFilter.FIND_EDGES,
    • 0:12:55which is a feature that just comes with this library.
    • 0:12:57And then I'm going to go ahead and do after.save and, again, out.bmp.
    • 0:13:03I'm going to very quickly then run Python,
    • 0:13:05the name of the interpreter on edge.py, which
    • 0:13:07is going to use as input bridge.bmp again, which is the original version.
    • 0:13:11But if I now open up out.bmp and hit Enter, instead of looking like this,
    • 0:13:18now, after four lines of Python, it looks like this.
    • 0:13:21So if you've been feeling a little frustrated by just how much
    • 0:13:23time, how much energy, how many lines of code
    • 0:13:25it takes to solve problems that ultimately may very well be
    • 0:13:29interesting visually or otherwise, it's now
    • 0:13:31going to get a lot easier to do some of those same features.
    • 0:13:34But, of course, we'll give you the capability
    • 0:13:36to do some more things as well.
    • 0:13:38But, before we do that, let's actually take a tour of what some of the features
    • 0:13:42are that we're going to get now with a language called Python, sort of evoking
    • 0:13:46memories of week 1 when we transitioned from Scratch to C. So,
    • 0:13:49in the world of Python, there's absolutely functions.
    • 0:13:52You just saw a whole bunch of them.
    • 0:13:53And, again, the syntax looks new and different and perhaps a little weird
    • 0:13:56versus C. But, over the course of today and this week, everything I just typed
    • 0:14:00will become more familiar.
    • 0:14:02Here is going to be a side-by-side comparison now of Scratch,
    • 0:14:04just like from week 0, to this week in Python.
    • 0:14:07But we'll compare it along the way to some C code as well.
    • 0:14:10So this was, of course, the simplest function
    • 0:14:12we used back in Scratch to just say hello, world on the screen.
    • 0:14:15In C, it looked a little something like this,
    • 0:14:18but I've claimed already today, in Python,
    • 0:14:20it's going to instead look like this.
    • 0:14:22And, just as a little bit of a comparison, what's different?
    • 0:14:27Let's see, yeah.
    • 0:14:29So there's no semicolon.
    • 0:14:31Amazingly, Python largely gets rid of the semicolon.
    • 0:14:34So, when your thought is done, that's it.
    • 0:14:35Python will figure out that it's done.
    • 0:14:37You don't need to terminate your thought with a semicolon.
    • 0:14:39What else is different here?
    • 0:14:41Yeah.
    • 0:14:41AUDIENCE: Backslash n.
    • 0:14:42DAVID J. MALAN: Yeah, so backslash n is missing, which, in C,
    • 0:14:45we needed to tell the computer to add a new line, so to speak.
    • 0:14:48Move the cursor to the next line.
    • 0:14:49Turns out that, after years of experience,
    • 0:14:52humans decided that, gosh, we are so often using backslash n in our print
    • 0:14:57statements, let's just make it the default instead of vice versa.
    • 0:15:00That does invite the question, well, how do you undo that?
    • 0:15:03But we'll come back to that before long.
    • 0:15:04But, indeed, you don't need the backslash n.
    • 0:15:07The third and final difference, perhaps obvious now,
    • 0:15:09is that it's print instead of printf.
    • 0:15:11That doesn't mean you can't format strings,
    • 0:15:13but the word print is just so much easier to remember.
    • 0:15:16It's a little less arcane.
    • 0:15:17So the Python community decided, in their language,
    • 0:15:19to call this print instead.
    • 0:15:21And what you're seeing already is the slightest hints of the reality
    • 0:15:24that, after years pass and different programmers start using languages,
    • 0:15:29they come up with opinions, what they like, what they don't like.
    • 0:15:31They eventually decide we're going to invent our own language that's
    • 0:15:34better than everything before it.
    • 0:15:36And so what you'll see is that a lot of the frustrations,
    • 0:15:38confusions you might have encountered, you're in good company
    • 0:15:41because some of those now will go away.
    • 0:15:43The catch is, of course, sometimes people
    • 0:15:45will disagree as to what the right outcome is, the right design.
    • 0:15:49And this is why there's actually hundreds, maybe thousands,
    • 0:15:52of programming languages in the real world.
    • 0:15:54Thankfully, there's probably only a few dozen
    • 0:15:56that are actually very popular and commonly used in practice.
    • 0:16:00All right, so, in the real world too, we, of course, have libraries.
    • 0:16:03And we saw some of those libraries in the world of C,
    • 0:16:06we're also going to see them in the world of Python,
    • 0:16:09even more powerfully so, like the filtration
    • 0:16:11we just did of images being able to very quickly implement a spell
    • 0:16:14checker with the code that I wrote.
    • 0:16:18In the world of Python, just know that libraries are generally
    • 0:16:20called modules and packages.
    • 0:16:22And there's some slight difference between those two,
    • 0:16:24but, for now, module packages are just Python terminology
    • 0:16:27for what we already to be libraries.
    • 0:16:30CS50 has its own library.
    • 0:16:31And, in fact, in C, we use this atop any program
    • 0:16:34that we want to use get_string, get_int, and strings themselves.
    • 0:16:38In Python, they're still going to be a CS50 library, but very
    • 0:16:41brief training wheels that are available,
    • 0:16:43if only to ease the transition from C to Python.
    • 0:16:46But the syntax for using CS50's library henceforth is going to be more
    • 0:16:50simply import CS50, very similar to what we saw a moment ago with that Python
    • 0:16:54imaging library--
    • 0:16:56Python image library.
    • 0:16:57There's alternative syntax you might see over time where
    • 0:17:00if you only want to import one or specific things,
    • 0:17:03you don't have to import the whole library.
    • 0:17:05You can import from cs50 a specific function or symbol more generally
    • 0:17:10like this.
    • 0:17:10So you'll see two different techniques like that.
    • 0:17:13Well, let's go ahead now and actually build
    • 0:17:15on the program we wrote already by doing something just like we did in week 0
    • 0:17:20as well as in week 1, where we actually got input from the user.
    • 0:17:23So, in Scratch, here was how we prompted the user.
    • 0:17:26What's your name?
    • 0:17:27We got back a so-called return value.
    • 0:17:29And then we joined hello comma space with that there return value.
    • 0:17:34In C, this didn't translate nearly as cleanly.
    • 0:17:38We had to introduce, of course, not only get_string for the same function.
    • 0:17:42But we also had to introduce, in the context of printf,
    • 0:17:45these placeholders like %s.
    • 0:17:47For better or for worse, what you're about to see
    • 0:17:49is several different ways to solve the same problem in Python, some of which
    • 0:17:53are a little more similar to Scratch, some of which
    • 0:17:56are a little different from scratch as well.
    • 0:17:58Don't have to absorb them all from the get-go.
    • 0:18:00But here's how we might do this in Python instead.
    • 0:18:03One, we can declare a variable called answer.
    • 0:18:06We can then set it equal to the return value of get_string, which, for now, is
    • 0:18:10in the CS50 library for Python.
    • 0:18:13You don't need it per se in the real world.
    • 0:18:15But, for now, for parity with C, we've given you this get_string function.
    • 0:18:18It, like in C, takes an argument like, quote, unquote, "what's your name?"
    • 0:18:22But no semicolon at the end of this line.
    • 0:18:25Second line of code, notice that we're again using print in Python, not printf.
    • 0:18:30We're saying, quote, unquote, "hello comma space".
    • 0:18:33And then a little weirdly, we're using what looks like the addition operator
    • 0:18:36to add, so to speak, the answer to that end of that phrase.
    • 0:18:40But those familiar or not, what might the plus really represent here?
    • 0:18:44It's not addition in a mathematical sense.
    • 0:18:47Yeah.
    • 0:18:47AUDIENCE: Concatenation.
    • 0:18:48DAVID J. MALAN: So it's what we would call concatenation,
    • 0:18:50to take one string on the left, one string on the right, and join them,
    • 0:18:53that is, concatenate them together, which is why I need not only the comma
    • 0:18:57grammatically here but also a space so that we actually have
    • 0:19:00a string that looks the way we intend.
    • 0:19:02So this is one way then to implement this here program that we already
    • 0:19:05implemented in Scratch as follows.
    • 0:19:08But there's other ways as well.
    • 0:19:10I can also change this, a little weirdly,
    • 0:19:13to be a comma-separated list of arguments.
    • 0:19:15So, it turns out, unlike in C, in Python, if you pass one, two, three,
    • 0:19:21or more arguments to the print function, by default, they
    • 0:19:24will just all be printed 1, 2, 3, but with a single space in between them.
    • 0:19:29So that's just the way the print function works per its documentation,
    • 0:19:32which we'll see before long.
    • 0:19:33So here I've gotten rid of that space, and I've just
    • 0:19:35said my first argument is hello comma.
    • 0:19:37And my second argument is answer.
    • 0:19:39And I just leave it to print to effectively concatenate them together
    • 0:19:42on the screen by printing one followed by the other.
    • 0:19:45So that's the second way we might do this in Python.
    • 0:19:48Here's a weird-looking third that, for better or for worse,
    • 0:19:51is probably the most common way to do things nowadays even
    • 0:19:55though it's more of a visual mouthful.
    • 0:19:57So I'm still using the print function, but there's that f
    • 0:19:59again but in a weird place.
    • 0:20:01It turns out, if you want Python's print function to format a string for you
    • 0:20:06by plugging in one or more values, the way you do that is you tell Python,
    • 0:20:11not next to the print function, but to the left of the string itself
    • 0:20:15that, hey, Python, here comes a format string, aka, an f string.
    • 0:20:20And then, inside of those quote marks nicely enough,
    • 0:20:23you can actually use literal placeholders,
    • 0:20:25these curly braces, that say put the value of the answer variable there.
    • 0:20:30So it's sort of a new and improved version of printf in C, which,
    • 0:20:33annoyingly, always had us using %s, %i, %f, and so forth.
    • 0:20:38Now, you just put curly braces and the name of the actual thing
    • 0:20:41you want to plug in to that location.
    • 0:20:44This is called variable interpolation whereby the variable's value, answer
    • 0:20:48in this case, will be substituted without the curly braces appearing
    • 0:20:52in the final output.
    • 0:20:54So that's then how we might implement exactly
    • 0:20:57that same feature using this thing called a format string.
    • 0:21:01So how might I go about doing this?
    • 0:21:03Well, let me actually go back to VS Code in just a moment here.
    • 0:21:06And let's go ahead and open up my same file called hello.py.
    • 0:21:11So code of hello.py, let's go ahead and implement this variant thereof.
    • 0:21:16So, in hello.py, I previously had just this single line of code-- uh-oh.
    • 0:21:24Yes, what's going wrong?
    • 0:21:25IAN: Just a little crimp.
    • 0:21:26DAVID J. MALAN: Oh, it was making noises.
    • 0:21:28Sorry.
    • 0:21:29OK.
    • 0:21:30That was Ian.
    • 0:21:31Thank you, Ian.
    • 0:21:32[APPLAUSE]
    • 0:21:32OH, thank you, thank you, Ian.
    • 0:21:36So, here, let me go ahead and open a file called hello1.c, which
    • 0:21:41I brought back from week 1 itself.
    • 0:21:42And let's go ahead and open up hello.py here again.
    • 0:21:46Just so we can see these things side by side,
    • 0:21:48I'm going to drag this one over to top-right
    • 0:21:50so we can see hello.c on the left, albeit somewhat cut off, and hello.py
    • 0:21:54on the right.
    • 0:21:54And let's now change hello.py to actually get some user input.
    • 0:21:58So, from CS50's library, I'm going to import a function called get_string.
    • 0:22:03And then, inside of this actual program, I'm
    • 0:22:05going to create a variable called answer.
    • 0:22:07I'm going to set it equal to the return value of string.
    • 0:22:10I'm going to pass in a prompt like, what's your name question mark space,
    • 0:22:15and then close quote and close parentheses.
    • 0:22:18And then, lastly, I'm going to use one of those f strings
    • 0:22:20and print out, quote, unquote--
    • 0:22:23or, rather, f, quote, unquote, "hello comma answer", close quotes.
    • 0:22:29And it's a little weird now with the f and the quotes
    • 0:22:31and the curly braces and the parentheses,
    • 0:22:33but if you just follow them from inside out,
    • 0:22:35they are all nicely symmetric and balanced.
    • 0:22:38If now, in my prompt, I go back down and run Python of hello.py, Enter.
    • 0:22:43Instead of seeing, of course, hello comma world Immediately,
    • 0:22:45I can type in my name and hit Enter.
    • 0:22:47And now I see exactly that.
    • 0:22:49But there's a few things I could do wrong here.
    • 0:22:51For instance, if I forget this here format string and just do, quote,
    • 0:22:55unquote, "curly brace answer" and then I go back and run Python of hello.py,
    • 0:23:01I'm still going to be prompted for my name, like David.
    • 0:23:04But what's going to go wrong now intuitively?
    • 0:23:07What am I going to see?
    • 0:23:08Yeah.
    • 0:23:09AUDIENCE: You're going to [INAUDIBLE]
    • 0:23:10DAVID J. MALAN: Perfect, because I haven't told Python
    • 0:23:13that this is a special formatted string with that little f,
    • 0:23:15it's indeed going to print out hello comma curly brace answer
    • 0:23:19just as we see here.
    • 0:23:21So a subtle bug, but one that's very easily fixed with that there f,
    • 0:23:25but there's something else worth noting here.
    • 0:23:27Let me go back over to highlight this code.
    • 0:23:29This varies from C, oh, in another way too.
    • 0:23:33There's indeed no semicolons on lines three or four.
    • 0:23:36But what else is different vis-a-vis the C version here still at left?
    • 0:23:42What's different?
    • 0:23:46How about here?
    • 0:23:46AUDIENCE: There's no main.
    • 0:23:47DAVID J. MALAN: So there's no main.
    • 0:23:49So there's none of this.
    • 0:23:50There's none of this, and there's no curly braces.
    • 0:23:52Yeah, what else?
    • 0:23:53AUDIENCE: Declare the type.
    • 0:23:54DAVID J. MALAN: I didn't have to declare the type of the variable.
    • 0:23:56So this too, for better or for worse, is a feature of Python.
    • 0:23:59We'll see that Python has data types.
    • 0:24:01There are strings, there are ints, there are floats,
    • 0:24:03but you don't need to tell the interpreter what your variables are.
    • 0:24:08Rather, Python as an interpreter will just figure it out from context.
    • 0:24:11So if you're assigning a variable called answer
    • 0:24:14to what clearly is going to be a string, the type of that variable answer
    • 0:24:18will be a string.
    • 0:24:19If, though, you used get_int or something similar,
    • 0:24:21the type of that variable might be an int, instead.
    • 0:24:24So here too, a lot of the things that, why doesn't the computer just figure it
    • 0:24:27out? are baked into Python as features.
    • 0:24:31So if I go back over here after now having
    • 0:24:33implemented this version of hello, we can revisit perhaps something
    • 0:24:39that I glossed over earlier whereby, in Python, the default seems
    • 0:24:43to be to give you a new line at the end of any print statement.
    • 0:24:46But that does invite the question, well, how do you actually get those back--
    • 0:24:50or get rid of that if you indeed do?
    • 0:24:53Well, this gives us a brief opportunity to talk about one piece of jargon
    • 0:24:56in the world of Python and certain other languages, which
    • 0:24:59is that all of these parameters or arguments we've been using for weeks,
    • 0:25:02where you just put a comma-separated list of arguments or values
    • 0:25:06inside of parentheses when calling a function to give those functions input,
    • 0:25:10those have, all this time, been called positional parameters because the order
    • 0:25:14has always mattered.
    • 0:25:15The first thing, the second thing, the third thing
    • 0:25:17influences what the function does with those arguments.
    • 0:25:20But, in Python and certain other languages,
    • 0:25:22there's also what we're going to call named parameters whereby
    • 0:25:26you can actually specify not just a generic comma-separated list of values
    • 0:25:29for which the order matters.
    • 0:25:31You can instead provide the name of a variable and its value,
    • 0:25:35the name of a variable and its value, specifically, the name of a parameter
    • 0:25:39and its value as a comma-separated list, the upside of which
    • 0:25:42is that it's a little clearer to you, the reader, you the programmer,
    • 0:25:45what does what?
    • 0:25:46And it's also not nearly as vulnerable to you just screwing up the order
    • 0:25:50and getting them slightly out of order and constantly
    • 0:25:53having to check the documentation as to what goes in what order.
    • 0:25:56If you recall using fread or fwrite, for instance, which takes a few arguments,
    • 0:25:59I mean, those two are particularly annoying.
    • 0:26:01And even I always forget which comes first.
    • 0:26:04If I could just use the names of those parameters,
    • 0:26:06it might've eliminated some ambiguity.
    • 0:26:09So how can we use in Python named parameters.
    • 0:26:11Well, let's just do a relatively simple example
    • 0:26:13that's actually pretty commonly leveraged, which is this.
    • 0:26:18If I, for whatever reason--
    • 0:26:20let me get rid of my C version now.
    • 0:26:22And, in fact, let me simplify this and just go back
    • 0:26:24to printing out in hello.py, hello comma world.
    • 0:26:28This, as before, will print out hello comma world with a new line.
    • 0:26:33If I want to get rid of this, though, I can do that
    • 0:26:37by consulting the documentation for Python.
    • 0:26:40And, in fact, the official documentation for Python lives at this URL,
    • 0:26:44docs.python.org.
    • 0:26:46The upside of this documentation existing
    • 0:26:48is that, unlike C, which doesn't really have an official place
    • 0:26:51to go for documentation other than the manual pages
    • 0:26:54that we, recall, at manual.cs50.io have given you student-friendly versions
    • 0:26:58thereof.
    • 0:26:59Everyone in the world goes to this URL when looking up things for Python
    • 0:27:03officially in its own documentation.
    • 0:27:06For instance, at this particular URL, there is a list of all of the functions
    • 0:27:10that come built into Python itself.
    • 0:27:12And if we poke around further there, there's
    • 0:27:14one indeed called print, which is really the only one I've been using
    • 0:27:17thus far that comes with the language.
    • 0:27:19And in that documentation, you'll see a somewhat cryptic line like this.
    • 0:27:23This is the so-called signature or prototype for the print function.
    • 0:27:28The syntax for this is a little different from what we saw in C,
    • 0:27:31but what I see here in the documentation,
    • 0:27:33if you go to that same URL, is that there's
    • 0:27:35a function called print that takes potentially one, two, three, four,
    • 0:27:39five or more arguments, five more arguments or parameters.
    • 0:27:44But what are they?
    • 0:27:46Well, over here is some new syntax.
    • 0:27:48And, trust me, this does not mean pointers.
    • 0:27:50There's a * but nothing to do with memory or * or memory or pointers.
    • 0:27:54This just means that there's going to be 0 or more objects that
    • 0:27:58can come as a comma-separated list.
    • 0:28:00And we've used that feature already when I printed hello plus name.
    • 0:28:05When I printed hello comma name, I got back one--
    • 0:28:10I passed in one or two arguments.
    • 0:28:12This just means you can pass in 0 or more just by their position.
    • 0:28:15The rest of these are so-called named parameters
    • 0:28:18whereby the print function comes with one named parameter called sep
    • 0:28:22for separator, whose default value is a single space per the, quote, unquote.
    • 0:28:27The print function also comes with an end named parameter whose default
    • 0:28:31value-- and here is going to be the answer to that question earlier--
    • 0:28:33is backslash n.
    • 0:28:36So this is why every line ending, from the print function,
    • 0:28:40has a backslash n automatically given.
    • 0:28:43There's something called file.
    • 0:28:44There's something called flush.
    • 0:28:45More on those perhaps another time.
    • 0:28:46But this is why I automatically got a free space
    • 0:28:50when I passed in two arguments.
    • 0:28:51This is why I keep seeing my cursor moved to the next line.
    • 0:28:54But the fact that these things have names sep and end
    • 0:28:57means I can use these named parameters if I so choose
    • 0:29:01to override their default arguments.
    • 0:29:04So, for instance, if I want to override the separator, I can use, quote,
    • 0:29:08unquote, "something else" in between words.
    • 0:29:10If I want to override the new line, I can change the backslash n to something
    • 0:29:15else as well.
    • 0:29:16So if I go back to VS Code here and, for whatever reason,
    • 0:29:19I do want to get rid of that new line ending,
    • 0:29:22I can pass a second argument into print, specify that the name of this parameter
    • 0:29:26is E-N-D, end, and set it equal to not backslash n, but really anything I want.
    • 0:29:33So, just to be dramatic, let's use an exclamation point to excitedly
    • 0:29:36say hello, world.
    • 0:29:37And if I now rerun this program as such, now I see hello, world!
    • 0:29:42But then my prompt is immediately on the same line.
    • 0:29:45I can get rid of that too if I really want.
    • 0:29:46I can do backslash n after the exclamation point and rerun this again.
    • 0:29:51And now we're back to the usual.
    • 0:29:53But I do get that exclamation point now for free as default functionality.
    • 0:29:58So it's a little weird because I'm mixing sort of apples and oranges,
    • 0:30:01so to speak, whereby this is positional and this is named,
    • 0:30:05but, so long as you put your positional arguments first and any things that
    • 0:30:08have explicit names after those, Python can distinguish one from the other.
    • 0:30:14Questions then on any of this just yet?
    • 0:30:19Questions?
    • 0:30:20Yeah.
    • 0:30:20AUDIENCE: Can you change the type of the variable [INAUDIBLE]?
    • 0:30:24DAVID J. MALAN: Oh, really good question.
    • 0:30:25Can you change the type of a variable once it's there?
    • 0:30:27Can you change, for instance, a string to an integer or maybe vice versa?
    • 0:30:30Short answer, yes.
    • 0:30:31And we're going to trip over that with an example in just a bit.
    • 0:30:34And let me call out one other thing that's worth noting here.
    • 0:30:37In the documentation for Python and even in your own code,
    • 0:30:40it turns out that you can use single quotes in ways we have not thus far.
    • 0:30:44Recall that in C double quotes meant it was
    • 0:30:46a string, so typically a phrase, a sentence, a paragraph, whatever.
    • 0:30:50But single quotes in C represented what?
    • 0:30:53So a single character.
    • 0:30:55That is the definition.
    • 0:30:56In Python, this seems to suggest single characters too,
    • 0:31:00but I clearly just did an exclamation point and then
    • 0:31:03backslash n, so two characters.
    • 0:31:05And that's in fact allowed.
    • 0:31:06In Python, there's no difference between single quotes and double quotes.
    • 0:31:10Stylistically, in CS50 and style50, we'll
    • 0:31:13actually nudge you toward using double quotes just for parity with C,
    • 0:31:17but it is perfectly reasonable to use single quotes instead in Python,
    • 0:31:21but, stylistically, you should be consistent.
    • 0:31:23Why are they both tolerated?
    • 0:31:25Well, all these weeks, you've been holding the darn shift key
    • 0:31:28and then hitting the quote mark to get double quotes.
    • 0:31:30Now, you don't have to hit the Shift key anymore
    • 0:31:32if you don't want to just speed up your code even more.
    • 0:31:34And that, frankly, is probably part of the motivation for even
    • 0:31:38little syntactic differences like that.
    • 0:31:40All right, how about some other features that we
    • 0:31:42might want to bring into the mix?
    • 0:31:44We've seen use of variables already, like answer.
    • 0:31:47Let's make this a little more--
    • 0:31:49let's do this side by side with Scratch and with C as well.
    • 0:31:52So, in Scratch, this is how we created a variable called counter and initialized
    • 0:31:56it to 0.
    • 0:31:57In C, we achieved that by doing int counter equals 0 semicolon.
    • 0:32:02In Python, we've already seen something reminiscent
    • 0:32:04of this, albeit with strings instead of integers,
    • 0:32:07but probably not a logical leap to assume that this, in Python, is
    • 0:32:10how you could create a variable called counter,
    • 0:32:12assign it an integer, namely 0, no semicolon, no data type.
    • 0:32:17And this will simply be an int because it's pretty obvious to the interpreter
    • 0:32:21that 0's an int, not a string.
    • 0:32:23So, of course, underneath the hood, this is going to be an int.
    • 0:32:25What else could we do in Scratch?
    • 0:32:27We could change the counter by 1, by incrementing it, adding 1 to it.
    • 0:32:31In C, we saw a few different ways to do this.
    • 0:32:33We can do counter equals counter plus 1, which
    • 0:32:35seems like a paradox that how could that possibly be.
    • 0:32:38But, recall, we do the addition at right.
    • 0:32:40We copy the value from right to left when using the assignment operator.
    • 0:32:43In Python, meanwhile, we would do this-- counter equals counter plus 1.
    • 0:32:47Same exact thing, except for, of course, the semicolon no longer being necessary.
    • 0:32:52But, in C, we could also do this-- counter plus equals 1 semicolon.
    • 0:32:56Turns out you can do the exact same thing in Python without the semicolon.
    • 0:33:01But there's one thing you can't do.
    • 0:33:03Who knows why?
    • 0:33:04But what can you probably not do?
    • 0:33:06AUDIENCE: counter++.
    • 0:33:07DAVID J. MALAN: Yeah, so counter++.
    • 0:33:09If you've been in the habit of using ++ and --, for better or for worse,
    • 0:33:12Python does not have those.
    • 0:33:13So we're back to the slightly more verbose version here.
    • 0:33:16So we get two out of the three possibilities,
    • 0:33:19but just a minor difference that will be ingrained over time.
    • 0:33:22Well, what about the actual data types that Python supports?
    • 0:33:26Well, we've used strings already.
    • 0:33:27I just showed some integers there.
    • 0:33:29Python does have its own list of data types, which is actually, at a glance,
    • 0:33:33shorter than C's when it comes to the most primitive ones.
    • 0:33:36In C, we saw at one point pretty much this list.
    • 0:33:40And then we created some of our own.
    • 0:33:41In Python, this list indeed gets a bit shorter such
    • 0:33:44that we have bools still for true/false values.
    • 0:33:47But, as you might have glimpsed earlier, it's
    • 0:33:49capital True and capital False, T and F, respectively, just because.
    • 0:33:54There are still floats in the world of Python,
    • 0:33:56there are still ints in the world of Python, and there are strings,
    • 0:33:59but they're called strs, S-T-R for short.
    • 0:34:02And there are indeed some other ones as well.
    • 0:34:04But there are no doubles, per se.
    • 0:34:06There are no longs.
    • 0:34:07Rather, Python generally uses a bit more memory so you as the programmer
    • 0:34:11don't need to worry about how many bits are being used, particularly
    • 0:34:14for something like integers, so more on that before long.
    • 0:34:17AUDIENCE: Are there no characters?
    • 0:34:18Would that be strings?
    • 0:34:19DAVID J. MALAN: Good question.
    • 0:34:20Are there no characters?
    • 0:34:21Short answer, correct.
    • 0:34:23There are no characters.
    • 0:34:24There are only strings which can be single characters and even 0 characters
    • 0:34:29because, heck, that seems sufficient rather than distinguishing
    • 0:34:32between one or the other.
    • 0:34:34So if you want a character in Python, really, the best you can do
    • 0:34:37is a string with a single character instead.
    • 0:34:39Now, it turns out, in Python, there's going
    • 0:34:41to be other features as well, data structures.
    • 0:34:44So, just a week ago, we spent on week 5's material
    • 0:34:48when looking at trees and tries and hash tables and more.
    • 0:34:51Python just gives you those and other data structures built in.
    • 0:34:55No longer do you implement your own spell checker with your own dictionary.
    • 0:34:59You can use, as we did earlier, a set.
    • 0:35:01Turns out there are dictionaries or dict objects
    • 0:35:04that come with Python that you can yourself use.
    • 0:35:06There are tuples which are like x comma y values
    • 0:35:10or latitude comma longitude, so short lists of values.
    • 0:35:13There's actually lists, which are similar in spirit to C's arrays.
    • 0:35:17But recall that the headache of C's arrays as of week 5 was it's
    • 0:35:22not very easy to grow them or shrink them because of all
    • 0:35:25the darn memory management.
    • 0:35:26Python, if you use a list, essentially gives you a linked list automatically.
    • 0:35:30You don't have to think or use any memory management or pointers at all.
    • 0:35:35And range, we're going to see, just gives you a range of values.
    • 0:35:37If you want to count from 1 on up to something else,
    • 0:35:40range is actually a function that can give us some
    • 0:35:43of that same functionality as well.
    • 0:35:45So let's perhaps take some of these out for a spin here.
    • 0:35:47Let me go back to VS Code.
    • 0:35:49Let me close up hello.py.
    • 0:35:51And let's focus on maybe implementing a simple calculator
    • 0:35:54as we did a few weeks ago.
    • 0:35:56In fact, let me go ahead and open up from my distribution code from lecture
    • 0:36:00today wherein I brought in advance-- and these were on CS50's website--
    • 0:36:04a whole bunch of examples from earlier weeks that we already
    • 0:36:07implemented together.
    • 0:36:08So, for instance, in week 1, we actually implemented a calculator
    • 0:36:11that prompted the user for two ints, x and y,
    • 0:36:14and then simply added them together using printf in this way,
    • 0:36:17with percent i as the placeholder and a second argument,
    • 0:36:20which was the sum thereof.
    • 0:36:22Well, if I want to implement this in Python,
    • 0:36:24it's actually going to be pretty similar.
    • 0:36:26So let me also run code of calculator.py.
    • 0:36:30That's going to open a second tab.
    • 0:36:31For the sake of comparison, let me drag this over to the right
    • 0:36:35so we can see these things side by side.
    • 0:36:36And now let me do this, from CS50's library import
    • 0:36:40the get_int function, which I claim exists in that library.
    • 0:36:44Then let's go ahead and create a variable
    • 0:36:46called x, set it equal to get_int, and pass in a prompt of x colon space
    • 0:36:51just so the user knows what we're asking for.
    • 0:36:54Then let's do y equals get_int and prompt the user for a y value.
    • 0:36:58And then, down here, let's go ahead and print out x plus y.
    • 0:37:02I think it's pretty straightforward as written there.
    • 0:37:05We don't mention the semicolons.
    • 0:37:06We don't mention the data types.
    • 0:37:07But, for the most part, the logic is exactly the same.
    • 0:37:10Let me run Python of calculator.py, type in 1, type in 2,
    • 0:37:14and I do get back, in fact, 3.
    • 0:37:17So that calculator seems actually to work.
    • 0:37:19But let's get rid of CS50's library.
    • 0:37:22So, just as quickly as we put these training wheels on today,
    • 0:37:24let's take them back off so, at the end of the week, at the end of the course,
    • 0:37:28certainly, you're not relying on any of these training wheels anymore.
    • 0:37:31So let me get rid of this line of code at the very top,
    • 0:37:35no longer using get_int.
    • 0:37:36And let's do this using Python's own built-in functionality.
    • 0:37:41So Python itself supports this here function
    • 0:37:46called input, which similar to get_string and get_int and get_float
    • 0:37:49takes a prompt as input.
    • 0:37:51So I'm going to say x colon as before.
    • 0:37:53I'm going to go ahead and say input y colon as before,
    • 0:37:57and then I'm just going to print these both out using Python's own input
    • 0:38:00function instead of CS50's get_int.
    • 0:38:04Let's run Python of calculator.py again, Enter.
    • 0:38:07Type in 1, type in 2, and the answer, of course, should be not 12.
    • 0:38:14So what just happened here?
    • 0:38:17Should still be 3.
    • 0:38:18Yeah.
    • 0:38:19AUDIENCE: Yeah, format [INAUDIBLE] strings.
    • 0:38:21DAVID J. MALAN: Yeah, so it seems that x and y came back as strings.
    • 0:38:24And so what's happening with the plus operator here
    • 0:38:26is it's actually being interpreted as concatenation.
    • 0:38:28So I'm really saying not 12 per se, but 1 2 join together because the variable
    • 0:38:34that apparently-- the return value that comes back from Python's own input
    • 0:38:37function appears to be a string, that is, a str by default.
    • 0:38:41Now, there are ways to fix this in Python.
    • 0:38:43And, in C, recall that we were able to cast some values from one
    • 0:38:47to another, like ints to chars and back and forth.
    • 0:38:50It's not quite as easy as that in Python because, technically,
    • 0:38:53a string, as we know underneath the hood has one or more characters.
    • 0:38:57Maybe there's a backslash 0 somewhere in there.
    • 0:39:00Who knows how Python is doing it, but there is a function in Python
    • 0:39:04called int, which takes as input a string.
    • 0:39:07And it will do its best to convert that string
    • 0:39:10to the actual int that resembles it.
    • 0:39:13So if it's, quote, unquote, "1", it's going to give me the actual int known
    • 0:39:16as 1 and so forth.
    • 0:39:18So let me do that here as well as here.
    • 0:39:20Let me again run Python of calculator.py, Enter.
    • 0:39:241 again, 2 again, and this time 1 plus 2 equals 3.
    • 0:39:28So similar in spirit, but now I just needed new tool in my toolkit,
    • 0:39:32this int function which does that conversion for me.
    • 0:39:36Now, what actually is in this library, CS50's own
    • 0:39:39that you may or may not want to use?
    • 0:39:40So, in C, we had these functions as well as some other stuff,
    • 0:39:43including the actual definition of string.
    • 0:39:45In Python, there are indeed strings that come with the language.
    • 0:39:48They're simply called strs, S-T-R.
    • 0:39:50In CS50's library for Python, though, we kept
    • 0:39:53it simpler and consistent with Python the language itself.
    • 0:39:56So CS50's library for Python has get_string.
    • 0:39:59It has get_int.
    • 0:40:00It has get_float.
    • 0:40:02These we'll see are still useful because, just like in C,
    • 0:40:05recall that if the user types in like cat or dog
    • 0:40:08when you're actually asking them for an integer, our functions
    • 0:40:11prompt the user again and again and again.
    • 0:40:13So these functions will do that as well.
    • 0:40:16We'll soon see that the input function in Python,
    • 0:40:18it's quite similar to get_string, but it's not
    • 0:40:21as tolerant of invalid input like cat or dog.
    • 0:40:24If you're actually trying to get an int or a float,
    • 0:40:26you're just going to see a scary error message instead on the screen, which
    • 0:40:29we'll come back to before long.
    • 0:40:31But this is to say the library is there to get you started, but not
    • 0:40:35strictly necessary, ultimately.
    • 0:40:36But if you want to use those functions, you
    • 0:40:38can do as before, from cs50, import the name of the function,
    • 0:40:42and you can do this three times.
    • 0:40:43If, for whatever reason in a program, you're using all three of these
    • 0:40:46can just separate them by commas in this way and import all three of them
    • 0:40:50here at once.
    • 0:40:51Or, as you might recall earlier, you can just
    • 0:40:53import the name of the library, so something like import cs50,
    • 0:40:57though, the syntax thereafter changes a bit.
    • 0:41:00Before we forge ahead to now conditionals,
    • 0:41:02just comparing something side by side, and then we'll
    • 0:41:04build up some more interesting programs.
    • 0:41:06Questions?
    • 0:41:07For the most part, it's just syntactic differences and not
    • 0:41:10really fundamentally different intellectual ideas under the hood
    • 0:41:13just yet.
    • 0:41:14So here we are with conditionals.
    • 0:41:16In Scratch, if you wanted to compare x and y as variables
    • 0:41:18and say conditionally x is less than y, we converted that to C as follows.
    • 0:41:23The curly braces are about to go away, the semicolon's about to go away,
    • 0:41:26and there's going to be one new piece of syntax here.
    • 0:41:28In Python, the same idea looks like this.
    • 0:41:31What is the one piece of syntax that did get added, though, in this case?
    • 0:41:37Feel free to shout it out.
    • 0:41:38AUDIENCE: Colon.
    • 0:41:39DAVID J. MALAN: There's a colon suddenly,
    • 0:41:41which we did not have in C. It turns out,
    • 0:41:43in Python, though, this is both a plus and a minus depending on your religion
    • 0:41:48when it comes to whitespace in programs.
    • 0:41:50So, in C, if you were not in the habit of clicking style50 and letting
    • 0:41:54it guide you toward better formatted code,
    • 0:41:57frankly, you could just left align everything in your C programs,
    • 0:42:00and, even though it would be a mess to read, difficult to grade,
    • 0:42:04it would still work.
    • 0:42:05It would still be correct, but just stylistically bad.
    • 0:42:08In Python, it seems that humans over the years
    • 0:42:10were just so darn frustrated by students and presumably colleagues
    • 0:42:14alike formatting their code poorly that, in Python, indentation matters.
    • 0:42:19So if you want to execute print conditional on x being less than y,
    • 0:42:24you can't just put print right below if and expect
    • 0:42:27the reader and the interpreter to figure things out.
    • 0:42:30You must indent by convention four spaces instead.
    • 0:42:33You can override that, and you can adopt different paradigms
    • 0:42:36within your own company or school.
    • 0:42:37But four is what style50 would now expect.
    • 0:42:41So this is to say, the colon means execute conditionally
    • 0:42:44everything that's indented below that as though there were curly braces instead.
    • 0:42:48All right, how about something else in Scratch?
    • 0:42:50If you wanted to do an if-else, it looked like this.
    • 0:42:53In C, it looked like this, which is identical except for the else
    • 0:42:57block here.
    • 0:42:58In Python, you can probably predict how this
    • 0:43:00is going to get a little more succinct.
    • 0:43:02No more semicolons, no more curly braces, no more backslash
    • 0:43:06ends for that matter, but a colon here and a colon here.
    • 0:43:09And, again, indentation matters and must be consistent,
    • 0:43:13four spaces in this case for both.
    • 0:43:15Finally, if, else if, else we did in Scratch.
    • 0:43:19You can do that same thing in C almost identical,
    • 0:43:22except we've got this else if.
    • 0:43:23This is the only one that's weird, and even
    • 0:43:25I forget how to spell this all of the time.
    • 0:43:27In Python, the semicolons are about to go away,
    • 0:43:29the new line is going to go away, the curly braces are going to go away,
    • 0:43:32and we're going to misspell else if as such.
    • 0:43:35So it's elif, in Python, colon, which is how
    • 0:43:39you would implement if, elif, elif, elif, else for a conditional like this.
    • 0:43:44Some languages very confusingly use else if or elsif but no e
    • 0:43:49and probably shouldn't've said that because now you'll
    • 0:43:51be as confused as I have been for years.
    • 0:43:53But let's move on to what we can actually do now with these here strings.
    • 0:43:56So we know what we can use these conditionals in this way.
    • 0:44:00Let's go ahead now and revisit some programs
    • 0:44:02from C but this time using some new syntax and features.
    • 0:44:06So let me go back to here VS Code.
    • 0:44:08Let me open up in one window here.
    • 0:44:12How about compare3.c?
    • 0:44:15So this was from today's distribution code,
    • 0:44:18a file called compare3.c, which we looked at some time ago.
    • 0:44:21And what this program did, quite simply, is
    • 0:44:23exactly what we just saw on the screen, but with a full-fledged main function
    • 0:44:27and the header files and the like.
    • 0:44:28But all this program does is tell us whether x is less than y or not.
    • 0:44:33All right, how can we go about implementing this in Python?
    • 0:44:36Pretty straightforward.
    • 0:44:37Let me open my terminal.
    • 0:44:38Let me do code of compare.py for this version.
    • 0:44:43Let me drag it over to the right so I can see these things side by side
    • 0:44:47and hide my terminal again.
    • 0:44:48Let's go ahead and import from cs50 the get
    • 0:44:51int function just to make our lives a little easier for now.
    • 0:44:54Let's use x equals get_int and prompt the user for What's x question mark,
    • 0:44:59just like I did at left.
    • 0:45:01Let's do y equals get_int, passing in, What's
    • 0:45:04y question mark, just like at left.
    • 0:45:06Then let's just do if x is less than y colon, Enter.
    • 0:45:11And, notice, VS Code is not only smart enough but deliberately configured by us
    • 0:45:15to know something about Python.
    • 0:45:17So it automatically indented for me.
    • 0:45:19Just like C very often has to.
    • 0:45:21Let's print out x is less than y quote unquote.
    • 0:45:25Elif x greater than y colon, then let's print out x is greater than y,
    • 0:45:31close quote.
    • 0:45:32Else colon print out x is equal to y.
    • 0:45:36So nothing different versus the slides, but you can kind of
    • 0:45:40see visually just how much more compact the code is, like 11 actual lines
    • 0:45:43instead of 21.
    • 0:45:44So it's just eliminating a lot of distraction and clutter
    • 0:45:47and tightening things up.
    • 0:45:48If nothing else, let's go ahead and run Python of compare.py, Enter.
    • 0:45:52Let's type in 1, type in 2, and let me just wave my hand at the reality
    • 0:45:56that I'm pretty sure the code is correct and would work correctly
    • 0:45:59if we typed in 2 and 1 or 1 and 1, 2 and 2, and so forth.
    • 0:46:03So this is to say that comparing integers in Python
    • 0:46:07logically works exactly the same way as in C, but things, recall, in Python
    • 0:46:13got a little weirder when we actually tried comparing, say, strings instead.
    • 0:46:19And recall that when we compared strings in Python,
    • 0:46:23we had a solve a problem we encountered.
    • 0:46:26The very first time we compare two strings in C, s and t,
    • 0:46:30as I think I called them weeks ago, they were never the same
    • 0:46:33according to my first version of my code.
    • 0:46:36Why is it harder to compare strings in C?
    • 0:46:42AUDIENCE: The address [INAUDIBLE] the wrong address.
    • 0:46:45DAVID J. MALAN: Exactly.
    • 0:46:46So recall from week 4, where we really looked underneath the hood
    • 0:46:49and we realized that, oh, a string is really
    • 0:46:51a char star, which is the address of the first character in the string.
    • 0:46:55So whenever you compare two strings with equals equals in C,
    • 0:46:57you're really comparing the memory addresses,
    • 0:46:59and those probably are not going to be the same.
    • 0:47:01So even if the strings look the same, they're always different.
    • 0:47:03That was a pain in the neck.
    • 0:47:04We had to add in the string library and the str
    • 0:47:06compare function, str comp-- strcmp.
    • 0:47:09It was just a lot of work to do something so darn common.
    • 0:47:11It is super common to want to compare strings.
    • 0:47:14In Python, wonderfully-- let me close the int-based version from C here--
    • 0:47:19let me propose here that in Python, if you want to manipulate strings,
    • 0:47:24you could use CS50's own get_string function.
    • 0:47:26But I don't even need that.
    • 0:47:27I can use the input function, as we saw earlier.
    • 0:47:30So if I want to prompt the user for s equals, the return value of input,
    • 0:47:33and just prompt them for a string like s. t equals the input function-- prompt
    • 0:47:38them for a string called t.
    • 0:47:39In Python, wonderfully, it works the way you would hope.
    • 0:47:42If s equals equals t, then print out, quote unquote, "Same."
    • 0:47:48Else, print out, quote unquote, "Different."
    • 0:47:51So here, again, it just works the way you would hope.
    • 0:47:54And you don't have to pull out your textbook or your old examples
    • 0:47:56to figure out how to do something relatively straightforward--
    • 0:47:59conceptually is comparing two strings.
    • 0:48:02Let's do one other example that evokes a past example as well.
    • 0:48:06Let me open up a program that, in week one, we called agree.c.
    • 0:48:11So at left, here is a program that we wrote several weeks ago now that used
    • 0:48:15the CS50 library, the standard IO library.
    • 0:48:18It used the getchar function to ask the user,
    • 0:48:20do you agree with some terms and conditions or whatever.
    • 0:48:23And then we use this syntax, which was very new in week one
    • 0:48:26because not only were we using equals equals,
    • 0:48:28we used the vertical bars, which meant what logically?
    • 0:48:32Or.
    • 0:48:33So we used or to detect if someone typed in uppercase or lowercase for either y--
    • 0:48:39or big Y, little y or big N, little n as well.
    • 0:48:43So, in Python, let's do this instead--
    • 0:48:45code of agree.py.
    • 0:48:47I'll hide my terminal window, but I'll drag this here over at left.
    • 0:48:51And in the Python version of this, turns out,
    • 0:48:54I can do something similar as follows.
    • 0:48:56Let's do S equals input and prompt the user, do you agree, question mark.
    • 0:49:03Then let's say if s equals equals quote unquote y or s equals quote unquote
    • 0:49:11little y, then print out quote unquote "Agree," just like in the C version.
    • 0:49:16Elif s equals equals capital N or s equals equals lowercase n,
    • 0:49:23then print out "Not agreed," just like in the C version.
    • 0:49:26And here, again, we're sort of seeing just how much this condenses our code.
    • 0:49:30It's working logically the same, but what are some of the differences
    • 0:49:33visually?
    • 0:49:33Well, there's no curly braces, there's no semicolons, there's no new lines.
    • 0:49:37But what is there?
    • 0:49:39This is why Python 2 is considered more user-friendly.
    • 0:49:42If you want to express the idea of "or," literally write "or" instead of vertical
    • 0:49:46bars and double ampersands and the like.
    • 0:49:48So I'm using or here as well as or here.
    • 0:49:51Notice there's no parentheses either around these conditionals.
    • 0:49:54So we didn't see those on the slides.
    • 0:49:56We don't see them here.
    • 0:49:56What Python does with parentheses is that if you
    • 0:49:59don't need them logically to combine Boolean expressions,
    • 0:50:03just don't use them at all.
    • 0:50:05You could use them here and here and here and here.
    • 0:50:08But if it's not necessary, why bother further cluttering your code?
    • 0:50:12You simply do not need to do it.
    • 0:50:14But let's see if there's a way to improve this.
    • 0:50:17Let me first run this and make sure it works as intended--
    • 0:50:20python of agree.py.
    • 0:50:22Do I agree?
    • 0:50:23An emphatic yes.
    • 0:50:25Let's do a lowercase n.
    • 0:50:28And agreed and not agreed are indeed the answers I get back.
    • 0:50:31But this feels a little redundant, I would say.
    • 0:50:35Notice that my code here is really just asking the same question twice,
    • 0:50:40albeit for lowercase, and it's asking the same question twice here,
    • 0:50:43albeit for lowercase for the n as well.
    • 0:50:46Well, it turns out, in Python, I can actually tighten this up.
    • 0:50:48Let me get rid of my C version and focus on this one, and let me go ahead
    • 0:50:52and condense this further as follows.
    • 0:50:55If s is in the following list of values, quote unquote, "Y," quote unquote,
    • 0:51:04little "y", colon, and then, down here, I'm going to do the exact same thing,
    • 0:51:08logically.
    • 0:51:09Elif s is in this list of comma-separated values, capital N,
    • 0:51:14lowercase n, this now would achieve the same result.
    • 0:51:17It's a little tighter because I'm not using or.
    • 0:51:19I'm not using equals equals four times.
    • 0:51:22I'm using it not at all, in fact.
    • 0:51:23I'm using a new keyword which, in Python, exists--
    • 0:51:26"in"-- as a preposition-- is a Python keyword, does not exist in C.
    • 0:51:30But this here would be a little tighter as well.
    • 0:51:32So let me go ahead and run Python of agree.py, Enter.
    • 0:51:35Do I agree?
    • 0:51:36Capital Y-- it still works.
    • 0:51:37Or if I do lowercase y, it still works.
    • 0:51:40But this isn't as featureful as would be ideal because what if the user types
    • 0:51:43in, for instance, an emphatic YES in all caps?
    • 0:51:46Well, now it just ignores me altogether.
    • 0:51:48Now you could go in and, of course, address that.
    • 0:51:51I could do capital YES and lowercase yes.
    • 0:51:53But wait a minute, what if they just capitalize the first letter?
    • 0:51:55So I should really have y.
    • 0:51:57And then, well, what if their Caps Lock is not working as intended, and maybe
    • 0:52:01we do something like this?
    • 0:52:03And now we've got to do this.
    • 0:52:05I mean, these are all spelled the same, even if they're miscapitalized.
    • 0:52:09So this just feels like it's becoming a mess pretty quickly.
    • 0:52:12So, logically, whether it's in C now or in Python,
    • 0:52:15what would ideally be a better logical solution
    • 0:52:18to this than enumerating all possible values that we care about?
    • 0:52:22Yeah?
    • 0:52:23AUDIENCE: Change the input to lowercase.
    • 0:52:24DAVID J. MALAN: Yeah, why don't we just change the user's input
    • 0:52:27to lowercase or equivalently-- just change
    • 0:52:29it to uppercase, to canonicalize it, make it the way I expect it to be,
    • 0:52:33and then compare it against a much shorter, finite list of values?
    • 0:52:37So how do we do this?
    • 0:52:38Well, in the C type library, we had a tolower function, which was handy,
    • 0:52:43and we had toupper.
    • 0:52:45But in Python, what's nice is that Python actually has not only strs,
    • 0:52:50or strings, as first-class objects that come with the language itself,
    • 0:52:55Python itself as a language is known as an object-oriented language.
    • 0:52:59And it has other features as well.
    • 0:53:00And some of you in high school, if you ever studied Java or the like,
    • 0:53:02you might already know about object-oriented programming, otherwise
    • 0:53:05known as OOP.
    • 0:53:07And what this is referring to is a new and improved version of C structs.
    • 0:53:13Recall that in C we had structs whereby we could create our own data
    • 0:53:16types for like persons or nodes--
    • 0:53:19for instance, by creating our own data types
    • 0:53:21that have one or more other values inside of them.
    • 0:53:25Well, what C doesn't offer you-- at least not easily--
    • 0:53:28is to associate functionality with those structures as well.
    • 0:53:31For instance, for a person object, wouldn't it
    • 0:53:33be nice if there were a function, especially
    • 0:53:35if running the code on your phone, that was a call function that would just
    • 0:53:38automatically call that person or an email
    • 0:53:40function that would just automatically email that person if we're keeping
    • 0:53:43track of their email address as well?
    • 0:53:45Well, you could implement a call function
    • 0:53:46and pass the person in as input.
    • 0:53:48You could implement a call function and pass the person in as input,
    • 0:53:52and then it would work.
    • 0:53:53But wouldn't it be nice to associate more tightly
    • 0:53:56and encapsulate related functionality, just like we've
    • 0:53:59been encapsulating related data?
    • 0:54:02And this is what object-oriented programming allows you to do.
    • 0:54:05Instead of having what are called structs in C,
    • 0:54:08you have what are called objects in Python
    • 0:54:11and certain other languages as well.
    • 0:54:13And those objects are typically defined--
    • 0:54:15what's called a class, when a Class is really
    • 0:54:17just like a blueprint or a template out of which multiple objects can be made.
    • 0:54:22And, specifically, in the context of this here example,
    • 0:54:26we could consult the documentation for the functions that come with the str
    • 0:54:32object, the string object.
    • 0:54:34And technically, whenever functionality is associated with a specific data type,
    • 0:54:38it's encapsulated inside--
    • 0:54:39it's still a function, but you technically
    • 0:54:42call it a method, in that case, instead.
    • 0:54:44So a function is what all we've been discussing in C and in Scratch.
    • 0:54:49In Python, you still have functions, but if those functions
    • 0:54:52are associated with a data type, tucked away inside of them,
    • 0:54:55then they're just also called methods.
    • 0:54:57It's a minor nuance there.
    • 0:54:58And among the functions, among the methods,
    • 0:55:01rather, that comes with strs, or strings,
    • 0:55:04is a little something called lower.
    • 0:55:06And there's different ways to go about doing this.
    • 0:55:08So let me go ahead and, one, simplify this list to just be the list of values
    • 0:55:13that I actually care about.
    • 0:55:14So let's suppose that I want to support, quote unquote, "y" and quote unquote,
    • 0:55:18"yes," but I don't care about the capitalization thereof.
    • 0:55:22So I could do this.
    • 0:55:23I could take the s variable and I could-- actually, let's do this.
    • 0:55:26I can create another variable, t, set it equal to s.lower,
    • 0:55:31open paren, close paren.
    • 0:55:33So notice the dot operator, just like in C, goes inside of the object.
    • 0:55:36Same thing in Python, but here, I'm not going inside of it
    • 0:55:39to get the person's name or their number or their email address.
    • 0:55:43I'm going inside of it to call a method that just comes with that type of value.
    • 0:55:49So in C, just to be super clear, we would have done tolower and pass in s.
    • 0:55:54Python-- in an object-oriented programming more
    • 0:55:56generally-- just kind of flips that paradigm
    • 0:55:58and says start with the variable in question
    • 0:56:00and call its own lowercase method as such.
    • 0:56:04And now, if I change this code to t, down here and here,
    • 0:56:08and I go in here and I search for lowercase n or lowercase no,
    • 0:56:15and I run this version of agree.py, Enter, I can now type in "Y" for yes,
    • 0:56:20capitalized, "y" for yes lowercase, YES all capitalized for yes,
    • 0:56:25y lowercase capital S, like that, any of those variants that exist,
    • 0:56:29and I only have to enumerate canonical versions thereof.
    • 0:56:33Even better, I can tighten this up further.
    • 0:56:35I don't really need a t variable.
    • 0:56:37In fact, I could just do s equals s.lower and change the value of s
    • 0:56:42to be the lowercase version thereof.
    • 0:56:43What's nice about Python, too, is you can chain method calls together.
    • 0:56:48So if you know that input as a function already returns a string,
    • 0:56:52you don't need to tuck it in a variable before you
    • 0:56:54call that string's lower method.
    • 0:56:57And you can just chain them together in this way.
    • 0:56:59And you could do this sort of again and again.
    • 0:57:02This is not a real function, but you could
    • 0:57:04keep chaining these things together one or more times.
    • 0:57:06At some point, it's going to look stupid because it's just
    • 0:57:08going to be too long of a line of code, and then we
    • 0:57:10get into discussions of style.
    • 0:57:11But for now, having two function calls like this is pretty reasonable,
    • 0:57:16I would argue.
    • 0:57:17And so this just tightens up the code further.
    • 0:57:21So that is perhaps the newest feature that we've now
    • 0:57:24seen of Python, this notion of methods, which
    • 0:57:27derives from this feature of object-oriented programming.
    • 0:57:30But any questions before we take a quick tour of a few other features as well?
    • 0:57:35No?
    • 0:57:35OK, about a couple more examples, then introduce some loops,
    • 0:57:38and we'll skate our way toward some snacks in just a few.
    • 0:57:42So let me propose that we look at one other problem from our week
    • 0:57:474, where in memory and the fact that it exists and has to be managed by
    • 0:57:52us was creating some underlying problems.
    • 0:57:54So let me open up a program from week 4 that was called copy5.c.
    • 0:57:59At least that was our several iterations in.
    • 0:58:02And that program looked a little something like this.
    • 0:58:04And I'll just skim it for a second.
    • 0:58:06This was getting kind of annoying just to copy one string into another.
    • 0:58:10So I had to use all of these libraries in C. I used CS50's get_string
    • 0:58:15function still, but this is when we took the training wheels of strings off,
    • 0:58:18quote unquote, and started talking about them as char stars.
    • 0:58:20I checked to make sure that s is not null, just in case
    • 0:58:23we're out of memory for some reason.
    • 0:58:25I used malloc, ultimately, to create more memory,
    • 0:58:28to get more memory for the copy, but still checking if it's null.
    • 0:58:32I then copied the string from one to the other using strcpy.
    • 0:58:37I then made sure the string was long enough,
    • 0:58:39and then I uppercased the first letter in it.
    • 0:58:41Then I printed them out, then I freed the string, and so forth.
    • 0:58:45Like, it was a lot of work just to make a copy of a string, which
    • 0:58:48in programming in general, it'd be nice if you could just do it more simply.
    • 0:58:53So in Python, here too, it's as simple as that.
    • 0:58:56Let me go into VS Code, open up a new file called copy.py Then
    • 0:59:01let me put these two side by side.
    • 0:59:03And in the right-hand version in Python, let's do this. s equals input,
    • 0:59:08and prompt the user as before for a string like s, quote unquote.
    • 0:59:12Then let's go ahead and create a second variable called t,
    • 0:59:15set it equal to the s variables, capitalize methods return value,
    • 0:59:22and then print out down here--
    • 0:59:24how about s and then print out t.
    • 0:59:29Let me open my terminal.
    • 0:59:30Let me run Python of copy.py.
    • 0:59:33Recall that, last time, when I did "hi!," it capitalized the whole thing,
    • 0:59:40as I recall, as opposed to capitalizing just the first letter.
    • 0:59:44Enter-- this time, it works as expected.
    • 0:59:47Now the print is technically a little different.
    • 0:59:49Down here, I use these format strings.
    • 0:59:50So if I really want to make this identical,
    • 0:59:52I can do f quote unquote s colon and then plug in the value of s
    • 0:59:56with curly braces, f quote unquote t colon t.
    • 1:00:00This looks uglier, but it's just now printing out prefixes,
    • 1:00:03s and t respectively.
    • 1:00:05So if I run this again and do hi in all lowercase,
    • 1:00:08it capitalizes it correctly for t and only for t.
    • 1:00:13So here, more so than ever, 33 lines of code at the left, 6 lines, two of which
    • 1:00:18are blank at right in Python.
    • 1:00:22Questions about this here example?
    • 1:00:26Yeah?
    • 1:00:27AUDIENCE: [INAUDIBLE] question about style.
    • 1:00:29Those blank lines [INAUDIBLE] not make it all [INAUDIBLE]?
    • 1:00:33DAVID J. MALAN: Those blank lines--
    • 1:00:36do you mean get rid of the blank lines?
    • 1:00:37Oh, you absolutely could.
    • 1:00:39I have been doing this visually just to make related chunks of code stand out.
    • 1:00:43So I got s, then I capitalize t, and then I printed them both,
    • 1:00:47but yes, you could totally format this in different ways,
    • 1:00:49just as I did at left as well.
    • 1:00:51Other questions about what we've done here?
    • 1:00:58How about this?
    • 1:01:01Let me propose that, in C, we also at one point
    • 1:01:04try to just uppercase everything in a string.
    • 1:01:07So let me open up what was a program called, from week 2,
    • 1:01:11uppercase.c, or really version 2 thereof here.
    • 1:01:16And this was a program that looks a little cryptic, but all it does
    • 1:01:19was ask the user for a string, the before version.
    • 1:01:22It then printed out after colon.
    • 1:01:24It's just a placeholder for an uppercase version thereof.
    • 1:01:27We then use strlen and this for loop to iterate over
    • 1:01:30all of the characters in the string.
    • 1:01:32And then, one at a time, we use the C type library's toupper function
    • 1:01:35to capitalize them again and again.
    • 1:01:37So you can probably imagine where this is going.
    • 1:01:39We don't need toupper anymore.
    • 1:01:40We can just use dot upper in some way.
    • 1:01:42But we do need to have the ability to do things with loops.
    • 1:01:45So, in Python, we still have loops, but the syntax
    • 1:01:48is going to be a little different and, frankly, a little easier, ultimately.
    • 1:01:51So in Scratch, if you wanted to repeat something three times like this,
    • 1:01:54you could implement it in C very mechanically,
    • 1:01:57so to speak, like this-- create a variable i,
    • 1:02:00increment it with plus plus again and again
    • 1:02:02and again, so long as it's less than three printing meow each time.
    • 1:02:06In Python, you can do the exact same thing, if you really want,
    • 1:02:09by saying variable equals value, but no semicolon, no data
    • 1:02:12type, while i less than 3 colon.
    • 1:02:15So just like conditionals, you don't need parentheses
    • 1:02:17if they're not logically necessary.
    • 1:02:19But you do need the colon, and you do need indentation.
    • 1:02:22You don't have the plus plus, so we have to do this slightly more verbose Python
    • 1:02:26version here, but that's exactly the same idea
    • 1:02:28to implement meowing three times.
    • 1:02:31Suppose, though, that we wanted to take a different approach here.
    • 1:02:35We could, in C, use not a while loop but a for loop.
    • 1:02:38And maybe you're nowadays in the habit of using these a bit more.
    • 1:02:40They're a little more succinct without all of the vertical clutter.
    • 1:02:43But this is how we could implement the same in C.
    • 1:02:45In Python.
    • 1:02:47It's not quite as obvious how to do this, but we could do it this way.
    • 1:02:50We could say for i in the following list of values--
    • 1:02:54and literally in square brackets, as I did
    • 1:02:56earlier, just enumerate one after the other the things I want to check for.
    • 1:02:59Instead of y and yes and no and n, I can iterate over three values.
    • 1:03:04This is fine, but just allow your mind to wander, if it hasn't already,
    • 1:03:09into thinking how this could get us in trouble.
    • 1:03:12Why is this approach of just enumerating 0, 1, and 2 probably not the best way
    • 1:03:17long term to do this?
    • 1:03:19What do you think?
    • 1:03:20Yeah?
    • 1:03:21AUDIENCE: What if you need a lot of values, like 100?
    • 1:03:23DAVID J. MALAN: Yeah, are you really going
    • 1:03:24to go-- what if you need a lot of value, like 100 of them?
    • 1:03:27Are you really going to do 0 comma 1 comma 2 comma 3 dot, dot,
    • 1:03:30dot to comma 99?
    • 1:03:32That's got to be a better-- there's got to be a better way than that, if only
    • 1:03:35because it's going to wrap around the screen.
    • 1:03:37I'm going to miscount and screw something up.
    • 1:03:38So indeed there is.
    • 1:03:40You can alternatively use a function in Python
    • 1:03:42called range, which does, as I said earlier, give you a range of values.
    • 1:03:45And if you want a range of three values, starting at 0 by default,
    • 1:03:49and going up to but not through this value,
    • 1:03:52you literally call the range function and say, how many values do you want?
    • 1:03:55And, essentially, what the range function does
    • 1:03:57is it hands you out one value at a time more
    • 1:04:00efficiently than the hardcoded list, which puts them all in memory at once.
    • 1:04:04Range is a little smarter and it knows how to give you, indeed,
    • 1:04:06just one value at a time.
    • 1:04:09But notice here, I'm using for i in range of 3, which is similar in spirit
    • 1:04:14to C, because I have this variable i but I'm not actually using i anywhere.
    • 1:04:18I'm not incrementing it.
    • 1:04:19I'm not comparing it against a value.
    • 1:04:21So strictly speaking, in Python, this is correct.
    • 1:04:24But stylistically, some people would actually, by convention,
    • 1:04:27change the i to just an underscore character, which
    • 1:04:30is a valid character for a variable, but it's just this visual indicator
    • 1:04:35that yes, this is a variable because for loop requires it in Python,
    • 1:04:38but who cares what it's called because I'm never actually going to use it.
    • 1:04:41So you'll see this convention sometimes but perfectly
    • 1:04:44reasonable to also use i by convention because i means integer,
    • 1:04:47and that's really what's happening anyway.
    • 1:04:49But just FYI-- a convention there in Python.
    • 1:04:52So how can we now use these loops in some actual code?
    • 1:04:57Well, let me propose that what we could do here is the following.
    • 1:05:03Let me go back to VS Code here in my uppercase version,
    • 1:05:06and let me quickly whip up a Python version that
    • 1:05:09achieves something quite similar.
    • 1:05:11Let me go ahead and run code of uppercase.py at top left,
    • 1:05:16after dragging this over.
    • 1:05:18Let's go ahead and implement the following.
    • 1:05:20In a variable called before, set it equal to the return value of the input
    • 1:05:24function with quote unquote "Before" as the prompt.
    • 1:05:27Then let's just do a placeholder of quote unquote "After" colon space,
    • 1:05:31space, so they lined up in terms of numbers of letters, close quote, comma,
    • 1:05:35but let me do end equals quote unquote because I don't want a new line to move
    • 1:05:39the word below the word After.
    • 1:05:41So this is just a silly aesthetic detail,
    • 1:05:43but that overrides the default new line to being no new line.
    • 1:05:47Now let's do this.
    • 1:05:48In Python, instead of using this convoluted for loop and the semicolons
    • 1:05:53that in and this constant checking of a conditional,
    • 1:05:56I can actually just do this.
    • 1:05:57For every character called c in the Before string,
    • 1:06:02go ahead and print out that character uppercase, like that.
    • 1:06:07But don't print out a new line yet until we get to the very end,
    • 1:06:10go ahead and print a new line-- by printing nothing, but by default,
    • 1:06:14I'm going to get a new line.
    • 1:06:15So passing nothing in gives me one new line, and that's it.
    • 1:06:18So let me open VS--
    • 1:06:19let me open my terminal.
    • 1:06:20Run Python of uppercase.py, hi exclamation point in lowercase,
    • 1:06:25Enter, and I've messed something up.
    • 1:06:29Not intentional, but so be it.
    • 1:06:32Notice the error here.
    • 1:06:33So this is-- I can make this work.
    • 1:06:35So there's these things in Python called tracebacks which kind of trace
    • 1:06:38backwards what you did wrong.
    • 1:06:41And, in this case, what I did wrong, as for all of these carrot symbols,
    • 1:06:44is c dot uppercase is bad, but you probably already know that from earlier.
    • 1:06:48What I should have typed?
    • 1:06:50AUDIENCE: Dot upper.
    • 1:06:50DAVID J. MALAN: So dot upper.
    • 1:06:51So there's a lot of distraction here.
    • 1:06:53But much like Clang's output, there is some helpful information.
    • 1:06:56One, the file in question is uppercase.py.
    • 1:06:58Line 4 is where I made the mistake.
    • 1:07:00So even though the output is different from Clang's, it is similar in spirit.
    • 1:07:04Specifically, I messed up an attribute error
    • 1:07:06because some string object doesn't have an attribute that
    • 1:07:09is a method called uppercase.
    • 1:07:11Well, that's an easy fix.
    • 1:07:12As you noted, I should have written c.upper.
    • 1:07:16Delete, delete, delete, and now let's clear
    • 1:07:19my screen, rerun Python of uppercase.py, Enter, hi exclamation point,
    • 1:07:23and there we have the After version thereof.
    • 1:07:26But even here, note that, in Python, I'm doing even more work than I need to.
    • 1:07:31This is indeed how, in Python, I can enumerate all of the characters--
    • 1:07:36I can iterate over all of the characters in a string.
    • 1:07:39There's no i's.
    • 1:07:40There's no conditionals.
    • 1:07:42Python will just, on every iteration, update the variable c
    • 1:07:46to contain one letter, then the next, then the next, then the next.
    • 1:07:49It just sort of works the way you would hope.
    • 1:07:51But, in Python 2, recall that you don't have individual characters anyway,
    • 1:07:56so technically, I'm wasting my time by doing this one string of size
    • 1:08:001 at a time again and again and again.
    • 1:08:02I can tighten all of this up here, and I can just, for instance, do this.
    • 1:08:07I can go ahead and print out, for instance,
    • 1:08:12before.upper and just uppercase the whole thing all at once.
    • 1:08:16And then I could technically get rid of the new line,
    • 1:08:18but now I'm just wasting my time, too.
    • 1:08:20Let me get rid of all of this.
    • 1:08:21Let me go over here and let me output, for instance--
    • 1:08:28let me create a variable called After equals Before.upper.
    • 1:08:33That's going to store in the After variable exactly what I want all at once
    • 1:08:36without even using a for loop.
    • 1:08:38And now I can print out as before an f string saying after colon space, space,
    • 1:08:43and the value of the After variable.
    • 1:08:46So this, if I run it again, Python of uppercase.py,
    • 1:08:49Enter, hi in all lowercase, Enter, that too now works.
    • 1:08:53And one final flourish-- strictly speaking,
    • 1:08:55you can interpolate the value of what's returned from a function as follows.
    • 1:09:01Instead of even bothering with a variable here,
    • 1:09:04I could put a modest amount of code inside of the curly braces.
    • 1:09:09And I say modest because if this gets too long,
    • 1:09:11it's just going to confuse everyone, yourself included.
    • 1:09:13But in this case here, I can run this one more time, type in hi
    • 1:09:16in all lowercase, and that, too, now works
    • 1:09:19because I'm formatting it as an f string.
    • 1:09:21So, in short, I'm just getting more and more features at my disposal
    • 1:09:25that I can now use to solve some of these same problems.
    • 1:09:28So that there was a lot.
    • 1:09:29Let's go ahead and take a 10-minute break with some Fruit by the Foot,
    • 1:09:32and we'll be back with more complicated problems.
    • 1:09:34All right, we are back.
    • 1:09:36So let's go and use some of this new syntax
    • 1:09:38to actually make a meowing cat, albeit textually in Python.
    • 1:09:42So back here in VS Code, I'm going to go ahead and create
    • 1:09:44a program called meow.py.
    • 1:09:47And let's first do it the super simple way.
    • 1:09:49If we want the cat to meow three times, let's literally just do that in code.
    • 1:09:53So print, quote unquote, meow.
    • 1:09:54And we get the new line for free.
    • 1:09:56And then I'm just going to copy paste this again and again.
    • 1:09:58It's just going to give me three such lines, python of meow.py,
    • 1:10:02Enter, and there we have it, a cat that meows three times.
    • 1:10:05Of course, this is correct, but not well-designed
    • 1:10:07because what should I obviously be using instead as a feature of any language,
    • 1:10:12instead of three copy-pasted statements?
    • 1:10:15Probably a loop of some sort.
    • 1:10:16So let's borrow some of the inspiration from those previous slides.
    • 1:10:19Let's go into meow.py and change this to maybe a while loop, initially.
    • 1:10:23So how about i equals 0 then while i is less than 3,
    • 1:10:29go ahead and print out meow.
    • 1:10:31And then, let's go ahead and do i plus equals 1,
    • 1:10:35which is the relatively quick way to do that in Python but not like C++.
    • 1:10:41Python of meow.py, Enter--
    • 1:10:43so correct and better designed now.
    • 1:10:45How else could I do that?
    • 1:10:47Well, we saw earlier that I could do for i in 0, 1, 2, colon,
    • 1:10:52and then I can do print quote unquote "meow."
    • 1:10:55That too would work.
    • 1:10:56If I rerun Python of meow.py, that works.
    • 1:10:58But notice I'm not using i, and indeed, I'm not using 0 or 1 and 2.
    • 1:11:02So, technically, I could do something like, quote unquote, "cat," "dog,"
    • 1:11:08"bird."
    • 1:11:09I just need three things to enumerate over.
    • 1:11:11And that too is going to give me three meows.
    • 1:11:13So to be clear, the square brackets, much like in C,
    • 1:11:17are giving me a list of values, but it's not an array.
    • 1:11:19It's indeed a Python list.
    • 1:11:21And as we'll see over time, a list in Python is nice versus an array in C
    • 1:11:25because lists in Python can grow and shrink automatically for you.
    • 1:11:30So not only are they linked lists of some sort, underneath the hood,
    • 1:11:33you do not need to worry about resizing them anymore.
    • 1:11:35But, of course, as we saw before the break,
    • 1:11:38we should probably just do this more dynamically.
    • 1:11:40So for i in the range of three values and let Python generate those for me.
    • 1:11:46If I rerun Python of meow.py, I still get three values.
    • 1:11:49But here too, stylistically, recall, we said that you don't really
    • 1:11:52need the name of the variable if you're just
    • 1:11:54going to do something three times without ever touching that value.
    • 1:11:56So we could just use an underscore by convention,
    • 1:11:59which just kind of looks like there's no variable there,
    • 1:12:01even though there in fact is.
    • 1:12:03But let's build on this and actually now introduce and really revisit
    • 1:12:07the ability to define our own functions, which we've seen in Scratch.
    • 1:12:10We've seen in C, and I technically, at the start of class,
    • 1:12:13used it to implement my own spell checker.
    • 1:12:15In dictionary.py, i used def, which stands for define,
    • 1:12:19and that's how I defined four functions identically named to problem set 5.
    • 1:12:23Well, let me go ahead and do this and implement an abstraction for meowing,
    • 1:12:27much like we did in Scratch, much like we did in C. Let me go ahead
    • 1:12:30and define a function called meow whose purpose in life is simply for now
    • 1:12:38to print out, quote unquote, meow.
    • 1:12:40And now let me use that.
    • 1:12:41Let me go ahead and do something like before.
    • 1:12:43So for i in range of 3, go ahead and call meow, like this.
    • 1:12:49I think that's going to get the job done.
    • 1:12:51Python of meow.py, Enter, and indeed, it's
    • 1:12:53still working exactly as I expected.
    • 1:12:55But recall from our discussion of C, we generally stylistically encourage you
    • 1:12:59to put your main code at the top of the file, if only
    • 1:13:02because that's the entry point to the program.
    • 1:13:04If you want to wrap your mind around the code in there,
    • 1:13:06it makes sense to start with main instead of random functions like meow
    • 1:13:09at the top of the file.
    • 1:13:10So let me actually kind of practice what we preached in C.
    • 1:13:13Let me move this meow function just to the bottom of my file
    • 1:13:17so that it's sort of out of sight, out of mind
    • 1:13:19because, now that it's implemented, it just exists.
    • 1:13:21Let me go back to VS Code and my terminal in VS Code, run Python of meow
    • 1:13:25again, and hit Enter.
    • 1:13:28And there's one of those tracebacks, a different one this time.
    • 1:13:31This time, it's a name error instead of an attribute error.
    • 1:13:34But where did I go wrong?
    • 1:13:35Apparently, M-E-O-W no longer exists by nature of having moved it from top
    • 1:13:40to bottom.
    • 1:13:41So, intuitively, even if you're new to Python, why might that be?
    • 1:13:46Yeah?
    • 1:13:46AUDIENCE: Because you need to define before you call it.
    • 1:13:49DAVID J. MALAN: Exactly.
    • 1:13:50I need to define it before I call it, very
    • 1:13:52similar to C, whereby at least in C, we had
    • 1:13:55that little trick of just copy pasting the prototype of the function,
    • 1:13:58just a borrowing its very first line.
    • 1:14:00Python actually doesn't use that mechanism.
    • 1:14:02Instead, Python has a different convention instead.
    • 1:14:06Technically, in Python, you do not need a main function.
    • 1:14:10Clearly, from all of the programs I've written,
    • 1:14:12it just works without a main function.
    • 1:14:14But if you get yourself into a situation where
    • 1:14:16you're defining your own functions, but the order in which you
    • 1:14:20define them and then use them clearly matters,
    • 1:14:22you might as well go ahead and implement a main function after all.
    • 1:14:26And the convention would be to do this, literally
    • 1:14:28define with the def keyword a function called main that
    • 1:14:31doesn't need to take any arguments.
    • 1:14:33And then, inside of that main function, put your actual code.
    • 1:14:36Indentation in Python matters, and so I've
    • 1:14:38hit Tab to indent everything all at once.
    • 1:14:41And now I have a main function.
    • 1:14:42So it would seem that maybe now the problem
    • 1:14:46is solved by just introducing main.
    • 1:14:48So Python of meow.py, Enter--
    • 1:14:51it's solved in the sense that I'm not seeing an error message anymore,
    • 1:14:55but explain to me, intuitively, why I'm not seeing anything at all?
    • 1:14:58Yeah?
    • 1:14:59AUDIENCE: You did not call main.
    • 1:15:00DAVID J. MALAN: I didn't call main.
    • 1:15:01So it's sort of like we're taking a step forward but then another step
    • 1:15:04backwards here in the sense that Python doesn't come with support
    • 1:15:09for a main function by default. So if you invent it yourself,
    • 1:15:12the onus is on you to call that function.
    • 1:15:14So this is going to look a little stupid.
    • 1:15:16But the convention in Python is, indeed, at the very bottom
    • 1:15:19of your program, if it's contained in a single file,
    • 1:15:23is literally call main at the very bottom.
    • 1:15:25So now I'm going to go back to VS Code.
    • 1:15:27I'm going to rerun meow.py, and now I get back the functionality,
    • 1:15:31but I don't get an error message either.
    • 1:15:33Why?
    • 1:15:34Well, in this case, on line 1, I'm defining the main function as follows.
    • 1:15:38On line 6, I'm defining the meow function as follows.
    • 1:15:42I am not using either of those functions in actuality
    • 1:15:47until line 10 calls main, which then calls meow.
    • 1:15:51So I fixed my sort of order of operations, so it's fine for main
    • 1:15:55to be defined above it so long as I don't actually call meow
    • 1:15:58until I've defined it as well.
    • 1:16:00So this defines main, defines meow, and then actually calls main.
    • 1:16:05So this is a nice way in Python to avoid what could be a very complicated design
    • 1:16:10problem by just defining our own functions, including one called main.
    • 1:16:14Strictly speaking, it doesn't even have to be called main,
    • 1:16:16but it would be frowned upon as a matter of design, as a matter of style,
    • 1:16:20to call it anything other than main, even though that has
    • 1:16:23no special meaning beyond convention.
    • 1:16:25Well, let's make one tweak here, just as in C, just as in Scratch,
    • 1:16:28it would be nice if meow actually took an argument, which
    • 1:16:31is the number of times I want to meow.
    • 1:16:33So let's assume that that functionality exists by calling meow of 3
    • 1:16:36as the input to that function.
    • 1:16:38But how do I now change the definition of meow?
    • 1:16:41Well, just like in C, you put inside of the parentheses
    • 1:16:44when defining the function a comma separated list of one or more
    • 1:16:47of 0 or more parameters, and I can call it anything I want.
    • 1:16:50I'll call it n for number of times.
    • 1:16:53I don't have to specify int though because we know that already.
    • 1:16:56But in, now, this loop, I can do for i in range of n--
    • 1:17:01i doesn't have to be 3.
    • 1:17:02It can be n as a variable's value.
    • 1:17:05Then indent this line so that it indeed iterates n times, printing out "meow,"
    • 1:17:10in this case.
    • 1:17:11If I run it again as Python of meow.py, Enter, now I see meow, meow meow.
    • 1:17:16But this is arguably the best designed of my versions
    • 1:17:19thus far because it is indeed parameterizing
    • 1:17:23how many times I'm meowing.
    • 1:17:25Now as an aside, especially those of you who might have used Python before
    • 1:17:28or might go on and look at tutorials and such for Python
    • 1:17:31itself as a language, technically the conventional way to call main
    • 1:17:34is with this weird syntax.
    • 1:17:36If __name__ equals equals quote unquote "__main__" colon Tab,
    • 1:17:45we don't bother doing this in most of our class examples because it
    • 1:17:48doesn't actually solve a problem that we ourselves will encounter,
    • 1:17:51and it's just really hard to remember and confusing to read.
    • 1:17:55But you will see this in the wild, in the real world.
    • 1:17:57And long story short, this syntax of line 10 being added
    • 1:18:02solves problems where you're implementing not your own program per
    • 1:18:04se, but your own library, your own library that may
    • 1:18:07very well have its own main function.
    • 1:18:09But for now, I'm going to wave my hand and make that go away
    • 1:18:12and keep it simple because this is the juicy idea for now.
    • 1:18:16As an aside, there's other ways to have loops in Python that's worth noting.
    • 1:18:19So, for instance, in Scratch we had this forever block
    • 1:18:22saying meow again and again and again without ever stopping.
    • 1:18:24In C, maybe one way to do this was like this, like while true because true
    • 1:18:28is always true.
    • 1:18:29So this condition is always true.
    • 1:18:30So it's just going to print endlessly.
    • 1:18:32In Python, the syntax is roughly the same,
    • 1:18:35while True, but capital T and capital F for False,
    • 1:18:38this too would achieve the same result.
    • 1:18:40And so just to demonstrate, though, a very common mistake
    • 1:18:42might be to have some kind of infinite loop in your code
    • 1:18:46that might happen just the same in Python.
    • 1:18:49So if I go back to meow.py, and just for kicks,
    • 1:18:51I simplify this to literally just while capital True colon print quote unquote
    • 1:18:56"meow," you could get yourself into some trouble here by running that code,
    • 1:19:01and it just seems to meow endlessly.
    • 1:19:04How do I get out of this situation besides reloading my browser
    • 1:19:07and closing the terminal?
    • 1:19:09What's the more elegant way.
    • 1:19:10AUDIENCE: [INAUDIBLE]
    • 1:19:11DAVID J. MALAN: Yeah, Control-C. So Control-C for interrupt
    • 1:19:14will cancel what's going on there, just like in C. This, though, does not
    • 1:19:17mean there's an error in your code.
    • 1:19:19C did not do this.
    • 1:19:20Python does show a keyboard interrupt error, if you will,
    • 1:19:23but that's because you literally interrupted
    • 1:19:25the program while it was running.
    • 1:19:26This doesn't mean there's a problem in your code.
    • 1:19:28You've simply interrupted it because you lost control over the thing.
    • 1:19:33So what are some other issues we can perhaps now revisit together?
    • 1:19:36So in the world of C, recall that we ran into issues of truncation, whereby
    • 1:19:41if we did integer math, like 1 divided by 3, that would give me, ideally
    • 1:19:45in the real world, 0.3333333 forever.
    • 1:19:49But it ended up coming out as 0 in C as well.
    • 1:19:53So let's see what happens in the world of Python now.
    • 1:19:55And I'm going to move away from showing left and right C in Python for now.
    • 1:19:59Let's go ahead and just focus on the Python code.
    • 1:20:02So let's try this.
    • 1:20:03Let me go and create a new program after closing me out up high called,
    • 1:20:07say, calculator.py again.
    • 1:20:11Let me throw away the relatively simple code
    • 1:20:12earlier that simply added two numbers together, and let's
    • 1:20:16do some division now.
    • 1:20:18So let's do x equals int, passing in the input, asking for an x-value, like this.
    • 1:20:24Let's do y equals int input, passing in a y prompt like that.
    • 1:20:29Then let's do a variable called z equals x divided by y,
    • 1:20:33and then let's print out z.
    • 1:20:35So this is actually very similar to something we did weeks ago in C
    • 1:20:38when we first tripped over this issue.
    • 1:20:39Let me run Python of calculator.py, type in 1 for x, 3 for y,
    • 1:20:44and it would seem as though truncation is not an issue in Python.
    • 1:20:49By simply using the slash symbol for division.
    • 1:20:52It turns out there's another symbol you can use in Python if you
    • 1:20:55want to get back truncation.
    • 1:20:57You can do slash slash, which is not a comment.
    • 1:20:59It actually means do division, like the way C used to do it.
    • 1:21:03But in Python, probably for the benefit of all of us
    • 1:21:06globally, division works as you would expect, and you get back, in fact,
    • 1:21:10this here value instead.
    • 1:21:12What about another issue we saw in C?
    • 1:21:14That a floating point imprecision, whereby
    • 1:21:17even though something's supposed to be 0.3333333, infinitely many times,
    • 1:21:21it seemed, remember, like grade school was lying to us
    • 1:21:24because there were weird numbers in even a fraction like one third.
    • 1:21:28Well, let's try this out in Python.
    • 1:21:30Let's go back to my here calculator, and I only
    • 1:21:33need to make a slight tweak here, for instance, though, the syntax is
    • 1:21:36going to be a little weird here.
    • 1:21:37Instead of just printing out z to some default number of significant digits,
    • 1:21:42let's actually format the string as follows.
    • 1:21:44And this is not syntax you'll need frequently,
    • 1:21:46but in Python, you can use an f string by doing f quote unquote something.
    • 1:21:51And inside the double quotes this time, instead of just doing
    • 1:21:54z to print out and interpolate the value of z inside of those curly braces,
    • 1:21:59let's specify that, yes, I Want the value of z,
    • 1:22:02but I want to print it to, like, 50 decimal places as a floating point
    • 1:22:06value.
    • 1:22:07I have to google this syntax all the time to remember what it is,
    • 1:22:09but this is saying exactly that.
    • 1:22:11Show me 50 significant digits in this here number.
    • 1:22:14So let's go back to my terminal, Python of calculator.py, Enter, 1, 3
    • 1:22:20should get 0.33 repeating forever.
    • 1:22:23But, of course, we do not.
    • 1:22:24So, unfortunately, Python does not solve all of our problems.
    • 1:22:28Floating point in precision is still an issue.
    • 1:22:30Does that mean you shouldn't use it for scientific computing,
    • 1:22:33for financial computing and the like?
    • 1:22:35No, there are libraries that you can use,
    • 1:22:37third-party code that sort of addresses this kind of concern.
    • 1:22:40But you still need to be mindful of the fact that these problems still exist,
    • 1:22:44and either you or someone else still needs to handle something like this.
    • 1:22:48What about something like integer overflow?
    • 1:22:51Well, wonderfully in Python, integer overflow is not a thing.
    • 1:22:55Recall that in C, if you use an int of 32 bits,
    • 1:22:59it's eventually going to overflow and go negative
    • 1:23:02or go back to 0 once you count beyond, 2 billion or 4 billion,
    • 1:23:05depending on if you're doing negatives or not.
    • 1:23:07You could use a long in C, which gave you
    • 1:23:1064 bits, which means it's still going to overflow,
    • 1:23:13but probably after we're all dead because the number is going
    • 1:23:15to count up much, much, much higher.
    • 1:23:19Fortunately, in Python, you don't have to worry about int.
    • 1:23:21You don't have to worry about long.
    • 1:23:23It will just allocate more and more bits for you automatically, secretly,
    • 1:23:27underneath the hood so you can just iterate from 0 on up toward infinity,
    • 1:23:32and the program will run theoretically forever
    • 1:23:34without ever actually overflowing the int.
    • 1:23:36So at least integer overflow-- not a problem.
    • 1:23:40But there are problems that might still happen.
    • 1:23:42And let's explore how there are new mechanisms in Python
    • 1:23:45and languages like it that we didn't have in C. So,
    • 1:23:48in particular, let's introduce something called
    • 1:23:50exceptions, which is sort of a concept and a feature
    • 1:23:52that's worth understanding so that you'll
    • 1:23:54encounter it not only in Python but also likely in the real world.
    • 1:23:58And let's do it as follows.
    • 1:23:59Let me go back to VS Code after closing my calculator and let me go ahead
    • 1:24:04and open up a new program called integer.py just
    • 1:24:06to play around with integers.
    • 1:24:08And let me go ahead and do this.
    • 1:24:10Let me first prompt the user for a number n,
    • 1:24:12set it equal to the return value of input
    • 1:24:15by just asking them in between quotes a prompt of input.
    • 1:24:18Like, I really just want them to type a number, but maybe they won't.
    • 1:24:21So let's see what happens.
    • 1:24:23There are ways now to detect if the human has typed in
    • 1:24:26not only a string but a numeric string, like 1 or 3 or something else.
    • 1:24:31I can simply use a conditional in Python pretty easily.
    • 1:24:34In C, I would have to do this pretty much character by character.
    • 1:24:37By character.
    • 1:24:38In Python, I can do it the whole string at once.
    • 1:24:40If n.isnumeric, open paren, close paren, thereby
    • 1:24:47using a method that comes with all strings in Python that will just
    • 1:24:50tell me true or false, this whole thing is numeric or not,
    • 1:24:54then I can go ahead and print out, for instance, integer, just concluding
    • 1:24:57that this here thing is an integer.
    • 1:25:00Else, if it is not all numeric, I'm going to go ahead and print out "not
    • 1:25:04integer," quote unquote.
    • 1:25:06Let's try this out.
    • 1:25:07Let me run Python of integer.py.
    • 1:25:09I'll type in one.
    • 1:25:10That's an integer.
    • 1:25:12Let's run it again, type in 3, that's an integer.
    • 1:25:14Let's run it again, type in cat, that is not an integer.
    • 1:25:17So it seems to work at a glance.
    • 1:25:20But how else might we go about doing this, especially if--
    • 1:25:25so that we don't have to litter our code with all of these darn conditionals
    • 1:25:28every time I'm just trying to get an int?
    • 1:25:30I don't want to resort to the CS50 library.
    • 1:25:32Ideally, I don't want training wheels.
    • 1:25:33But I want to do this the Python way, and there's a word for that--
    • 1:25:36the "Pythonic" way.
    • 1:25:38So that too is a term of art, which means
    • 1:25:40there might be different ways to do it, but do it the way
    • 1:25:43where a majority of people out there would probably
    • 1:25:45agree with you Pythonically.
    • 1:25:47So let's do this.
    • 1:25:49Instead of bothering with the conditional,
    • 1:25:51because this is kind of annoying that one line of code
    • 1:25:53really becomes four all of a sudden, let's just go ahead and proactively
    • 1:25:57convert what the human types in to an int,
    • 1:25:59as I did before, to fix the 12 problem.
    • 1:26:02Let's run Python of integer.py, Enter.
    • 1:26:05Let's do 1, Enter--
    • 1:26:07seems to not make any errors.
    • 1:26:09Nothing bad happened.
    • 1:26:10Let's type in 3.
    • 1:26:11That there works, too.
    • 1:26:13Let's type in cat, and that throws one of those tracebacks, where the traceback
    • 1:26:18itself is not the error, but it's diagnostic information
    • 1:26:20that's trying to help me figure out where I screwed up.
    • 1:26:23Apparently, I screwed up somewhere in this whole thing,
    • 1:26:25and this is a little cryptic, but this is a value error, something--
    • 1:26:28I screwed up a value here.
    • 1:26:30Invalid literal for int with base 10 "cat."
    • 1:26:34So that's a very verbose way of saying, by default, the int function
    • 1:26:37assumes base 10, a.k.a. decimal, and it doesn't understand cat,
    • 1:26:42so it's just not working on cat.
    • 1:26:43So how do I solve this?
    • 1:26:45Well, notice what's happening here.
    • 1:26:47Simply trying to convert cat to an integer
    • 1:26:51is not just returning some special value, like 0 or negative 1.
    • 1:26:55Like, it's literally terminating my whole program.
    • 1:26:57And this is different from C. Recall that, in C,
    • 1:26:59the only way you could signal errors that we've seen
    • 1:27:02is that you have to return a sentinel value, like 0 or negative 1
    • 1:27:06or positive 1 or null or whatever.
    • 1:27:09You have to know in advance what special value is going to come back.
    • 1:27:12But there's a problem with integers in particular.
    • 1:27:14Suppose that the int function was defined in its documentation
    • 1:27:18as printing out-- as returning 0 if anything goes wrong.
    • 1:27:23You could check for 0.
    • 1:27:25So if n equals equals 0, then you could say print not
    • 1:27:30integer because, according to the documentation I'm pretending exists,
    • 1:27:34that is an invalid value.
    • 1:27:36Of course, where does this get me into trouble if I run Python of integer.py?
    • 1:27:40Type in 1.
    • 1:27:41We're good.
    • 1:27:41Type in 2, we're good.
    • 1:27:43Type in 0--
    • 1:27:440 is not an integer, but I'm pretty sure it is.
    • 1:27:47So there's a problem whereby if you're relying on return values
    • 1:27:50to signal that something went wrong, you have
    • 1:27:52to sacrifice a potentially valid value.
    • 1:27:55And that's fine, but you're going to have to pick a number.
    • 1:27:58It's got to return 0, negative 1, positive 1, 4 billion,
    • 1:28:00negative 4 billion-- like, you've got to pick a lane.
    • 1:28:03And that's unfortunate because you're sacrificing some value unnecessarily.
    • 1:28:07So what Python does and what other languages
    • 1:28:09do is instead of returning some sentinel value that means something went wrong,
    • 1:28:13they just throw up their hands, so to speak.
    • 1:28:16They throw an exception.
    • 1:28:17And an exception, by default, just terminates the program
    • 1:28:20because something unexpected happens, something exceptional where,
    • 1:28:24in this case, exceptional is a bad thing.
    • 1:28:26Something exceptional happened.
    • 1:28:27So how can we handle this?
    • 1:28:30How can we actually detect that something has gone wrong?
    • 1:28:34Well, it turns out-- this is sort of encouraging--
    • 1:28:36you can try to do something instead in Python as opposed
    • 1:28:40to just blindly doing it.
    • 1:28:41So if I go back into VS Code here and I try to do that, let's do the following.
    • 1:28:48Ideally, I want the end result to look like this-- print integer
    • 1:28:52if this thing works.
    • 1:28:53And so, to be clear, let me run this once more.
    • 1:28:55Python of integer.py, 1 is an integer, 2 is an integer, cat--
    • 1:29:00not an integer.
    • 1:29:01But I'd like to see not integer, and not some crazy message on the screen.
    • 1:29:05So how can I fix this?
    • 1:29:06Well, let's do this instead.
    • 1:29:08Please try to do all of this, except if there's a value error,
    • 1:29:15as I know can happen because I just experienced it,
    • 1:29:17then go ahead and print out "not integer," quote unquote.
    • 1:29:23So let me just keep my grammar the same.
    • 1:29:25Python of integer.py, Enter--
    • 1:29:271 works.
    • 1:29:28Python of integer.py-- 3 works Python of integer.py-- cat doesn't work per se,
    • 1:29:34but it doesn't throw an error message anymore and that scary traceback.
    • 1:29:37I'm somehow catching the exception or handling the exception, so to speak.
    • 1:29:42Now, as an aside, the slightly better way to do this would also be as follows.
    • 1:29:47Generally speaking, it's considered a bit lazy and bad design
    • 1:29:51to put more lines of code in a try statement
    • 1:29:53than you strictly need because imagine a program has 30 lines of code.
    • 1:29:57Maybe it's your whole Pset problem, and you
    • 1:29:59know you're occasionally getting those traceback errors on the screen.
    • 1:30:02A bad student, for instance, would just put everything in the try block
    • 1:30:08and literally just try to do your homework.
    • 1:30:10And if there's an exception, then you just catch it at the very bottom.
    • 1:30:13That's frowned upon because there's just bad design.
    • 1:30:16When you're trying to do something, you should really
    • 1:30:18only wrap the one or more lines that will actually
    • 1:30:22raise an exception inside of it.
    • 1:30:24So, technically, print is not going to fail.
    • 1:30:27You can't screw up print when you're just printing out, quote unquote,
    • 1:30:30"integer."
    • 1:30:31So, weirdly, the try accept statement in Python
    • 1:30:35also supports an else whereby if there's not an exception,
    • 1:30:40you can then do this statement instead.
    • 1:30:43It's a little weird because we've only seen elses and conditionals.
    • 1:30:46But you'll see this in the real world.
    • 1:30:48This, though, would achieve the exact same thing.
    • 1:30:50But it's a little better because now the only line of code I'm wrapping
    • 1:30:53is the one that can actually raise this exception in the first place.
    • 1:30:56So Python of integer.py--
    • 1:30:581 works.
    • 1:30:593 works.
    • 1:31:00Wait a minute.
    • 1:31:02Oh, wait, that's completely logical--
    • 1:31:04it does not work.
    • 1:31:06This is supposed to say integer if it is not, in fact,
    • 1:31:11an exception-- sorry, user error.
    • 1:31:13Python of integer.py-- 1 works.
    • 1:31:163 works.
    • 1:31:17Cat is caught but therefore not an integer in this case.
    • 1:31:22So long story short, why do we introduce this?
    • 1:31:24Well, one, these exceptions are actually omnipresent in higher level languages,
    • 1:31:28and this is the way that many languages actually
    • 1:31:31raise exceptions to signal that error has happened as opposed
    • 1:31:34to reserving arbitrarily some special return value that you must check for.
    • 1:31:38But you need to now try to do certain things, except if errors happen,
    • 1:31:42in which case you can catch them, so to speak, in this way.
    • 1:31:45As an aside, how does CS50's get_int function in our library work?
    • 1:31:49We essentially are using try and accept inside
    • 1:31:52of a loop that just keeps prompting and prompting and prompting
    • 1:31:55the user for an actual integer until you oblige,
    • 1:31:57and then we return that value in CS50's Python version of get_int.
    • 1:32:02So we're using the same fundamental in there.
    • 1:32:05Let's try now a few familiar things here on stage in homage to the Python
    • 1:32:10crawling on Mario's bricks here.
    • 1:32:12So recall that, a few weeks ago, we played around with something
    • 1:32:15super simple like this in C, which wasn't syntactically as simple,
    • 1:32:18but the idea was to print out a column of for instance, three bricks.
    • 1:32:22How might I go about doing this in code?
    • 1:32:24Well, let's see.
    • 1:32:25Let me open up a new file called mario.py today.
    • 1:32:28And let's just do it the simplest way possible.
    • 1:32:30If I want to print three bricks, I could do for i in range of 3,
    • 1:32:35and then I could print out a single hash mark to represent exactly that.
    • 1:32:39I'm going to get the new line for free because that's the automatic default
    • 1:32:42behavior for print.
    • 1:32:43So if I run this, I get something that's a little underwhelming but pretty close
    • 1:32:47to the spirit of what I just did here on the screen.
    • 1:32:51What if, though, I want to prompt the user for the height of this thing,
    • 1:32:54just as we did in problem set 1 with the Mario problems?
    • 1:32:58How can I make sure the user actually gives me a number I want?
    • 1:33:02Well, let's go back to VS Code here, and just so that I don't have to implement
    • 1:33:05all the try-except stuff myself, let's go ahead and, from CS50 library,
    • 1:33:09import the get_int function that I've claimed exists, and then let's do this--
    • 1:33:14while True.
    • 1:33:16It turns out, in Python especially, it's actually pretty common
    • 1:33:20to deliberately induce infinite loops if only because Python does not
    • 1:33:25have do-while loops.
    • 1:33:27Recall that do-while loops and C were super useful
    • 1:33:29because they guarantee that you do something
    • 1:33:31while a condition is still true.
    • 1:33:33And that allowed us to get user input at least once and maybe again and again
    • 1:33:37and again and again.
    • 1:33:38Python does not have a do-while.
    • 1:33:40But you can implement the idea of it by just
    • 1:33:42saying start an infinite loop that I'm going to plan
    • 1:33:45to break out of when I am ready.
    • 1:33:47And I can do something like this-- n equals get_int, prompting
    • 1:33:51the user for height here as a prompt.
    • 1:33:53Then, if n is what I want it to be, a value greater than 0 as in problem
    • 1:33:58set 1, go ahead and break out of this loop.
    • 1:34:02So even though I don't have a do-while, I
    • 1:34:03can certainly deliberately get myself into an infinite loop
    • 1:34:06and break out of it when I'm logically ready to do so.
    • 1:34:09And now, here, I can do for i in range of n,
    • 1:34:12which is just going to iterate from 0 on up to that value
    • 1:34:15and then print out a hash mark as follows.
    • 1:34:18Let me go ahead and run Python of mario.py, type in a height of 3,
    • 1:34:22and it still works.
    • 1:34:23Type in a height of, say, 5--
    • 1:34:24it too works by iterating five times instead of three.
    • 1:34:28As an aside, what are some modifications that might be germane here?
    • 1:34:32Well, if I want to import the entirety of CS50 library,
    • 1:34:35I can indeed, as I said earlier, just import the library itself.
    • 1:34:39But notice what happens now.
    • 1:34:41Python of mario.py, Enter--
    • 1:34:43a traceback, specifically a name error, get_int is not defined.
    • 1:34:47This is because Python actually solves a problem that C does not.
    • 1:34:51In C, we didn't actually encounter this because our programs
    • 1:34:53haven't been too big.
    • 1:34:54But in C, if you include this library and this one and this one and this one,
    • 1:34:57you will get into trouble if two people out there
    • 1:35:00have named a function the same thing.
    • 1:35:02If they've typed up something the same thing-- there's no notion of scope
    • 1:35:05when it comes to importing libraries in C. You will get name collisions,
    • 1:35:09and the solution is just don't do that.
    • 1:35:11Don't use that library that conflicts with one you're using.
    • 1:35:14Humans realized, eventually, this is probably not the best design,
    • 1:35:17so they introduced the notion of namespacing,
    • 1:35:19whereby you can scope certain symbols to specific files in effect.
    • 1:35:24And so there is a solution to this.
    • 1:35:26If you import the entirety of CS50, that's fine.
    • 1:35:29But you have to say that you want the function called get_int
    • 1:35:32that's inside of the CS50 library.
    • 1:35:35So if I do cs50.get_int and rerun this, now I no longer see that error,
    • 1:35:40and I'm on my way again with the code.
    • 1:35:43And this just allows me to keep all of my
    • 1:35:45get underscore something functions scoped to the CS50 symbol
    • 1:35:49as opposed to importing them all into the top-level namespace, where they're
    • 1:35:53just essentially global instead.
    • 1:35:57Questions about this-- the new ideas here
    • 1:36:01really being now infinitely looping, deliberately,
    • 1:36:04until you're ready to break out.
    • 1:36:09No-- seeing none.
    • 1:36:10All right, how about this.
    • 1:36:11So we had these four coins, question marks in the sky here,
    • 1:36:14different in that they were horizontal instead of vertical.
    • 1:36:16How we might implement this in code instead?
    • 1:36:19Well, let's go back to mario.py.
    • 1:36:20Let's delete the vertical version we just did,
    • 1:36:22and there's a bunch of ways I can do this.
    • 1:36:24But let's do it in a way that lets us play
    • 1:36:26around with some new features of Python as well.
    • 1:36:29For i in range of, let's say, 4--
    • 1:36:33though I could use a variable if I want--
    • 1:36:35print out quote unquote question mark, and let's try this.
    • 1:36:39Python of mario.py, Enter--
    • 1:36:41this is, of course, buggy because they're coming out
    • 1:36:43vertical instead of horizontal.
    • 1:36:45So what's the fix there, intuitively?
    • 1:36:49What do I-- yeah?
    • 1:36:51AUDIENCE: Add end equals--
    • 1:36:53DAVID J. MALAN: Yeah, so add end equals quote unquote
    • 1:36:55to turn off the new line by default. That's close now,
    • 1:36:59so if I run mario.py again, I get 4 horizontally,
    • 1:37:02but I don't get the prompt on the new line.
    • 1:37:04So I think I just need one extra print at the end, which
    • 1:37:07does give me a default new line.
    • 1:37:09So if I now run this one more time--
    • 1:37:11there we go.
    • 1:37:11Now we're back in business.
    • 1:37:12So pretty straightforward-- pretty much the same as in C,
    • 1:37:15albeit with Python's more succinct syntax.
    • 1:37:17But this is kind of cool.
    • 1:37:18What you can alternatively do in Python, which we've not seen before,
    • 1:37:21if you want to print something four times or some number of times,
    • 1:37:24you can literally say print out a question mark four times.
    • 1:37:28So multiplication is now used in the way that plus kind of is for concatenation.
    • 1:37:33But this does something again and again.
    • 1:37:35Python of mario.py, and that too now works.
    • 1:37:38Doesn't really save us a huge amount of time,
    • 1:37:40but it's kind of cool now that you can do these one liners, so to speak,
    • 1:37:43that achieve a lot more functionality as well.
    • 1:37:46What about this final example we had from the world
    • 1:37:48of Mario Underground, which was a 3 by 3 grid?
    • 1:37:51How could I do this in Python instead?
    • 1:37:54Well, let's go back here and delete the version of code I had there.
    • 1:37:58Just like in C, we can have nested loops,
    • 1:38:00so I could do something like for i in range of 3 and then maybe for j
    • 1:38:06in range of 3, using different variables deliberately here.
    • 1:38:10Let me go ahead and print out a hash mark
    • 1:38:13with no line ending until we're at the end of that row, at which point
    • 1:38:18I do want a line ending, the new line character there.
    • 1:38:21So if I run Python of mario.py, I get a 3
    • 1:38:23by 3 grid, which roughly resembles what this thing here looks like.
    • 1:38:27Now you don't strictly need all of that because we can combine
    • 1:38:30these ideas for better or for worse.
    • 1:38:31If I go back to my code here, well, if I want to just print out three things,
    • 1:38:35I could just do-- let's see, print quote unquote hash mark times 3
    • 1:38:40and allow me to have a new line there.
    • 1:38:42And if I run this version, which is a little tighter,
    • 1:38:45I get the same exact thing, too.
    • 1:38:47So where is the line?
    • 1:38:48Which way do you do it?
    • 1:38:49Whatever is most comfortable to you.
    • 1:38:50And, in fact, when I said earlier that I was
    • 1:38:52doing-- kind of flexing when I implemented dictionary.py using
    • 1:38:55the fewest lines of code possible, that was just because I really
    • 1:38:58wanted to distill it into the essence of the minimal number of lines of code.
    • 1:39:02But I could absolutely have used some loops in dictionary.py.
    • 1:39:05I could have used a little more verboseness.
    • 1:39:08But, as we're seeing here, it's not strictly necessary.
    • 1:39:10Python has even more syntactic sugar, if you will,
    • 1:39:13that lets you achieve more stuff more succinctly.
    • 1:39:19How about, now, some more on lists and dictionaries, just to dovetail
    • 1:39:24with what we did last week.
    • 1:39:25We'll touch on some final features, too, when it comes to command line arguments
    • 1:39:29and using exit commands.
    • 1:39:31And then we'll end with a couple of fun examples that kind of ties
    • 1:39:34this all together.
    • 1:39:35So, in Python, we indeed have lists, which are like arrays,
    • 1:39:37but they dynamically resize themselves.
    • 1:39:39So they're effectively linked lists that you don't need to manage yourself.
    • 1:39:43It turns out the documentation for those are at this URL here,
    • 1:39:46but that's discoverable via docs.python.org itself.
    • 1:39:49In particular, there's functions you can use on lists like len,
    • 1:39:52L-E-N, for short, which gives you the length of a list.
    • 1:39:56In C, it was up to you to keep track of the length of an array.
    • 1:39:59In Python-- like in Java, like in JavaScript, if you're familiar--
    • 1:40:02you can just ask the list how long it is at any moment in time.
    • 1:40:06So that's going to make our lives a little easier as well.
    • 1:40:09In particular, here's some documentation for that length function,
    • 1:40:11and let me take it out for a spin by recreating some of our prior examples
    • 1:40:15in code.
    • 1:40:16Let me go back to VS Code here, and let me go ahead
    • 1:40:19and create a program called scores.py, which, just like our example in week 2,
    • 1:40:25sort of iterates over quiz scores or homework scores or however
    • 1:40:28you want to think about scores.
    • 1:40:30In Python, I'm going to give myself just a list
    • 1:40:33of three scores, same as in week 2.
    • 1:40:35So scores equals square brackets 72, 73, 33.
    • 1:40:39So this is different from C. In C, if you were initializing
    • 1:40:43an array with values like these, you would actually
    • 1:40:46use curly braces and a semicolon.
    • 1:40:49And the data type in Python, you use square brackets, no data type,
    • 1:40:53no semicolon, as before.
    • 1:40:56Now let's compute the average of my score.
    • 1:40:58So average equals-- and here's another function that actually
    • 1:41:02exists in Python's documentation.
    • 1:41:04You can actually call a function called sum pass.
    • 1:41:07In most anything that you can iterate over, like a list,
    • 1:41:10passing in scores, and then divide by how many of those things
    • 1:41:13there are, like len, passing in scores there.
    • 1:41:15And now, if I want to print out the average,
    • 1:41:17I can print out, for instance, a format string that says average, colon,
    • 1:41:21and then plugs in that value there.
    • 1:41:23I can try running this Python of scores.py,
    • 1:41:26and there's my average as we've seen before, weeks ago, 59.33333
    • 1:41:30with a little bit of imprecision thrown in for good measure, as before.
    • 1:41:34But what's nice is that, notice, sum just comes with the language.
    • 1:41:38Length just comes with the language.
    • 1:41:40You don't need some annoying for loop or a while
    • 1:41:42loop just to figure out the average of these values by doing all of that math
    • 1:41:46yourself.
    • 1:41:47So that seems to be nice, at a glance.
    • 1:41:49What else can we do with these here scores?
    • 1:41:51Well, let me propose that we could get them one at a time from the user
    • 1:41:55instead of hard coding them.
    • 1:41:56So let me do this.
    • 1:41:57Let me go ahead and, from CS50's library,
    • 1:42:00import get_int, just so I don't throw any of those exceptions
    • 1:42:03by typing in cat or dog or anything not an integer.
    • 1:42:06Let's give myself an empty list by just using two square brackets, like that.
    • 1:42:11And now let's go ahead and put things in that list as follows.
    • 1:42:16For i in range of 3, if I want to prompt the user still
    • 1:42:19for three scores for the sake of discussion,
    • 1:42:22let's prompt the user for a score, putting it in a variable called score,
    • 1:42:25setting it equal to the get_int function,
    • 1:42:27prompting them for their first score.
    • 1:42:30But then let's put that score in the list.
    • 1:42:33In C, this was a pain in the neck.
    • 1:42:35In C, this was like what you had to do in problem set 5
    • 1:42:38and build the darn linked list yourself by iterating over the chains
    • 1:42:41and appending it to the end or to the beginning or something like that.
    • 1:42:44In Python, if you want to append a value to an existing list,
    • 1:42:47you do whatever that list is called, scores in this case.
    • 1:42:51You use a method that comes with it called append,
    • 1:42:54and you append that score, and voila, Python takes care of it for you,
    • 1:42:59putting it at the end of the list.
    • 1:43:01Now, outside of that loop, let me calculate the average, just as before,
    • 1:43:04the sum of those scores divided by the length of those scores.
    • 1:43:08Then let's go ahead and print out an f string that says average, colon,
    • 1:43:12and then interpolates the value of that variable.
    • 1:43:15Now, if I didn't screw up, let's try this again.
    • 1:43:17Python of scores.py--
    • 1:43:1872, 73, 33, which are now, per that for loop, being added to the list.
    • 1:43:25And then the logic is exactly the same.
    • 1:43:27So way easier than it would have been in C to navigate or manage
    • 1:43:31all of that stuff for me.
    • 1:43:32There's another way to see this syntactic sugar, if you will.
    • 1:43:36If you don't like this syntax, whereby you are adding to the scores
    • 1:43:40variable a new score by appending it using the built-in append function
    • 1:43:45or method that comes with any list in Python, you can also do this.
    • 1:43:49You can set scores equal to the existing scores
    • 1:43:53list plus another mini list containing just that score.
    • 1:43:58Or I can condense this a little further and say plus equals score.
    • 1:44:02So it turns out, plus is overloaded in Python in the sense
    • 1:44:06that it's not a concatenation per se, like for strings, but it's append.
    • 1:44:11You can append more and more things to a list
    • 1:44:14by concatenating two lists together in this way.
    • 1:44:17So, again, it seems the exact same thing,
    • 1:44:18but maybe you prefer the syntax if only because it's a little more concise.
    • 1:44:23But, in short, lists are wonderfully useful in this way.
    • 1:44:27Questions, then, on this here feature as well?
    • 1:44:32We're essentially just solving past problems more easily is the theme,
    • 1:44:36hopefully.
    • 1:44:38How about one other problem, when we implemented a phone book back in week 3?
    • 1:44:42Let me go ahead and do this.
    • 1:44:43In VS Code, let me clear my terminal and close out scores.py, and let me go ahead
    • 1:44:47and create a new program called phonebook.py.
    • 1:44:51And, in this, let's write a program that just iterates over some names,
    • 1:44:54looking for one that I want.
    • 1:44:56So maybe I have an array, a list called names, set it equal to 3 of us,
    • 1:45:01as in week 3, so Yuliia and David and maybe John Harvard, like this, all three
    • 1:45:06strings.
    • 1:45:07Then let's go ahead and prompt the user for a specific name using Python's input
    • 1:45:10function or our get_string function, prompting them for a specific name.
    • 1:45:15And now let's do this old school with a for loop for each name in names.
    • 1:45:20And I'm just keeping it short--
    • 1:45:23n for each name.
    • 1:45:26If the name I'm looking for equals the current name that I'm iterating over,
    • 1:45:31then print out "Found," as we did weeks ago,
    • 1:45:34and then break out of this loop because I'm done,
    • 1:45:38and let's see what happens here.
    • 1:45:39So Python of phonebook.py-- let's search for my own name, D-A-V-I-D, Enter,
    • 1:45:44and David's name is found.
    • 1:45:46So that's kind of handy.
    • 1:45:47Let's do this once more, search for John.
    • 1:45:50John is now found.
    • 1:45:51Let's search for, say, another name.
    • 1:45:55But let me mistype it, maybe like YULIIA in all caps.
    • 1:45:58I'm not handling any of the capitalization here,
    • 1:46:00so I don't think she will be found.
    • 1:46:02And, indeed, we see no mention of found.
    • 1:46:04Now this is a feature of Python that's kind of handy, too.
    • 1:46:06And it's a little weird because, in C and in Scratch,
    • 1:46:09the only time you could use else was with conditionals.
    • 1:46:13But we've seen in Python, you can also use else with exceptions,
    • 1:46:16those special errors that can be triggered. .
    • 1:46:18You can even use elses in Python with for loops by saying else print "Not
    • 1:46:24found."
    • 1:46:25And what happens in Python is if Python realizes you never actually break out
    • 1:46:30of this loop yourself, it will then print out this
    • 1:46:34only if you've not broken out, the logic being that,
    • 1:46:38OK, you clearly didn't find who you were looking for,
    • 1:46:40so else let's just say as much.
    • 1:46:42So if I now run this again, typing in Julia's name all capitalized--
    • 1:46:46so miscapitalized here--
    • 1:46:47Enter, I do now see that she's not found.
    • 1:46:50So it's just a nice little trick because it's
    • 1:46:52so common to iterate through things, fail to find a value,
    • 1:46:55and then you just want to say some default--
    • 1:46:57you want to execute some default line of code as well.
    • 1:47:00But, turns out, let's tighten this up too.
    • 1:47:03Python does not need you to do all of this work
    • 1:47:05by iterating over every name in the list, checking if each name is in there.
    • 1:47:10Rather, we can tighten this up even more.
    • 1:47:13Let me get rid of this entire for loop and just say this.
    • 1:47:16If the name you're looking for is in the list of names, then print "Found."
    • 1:47:22Else, in this conditional, print "Not found."
    • 1:47:26In other words, I can literally just ask Python,
    • 1:47:29you search over the darn list for me, and if it's in there, wherever it is,
    • 1:47:34return True in that Boolean expression--
    • 1:47:37in that if conditional, the Boolean expression in effect,
    • 1:47:40so I can print out "Found" or "Not found."
    • 1:47:43So this, too, will just work.
    • 1:47:44Let me go ahead and run this again at the bottom.
    • 1:47:46Python of phonebook.py, search for myself, David, and I am indeed found.
    • 1:47:50But I don't need to implement the searching for it left to right.
    • 1:47:53It's still using linear search under the hood,
    • 1:47:55but someone else has now written that code for me, built into the language
    • 1:48:00itself.
    • 1:48:02So what more do we get?
    • 1:48:04So it turns out that, in the world of programming,
    • 1:48:06maybe the most useful, one of the most useful data structures
    • 1:48:09is indeed a hash table, which gave us the abstract data type last time
    • 1:48:13known as a dictionary, which is just a set of key value pairs.
    • 1:48:16What's wonderful about Python, unlike Pset 5 in C,
    • 1:48:19is that you actually get a data type called dict, short for dictionary,
    • 1:48:24which gives you exactly that-- key value pairs,
    • 1:48:27but you don't have to implement any of the darn logic of problem set 5.
    • 1:48:30It still gives you, in effect, something that
    • 1:48:32looks a little something like this in memory--
    • 1:48:34key value, key value, key value.
    • 1:48:36But you don't have to worry about the array.
    • 1:48:38You don't have to worry about the chains of linked lists.
    • 1:48:40You don't have to worry about the hash function, even.
    • 1:48:43Python takes care of all of that for you.
    • 1:48:46Now this will be a bit of a mouthful to set up, but let me go ahead and do this.
    • 1:48:49Back in VS Code, I'm going to go ahead and create
    • 1:48:52another version of phonebook.py here by first creating
    • 1:48:56a dictionary of people instead of just a list because, up until now,
    • 1:49:00we've had no phone numbers involved.
    • 1:49:01I do actually want to have a bunch of names and phone numbers.
    • 1:49:05And the way I'm going to do this is as follows.
    • 1:49:08At the top of this file, I'm going to go ahead and create a list called people.
    • 1:49:12Rather, I'm going to create a list called people.
    • 1:49:15And a list, of course, uses square brackets.
    • 1:49:17But every person now I want to have some keys
    • 1:49:20and values, like a name and a number.
    • 1:49:23So how can I do this?
    • 1:49:24Well, I'm going to make some room for this.
    • 1:49:26This is not incorrect.
    • 1:49:27I'm moving this closed square bracket to a new line
    • 1:49:30because I want every element of this list to be very clearly
    • 1:49:34a dictionary, a set of key value pairs.
    • 1:49:37And you couldn't do this in C, but you can do this in Python.
    • 1:49:40In Python, you can use curly braces to represent
    • 1:49:44a dictionary of key value pairs.
    • 1:49:46How do you define the keys?
    • 1:49:48You put the first key in quotes.
    • 1:49:50You then put a colon, and then you specify the value for that key.
    • 1:49:55If you want another one, you do a comma, you then do quotes,
    • 1:49:58and you do another key, colon, and then its value.
    • 1:50:03And if I think back to week 3, we used plus 1-617-495-1000 for Yuliia's number
    • 1:50:11then.
    • 1:50:12And that's it.
    • 1:50:13It's a little cryptic because it's all in just one line,
    • 1:50:15but it's like having two rows in this visualization here--
    • 1:50:18name, Julia, number, plus 1-617-495-1000 in that there chart.
    • 1:50:25So if I want a second one of these, I'm going
    • 1:50:27to put a comma at the end of Yuliia's dictionary.
    • 1:50:30I'm going to put myself on the second line.
    • 1:50:32So open curly brace, quote unquote, name, colon, and then David in quotes,
    • 1:50:36then comma, number, close quote, colon, plus 1-617-495-1000 as well, and then,
    • 1:50:44lastly, a second comma, so that we'll put John Harvard in here so his name is
    • 1:50:49quote unquote "John."
    • 1:50:50His number is +1-949-468-2750.
    • 1:50:59And now we have a list of three dictionaries.
    • 1:51:03Each of those dictionaries has two keys and two values, respectively.
    • 1:51:07Syntactically, this is a pain in the neck,
    • 1:51:09and we would probably just store all of this information in a CSV
    • 1:51:12or a database or something like that.
    • 1:51:13But for now, I typed it all up manually so we have a working example.
    • 1:51:17Now let's actually search this list of dictionaries for the people I want.
    • 1:51:22Let's set a variable called name equal to the return value of input,
    • 1:51:26prompting, as before, the name we care about.
    • 1:51:28Then let's do this for each person in that list of people,
    • 1:51:34let's check if the current person's name equals equals the name the user typed
    • 1:51:40in, then get their number by looking at that person's number field and then go
    • 1:51:48ahead and print out with an f string something like "Found."
    • 1:51:51And then I'll just print out that number in curly braces,
    • 1:51:54and then I will break out of all of this.
    • 1:51:56Or, as before, else let's go ahead and print out "Not found."
    • 1:51:59So this is a mouthful, but let's consider what's happening here.
    • 1:52:02First, on line 8, I'm iterating over every person in people.
    • 1:52:06What is people?
    • 1:52:07It is a list of three dictionaries.
    • 1:52:09So on the first iteration is this person, second iteration, this person,
    • 1:52:14third iteration, this person.
    • 1:52:15And Python just takes care of that for me, like we've seen with our for loops
    • 1:52:18already.
    • 1:52:19If that person's name field has this name,
    • 1:52:23then I found the person I'm looking for-- get their number stored
    • 1:52:27in a variable called number if only so that I can print it out
    • 1:52:29with this f string.
    • 1:52:30Else, let's go ahead and print out "Not found"
    • 1:52:33if I never actually break out having found someone.
    • 1:52:36Notice, then, that just like in C, when we use square brackets to index
    • 1:52:40into an array, in Python, you can index into a dictionary
    • 1:52:45by literally using the same square bracket notation.
    • 1:52:48So instead of saying bracket 0, bracket 1, bracket 2,
    • 1:52:50you can say bracket name, quote unquote, and that
    • 1:52:54will look up the value for that key.
    • 1:52:57So, again, it's like going into this chart that we see here visually,
    • 1:53:00looking for name in the left column, finding that person's name,
    • 1:53:04looking for the number value in the left column,
    • 1:53:08and looking for its corresponding value at right.
    • 1:53:11It's all sort of happening for us automatically.
    • 1:53:14Now It turns out we can do this more simply if we, instead,
    • 1:53:16restructure our variable called people.
    • 1:53:18So let me go ahead and do this.
    • 1:53:20Let me go ahead and delete all of the code we just wrote,
    • 1:53:22including that for loop.
    • 1:53:23And let me redefine people as follows.
    • 1:53:26And I'm going to leave the first version up there so we can see before and after.
    • 1:53:29Let's redefine this variable as equaling people,
    • 1:53:32but instead of people being a list of dictionaries, let's just make people
    • 1:53:36one big dictionary, whereby it has two columns, key and value,
    • 1:53:41but where the key this time is going to be the person's name
    • 1:53:44and the value is going to be their number.
    • 1:53:46This is super useful in this case because I only have
    • 1:53:49keys and values, names and numbers.
    • 1:53:50This will not work if I also want to keep
    • 1:53:52track of their email address, their student ID, and multiple values as well.
    • 1:53:57In this case, it suffices to keep track of names and numbers,
    • 1:53:59if only so that I can remove some of this redundancy of saying name, name,
    • 1:54:03name, number, number, number.
    • 1:54:05Let's do it as follows.
    • 1:54:06So people equals open curly brace, close curly brace,
    • 1:54:09and let's add a key of Yuliia, whose number is exactly this one here.
    • 1:54:15I'll copy-paste to save time.
    • 1:54:16Let's add another key whose name is David whose
    • 1:54:19value happens to be the same number.
    • 1:54:21Let's add a third key whose value is John
    • 1:54:24and set that equal to this number so that
    • 1:54:27now, at the end of these lines of code, we have Yuliia as a key,
    • 1:54:32David as a key., John as a key, and their numbers
    • 1:54:34respectively as values effectively implementing
    • 1:54:36this chart for everyone instead of one of these charts for each person.
    • 1:54:41So if I go back to VS Code, let's get rid of the old, more verbose version.
    • 1:54:45Let's go back here and, instead of using any kind of loop
    • 1:54:47now, because there's no list involved, let's just
    • 1:54:49do this-- prompt the user using the input function
    • 1:54:52for the name whose number they want.
    • 1:54:54Then let's just say if the name you're looking for
    • 1:54:57is in that people dictionary, well, great.
    • 1:54:59Go ahead and print out a format string that
    • 1:55:02says that person's number is whatever is in the people dictionary at that name's
    • 1:55:09location.
    • 1:55:10Else let's go ahead and print out, for instance, "Not found."
    • 1:55:13So the only weird thing here, I dare say, is this--
    • 1:55:17if naming people works just like searching a list,
    • 1:55:19but you can search a dictionary by key, and if you
    • 1:55:22find a key like Julia or David or John, it's
    • 1:55:24going to allow you to use people as well indexed into that chart
    • 1:55:28at the name location with the appropriate row,
    • 1:55:31and that's going to give us implicitly that person's number
    • 1:55:34because even though we don't mention name, we don't mention number,
    • 1:55:37this is what a dictionary is, a collection of key value pairs.
    • 1:55:40And the key can be any string you want, and the value
    • 1:55:43can be anything you want as well.
    • 1:55:46So that was a lot.
    • 1:55:48But you'll see, then, in the real world, these dictionaries,
    • 1:55:51really, these hash tables underneath the hood
    • 1:55:53are so useful because you can constantly associate one thing with another.
    • 1:56:00Questions on any of this to date?
    • 1:56:04OK, a few final examples--
    • 1:56:06I feel like it's a tough crowd because we're
    • 1:56:07teaching an entire language in a week.
    • 1:56:09But we're almost at the finish line here,
    • 1:56:11and then everything else is going to be icing on the cake.
    • 1:56:13How do we go about implementing now from, in Python, some of the features
    • 1:56:17we eventually introduced in C, namely things
    • 1:56:19like command line arguments, which we've not used thus far in Python.
    • 1:56:24I've gotten all of my input using get_int, get_string,
    • 1:56:27and Python's own input function, but I've
    • 1:56:29never typed any words after the prompt when
    • 1:56:31running Python and the name of a file.
    • 1:56:34Well, how can I go about doing this in Python?
    • 1:56:36Well, let me open up my terminal window here.
    • 1:56:38Let's open up a program like greet.py, reminiscent of week 2's greet.c program,
    • 1:56:43and let's do this.
    • 1:56:44From a feature of Python called sys, import argv,
    • 1:56:51which is very different from C, but the same idea at the end of the day.
    • 1:56:54If the length of that argv variable happens to equal 2,
    • 1:57:00let's go ahead and print out a format string that says "hello,
    • 1:57:03comma argv bracket 1," close quote.
    • 1:57:08Else, go ahead and print out the default from week 2, which was just "Hello,
    • 1:57:12world."
    • 1:57:13All right, what has just happened?
    • 1:57:14Well, first, let's run it and try to infer.
    • 1:57:16So.
    • 1:57:16Python of greet.py, Enter--
    • 1:57:18I didn't write any other words after the prompt, so I literally see the default,
    • 1:57:23"Hello, world."
    • 1:57:24What if, though, I write Python of greet.py and then David?
    • 1:57:28Well, what's going to happen here is Python, via this sys library,
    • 1:57:31is going to automatically put every word I typed at the prompt after the name
    • 1:57:36Python into a list called argv by convention.
    • 1:57:41By definition, I can then check how many words are in argv,
    • 1:57:46and if it's 2, that means that the human typed in not only the name of the file
    • 1:57:50to execute but also something after that as well.
    • 1:57:53So if I now run this by hitting Enter, now I see "Hello, David,"
    • 1:57:58because there's two things in that list, greet.py and David.
    • 1:58:02There's no mention of Python because that's the interpreter.
    • 1:58:04And without the interpreter, none of this would work anyway.
    • 1:58:07You get the name of the file and the word you typed after that.
    • 1:58:09It's not going to work, though, just like in week
    • 1:58:112, if I do David Malan because now, argv's length will be 3 instead of 2,
    • 1:58:16so I'm again going to get the default. But this is to say there is still argv.
    • 1:58:20There's no argc because you can just use the length function, len, to find out
    • 1:58:25what the length of argv now is.
    • 1:58:28What more can we now do?
    • 1:58:30Well, let me go ahead and propose that we introduce how about exit statuses
    • 1:58:38as well, whereby recall that, in C, we had the ability
    • 1:58:41to actually exit with some value, like 0 on success or 1 or anything else
    • 1:58:46upon failure.
    • 1:58:47Turns out that that feature is also tucked away inside of this sys library.
    • 1:58:51Let me go ahead and create another program called, say, exit.py,
    • 1:58:54just to demonstrate this one, let me go ahead
    • 1:58:56and import sys so as to have access not only to argv
    • 1:58:59but also a function in there called exit, which just worked in C,
    • 1:59:04but in Python, we'll see that we want to use the version tucked away in sys.
    • 1:59:08Let's do something like this.
    • 1:59:09After importing sys, let's check if the length of argv does not equal two
    • 1:59:16things, let's go ahead and yell at the user quote unquote "Missing command-line
    • 1:59:20argument."
    • 1:59:21And we didn't spend long on this in C, but we did something
    • 1:59:23like this a few weeks back.
    • 1:59:24And then let's go ahead and call exit of 1.
    • 1:59:28Otherwise, if we get down here, let's go ahead and say,
    • 1:59:30as always, a format string of Hello comma sys.argv bracket 1,
    • 1:59:35just as before, so as to greet the user, and then we'll say exit(0).
    • 1:59:39But I do want to use argv that's inside of sys
    • 1:59:42and I want to use exit that's inside of sys because, according
    • 1:59:45to the documentation, that's where these symbols are.
    • 1:59:48So I can now do sys.argv, and I can do sys.exit and sys.exit, which
    • 1:59:55just makes super clear that those two symbols, argv and exit,
    • 2:00:00are inside of that sys library.
    • 2:00:02And we did this earlier when I played around with the CS50 library.
    • 2:00:05Either importing specific things or the whole library itself,
    • 2:00:08the idea here is ultimately the same.
    • 2:00:10So let me run Python of exit.py with no command line argument, so Enter,
    • 2:00:15and I indeed get an error message.
    • 2:00:17And this is probably not something you've
    • 2:00:18needed to run since I last did it.
    • 2:00:20But if you do dollar sign question mark after echo,
    • 2:00:23you can quickly see what was the actual secret exit status.
    • 2:00:27If I run this again with my actual name, David, Enter, I actually get greeted.
    • 2:00:32And if I do that dollar sign question mark again after echo,
    • 2:00:35I see now the secret exit status.
    • 2:00:37So, again, not something we've used often,
    • 2:00:38but by convention-- we can still do in Python what we've been doing in C,
    • 2:00:42namely signaling that something was successful or a failure.
    • 2:00:46Let's do one last set of examples that are reminiscent of past ones,
    • 2:00:50and we'll conclude with two new ones altogether.
    • 2:00:53Recall that we've had this phone book that previously took input just
    • 2:00:57from a hardcoded list of dictionaries or one dictionary.
    • 2:01:01Let's actually reintroduce the idea of CSV files, comma-separated values,
    • 2:01:05whereby we can actually save this information to disk so
    • 2:01:08that we can add and add and add and, heck, even remove
    • 2:01:11names and numbers eventually.
    • 2:01:12In Python, one of the things that's wonderful
    • 2:01:14is that you have built in support for CSV files.
    • 2:01:17You don't have to worry about the commas, the quotes, or anything
    • 2:01:20like that, as follows.
    • 2:01:22So let me run code of phonebook.py to reopen that same file from earlier.
    • 2:01:27But let's delete everything therein and let me now do this.
    • 2:01:31Let me import Python's own CSV library, which is against comma-separated values,
    • 2:01:37and we used this briefly for my last phonebook a few weeks back.
    • 2:01:40Let's now open a file using the open function that
    • 2:01:44comes with Python it turns out, opening a file
    • 2:01:46called phonebook.csv in append mode so we can add to it as we
    • 2:01:51did done in the past line by line.
    • 2:01:53Let me then go ahead and ask the user for a name using input,
    • 2:02:02and then let's ask the user for a number using input.
    • 2:02:07And then let's actually put those that name and number into the file.
    • 2:02:12How can I do this in Python?
    • 2:02:13And, again, the goal here is not to absorb
    • 2:02:17exactly how to do this in Python-- it's certainly reasonable to look this up--
    • 2:02:20but just to show you how relatively easy it is.
    • 2:02:23I'm going to create a variable called writer.
    • 2:02:25So we could call it anything I want.
    • 2:02:26And I'm going to set that equal to the CSV library's writer
    • 2:02:30function that just comes with it, and I'm
    • 2:02:31going to pass to it the name of that file.
    • 2:02:34This is a feature that says open this file
    • 2:02:36and be ready to write to it hereafter.
    • 2:02:39How do I do that?
    • 2:02:40I can do writer.writerow, and I can pass in a list
    • 2:02:44of the things I want to write to it.
    • 2:02:45So I can say name comma number in square brackets,
    • 2:02:49so that prints out a new line to the file.
    • 2:02:51And then at the very end of this, let's do file.close to close the whole thing.
    • 2:02:55Now let's see what just happened.
    • 2:02:56Let me go ahead and open up phonebook.csv, Enter, which is empty
    • 2:03:00initially because nothing's in there.
    • 2:03:01Let me show it at write continually.
    • 2:03:04Let me now run Python of phonebook.py, Enter, and let's do Yuliia's name--
    • 2:03:09Yuliia, Enter, and then her number, plus 1-617-495-1000,
    • 2:03:13and watch what happens at top right when I hit Enter because that row will be
    • 2:03:17written.
    • 2:03:18All right, she's now in the file.
    • 2:03:20Let me run it once more with my name, and plus 1-617-495-1000, Enter,
    • 2:03:26and now I am written to that file.
    • 2:03:29And if I want to do this for John Harvard or anyone else,
    • 2:03:31I can do that, then, as well.
    • 2:03:33So what's nice is that notice that the writerow function is actually
    • 2:03:38outputting the commas for me.
    • 2:03:39And if there were weird characters or commas,
    • 2:03:41it would actually escape them by using quotes as well.
    • 2:03:44As with Python in general, I can tighten this up further.
    • 2:03:47In fact, it turns out that, in Python, you
    • 2:03:49don't need to be so pedantic as to open the file, then do some stuff,
    • 2:03:53then close the file.
    • 2:03:54There's this weird other preposition in Python, namely width,
    • 2:03:58that allows you to do multiple things at once.
    • 2:04:00So let me do this.
    • 2:04:00Let me get rid of the close line and let me instead do this--
    • 2:04:04with open as file colon, and then let me indent all of this here.
    • 2:04:11That now is going to have the effect of actually doing all of that
    • 2:04:16but automatically closing the file for me
    • 2:04:18so I don't run the risk of forgetting, maybe leaking some memory somehow,
    • 2:04:22and so forth.
    • 2:04:22And there's one final flourish I can do here, too.
    • 2:04:25Right now, I'm using this basic writer function which essentially just writes
    • 2:04:29a list, writes a list, writes a list.
    • 2:04:31There's one other way where I can write dictionary after dictionary
    • 2:04:34after dictionary, which is handy, especially
    • 2:04:36if I don't just have names and numbers, but maybe email addresses and student
    • 2:04:40ID numbers and other types of values as well.
    • 2:04:43And I can do it as follows.
    • 2:04:44Let me go ahead and let me say--
    • 2:04:50oops, and, actually, just to be clear, this code can be outside of that width
    • 2:04:54because I can ask for this once without the file actually being opened yet.
    • 2:04:57So let's change just these two lines here.
    • 2:04:59I can create a writer, but this time use a dictionary writer,
    • 2:05:03which allows me, again, to write dictionaries-- key value pairs instead
    • 2:05:06of just lists of values lists.
    • 2:05:08I can say use this file for my dictionaries.
    • 2:05:11Let's use field names of quote unquote name comma number,
    • 2:05:17and then let's go ahead after that and do writer dot write row.
    • 2:05:22And I can now pass in any dictionary I want that I want written to that file.
    • 2:05:26So I can do name colon name and then, for instance, number colon number.
    • 2:05:32And let me go ahead and reopen phonebook.csv, Enter.
    • 2:05:37Let me move it right here.
    • 2:05:39Let me delete all of that.
    • 2:05:41And notice what happens this time.
    • 2:05:43More like your real world of using Excel and Google Sheets and Apple Numbers,
    • 2:05:47notice now, when I run Python of phonebook.py, Enter,
    • 2:05:50and I type in Yuliia and plus 1-617-495-1000, Enter, notice that it,
    • 2:05:58too, works as well.
    • 2:06:00And if I wanted to, as well, using a dictionary writer,
    • 2:06:02I could additionally tell this writer to include the names of these columns
    • 2:06:07in that file so that when I open it up in Excel or Apple Numbers or Google
    • 2:06:10Sheets, also, the data is described in that first row of headers
    • 2:06:13that you're probably familiar with from having just
    • 2:06:16used spreadsheets in the real world.
    • 2:06:17So, long story short, this is not to ingrain in you exactly how you
    • 2:06:21read and write CSVs or write in this case,
    • 2:06:23but rather, with just a few lines of code, like six lines of code,
    • 2:06:27you can do a lot more in Python than you can in C.
    • 2:06:30So now to end on a lighter note, let's do this.
    • 2:06:33It turns out, in Python, there's not only all
    • 2:06:35of these libraries that come with the language,
    • 2:06:38but there's also third-party ones that you can install as well.
    • 2:06:41And there's a program you can run in a Linux environment,
    • 2:06:45like your own code space, called pip, which
    • 2:06:47allows you to install additional packages-- that is to say,
    • 2:06:50third-party libraries that other people have written.
    • 2:06:52What this means is that, in advance, of your using cs50.dev,
    • 2:06:57we essentially ran pip install cs50 to make sure that, by default,
    • 2:07:00you just have access to CS50's own library.
    • 2:07:02It does not come with Python, but it's out there in the cloud somewhere,
    • 2:07:05and pip knows how to install it.
    • 2:07:07But suppose I want to do something fun, like from a few weeks
    • 2:07:10back, where we did cowsay, and we had a cow moo on the screen.
    • 2:07:14And we had a dragon and other things too.
    • 2:07:16Well, it turns out there's a package called cowsay
    • 2:07:18that I can install for Python with pip install cowsay, Enter.
    • 2:07:23You'll see on the screen a bunch of stuff happening
    • 2:07:25because it's downloading it, and it's installing it
    • 2:07:27into the appropriate location.
    • 2:07:28But now this means there is a library called cowsay in my own code space.
    • 2:07:33So if I go ahead and create a program called, like, moo.py in this file,
    • 2:07:37I can now import cowsay, which will give me access
    • 2:07:40to any functions and symbols therein.
    • 2:07:42And I can do something like this per its documentation-- cowsay library dot cow,
    • 2:07:47because this is going to print a cow on the screen,
    • 2:07:49and I can say "This is CS50."
    • 2:07:52And down here, I can do Python of moo.py,
    • 2:07:54Enter-- oh, let's make the terminal window bigger.
    • 2:07:57Let's do this again--
    • 2:07:58Python of moo.py, Enter, and I get a cow saying, "This is CS50"
    • 2:08:02in a little speech bubble, like that.
    • 2:08:04I can make it more interesting now in code, though, as follows.
    • 2:08:07If I shrink my terminal window and I use something like Python's input function,
    • 2:08:11I can ask the user for their name, like, what's
    • 2:08:14your name, as we did way back with Scratch and then C.
    • 2:08:17And then I can use one of these f strings in here.
    • 2:08:19And instead of saying, "This is CS50," I can say something like, "Hello, name"
    • 2:08:23in curly braces.
    • 2:08:25Then, down here, I'll make my terminal window bigger.
    • 2:08:27Run Python of moo.py, Enter--
    • 2:08:29what's my name?
    • 2:08:31David, Enter-- and now the cow is mooing dynamically
    • 2:08:34based on what I've just actually typed in.
    • 2:08:37We can do things even fancier than this.
    • 2:08:40Lastly, let me see if I can type this out correctly.
    • 2:08:42In my terminal window, let me go ahead and install
    • 2:08:47pip install qrcode, these two-dimensional bar codes nowadays
    • 2:08:51that are seemingly everywhere.
    • 2:08:52This is going to install a library that's going to know how
    • 2:08:55to automatically create a 2D bar code for me based on any text that I give it,
    • 2:08:59including a URL, because someone else wrote the code that figured out how
    • 2:09:03to do all of that and output a two-dimensional code.
    • 2:09:06So let me go into a program called qr.py that I myself will write,
    • 2:09:10but I'm going to stand on that person's shoulders
    • 2:09:12and I'm going to import a Python OS library, which gives me access
    • 2:09:16to the file system so I can read and write files,
    • 2:09:18and I'm going to import that person's library, qrcode.
    • 2:09:21I'm going to now create a variable called
    • 2:09:23image, set it equal to qrcode.make, because I want to make a QR code,
    • 2:09:28and I'm going to type in the URL of one of CS50's lectures,
    • 2:09:31so https://youtu.be/xvFZjo5PgG0, and, hopefully,
    • 2:09:45I made no typographical errors there.
    • 2:09:46Then, on my next line, I'm going to call image, which
    • 2:09:49is the name of that variable, dot save.
    • 2:09:51I'm going to save this as a file called qr.png.
    • 2:09:54Turns out, this library supports different file formats, like PNG,
    • 2:09:57for Portable Network Graphics.
    • 2:09:58So I'm going to say, give me that type of file.
    • 2:10:01Then I'm going to go ahead and run this program as follows, Python of qr.py,
    • 2:10:06Enter--
    • 2:10:07no errors.
    • 2:10:08I'm going to now open up qr.png, Enter, hide my terminal window,
    • 2:10:15give you all a chance to open your phone,
    • 2:10:17and open the URL that's secretly embedded in this QR code,
    • 2:10:22and at the risk of incurring your ire--
    • 2:10:26there we go-- this was CS50.
    • 2:10:29We'll see you next time.
    • 2:10:30[APPLAUSE]
  • 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