CS50 Video Player
    • 🧁

    • 🥧

    • 🍌

    • 🍿
    • 0:00:00Introduction
    • 0:00:24Loops
    • 0:00:50cat.py
    • 0:03:24while
    • 0:16:21for
    • 0:27:00Validating Input
    • 0:34:59Iteration with Lists
    • 0:40:36len
    • 0:45:47Dictionaries
    • 0:57:02Lists of Dictionaries
    • 1:05:02Nested Loops
    • 1:20:17Conclusion
    • 0:00:00[MUSIC PLAYING]
    • 0:00:24DAVID MALAN: All right.
    • 0:00:25This is CS50's Introduction to Programming with Python.
    • 0:00:28My name is David Malan, and this week we focus on loops, this ability in Python
    • 0:00:33and a lot of other programming languages to do something again and again,
    • 0:00:37a cycle of sorts.
    • 0:00:38And let's see if we can't begin by motivating
    • 0:00:40exactly why we have this ability to do things cyclically using these loops.
    • 0:00:45I'm going to go ahead here and open up VS Code.
    • 0:00:48And in my terminal window, let's go ahead
    • 0:00:50and create via code cat.py, a Python program that meows like a cat.
    • 0:00:57And I'm going to go ahead here in this Code tab, and very simply, perhaps,
    • 0:01:00I'm going to start by implementing this cat just by using print.
    • 0:01:03We're going to have this cat not make audible sounds,
    • 0:01:06but just print meow, meow, meow on the screen three times.
    • 0:01:08Well, I think the simplest way I can do this is just to print meow once,
    • 0:01:12and to print meow again, and to print meow one last time on the screen.
    • 0:01:18And now let me go down to my terminal window, let me run Python of cat.py,
    • 0:01:23Enter, and meow, meow, meow.
    • 0:01:25All right, so this program works.
    • 0:01:27This program indeed works if my goal is to get the cat to meow three times.
    • 0:01:31And let me propose, just to help us wrap our minds around
    • 0:01:34what's going on inside of the computer, let
    • 0:01:36me propose that we consider this flowchart.
    • 0:01:38So as before, we have this flowchart that
    • 0:01:40starts with this oval, which just means start reading here.
    • 0:01:44And then notice, it goes via arrows to a meow, meow, meow, and then it stops.
    • 0:01:50It's perfectly correct, and honestly, it's wonderfully simple,
    • 0:01:53but I daresay we can find fault with my code nonetheless.
    • 0:01:58Why is my code arguably poorly designed?
    • 0:02:03Now the answer is going to be loops in some way,
    • 0:02:05but let's see if we can identify in what way
    • 0:02:08the code is actually poorly designed in some sense.
    • 0:02:12Let's see.
    • 0:02:13Any thoughts.
    • 0:02:14Alex?
    • 0:02:15AUDIENCE: OK.
    • 0:02:16So, I mean, repeating the same action like three times or even more
    • 0:02:21is not a good habit.
    • 0:02:23DAVID MALAN: Yeah, I'm just repeating myself.
    • 0:02:24And honestly, it's not that big a deal.
    • 0:02:27If we go back to my code here, am I really doing such a bad thing
    • 0:02:31by just printing meow, meow, meow three times?
    • 0:02:34Not really, but let's consider the logical extension of this.
    • 0:02:37Suppose I wanted to meow four times or five times or 50 times or 500 times.
    • 0:02:43Do you really think, even if you've never programmed before,
    • 0:02:46is the solution to this problem really going to be to hit copy-paste 50 times?
    • 0:02:50Like probably not.
    • 0:02:51We can probably do better than that.
    • 0:02:52And beyond it just being ugly at that point,
    • 0:02:54having so many lines of identical code, just
    • 0:02:57imagine if you wanted to change the code.
    • 0:02:59Maybe I change my mind and I don't want to make a cat, I want to make a dog.
    • 0:03:02So now it has to say woof, woof, woof multiple times.
    • 0:03:04Now I have to change that in 50 different places.
    • 0:03:07And yeah, sure, I could do find and replace,
    • 0:03:10but come on, like we're programmers now, there's
    • 0:03:12got to be a better way than just repeating ourselves.
    • 0:03:15So I bet we can do better than that if we think about a little
    • 0:03:18harder how we go about structuring this program.
    • 0:03:22And we can do that if we augment our vocabulary just a little bit.
    • 0:03:26It turns out in Python, and in other languages,
    • 0:03:28too, there's a keyword called while.
    • 0:03:31And while is one way that we can express what's called a loop,
    • 0:03:34a block of code that's going to do something again and again and again--
    • 0:03:380 times, 1 time, 2 times, 50 times, as many times as we want.
    • 0:03:43But while rather leaves to us the particulars
    • 0:03:48of how we express ourselves to do something again and again.
    • 0:03:52So let me go back over to VS Code here and let me propose that I do this.
    • 0:03:56While is a construct that allows me to ask a question again and again.
    • 0:04:01And any time we've seen a question, it's been
    • 0:04:03in the form of a Boolean expression, a question to which the answer is
    • 0:04:07true or false.
    • 0:04:08Well, how could I do this?
    • 0:04:10How could I print out meow three times and ask three times a question
    • 0:04:15to which the answer is true or false?
    • 0:04:18Well, what if I did some counting?
    • 0:04:20Like literally on my fingers.
    • 0:04:21And if I'm trying to count maybe down from three, I want to meow three times,
    • 0:04:25I can put three fingers up and I can meow.
    • 0:04:28And then I can put like one of the fingers down and then meow.
    • 0:04:31And I can put one of the fingers down and I can meow.
    • 0:04:33Put one of the fingers down.
    • 0:04:34And maybe the question I can ask every time I meow
    • 0:04:38is, do I have any fingers up still?
    • 0:04:40Do I have any fingers up still?
    • 0:04:42Do I have any fingers up still?
    • 0:04:43And if the answer is true, keep going.
    • 0:04:45If the answer is false, stop.
    • 0:04:48So how can I translate that to code?
    • 0:04:50Well, once we've added this while keyword--
    • 0:04:53I think we have all the building blocks already, let me propose that I do this.
    • 0:04:57Let me propose that I give myself a variable.
    • 0:04:59And I'll call it i for integer, but I could call it anything I want,
    • 0:05:02and I'm going to initialize it to 3.
    • 0:05:04Then I'm going to use this new feature of Python, while,
    • 0:05:07and I'm going to ask a question, the answer to which must be true or false.
    • 0:05:12And I'm going to say, while i does not equal 0.
    • 0:05:17So I'm going to ask the question, while i does not equal 0, do the following.
    • 0:05:22Notice the colon at the end of the line.
    • 0:05:24Notice my indentation.
    • 0:05:25And just like with functions, just like with conditionals,
    • 0:05:28you indent the lines that you only want to execute as part of this other thing.
    • 0:05:34What do I want to do while i does not equal 0?
    • 0:05:37Well, I think I just want to meow.
    • 0:05:41But it's not enough just to write this code.
    • 0:05:44If I were to very dangerously run Python of cat.py and hit Enter right now,
    • 0:05:52what might happen on the screen?
    • 0:05:55Whether you've programmed before or not.
    • 0:05:58Why is this a very bad thing potentially?
    • 0:06:01It's not going to break things, but it might lose control of my computer
    • 0:06:05somehow.
    • 0:06:07Any thoughts?
    • 0:06:08Yeah, Timo?
    • 0:06:10AUDIENCE: Hi.
    • 0:06:11I think it's going to continue to print out meow since i is always equal to 3
    • 0:06:18and the while is always true.
    • 0:06:20DAVID MALAN: Yeah, exactly.
    • 0:06:22If I'm initializing i to 3-- that is, setting it equal to 3 on line 1,
    • 0:06:26then I'm asking the question, while i does not equal 0,
    • 0:06:29and that's going to be true, it does not equal 0,
    • 0:06:31it obviously equals 3, print meow.
    • 0:06:34And the way a while loop works is that the Python interpreter just
    • 0:06:38keeps going back and forth.
    • 0:06:40It goes from line 1 to line 2, then to line 3,
    • 0:06:45and then it goes back to line 2 to ask the question again.
    • 0:06:48If the answer is still true, it goes to line 3.
    • 0:06:50It then goes back to line 2.
    • 0:06:52If the answer is still true, it goes back to line 3.
    • 0:06:55And to Timo's point, if you're never actually changing the value of i,
    • 0:07:00it's always 3, you're just going to be looping literally forever,
    • 0:07:04and this is an accidental infinite loop.
    • 0:07:07So we've got to be smarter than that.
    • 0:07:08And I'm not going to hit Enter because I don't
    • 0:07:09want to lose control over my computer here such that it's
    • 0:07:12printing out meow forever.
    • 0:07:14Fortunately, if you ever do do that and you find yourself
    • 0:07:16in an accidental infinite loop, Control-C for cancel or interrupt
    • 0:07:21is going to be your friend.
    • 0:07:23If you ever seem to lose control, you don't need to reboot
    • 0:07:26or turn off the computer.
    • 0:07:27You can just hit Control-C in your terminal window
    • 0:07:30and that will likely fix it.
    • 0:07:32All right, well what do I want to do, then, after meowing each time?
    • 0:07:35I think what I'd like to do here is maybe something like this.
    • 0:07:39Let me update i to equal whatever the current value is minus 1 here--
    • 0:07:46whoops, sorry.
    • 0:07:47Minus 1.
    • 0:07:48So if i on each iteration--
    • 0:07:51I'm updating i to be one less, one less, one less,
    • 0:07:55it should eventually hit 0, at which point the answer to 9.2's question
    • 0:08:00will now be false.
    • 0:08:02So let's see if this works.
    • 0:08:03I'm going to go down to my terminal window and run Python of cat.py,
    • 0:08:06and I indeed get three meows.
    • 0:08:09Why?
    • 0:08:10Because I've wired this up like a machine in software, if you will.
    • 0:08:14I've set i equal to 3, then I keep asking this question.
    • 0:08:17But I keep turning the gears, I keep changing the value of the variable
    • 0:08:21to make sure that ultimately it is actually
    • 0:08:25being decremented-- that is, decreased by 1 until we eventually hit 0.
    • 0:08:30Now for those of you who think I'm a little more graphically,
    • 0:08:33let me pull up one of our usual flow charts.
    • 0:08:35This is just a representation graphically of the exact same thing.
    • 0:08:38Notice what's happening.
    • 0:08:39I first start the program, and then I initialize i to 3,
    • 0:08:44and then I ask the first of my questions.
    • 0:08:46Again, the diamonds always represent questions.
    • 0:08:48And the answer is going to be true or false.
    • 0:08:50Does i not equal 0?
    • 0:08:52Well, it doesn't, it equals 3.
    • 0:08:54So if I follow the true line, I meow.
    • 0:08:56And then I follow this arrow, and I update i to equal i minus 1.
    • 0:09:01At this point in the story, i presumably equals 2 mathematically.
    • 0:09:05I follow the arrow.
    • 0:09:06And there's the loop.
    • 0:09:07This is why it's nice to see this graphically,
    • 0:09:09perhaps because you can literally see the loop back and forth.
    • 0:09:12Now I ask the question again.
    • 0:09:14Does 2 not equal 0?
    • 0:09:16Well, it does not equal 0, it's 2, so we meow again.
    • 0:09:20We change i from 2 to 1.
    • 0:09:21Well, does 1 not equal 0?
    • 0:09:23Well obviously 1 is not 0, so we meow again.
    • 0:09:27We decrement i again. i is now 0.
    • 0:09:30Does 0 not equal 0?
    • 0:09:33No, it equals 0, so the answer is false and we stop.
    • 0:09:37So there, perhaps more so than any of our flowcharts before,
    • 0:09:41do you really see the structure of what's happening inside of the program?
    • 0:09:45And you don't have to get into the habit of making these charts
    • 0:09:47or creating these charts, but just as a first pass at what's
    • 0:09:50going on inside of the computer, that's indeed one way to visualize it instead.
    • 0:09:55Well let me propose that, like always, there's many different ways
    • 0:09:57to solve this problem.
    • 0:09:58And suppose you just like to think a little differently.
    • 0:10:01Maybe you don't like starting at 3 and then counting down to 0.
    • 0:10:04Why?
    • 0:10:05Maybe you're just brain doesn't work that way
    • 0:10:07and you prefer to count up instead of down.
    • 0:10:09Totally fine.
    • 0:10:10Let me go ahead and change my code here to set i equal to 1 instead of 3.
    • 0:10:15And here, let me just change my logic.
    • 0:10:18Rather than checking for not equal to 0, like maybe
    • 0:10:20you don't like thinking in terms of not because it's a little confusing,
    • 0:10:23and it might be, let's just check that i is less than or equal to 3.
    • 0:10:28So we'll be a little more explicit.
    • 0:10:30We'll count from 1 up through 3, each time printing meow,
    • 0:10:34but I'm going to need to change this line here.
    • 0:10:36Let me see if we can't call on someone to change line for me.
    • 0:10:40How do I want to change line 4 to be consistent with counting from 1 up
    • 0:10:47to and through 3?
    • 0:10:52AUDIENCE: I would be plus 1 every time you meow.
    • 0:10:57DAVID MALAN: Yeah, exactly.
    • 0:10:58In this case, we want to add one not subtract 1.
    • 0:11:01And in fact, if you think about this, this 2 could end very poorly.
    • 0:11:05If you start counting at 1 and you keep subtracting 1, subtracting 1,
    • 0:11:09subtracting 1, I think we're going to find ourselves
    • 0:11:11with the same problem, which is that we're never going to stop because we're
    • 0:11:15going to keep getting more and more negative as opposed to ever getting up
    • 0:11:19to the number 3.
    • 0:11:20So I think you're right, I need to change this to be i equals i plus 1.
    • 0:11:24And now notice just for clarity, too, the equal sign
    • 0:11:27is, again, our assignment operator from right to left.
    • 0:11:30Logically, this might otherwise strike you as strange.
    • 0:11:33Like how can i equal itself plus 1?
    • 0:11:35Well, it doesn't until you execute this code from right to left.
    • 0:11:39You add 1 to i or you subtract 1 from i, and then you update the value of i
    • 0:11:44on the left.
    • 0:11:45The assignment copies the value from the right to the left.
    • 0:11:48Well, how else might I do this?
    • 0:11:49Well, I will say that most programmers, computer scientists more generally,
    • 0:11:55tend to start counting from 0.
    • 0:11:57It's a convention and it actually has upsides even
    • 0:11:59in Python and other languages where generally speaking,
    • 0:12:02it's a good thing to start counting from 0
    • 0:12:04instead of counting like we might in the real world from 1.
    • 0:12:07Let's go ahead and adopt that convention now.
    • 0:12:10Let me set i equal to 0, and I need to make a change now.
    • 0:12:14Notice, if I don't change my logic, this program just became buggy.
    • 0:12:19The cat has a bug.
    • 0:12:20It's now meowing four times if I run it as is.
    • 0:12:23But the easiest fix here would be to change my inequality
    • 0:12:27to be this, less than instead of less than or equal to.
    • 0:12:31Now I'm starting at 0, but I'm going up to but not through 3.
    • 0:12:36And even though this might, of all the things we've seen thus far,
    • 0:12:40seem maybe the least familiar, most of us might start at 1, 2, then 3,
    • 0:12:44it's a good habit to get into now, start at 0,
    • 0:12:47and go up to but not through the value that you care about ultimately,
    • 0:12:523 in this case here.
    • 0:12:53Well, let me tighten things up a bit here.
    • 0:12:55Not only will this now fix my counting problem,
    • 0:12:57it now meows 3 times as expected, there's
    • 0:13:00a more succinct way to express i equals i
    • 0:13:03plus 1, and this, is because it's such a popular thing to do in code.
    • 0:13:06You can instead just say i plus equals 1, and that's it.
    • 0:13:11You don't need to put everything on the right-hand side.
    • 0:13:14This is a special syntax that says the exact same thing, increment i,
    • 0:13:19but it does it with a few fewer keystrokes.
    • 0:13:21It's just a little more pleasant to type, it's a little faster to read,
    • 0:13:24it's just a convention.
    • 0:13:25Those of you who have programmed in C, C++, Python--
    • 0:13:29no, not Python.
    • 0:13:30C, C++, Java, JavaScript might have seen plus-plus before or minus-minus.
    • 0:13:36Sorry, Python doesn't have it, so you cannot use that.
    • 0:13:40This is as succinct as your line of code might get.
    • 0:13:44All right.
    • 0:13:44Let me pause here to see, then, if there's
    • 0:13:46any questions about these implementations of while loops.
    • 0:13:53AUDIENCE: Can we use stuff like for loops
    • 0:13:55which have a certain i-value initialized to it at the start
    • 0:14:02and it runs from the particular condition you put into the thing
    • 0:14:09and increment it as you go along?
    • 0:14:12DAVID MALAN: Short answer, no, you cannot do what you're describing,
    • 0:14:15but there is another type of for loop that we will soon see.
    • 0:14:18But let's come to that in just a moment.
    • 0:14:20Other questions on loops using while here?
    • 0:14:26AUDIENCE: So I had a question about that flowchart.
    • 0:14:28DAVID MALAN: OK.
    • 0:14:29AUDIENCE: There were-- yeah.
    • 0:14:30There were certain symbols for the certain kind of the statements were--
    • 0:14:36are they certainly used for that kind of statement that they--
    • 0:14:42DAVID MALAN: They are.
    • 0:14:43So I deliberate--
    • 0:14:44I deliberately use certain types of symbols, certain shapes
    • 0:14:47here whereby an oval is conventional for start and stop.
    • 0:14:51I used rectangles for any statement of code, like an assignment or a printing
    • 0:14:56and so forth.
    • 0:14:57And I used diamonds to represent questions that you might ask,
    • 0:15:02conditions as we've seen.
    • 0:15:03If you're doing this for yourself, if you're just
    • 0:15:06trying to make sense of your code and writing it down,
    • 0:15:07you certainly don't need to use these formal symbols,
    • 0:15:10but I tried to be consistent with some best practices.
    • 0:15:13And in fact, let me come back to the same picture,
    • 0:15:15because this was the first version of our picture,
    • 0:15:17but we've since modified our code a couple of times.
    • 0:15:19This, recall, was the version where the question we were asking
    • 0:15:22was i not equal to 0, let me go ahead and just change this code now
    • 0:15:26to represent the next version we did, which, recall,
    • 0:15:29changed our logic to start counting from 1,
    • 0:15:31it changed our question to check as i less than or equal to 3,
    • 0:15:36but then everything else was the same except for the counting, which
    • 0:15:39is now plus instead of minus.
    • 0:15:41And then we refined it a little bit further by counting now from 0 up to
    • 0:15:47but not through 3.
    • 0:15:48And we tightened up this code here by just incrementing 1
    • 0:15:52by using the slightly more succinct syntax.
    • 0:15:54So at this point, these flowcharts might become less and less useful
    • 0:15:57for us, because once you've wrapped your mind around the concept
    • 0:16:00and hopefully the picture helps bring that concept to life,
    • 0:16:03it certainly fine to focus entirely on the code
    • 0:16:06and only think about or even draw something like this
    • 0:16:09if you need to wrap your mind around something more complicated
    • 0:16:12than you're used to.
    • 0:16:13Well, let me go ahead, if I may, and propose
    • 0:16:15that we transition to another approach of types of loops using another
    • 0:16:20keyword here, namely a for loop.
    • 0:16:22And this is a word that does exist in other languages,
    • 0:16:25but doesn't necessarily have as many features as other languages might
    • 0:16:28use it for.
    • 0:16:29But there is a different type of loop-- not a while loop, but a for loop.
    • 0:16:33And a for loop is going to allow us to express ourselves a little differently,
    • 0:16:37but to do so, I propose that the easiest way
    • 0:16:40is if we introduce one other idea in Python, which is that of a list.
    • 0:16:43And here, too, no pun intended, we're adding to the list of data types
    • 0:16:48that Python supports.
    • 0:16:49We've seen strs or strings.
    • 0:16:51Ints or integers.
    • 0:16:53Floats or floating point values.
    • 0:16:54Bools or Boolean expressions.
    • 0:16:56Python also has lists, which is another type of data,
    • 0:17:00but wonderfully, this one is probably pretty familiar.
    • 0:17:02A list of things in the real world is a list of things in Python.
    • 0:17:06It's a way of containing multiple values all in the same place, all
    • 0:17:11in the same variable.
    • 0:17:12So what do I mean by this?
    • 0:17:14Well let me propose that we go back to our VS Code here,
    • 0:17:18and let me start fresh with my code here and not use a while loop at all,
    • 0:17:22but let me use this new keyword for.
    • 0:17:24The way for loop works is that it allows you to iterate over a list of items.
    • 0:17:30So what does this look like?
    • 0:17:31It might look like this--
    • 0:17:32for i and the following list of items, 0, 1, 2.
    • 0:17:39This is my starting point, and on each iteration
    • 0:17:41of this loop-- that is, on each execution of this loop again and again,
    • 0:17:45I want to print out meow.
    • 0:17:47Now I'll admit, I kind of like the look of this code already
    • 0:17:51even though there's some new syntax here,
    • 0:17:53because it's just shorter than the while loop.
    • 0:17:55The while loop had multiple lines a moment ago
    • 0:17:58and it was entirely up to me to decide what i is.
    • 0:18:01I have to check a condition, I have to increment or decrement i.
    • 0:18:04Like I was doing a lot of work, relatively speaking,
    • 0:18:07to make that thing turn, to make that loop going to go.
    • 0:18:10It was very mechanical in a sense.
    • 0:18:12You can in your mind's eye maybe see the gears turning as all of these variables
    • 0:18:18are changing and these questions are being asked.
    • 0:18:21A for loop simplifies all of that, and it just
    • 0:18:24says, if you want a variable like i, a number,
    • 0:18:27and you know in advance how many times want this loop to execute-- three
    • 0:18:31times, we'll just kind of specify what it
    • 0:18:34is you want i to take on as values explicitly.
    • 0:18:37In this loop, i will be automatically initialized by Python to be 0,
    • 0:18:41then meow will be printed.
    • 0:18:43Then Python would automatically update i to equal 1, then meow will be printed.
    • 0:18:48Then Python will automatically update i to be 2 and meow will be printed.
    • 0:18:53And because that's it for the values in that list, Python will stop
    • 0:18:57and it will only meow a total of three times.
    • 0:19:00What is the list?
    • 0:19:01The list in this program is exactly that, 0, comma, 1, comma, 2,
    • 0:19:05and notice the square brackets.
    • 0:19:07Those aren't parentheses, those are square brackets that represent a list.
    • 0:19:11That's how visually as the programmer-- that's how Python knows as the language
    • 0:19:15that you intend for that to be a list.
    • 0:19:18So let me go ahead and run this Python of cat.py, and it works just the same.
    • 0:19:23But it's only two lines.
    • 0:19:24It's pretty readable once you have familiarity with that construct,
    • 0:19:28but to my constant point about correctness not necessarily
    • 0:19:33being the same as design, in what sense is this program perhaps
    • 0:19:38poorly designed?
    • 0:19:40It seems to work.
    • 0:19:41It meows three times, but why might this not
    • 0:19:45be the best way to solve this problem?
    • 0:19:48Even if you've never programmed before, again,
    • 0:19:51think about corner cases, things that may or may not happen.
    • 0:19:54Think about extreme cases that really test the quality of this code.
    • 0:19:59AUDIENCE: OK.
    • 0:19:59I think that because we are saying 0, 1, 2 3 times.
    • 0:20:06And then if you want to take a million, you say 1, 2, 3.
    • 0:20:11DAVID MALAN: Yeah, exactly.
    • 0:20:12And that's what I mean about thinking about the extreme cases.
    • 0:20:15If you're trying to decide for yourself if your own code is good
    • 0:20:18or someone else's code is good, it might look so at first glance,
    • 0:20:22but think about the extreme.
    • 0:20:23Well, what if it's not three things, it's a million things?
    • 0:20:26I mean, are you really going to write out 0 through a million or 0
    • 0:20:31through 9--
    • 0:20:33999,999?
    • 0:20:38Like no, you're not going to write that many numbers on the screen
    • 0:20:40there's got to be a better way.
    • 0:20:42So let's do the better way from the get-go
    • 0:20:45rather than set the stage for doing something poorly.
    • 0:20:47And the one way we can solve this problem to improve the design
    • 0:20:52is don't just manually specify the list of values, use a function,
    • 0:20:56someone else's function that comes with Python
    • 0:20:59that gives you the list you want.
    • 0:21:00And the easiest way to do that in Python is
    • 0:21:02to use a function called range that returns to a range of values.
    • 0:21:07It expects as input at least one argument,
    • 0:21:09and that number is going to be the number of values you want back.
    • 0:21:14Those values are going to start at 0 and go to 1, to 2, and so forth,
    • 0:21:18but they will go up two but not through the number you specify.
    • 0:21:22So by specifying range 3, you're essentially
    • 0:21:26being handed back 1, 2, 3 values.
    • 0:21:29And by default, those values are 0, 1, and 2, and that's it.
    • 0:21:33But what's brilliant about this is that now, to Hope's point, if I do
    • 0:21:37want to meow a million times--
    • 0:21:38I mean, that is an angry cat, I can now do a million by just typing a million.
    • 0:21:44I don't have to literally type 0, comma, 1, comma, 2, comma, 3, comma,
    • 0:21:484, all the way up to 999,999, I just do this.
    • 0:21:53So that's got to be a better way long-term.
    • 0:21:57So that's indeed one improvement we can indeed
    • 0:21:59make here still using a for loop, but now using this range function.
    • 0:22:03And just to show you something else that's Pythonic--
    • 0:22:05this is not strictly necessary, but it's commonly
    • 0:22:07done, there's a minor improvement we can make here,
    • 0:22:11even if we're just meowing three times.
    • 0:22:14And notice that even though I'm defining a variable i, I'm not ever using it.
    • 0:22:20And it's kind of necessary logically, because Python, presumably,
    • 0:22:24has to use something for counting.
    • 0:22:26It has to know what it's iterating over.
    • 0:22:28But there's this convention in Python where
    • 0:22:30if you need a variable, just because the programming feature requires
    • 0:22:35it to do some kind of counting or automatic updating, but you, the human,
    • 0:22:38don't care about its value, a Pythonic improvement here
    • 0:22:42would be to name that variable a single underscore.
    • 0:22:45Just because it's not required, it doesn't
    • 0:22:48change the correctness of the program, but it
    • 0:22:50signals to yourself later, it signals to colleagues or teachers that
    • 0:22:54are looking at your code, too, that yes, it's a variable,
    • 0:22:57but you don't care about its name because you're not using it later,
    • 0:23:00it's just necessary in order to use this feature, this loop in this case here.
    • 0:23:04So just a minor improvement or change there.
    • 0:23:09But to really gets you intrigued by what's possible in Python,
    • 0:23:13let's take this one step further.
    • 0:23:15So if we really want to be Pythonic, this one, if you've programmed before,
    • 0:23:19is kind of going to blow your mind, so to speak,
    • 0:23:22whereby if I want the cat to meow three times, what if I actually do this?
    • 0:23:27print, open parenthesis, quote-unquote, meow times 3.
    • 0:23:34You have to be kind of a geek to think this is cool, but this is kind of cool.
    • 0:23:37So you can literally just print what you want,
    • 0:23:40multiply it by the number of times that you want it,
    • 0:23:44and you will get back exactly that result.
    • 0:23:47Now I've kind of made a mistake here.
    • 0:23:50So let's see what this does.
    • 0:23:51It's not quite as beautiful as this code might look to you-- to some of you,
    • 0:23:56to me.
    • 0:23:57Let me run Python of cat.py, Enter.
    • 0:24:00OK, it's a really like hungry cat or something.
    • 0:24:02It's meowing really fast.
    • 0:24:04But I can fix this, I bet.
    • 0:24:06Let's think about now some of the basic building blocks we've discussed.
    • 0:24:10The problem is clearly that literally meow, meow,
    • 0:24:13meow is being repeated three times, but it's not as pretty as I want it.
    • 0:24:16I want it to be meow, meow, meow on separate lines.
    • 0:24:19What might be a possible solution here while still
    • 0:24:22using this multiplication operator?
    • 0:24:26And think back.
    • 0:24:27We've used plus to concatenate strings.
    • 0:24:30You can apparently use multiplication to concatenate strings, but more than once
    • 0:24:33again and again and again.
    • 0:24:35How could I clean this up without reverting
    • 0:24:37to my for loop or my while loop and still use multiplication in this way?
    • 0:24:42AUDIENCE: We can use the escape sequence which would be backslash n.
    • 0:24:45DAVID MALAN: Amazing.
    • 0:24:46Yes.
    • 0:24:47Think back to backslash n, which is the way you as the programmer
    • 0:24:50can express a new line in code.
    • 0:24:52And I think, if I take your advice, I put a backslash in there inside
    • 0:24:57of my quotes, so that at the end of every M-E-O-W, there's a new line,
    • 0:25:02let's see how this looks.
    • 0:25:03Let me clear my screen and run Python of cat.py.
    • 0:25:06OK, so close.
    • 0:25:08I like this.
    • 0:25:09Let me call on someone else.
    • 0:25:10The only thing I don't like-- and I know I'm being really nitpicky now--
    • 0:25:13is that it's meow, meow, meow on separate lines,
    • 0:25:15but there's this extra blank line, which I'm just not loving aesthetically.
    • 0:25:20AUDIENCE: I think we can make n equal to column--
    • 0:25:25column, not-- like a slash n.
    • 0:25:27DAVID MALAN: Yeah.
    • 0:25:28So here, too, like all of these things we've seen in past weeks
    • 0:25:31are kind of coming together.
    • 0:25:32Recall that the print function lets you control what the line ending is.
    • 0:25:37By default, it's backslash n itself.
    • 0:25:39Which is why at the very end of this print,
    • 0:25:41the cursor is being moved again to the next line.
    • 0:25:44Well, we need to just override that.
    • 0:25:46So let me go into my code here and let me change this to comma n
    • 0:25:50equals quote-unquote so that it's no longer the default backslash n,
    • 0:25:54it's instead now going to be nothing whatsoever.
    • 0:25:59That should eliminate, then, hopefully that additional blank line.
    • 0:26:03So let me run this one last time here, Python of cat.py, Enter,
    • 0:26:07and there we have it.
    • 0:26:08So now, at least as programming goes, it's
    • 0:26:12kind of cool that I can distill this into a short line
    • 0:26:15and express myself all at once.
    • 0:26:17Now to be fair, it's a little less readable.
    • 0:26:19Like now I've got backslash n, I've got times 3,
    • 0:26:21I've got n equals quote-unquote.
    • 0:26:23So you don't have to do things this way.
    • 0:26:25My previous approach with a for loop, totally fine.
    • 0:26:28My previous approach with a while loop, totally fine, and in some sense,
    • 0:26:31perfectly well-designed.
    • 0:26:33But this is just yet another way to do it,
    • 0:26:36but it's not a good thing if you or your teacher, your colleague, your friend
    • 0:26:40are going to struggle to read your own code.
    • 0:26:42But this is a feature of Python that some languages do not, in fact, have.
    • 0:26:47All right, well let me propose that things get more interesting still
    • 0:26:51if we're not just meowing three times only,
    • 0:26:53but we're meowing some variable number of times.
    • 0:26:56Let's ask the user how many times this cat should meow.
    • 0:26:58So let me clear the screen here, and let me figure out, well,
    • 0:27:03how do I get a number from the user?
    • 0:27:05The catch here is that if I want the user to give me a number,
    • 0:27:08I'm not doing math, per se, I'm meowing, and therefore, the user
    • 0:27:12has to give me a positive value.
    • 0:27:14The user has to give me a positive value.
    • 0:27:17So how can I insist on this?
    • 0:27:18Well, if I just do this, n equals int of input, what's n, question mark?
    • 0:27:25Well, I want to check like--
    • 0:27:28I could say if n is less than 0--
    • 0:27:32like if it's negative, well I could do this.
    • 0:27:34Well, then ask again.
    • 0:27:35Int, input, what's n, question mark?
    • 0:27:40OK, well what if the user still doesn't give me a positive number?
    • 0:27:43What if being really difficult they're not paying attention
    • 0:27:45and they typed in two negative numbers?
    • 0:27:47Well, if n is less than 0, well, let's do it again. n equals--
    • 0:27:53this does not end well.
    • 0:27:54You can't infinitely many times keep checking, is it negative,
    • 0:27:58is it negative, or is it negative?
    • 0:27:59The program would never be done written.
    • 0:28:01So we can do this I think better maybe with a loop.
    • 0:28:05So let me propose this.
    • 0:28:06A very common paradigm in Python, when you
    • 0:28:09want to get user input that matches a certain expectation you have,
    • 0:28:14that it's all positive, that it's all negative, or just something like that,
    • 0:28:17you just immediately say while true.
    • 0:28:20You deliberately, and a little dangerously but a very conventionally,
    • 0:28:24induce an infinite loop.
    • 0:28:25Now what is an infinite loop?
    • 0:28:27It's just one that goes forever.
    • 0:28:28And we've seen how that can happen accidentally mathematically.
    • 0:28:31It's absolutely going to happen when you say while true.
    • 0:28:34Why?
    • 0:28:35Well, the answer to the true question is always true.
    • 0:28:39So this is a way of deliberately inducing a loop that
    • 0:28:41by default is going to go forever.
    • 0:28:43So we're going to need a way of breaking out of this loop when
    • 0:28:46we have the number we want.
    • 0:28:48The convention, though inside of this otherwise
    • 0:28:50an infinite loop is to ask the question you care about,
    • 0:28:52like give me an int by prompting the user for input.
    • 0:28:55Like what's n, question mark?
    • 0:28:57And then just ask your question.
    • 0:28:59So if n is less than 0, then I think we want Python to just continue
    • 0:29:04to prompt the user again.
    • 0:29:05That is, we want the code to stay in the loop, recall the input function,
    • 0:29:09and hope that the user gives us a better answer.
    • 0:29:11If this time around it's less than 0, so let's just literally
    • 0:29:14use Python's keyword continue, which says
    • 0:29:16just that-- continue to stay within this loop.
    • 0:29:20Else, if it's not less than 0, let's go ahead and just break out
    • 0:29:24of the loop altogether using another keyword in Python, break.
    • 0:29:27Break will break you out of the most recently begun loop in this case
    • 0:29:31if it's not the case that n is less than 0.
    • 0:29:34So this will work, and it will allow us to get a value that 0 or greater
    • 0:29:38from the user, but I think we can tighten it up further so as to not
    • 0:29:41bother having an if, and, and else.
    • 0:29:43Why don't we instead just say, if n is greater than 0, go ahead and break?
    • 0:29:49In fact, it's not that interesting a program
    • 0:29:51if we even allow the user to type in 0.
    • 0:29:52So let's wait until they give us an integer that is greater than 0
    • 0:29:56and then break out of this loop.
    • 0:29:59And what can I now do down here?
    • 0:30:00For i in range of whatever that value n is, print meow.
    • 0:30:07And honestly, I don't need i here, so let me come back to that principle
    • 0:30:10before.
    • 0:30:10And let me just change it to an underscore
    • 0:30:12just to be Pythonic, if you will.
    • 0:30:14So what's going on?
    • 0:30:15Lines 1 through 4 deliberately implement an infinite loop
    • 0:30:20that otherwise by default is going to go forever.
    • 0:30:23But I'm asking a question, inside of that loop,
    • 0:30:26after getting an int from the user on line 2, I'm then checking,
    • 0:30:30is it greater than 0?
    • 0:30:32Or is it 0?
    • 0:30:33Is it negative?
    • 0:30:34None of which makes sense for meowing cat.
    • 0:30:35Like I want the cat to meow at least one time.
    • 0:30:38So if it is greater than 0, break.
    • 0:30:41And this break statement, even though it's indented, indented twice,
    • 0:30:45has the effect of breaking out of the most recently begun while loop.
    • 0:30:50So once the user gives you a positive value,
    • 0:30:53then we get to line 6, at which point we meow that many times because
    • 0:30:58of line 6 and 7.
    • 0:30:59So if I run this now Python of cat.py, Enter, well, what's n?
    • 0:31:03Let's start with 3 where we began, meow, meow, meow.
    • 0:31:06Well this time, let me go ahead and increase the size of my terminal window
    • 0:31:10just temporarily.
    • 0:31:11Let me run Python of cat.py, let me do it 10 times, meow 10 times now
    • 0:31:16appears on the screen.
    • 0:31:17And the takeaways here are not just that we can meow 10 times
    • 0:31:20or do something again and again, but this
    • 0:31:22is a very common paradigm in Python when you want to do something again
    • 0:31:26and again and again, but only until the user actually gives you
    • 0:31:31a value that you care about here.
    • 0:31:34And let me propose actually now that we practice
    • 0:31:36a little more what we've been preaching, especially when it comes to, say--
    • 0:31:41especially when it comes to say writing your own functions.
    • 0:31:45Now that I'm doing all this meowing, it might
    • 0:31:46be nice to actually have a meow function that the inventors of Python
    • 0:31:50didn't envision, so let me do this.
    • 0:31:52Let me actually get rid of all this code and let me go ahead and do this.
    • 0:31:56Let me go ahead and say define a main function, as I've done before,
    • 0:31:59and let me just blindly call meow 3.
    • 0:32:02Meow doesn't exist yet, but when it does, that'll be great.
    • 0:32:05So let me go ahead now and define meow.
    • 0:32:08So am I meow function should take as input
    • 0:32:11a parameter called n or anything I want, and this part's pretty easy now.
    • 0:32:16How do you meow n times?
    • 0:32:17Well, for underscore n, the range of n, go ahead and just print meow.
    • 0:32:22So same code as before, nothing new here,
    • 0:32:24I'm just putting that logic inside of a meow function
    • 0:32:28that's going to have this side effect of printing meow.
    • 0:32:30And now, as before, let me go down here and let me make sure I call main.
    • 0:32:34And if I now run this code, Python of cat.py, meow, meow, meow.
    • 0:32:39It's always going to do three because I've hardcoded to 3.
    • 0:32:42Well, let's make one improvement here.
    • 0:32:44Let me go ahead now and maybe do this.
    • 0:32:48Let me ask the user for a number.
    • 0:32:50So let's say something like this, number equals get number.
    • 0:32:54All right.
    • 0:32:55Unfortunately, there is no function in Python
    • 0:32:57called get number that gets a positive number from the user,
    • 0:32:59but I can invent that.
    • 0:33:01So define get number, open paren, close paren.
    • 0:33:05And then inside of this function, let me do this.
    • 0:33:07While true, go ahead and get a number from the user,
    • 0:33:11converting it to an int asking them, what's n, question mark?
    • 0:33:14And then if n is what I want, it's a greater than 0 value,
    • 0:33:19a positive number, I don't want to break this time necessarily,
    • 0:33:24although I could.
    • 0:33:26I instead want to return the value so I can actually do this instead.
    • 0:33:30And this, too, is a feature of Python.
    • 0:33:32This ability not to just break out of a block of code,
    • 0:33:35but also to return a value in code.
    • 0:33:38To actually return a value gives you the ability, ultimately,
    • 0:33:42to return explicitly a value so that your function has not just a side
    • 0:33:47effect, necessarily, but it actually hands back, just like input does,
    • 0:33:51just like int does, just like float does, an actual value to the user.
    • 0:33:56Now to be clear, I don't have to return n here.
    • 0:33:58I can still break out of the loop as I've done in the past with code
    • 0:34:02like this, but then after the loop, I still have to return.
    • 0:34:06And so what's happening here is that if you use break to get out of the loop,
    • 0:34:10but you need to hand back a value from a function,
    • 0:34:13you still have to use the return keyword now
    • 0:34:15explicitly either in the loop as I did or now outside of the loop
    • 0:34:20but still inside of the function.
    • 0:34:24The last thing I'm going to do here now is change
    • 0:34:26that 3, which we hardcoded earlier, to actually
    • 0:34:28be the value of the variable we've gotten from the user
    • 0:34:31so that now down here, if I run Python of cat.py, Enter, what's n?
    • 0:34:36I can type in 3, I get my three meows, or if I only want one,
    • 0:34:40I now get one meow instead.
    • 0:34:43All right.
    • 0:34:43So if we now have this ability to do things again and again in these loops,
    • 0:34:48let's see if we can't solve some other problems via which
    • 0:34:51to express ourselves cyclically, but get back some interesting answers as well.
    • 0:34:55And let me propose, for instance, that we look
    • 0:34:58a little more closely at these lists.
    • 0:35:00It turns out that in Python, and really, in programs in general,
    • 0:35:03it's useful to have a list of values, because we're
    • 0:35:05going to be able to work with more and more data, larger and larger data sets.
    • 0:35:10So let me propose that we come back to VS Code here
    • 0:35:12and let's do something that's perhaps a little familiar to some folks,
    • 0:35:15the world of Hogwarts.
    • 0:35:17And let me go ahead and code up a file called Hogwarts,
    • 0:35:19and let's see if we can't have a list of students at Hogwarts here.
    • 0:35:23So I have a new tab called hogwarts.py.
    • 0:35:26and let me go ahead and propose that I just define in this program
    • 0:35:30a list of students whose names I know in advance.
    • 0:35:32So I'm not going to get user input for now.
    • 0:35:34I'm just going to know from the get-go that the three
    • 0:35:37students I want to consider are these.
    • 0:35:39Our variable is going to be called students.
    • 0:35:41It's going to equal, as I've done in the past, a square bracket, which
    • 0:35:44means, hey, here comes a list.
    • 0:35:46And those values are going to be Hermione in quotes, because it's
    • 0:35:49a string; Harry in quotes, because it's a string; and then Ron in quotes,
    • 0:35:53because it's a string as well.
    • 0:35:55So this is a list of length 3.
    • 0:35:57It's similar in spirit to my list of length 3 earlier,
    • 0:36:00but that had 3 ints, 0, 1, 2.
    • 0:36:02Now I have a list of three strings instead.
    • 0:36:06And this isn't very useful at the moment,
    • 0:36:08but let me just do something as a check for myself.
    • 0:36:11Let me print out each of these students.
    • 0:36:14Well wait a minute, how do I print the contents of a list?
    • 0:36:19Well, in the past, when we've printed a variable,
    • 0:36:22we've just printed out the name of the variable.
    • 0:36:24But I don't want to print out all of Hermione and Harry and Ron all at once.
    • 0:36:28Maybe I want to print out Hermione first, then Harry, then Ron.
    • 0:36:33So I need a way to express more precisely which
    • 0:36:36value do I want from this list?
    • 0:36:37And the way you do this in Python is you use square brackets in another way.
    • 0:36:42If you have a variable-- in this case, called students,
    • 0:36:45and you want to go inside of that variable and get a specific value--
    • 0:36:49that is to say, you want to index into the list,
    • 0:36:52you use square brackets this way using numbers inside of the square brackets.
    • 0:36:57And here's where we see that it is useful to think and count in terms of 0
    • 0:37:02on up instead of 1 on up.
    • 0:37:04These lists in Python are, shall we say, zero-indexed.
    • 0:37:08The first item in a list is at location 0, the second item in a Python list
    • 0:37:13is that location 1, and the third is that location 2.
    • 0:37:16So you're always kind of off by one mentally, but you get used to it,
    • 0:37:19if you've never programmed before, over time.
    • 0:37:22So let me print out all three students.
    • 0:37:23So let me print out students bracket 0, then students bracket 1.
    • 0:37:27Then lastly, let me print students bracket 2,
    • 0:37:30and this is my third and final line.
    • 0:37:32And of course, if I run this code, it probably does what you would guess.
    • 0:37:35If I run Python of hogwarts.py, there's Hermione, Harry, and Ron
    • 0:37:39each on their own lines there.
    • 0:37:41But there's got to be a better way, especially
    • 0:37:43if I don't know in advance who's going to be in this list,
    • 0:37:45if next year there's some new students at Hogwarts,
    • 0:37:48we can use a loop to do something automatically
    • 0:37:50without having to manually type out 0 and then 1 and 2.
    • 0:37:54Well, here's another feature of Python.
    • 0:37:57You can use a for loop not just to count from 0 to 1 to 2,
    • 0:38:01you can use Python to just iterate over anything.
    • 0:38:03Not just numbers, but strings.
    • 0:38:05So I could actually do this.
    • 0:38:07For student in students, colon, and then indented underneath that,
    • 0:38:13I can say print student.
    • 0:38:15Now it doesn't matter if I have 3 students or 4 or 400,
    • 0:38:19these two lines of code, this loop will print all of those students for me
    • 0:38:23one at a time.
    • 0:38:24So if I now run Python of hogwarts.py, there's the same list,
    • 0:38:28but I don't need to know in advance how long that actual list is.
    • 0:38:32Now notice, I made a conscious decision here.
    • 0:38:35I didn't call this variable underscore, because this time I'm
    • 0:38:39using the variable.
    • 0:38:40And while I could do this, now, no, no, no, no,
    • 0:38:44your code is getting way too cryptic.
    • 0:38:46If you're naming the variable underscore and you're
    • 0:38:48using the variable underscore, now you're helping no one.
    • 0:38:51Now you're confusing the reader, yourself down the line,
    • 0:38:54you should call your variables what they are.
    • 0:38:57So a very appropriate name, though I'm sure you could come up with others,
    • 0:39:00would be student, and here, you could say you would stay student as well.
    • 0:39:04If you'd prefer to be more succinct, it's
    • 0:39:06not unreasonable to do something succinct in a loop like this.
    • 0:39:09For s in students, using maybe the same letter that the list
    • 0:39:13itself begins with, but again, why bother?
    • 0:39:15Python is meant to be more readable.
    • 0:39:17If you have a list of students, iterate over them one student at a time.
    • 0:39:22Let me pause here to see if there's now questions about lists
    • 0:39:25as I've now defined them, a list of strings in this case,
    • 0:39:28or using a for loop now to iterate over and print each of those names.
    • 0:39:33AUDIENCE: Yeah.
    • 0:39:34So is it not necessary to initiate student in this case?
    • 0:39:38Or we can just declare a variable in the loop?
    • 0:39:40DAVID MALAN: Good question.
    • 0:39:41You do not need to manually initialize it.
    • 0:39:43Python takes care of initializing the student variable to Hermione
    • 0:39:47first, then Harry second, then Ron third.
    • 0:39:49Unlike other languages, you don't need to initialize it to something yourself,
    • 0:39:53it just exists and it will work.
    • 0:39:55Other questions on loops and lists in this way?
    • 0:39:58AUDIENCE: Since you describe break, so is there
    • 0:40:00any concept of continuing so that we can skip a particular case in loops?
    • 0:40:04DAVID MALAN: Yes.
    • 0:40:04You can continue using another syntax as well.
    • 0:40:06We haven't shown that.
    • 0:40:07For now we focused only on break.
    • 0:40:10AUDIENCE: OK.
    • 0:40:11So can this for loop work with either hash tables or different kind
    • 0:40:15of tables or arrays?
    • 0:40:17DAVID MALAN: Indeed.
    • 0:40:18So we're getting ahead of ourselves there,
    • 0:40:20but there are yet other types of data in Python,
    • 0:40:22and indeed, you can use a for loop to iterate over those as well.
    • 0:40:26Anything that is iterable, so to speak, is
    • 0:40:28a piece of data that can be used with a loop like this.
    • 0:40:32But more on those-- more on those soon.
    • 0:40:34In fact, let me transition here to show just another way of solving
    • 0:40:37this same problem, because up until now when we've used loops,
    • 0:40:40we really have relied on numbers, and that's fine
    • 0:40:43if you prefer to stay in that space.
    • 0:40:45Suppose I did want to iterate using numbers like i and 0,
    • 0:40:491, 2, and so forth.
    • 0:40:50Let me propose that we could change this code as follows.
    • 0:40:53If you would prefer to think about, or if the program you're
    • 0:40:56trying to implement requires that you use numbers like this,
    • 0:40:59you might do this.
    • 0:41:00For i in-- well, I don't want to just say students,
    • 0:41:04because then i is not going to be a number.
    • 0:41:07i is going to be literally Hermione, then Harry, then Ron.
    • 0:41:13I need to iterate from 0 to 1 to 2.
    • 0:41:17If I a list with three elements has these locations, 0, 1, 2,
    • 0:41:21I need to create a loop somehow that starts at 0 and ends at 2.
    • 0:41:25Previously when I wanted to do that, I needed range,
    • 0:41:28but this 2 is not going to work.
    • 0:41:30I can't just say in the range of students,
    • 0:41:32because students is not a number, it's not an integer,
    • 0:41:36so you can't pass it to range.
    • 0:41:37Range expects an integer.
    • 0:41:39But there is a solution here.
    • 0:41:41It turns out that there is a function in Python called length or len, L-E-N,
    • 0:41:47that will tell you the length of a list and other things down the line, too.
    • 0:41:51And now I think I can assemble these building blocks and a way that can
    • 0:41:55allow me to use numbers in this way.
    • 0:41:57So range doesn't take a list of strings, it takes a number,
    • 0:42:02and ideally, that number is going to be 3,
    • 0:42:04so I get a range of values, 0, 1, and 2.
    • 0:42:07So I think I can nest my functions like this.
    • 0:42:10If I first get the length of the students list, that's going to be 3,
    • 0:42:15then I pass that return value as the argument
    • 0:42:18to range, that's going to give me back a range of values, 0, then 1, then 2.
    • 0:42:23And what that's going to allow me to do then in code if I want
    • 0:42:26is not just this.
    • 0:42:28I could do print now students bracket i, and this is now
    • 0:42:33where the syntax we're seeing is getting very expressive-- new and perhaps
    • 0:42:38unfamiliar.
    • 0:42:39But if I can do open bracket, 0, close bracket, or open bracket, 1,
    • 0:42:44close bracket, or open bracket, 2, close bracket, turns out,
    • 0:42:47I can actually put a variable in there and I
    • 0:42:49can express any number inside of those brackets
    • 0:42:52so as to print these all out dynamically in a loop.
    • 0:42:54Let me do this, Python of hogwarts.py, Enter,
    • 0:42:57there's Hermione, Harry, and Ron.
    • 0:43:00And now if I'm just curious, I just want to poke
    • 0:43:02around or maybe I want to do a ranking, like who
    • 0:43:05are the top three students in the school or in Gryffindor?
    • 0:43:08Well, I can print multiple things at a time, we've seen.
    • 0:43:11Let me print out not just the students at location
    • 0:43:14i, but rather, let's print i first and then the student at location i.
    • 0:43:19So two things to print, and we know that print can take two arguments,
    • 0:43:22we've seen that before, they'll be separated by a space.
    • 0:43:25Let me go ahead and rerun this.
    • 0:43:26Now I see that, OK, Hermione is the top student, but she's in zeroth place.
    • 0:43:31That's a little weird.
    • 0:43:32Like we don't need to show the human using my program
    • 0:43:35that we started counting at 0.
    • 0:43:37I can clean this up.
    • 0:43:38I can just add 1 to the i up here, and now we
    • 0:43:41see a top three list of students.
    • 0:43:43Hermione is number 1, Harry's number 2, and of course, Ron is number 3.
    • 0:43:47So we can get access to all of those same values as well.
    • 0:43:50Are there any questions now on these lists?
    • 0:43:55Any questions now on these lists?
    • 0:43:58This length, these ranges, or otherwise?
    • 0:44:01AUDIENCE: My question is, for i in range, can you explain this once more?
    • 0:44:08DAVID MALAN: Sure.
    • 0:44:10So let me rewind in time.
    • 0:44:12We started off doing this.
    • 0:44:13For i in 0, 1, 2, and then we print it out meow three times in that way.
    • 0:44:20The way that for loop works is that it creates
    • 0:44:23for you a variable that I've called i, but I could call it anything I want.
    • 0:44:27It then assigns i initially to the first thing in the list.
    • 0:44:31It then automatically assigns i to the next thing in the list.
    • 0:44:34And then it assigns i to the third thing in the list.
    • 0:44:37And each time it does all of the indented code underneath.
    • 0:44:41We realize, though, that this is not going
    • 0:44:43to scale well if I want to do something like a million times.
    • 0:44:46So we introduced range instead.
    • 0:44:48That has the effect of doing the same thing.
    • 0:44:51It returns to me a range of values-- a list of three things, really,
    • 0:44:55so the behavior is exactly the same.
    • 0:44:57If we now fast forward to this Hogwarts example now, though, what I'm doing
    • 0:45:01is just combining these smaller ideas.
    • 0:45:04I'm still creating a for loop.
    • 0:45:06I'm still creating a variable called i.
    • 0:45:08I want to do it over a range of values, but how many values?
    • 0:45:11Well, if I use the length function and pass to the length function
    • 0:45:15the list of values, length's purpose in life
    • 0:45:18is to tell me how long is this list, and it's 3.
    • 0:45:21So that's almost as though before, I had just done something like this,
    • 0:45:25but I don't want to hardcode 3, I want to dynamically figure out
    • 0:45:29how many students are at Hogwarts.
    • 0:45:30So I'm just composing, composing, composing,
    • 0:45:32or nesting all of these various ideas.
    • 0:45:36All right, if I may, let me transition now to--
    • 0:45:38in Hogwarts still to introduce one final type of data before
    • 0:45:42we combine everything with a few final programs.
    • 0:45:45It turns out in Python, there's not just strings, not just
    • 0:45:49ints, not just floating point values, not
    • 0:45:51just bools, not just lists there are also
    • 0:45:53what are called dictionaries or dics, are a data structure that allows you
    • 0:45:58to associate one value with another.
    • 0:46:02Literally a dictionary like in the human world.
    • 0:46:04If you were to open a dictionary, be it in English or any other human language,
    • 0:46:07what's inside of a dictionary?
    • 0:46:09Well, it's a bunch of words and definitions.
    • 0:46:12A computer scientist, though, and a programmer
    • 0:46:14would describe those more generically as keys and values, something
    • 0:46:19associated with something else.
    • 0:46:21That's all a dictionary is.
    • 0:46:22It allows you to associate something with something else.
    • 0:46:25And notice, this is already more powerful, more interesting than a list.
    • 0:46:29A list is just a set of multiple values.
    • 0:46:32But a dictionary is two-dimensional, if you will.
    • 0:46:36Just like a human dictionary, a book, it associates something
    • 0:46:39with something else like words with their definitions.
    • 0:46:42Now what does this actually mean in practice?
    • 0:46:44Well suppose that we wanted to keep track
    • 0:46:48of who is in what house at Hogwarts.
    • 0:46:51Well, I could do it using lists alone.
    • 0:46:54Let me go back to VS Code here and let me
    • 0:46:55just temporarily-- but in a way that I'm not going to like ultimately--
    • 0:46:59let me create another variable called houses,
    • 0:47:01set it equal to Gryffindor, corresponding to Hermione's house,
    • 0:47:06Gryffindor, corresponding to Harry's house, and Gryffindor,
    • 0:47:09corresponding to Ron's house.
    • 0:47:11And let's add Draco in there.
    • 0:47:12So we now have four instead of three students
    • 0:47:14just so we have a little variety, and he was in Slytherin.
    • 0:47:18So now we have two lists.
    • 0:47:21And we could just agree amongst ourselves
    • 0:47:24that whoever is first in the students variable lives
    • 0:47:28in the first value in houses.
    • 0:47:31Whoever is second in students lives in the second house.
    • 0:47:34Who's ever third in students lives in the third house.
    • 0:47:37We could do that.
    • 0:47:38But honestly, that is going to break down quickly
    • 0:47:41when we have a lot of students, when we have a lot of houses,
    • 0:47:44and what if we want to keep track of more things than that?
    • 0:47:46What if we want to keep track of every student's house
    • 0:47:48and the patronus, this image that they conjure up magically?
    • 0:47:52Well, then we need a third list like-- this is just
    • 0:47:55going to get messy quickly if we're just on the honor system
    • 0:47:58using multiple lists where everything lines up logically.
    • 0:48:02It doesn't end up well when your code gets more complicated.
    • 0:48:05But I do want to implement this idea.
    • 0:48:07I want to associate something with something.
    • 0:48:09A student with a house, a student with a house, a student with a house
    • 0:48:12and so forth, so how can I go about doing this?
    • 0:48:15Well, let me go back to my code here and let
    • 0:48:18me propose that we do this using a Python dictionary.
    • 0:48:22And this is the last of the new syntax, really, that we'll see .
    • 0:48:25Here's the new syntax.
    • 0:48:26Instead of using square brackets, we're going
    • 0:48:29to use curly braces for dictionaries as well.
    • 0:48:32We've seen curly braces in the context of f strings completely unrelated.
    • 0:48:37Sometimes you run out of keys on the keyboard and the authors of a language
    • 0:48:40need to start reusing symbols in different ways, that's
    • 0:48:43what's about to happen.
    • 0:48:44We're using curly braces in a different way.
    • 0:48:46Now so let me create a variable called students.
    • 0:48:48And let me go ahead and set it equal to open
    • 0:48:51curly brace and closed curly brace.
    • 0:48:54This is an empty dictionary at the moment.
    • 0:48:56And here's how a dictionary works.
    • 0:48:58It allows you to associate something with something else,
    • 0:49:01and you do that like this.
    • 0:49:02Hermione, quote-unquote, colon, and then the value thereof.
    • 0:49:07What do you want to associate with Hermione?
    • 0:49:09Well, Gryffindor.
    • 0:49:11What do I want to associate Harry with?
    • 0:49:13Well, I want to associate him with Gryffindor.
    • 0:49:16What do I want to associate Ron with?
    • 0:49:18Well, I want to associate him with Gryffindor.
    • 0:49:21Well, this is actually not going to-- this is going to get very ugly quickly.
    • 0:49:24Once we add in Draco and Slytherin, my code is going to get too long,
    • 0:49:27it's going to start wrapping.
    • 0:49:28So this is purely aesthetic.
    • 0:49:30It is perfectly acceptable in Python and other languages
    • 0:49:33to format your code a little more readily and just add new lines
    • 0:49:36if it makes it more readable.
    • 0:49:38And one way of doing this might be as follows.
    • 0:49:40I still have my curly brace up here, I still have my curly brace down here,
    • 0:49:44but notice, it's a little more readable now
    • 0:49:47in that I have my keys on the left, my somethings, and my values
    • 0:49:51on the right, my other somethings.
    • 0:49:53It's just a little easier to skim top to bottom.
    • 0:49:55You could format it differently as well.
    • 0:49:57But I'm going to go ahead and add in now Draco
    • 0:50:00who lives, of course, in Slytherin.
    • 0:50:03So now I have each of these keys on the left
    • 0:50:07and values on the right, which is really, again,
    • 0:50:09just a code implementation of this idea, a little chart
    • 0:50:13that you might write up with paper pencil
    • 0:50:15when associating something with something else.
    • 0:50:17So how do I now use this code in an interesting way?
    • 0:50:20The syntax is almost the same.
    • 0:50:22If I want to print out the very first student, Hermione's house,
    • 0:50:26I could do this.
    • 0:50:27Print out the name of the variable, but I need to go inside of the variable.
    • 0:50:31I need to index into it.
    • 0:50:33And what's neat about dictionaries is that whereas lists
    • 0:50:38have locations that are numeric--
    • 0:50:410, 1, 2; Hermione, Harry, Ron respectively,
    • 0:50:45dictionaries allow you to use actual words as your indices, so to speak,
    • 0:50:50your indexes to get inside of them.
    • 0:50:52So if you want to print out Hermione's house,
    • 0:50:55the key you care about is, quote-unquote, Hermione,
    • 0:50:59and what this syntax here will do-- notice, it's not a number 0 or 1 or 2.
    • 0:51:04It's literally Hermione's name.
    • 0:51:05This is like going to the chart earlier and saying, all right, give me Hermione
    • 0:51:11is my key, Gryffindor is the value.
    • 0:51:13That's what we're doing here syntactically.
    • 0:51:15We're looking up Hermione and getting the value thereof.
    • 0:51:18So if I go back to my code, that should print out Gryffindor.
    • 0:51:21And if I do this a few times, students, bracket, quote-unquote,
    • 0:51:24Harry should give me Harry's house.
    • 0:51:26Print students, open bracket, Ron, that should give me Ron's house.
    • 0:51:30And then lastly, if I do this with students, bracket, Draco,
    • 0:51:33that should give me Draco's house.
    • 0:51:35Now it's a little manual still, and I bet we can improve this,
    • 0:51:38but let me run Python on hogwarts.py and we
    • 0:51:40should see Gryffindor, Gryffindor, Gryffindor, Slytherin, which
    • 0:51:44is exactly what we'd expect.
    • 0:51:46Now all we've done, again, is we've just now moved
    • 0:51:48from having just a simple list of names to, again, two dimensions,
    • 0:51:52associating like we would on paper-pencil something with something
    • 0:51:56else, keys with values respectively.
    • 0:51:58Allow me, if you will, even though I realize this is getting a little fancy,
    • 0:52:02allow me to escalate things slightly here and transition from looking
    • 0:52:07at just, for instance, that pattern there, just a hard coding those values
    • 0:52:13there to actually printing these out more dynamically.
    • 0:52:15Let me go ahead and use our loop, and this question came up earlier as well,
    • 0:52:19let me go ahead and say for each student in students,
    • 0:52:25go ahead and print out, for instance, the students variable at--
    • 0:52:31well, let's just say student first.
    • 0:52:32Let's keep it simple.
    • 0:52:33So this is not going to be that interesting yet,
    • 0:52:35but when I run Python of hogwarts.py and hit Enter, notice, what should I see?
    • 0:52:41Let me take a question here to see what am I
    • 0:52:44going to see when I hit Enter now when I'm doing for student in students?
    • 0:52:48AUDIENCE: Yeah, I think we will only see keys.
    • 0:52:51DAVID MALAN: Perfect.
    • 0:52:52So good intuition.
    • 0:52:53It could have gone both ways.
    • 0:52:53Could have been values, the houses.
    • 0:52:55But when you use a for loop in Python to iterate over a dictionary, by design,
    • 0:53:01it iterates over all of the keys.
    • 0:53:03So we should see, I think, Hermione, Harry, Ron, and Draco.
    • 0:53:07Let me hit Enter now, Enter, and indeed, you're exactly right,
    • 0:53:11we see just the keys.
    • 0:53:12But that's not really that useful if what I really care about
    • 0:53:15is who lives where, can I print out both?
    • 0:53:18Well, I think I can.
    • 0:53:19Let me go ahead and do this.
    • 0:53:21Let me print out not just the student's name, the key,
    • 0:53:24but let me use the key, their name, to index into the dictionary.
    • 0:53:30If I know the word in the dictionary, let me look up its definition.
    • 0:53:33If I know the student's name, let me look up their house,
    • 0:53:35and the syntax for this, just like a list, is students, bracket.
    • 0:53:40And just like in the past we used i when i was a number,
    • 0:53:44we can also with a dictionary use a string.
    • 0:53:48So if the student's name is the key, then this syntax, students,
    • 0:53:55open bracket, student, close bracket will go to Hermione's location
    • 0:54:00and get back her house.
    • 0:54:01Will go to Harry's location and get back his house and so forth.
    • 0:54:04So if I do Python of hogwarts.py, Enter, now I
    • 0:54:08see Hermione, Gryffindor; Harry, Gryffindor; Ron, Gryffindor;
    • 0:54:11and Draco Slytherin.
    • 0:54:12Now it looks like I've given them all new last names,
    • 0:54:14but I can clean that up.
    • 0:54:15This is just a print thing.
    • 0:54:17Let's go ahead and change our separator from the default space
    • 0:54:20to maybe a space, comma.
    • 0:54:21And just using print features now, let me run the same program again, Enter,
    • 0:54:26now I've just got some nice pretty commas in there to make clear
    • 0:54:29that Hermione's last name is not, in fact, Gryffindor,
    • 0:54:31but that's just a print detail.
    • 0:54:33Any questions, then, on these dictionaries and what I've just done?
    • 0:54:39Questions on these dictionaries and this looping over then here?
    • 0:54:45AUDIENCE: I just can't get my head around the for student in students.
    • 0:54:52If I'm-- just correct me if I'm right.
    • 0:54:54Does that mean it imports the list of students and uses the indexes--
    • 0:55:01or in other words, Hermione, Harry, and Ron as the indexes in the actual--
    • 0:55:09the list of students?
    • 0:55:10DAVID MALAN: Correct.
    • 0:55:11So this is just a feature of Python.
    • 0:55:13When you use a for loop with a dictionary, what happens is this.
    • 0:55:17If this is the dictionary here with the keys on top and the values on bottom,
    • 0:55:20you get to choose what the variable is called.
    • 0:55:22I called my variable student just because it makes sense,
    • 0:55:24because I want one student at a time.
    • 0:55:26And what for loop does, just like it did with numbers before,
    • 0:55:29the 0, the 1, and the 2, it allows me to, for instance,
    • 0:55:33set student equal initially to Hermelin's name.
    • 0:55:35And then the next iteration of the loop, the next cycle,
    • 0:55:38sets student equal to Harry's name, then Ron, then Draco.
    • 0:55:42It just happens automatically.
    • 0:55:44Like that is what the Python interpreter does for you when
    • 0:55:47it sees a for loop like that.
    • 0:55:49So it's very similar in spirit to iterating with a for loop over a list,
    • 0:55:53but rather than iterate over the numeric location,
    • 0:55:550, 1, 2, it iterates over the bold-faced keys in this representation here
    • 0:56:01graphically.
    • 0:56:02And allow me to give us one other example on Hogwarts
    • 0:56:05before we look at one other familiar domain.
    • 0:56:09At the risk of things escalating a little bit,
    • 0:56:11let me propose that we continue the story with one final Hogwarts
    • 0:56:15example like this.
    • 0:56:17What if we have more information about each of our students?
    • 0:56:21And this is inevitable.
    • 0:56:23If you're implementing a program that's a database with people or customers,
    • 0:56:26or employees or anything else, you can imagine
    • 0:56:29having a lot of data about anything you're representing in your program
    • 0:56:33here.
    • 0:56:33For the sake of discussion, suppose that every student at Hogwarts, of course,
    • 0:56:37has a name, they have already a house, but they also have a patronus.
    • 0:56:41For those unfamiliar, this is the animal or entity
    • 0:56:44that comes out of the end of their wand when they make a certain magical spell.
    • 0:56:48The point here being is that we want to associate not
    • 0:56:51just one thing with the student, but multiple things
    • 0:56:55as well-- their name, their house, and their patronus in this case.
    • 0:57:00Well, what might code like this look like?
    • 0:57:02Well, let me go back to hogwarts.py and let me start fresh for just a moment.
    • 0:57:07And let me propose that I enhance this with a bit more data.
    • 0:57:10And this data is going to look as follows.
    • 0:57:12My students variable now, I'm going to propose we think of it as a list.
    • 0:57:18What if we have a list of dictionaries as follows?
    • 0:57:21Indeed I want to literally implement this picture here.
    • 0:57:24So notice that my previous picture just represented a single dictionary.
    • 0:57:29But suppose I wanted to compose a list of dictionaries.
    • 0:57:33That is, for students-- so a list of four students.
    • 0:57:36And suppose that each of those students is itself a dictionary,
    • 0:57:41a collection of key value pairs, keys and values,
    • 0:57:46something and something else.
    • 0:57:48Well, here's one other way we can do this in code.
    • 0:57:50Let me go back to VS Code here and let me define a variable called
    • 0:57:55students that is equal to a list.
    • 0:57:58And I'm going to preemptively move my cursor onto separate lines,
    • 0:58:01because I know this is going to be long, and I
    • 0:58:03want to fit all of the elements of this list inside of it.
    • 0:58:07I'm now going to create a dictionary, one dictionary per student.
    • 0:58:10And how do I create a dictionary?
    • 0:58:11I just use those curly braces.
    • 0:58:13But it's up to me to define what those keys are.
    • 0:58:16And let me propose that one key this time
    • 0:58:18won't be the student's name explicitly, it
    • 0:58:20will literally be the word name, and there, going to have the name Hermione.
    • 0:58:24The same student is going to have another key called house
    • 0:58:28and the value is going to be Gryffindor.
    • 0:58:31And the same student is going to have a third key called patronus,
    • 0:58:34and the value of that is going to be--
    • 0:58:36I had to look it up-- an otter, according to the book.
    • 0:58:39Now I'm going to create a second dictionary inside of this list.
    • 0:58:43And again, a dictionary is like literally
    • 0:58:44like the human dictionary of words.
    • 0:58:46It's a book that contains keys and values, words and definitions.
    • 0:58:50What are the three words I'm storing in each of my dictionaries?
    • 0:58:53Name, house, and patronus.
    • 0:58:55What are the definitions of those words for Hermione?
    • 0:58:58Hermione, Gryffindor, and otter respectively.
    • 0:59:01For Harry, the definitions are going to be different in this new dictionary.
    • 0:59:05Let me give myself another pair of curly braces
    • 0:59:08and say this, name, quote-unquote, colon, Harry.
    • 0:59:12House here is, again, going to be Gryffindor.
    • 0:59:15And this one I knew, his patronus, is going to be, in this case, a stag.
    • 0:59:21Next, a third dictionary.
    • 0:59:23The name here will be Ron.
    • 0:59:25And I'm going to go ahead and do that just like this.
    • 0:59:27Next, I have the house, and he, too, was Gryffindor.
    • 0:59:31Lastly, had to look this one up, Ron's patronus was a Jack Russell terrier.
    • 0:59:38Lastly is Draco.
    • 0:59:42In a fourth dictionary now-- so another pair of curly braces,
    • 0:59:45the name of the student is, of course, Draco.
    • 0:59:47The house of this student is Slytherin.
    • 0:59:50And Draco, interestingly enough, at least according to the internet,
    • 0:59:55has no patronus.
    • 0:59:57Was never revealed in the books or the movies.
    • 0:59:59So it turns out, this is actually a wonderful teachable moment.
    • 1:00:02There is a special key word in Python that is literally None, and N-O-N-E,
    • 1:00:08with the first letter capitalized.
    • 1:00:10This represents officially the absence of a value.
    • 1:00:14So I could a little sloppily do something like quote-unquote,
    • 1:00:17but does that mean I didn't get around to typing it or not?
    • 1:00:20It's a little clear semantically to say literally None, a special keyword
    • 1:00:24in Python to make clear that I know Draco has no patronus,
    • 1:00:29it's not just an oversight on my part.
    • 1:00:32Now that I have this, what do I have in the computer's memory?
    • 1:00:36I have a list.
    • 1:00:37How do I know it's a list?
    • 1:00:38Because I see a square bracket at the beginning and another square bracket
    • 1:00:42at the end.
    • 1:00:42That's just my visual clue, OK, I don't know necessarily
    • 1:00:45what else is going on here, but there's a list of something.
    • 1:00:48What is in that list?
    • 1:00:50Well, here, too, the syntax is our clue.
    • 1:00:53Because this line 2 starts with a curly brace and ends with a curly brace,
    • 1:00:57I just know, that is a dictionary, a collection of key value pairs.
    • 1:01:02Now this all fit on my screen perfectly, so I
    • 1:01:04didn't bother moving all of the key value pairs onto new lines,
    • 1:01:08it would have made it really tall, so I kept it all together here this time.
    • 1:01:11But how many keys does this first dictionary have?
    • 1:01:15Put another way, in Hermione's physical dictionary,
    • 1:01:17how many words are in that dictionary?
    • 1:01:19Three.
    • 1:01:20The words are name, house, and patronus.
    • 1:01:22What are the three definitions or values of those words
    • 1:01:26in Hermione's dictionary?
    • 1:01:27Hermione, Gryffindor, and otter respectively.
    • 1:01:31And the same story goes for Harry, then for Ron,
    • 1:01:35then for Draco, I have, by design, chosen
    • 1:01:39to give them dictionaries that have all the same keys, all the same names,
    • 1:01:44but they all have unique values.
    • 1:01:47And that's my design, that's my prerogative as a programmer.
    • 1:01:50So why is this useful at the end of the day now?
    • 1:01:53I have access to a whole collection of interesting data about all
    • 1:01:57of these students, and I can still do a loop.
    • 1:01:59I can say for students in students, that's
    • 1:02:02going to allow me to iterate over this list of students.
    • 1:02:05And let me go ahead and print out just one thing at a time.
    • 1:02:08Let me print out the current student's name.
    • 1:02:10So as complicated as the dictionary is, this should be pretty comfortable.
    • 1:02:14For student in students is just going to iterate over every student in the list.
    • 1:02:181, 2, 3, 4 total.
    • 1:02:20The next line is just going to print out the value of the name key.
    • 1:02:24It's like opening a physical dictionary, looking up the word name,
    • 1:02:27and giving us Hermione, Harry, Ron, and Draco
    • 1:02:30respectively from each dictionary.
    • 1:02:32So if I run this version of Hogwarts and hit Enter, there, I get all three
    • 1:02:36of their names.
    • 1:02:37But what if I want more information than that?
    • 1:02:39I want both their names and their houses.
    • 1:02:42Well, just add to print's arguments student, open bracket, house,
    • 1:02:47close bracket.
    • 1:02:48All right, let's go ahead and run this.
    • 1:02:50Python of hogwarts.py and hit Enter.
    • 1:02:53So I now see Hermione, Gryffindor; Harry, Gryffindor; and so forth.
    • 1:02:56Well, we can aesthetically clean this up a little
    • 1:02:58bit by adding a separator with print, like a comma and a space,
    • 1:03:01just so that when I run this again, I now
    • 1:03:03see some comma separating these values.
    • 1:03:05But recall that students have not just a name, not just
    • 1:03:08a house, but also that patronus.
    • 1:03:09So if we want to print out that, too, we now
    • 1:03:12have the syntax via which to go into that same dictionary for each student
    • 1:03:18and output their patronus as well as their house in their name.
    • 1:03:22So if I run this program one final time, now I
    • 1:03:24see all of the data in this here dictionary.
    • 1:03:28So this is a lot to absorb all at once, I'm sure.
    • 1:03:31It's the last of our new data types.
    • 1:03:33On top of lists, we have these dictionaries,
    • 1:03:35but again, a dictionary, at the end of the day,
    • 1:03:37is just a collection of values similar to these values
    • 1:03:41here that allow you to associate keys with values.
    • 1:03:44And the first version of this program associated literally the student's
    • 1:03:48names with their houses, but then I realized
    • 1:03:51in my next version, wait a minute, what if every student has not
    • 1:03:53just a name in a house, but a patronus?
    • 1:03:55Let's actually standardize the names of our keys
    • 1:03:59to be name, house, and patronus, and then the values of those keys
    • 1:04:03can actually be the data, like Hermione, Gryffindor, otter, and so forth.
    • 1:04:08Questions now on these dictionaries and iteration thereof?
    • 1:04:13AUDIENCE: I just was wondering, suppose the dictionary is very huge,
    • 1:04:18and if I want to look up for a specific student,
    • 1:04:22so how do I know where to look that student from?
    • 1:04:26Like can we sort it out in alphabetical order
    • 1:04:29or numeric order or anything like that?
    • 1:04:32DAVID MALAN: In short answer, yes.
    • 1:04:33One of the features of Python is that it makes these dictionaries very highly
    • 1:04:37performant for you.
    • 1:04:38That is, even if they're very large, as they will be in future weeks
    • 1:04:42when we manipulate more data, Python will find the data
    • 1:04:45you care about quickly for you.
    • 1:04:48And in fact, that is a feature of the language,
    • 1:04:50that is a feature of a dictionary to get you the data quickly.
    • 1:04:53And there are functions that you can use.
    • 1:04:55You can sort the data, you can sift through it,
    • 1:04:57you can do very performant operations as we eventually will.
    • 1:05:01Allow me, then, to propose, as we wrap up these loops,
    • 1:05:05that we solve just a few final problems that will perhaps
    • 1:05:08evoke fond memories of yesteryear, at least
    • 1:05:11for me, wherein one of my favorite games growing up
    • 1:05:13was this one here on the original Nintendo.
    • 1:05:15And this is a two-dimensional world where the characters move up,
    • 1:05:19down, and right, not so much to the left, in jumping over
    • 1:05:23pyramids and obstructions like these.
    • 1:05:25And allow me to propose that we use this just for inspiration,
    • 1:05:27not to do something that's quite as colorful or graphical as this, but just
    • 1:05:31to focus on, for instance, this barrier in the middle of the world
    • 1:05:34here that Mario or Luigi had to jump over.
    • 1:05:38And so this here seems to be like three bricks stepped on top of one another.
    • 1:05:42And we won't do things quite graphically,
    • 1:05:44but let's just implement a very simple Python-based version of this textually
    • 1:05:48using maybe just hashes for bricks.
    • 1:05:50Because there's a pattern here, one on top of the other, and I
    • 1:05:53bet we can solve this in any number of ways.
    • 1:05:56Well, let me switch back over to VS Code here
    • 1:05:58and let me propose that we create a program called mario.py using code
    • 1:06:03in the terminal window.
    • 1:06:04And then up here, let me start by implementing that same picture
    • 1:06:07as simply as I can, printing out just literally the hash,
    • 1:06:11and then the hash, and then a third final hash.
    • 1:06:14This is going to be a very textual approximation of it,
    • 1:06:17but I think if I run Python mario.py, I've
    • 1:06:20got a very simple version of that same column of bricks, so to speak.
    • 1:06:25But you can imagine that certainly in a game
    • 1:06:28where maybe these columns get higher or lower,
    • 1:06:31it would be nice to write code that's actually a little more
    • 1:06:33dynamic than that and doesn't just use print, print, print, which is literally
    • 1:06:37copy and paste, it would seem.
    • 1:06:39So let me at least adopt some of today's lessons
    • 1:06:42learned and instead do something like this.
    • 1:06:44For underscore in range of 3, let's now print out just one of these at a time.
    • 1:06:50But the fact that I've now used a 3 to range
    • 1:06:53means if I want to change it to something bigger or smaller,
    • 1:06:55I change it in one place not in three or more places.
    • 1:06:59And this code, too, of course, if I got it right,
    • 1:07:01is just going to print out the exact same thing.
    • 1:07:05So we're iterating here.
    • 1:07:06But let's see if we can't now integrate our discussion
    • 1:07:08of writing functions of our own to begin writing something a little more dynamic
    • 1:07:13and solving more complicated problems ultimately.
    • 1:07:16One of the nice things about functions is
    • 1:07:18that they allow us to not just write code that we can use and reuse,
    • 1:07:21they allow us to create abstractions, if you will.
    • 1:07:24An abstraction is a simplification of a potentially more complicated idea.
    • 1:07:28And we've seen this a few times over the course of the weeks.
    • 1:07:31For instance, we had a function called hello, which, granted, didn't do
    • 1:07:35all that much, it just printed hello.
    • 1:07:37But it allowed me to think about the function as exactly what it does,
    • 1:07:40not generically printing something, but literally saying hello.
    • 1:07:44I've been able to get a number using something similar by defining
    • 1:07:48my own function like get number.
    • 1:07:50Well let me go ahead and, for instance, assume for the moment
    • 1:07:53that I've had the forethought to, in my function main,
    • 1:07:57use a function called print column.
    • 1:07:59That seems as good a name as any to use a function that
    • 1:08:03prints a column of bricks.
    • 1:08:05Well, how can I go about now implementing
    • 1:08:07this abstraction, this simple idea of print column with actual code?
    • 1:08:12Well, we've seen before with def, we can do just that.
    • 1:08:14Let me define a function called print column.
    • 1:08:16Let me accept as its input, generically speaking, a parameter called height.
    • 1:08:21I could call it n or h, but it would be a little more explicit now with height
    • 1:08:25just so I remind myself what it's doing.
    • 1:08:27And now I think I can just borrow some of that same code from before.
    • 1:08:30For underscore n range of height, go ahead and print out a single hash.
    • 1:08:37And then at the end of this whole program, let's just call main.
    • 1:08:41So I've kind of complicated the code.
    • 1:08:43It doesn't do anything more just yet, but it's
    • 1:08:45setting me up for solving what I think are going
    • 1:08:48to be more sophisticated problems.
    • 1:08:50If I run Python of mario.py, we're back where we began.
    • 1:08:53But I now have a function, an abstraction, print column,
    • 1:08:57that's going to allow me to think about printing
    • 1:09:00some chunk of the world of Mario at a time.
    • 1:09:03And I can do this in different ways, too.
    • 1:09:05Notice that if I really want, I could do something like this.
    • 1:09:09I could implement now print column in different ways,
    • 1:09:12especially if I am using print column all over my code,
    • 1:09:15or maybe still, a colleague of mine, a friend, someone else on the internet
    • 1:09:19is using my print column function.
    • 1:09:21What's also nice about functions you've written
    • 1:09:23is you can change the underlying implementation details of them,
    • 1:09:27but so long as you don't change the name of the function or its parameters
    • 1:09:31or what it returns, if anything no one else knows the difference.
    • 1:09:35You can change the internal implementation
    • 1:09:37as much as you want if you want to improve it or make fixes over time.
    • 1:09:41So for instance, another way we could implement print column,
    • 1:09:44recall, would be something like this.
    • 1:09:46A bit clever with one hash and then a new line,
    • 1:09:48and then maybe we could do multiplication of strings,
    • 1:09:51and then end this line with quote-unquote.
    • 1:09:54Again, it's OK if you're not comfortable with this syntax.
    • 1:09:57This was a more clever approach we saw in the past.
    • 1:09:59But if I run Python of mario.py here, I'll still see a column of three.
    • 1:10:04But what's important here is that main does not
    • 1:10:07need to know that the underlying implementation of print column
    • 1:10:12has changed.
    • 1:10:13Well, let's transition to a different dimension,
    • 1:10:15if you will, and rather than print out just these vertical bricks, let's
    • 1:10:19fast forward in the game to this part of the world here.
    • 1:10:22At some part, Mario encounters these bricks in the sky,
    • 1:10:25that if he jumps up underneath, they become coins.
    • 1:10:27And so he gains to his score.
    • 1:10:29But let's go ahead and focus only on those coins,
    • 1:10:32and let me propose that we print out, oh, just
    • 1:10:34these four question marks here.
    • 1:10:36And let me go back to VS Code here.
    • 1:10:38And let me propose that within VS Code here, just like before, we
    • 1:10:41try to abstract this away.
    • 1:10:43So let me go ahead and get rid of this version,
    • 1:10:45because we're now going horizontal instead of vertical with our output.
    • 1:10:49And let me just say, well, print row four times.
    • 1:10:53Let me just abstract away the problem at hand.
    • 1:10:56I don't know yet how I'm going to print those four question marks,
    • 1:10:59but let's call it print row 4, and I'll assume I'll now solve this problem.
    • 1:11:03Let's now go down that rabbit hole of solving the problem.
    • 1:11:06Define a function called print row.
    • 1:11:09It's going to take a width instead of a height,
    • 1:11:11because it's horizontal instead of vertical.
    • 1:11:14And how can I do this?
    • 1:11:15Well now, we have an opportunity to do string multiplication even more
    • 1:11:19elegantly.
    • 1:11:19I can say quote-unquote, question mark, times width.
    • 1:11:23And this is a very pretty Pythonic way of printing what could otherwise
    • 1:11:28be a loop, and that's fine, but this is going
    • 1:11:29to go ahead and print those question marks for me.
    • 1:11:32Let's do Python of mario.py, Enter, and now I've got four question marks.
    • 1:11:37It's not nearly as pretty as the more graphical version,
    • 1:11:39but it is at least a building block toward having
    • 1:11:44now a reusable function like print row.
    • 1:11:47And why am I doing all this?
    • 1:11:49Like why are we over engineering the solution to these problems
    • 1:11:52by having print column and print row?
    • 1:11:54Well, it's a useful problem-solving technique.
    • 1:11:57As soon as your world does not look one-dimensional
    • 1:12:00like this or with the column version, but what about this?
    • 1:12:04Later in Super Mario Brothers does Mario have to jump down into this world
    • 1:12:08where there's a lot of these underworld barriers.
    • 1:12:11And this one here, for instance, looks like a square.
    • 1:12:13It's two-dimensional there's a height and a width to it.
    • 1:12:16And that is to say there's a bunch of different ways
    • 1:12:18we could implement this thing if, maybe for discussion,
    • 1:12:21it's like a 3-by-3 grid, a 3-by-3 square of sorts.
    • 1:12:26Well, how can we go about solving this here problem?
    • 1:12:29Well, let me propose we come back to VS Code
    • 1:12:32and let me propose that we think about this in a couple of different ways.
    • 1:12:36I could do this like this.
    • 1:12:39If I know where I'm going, maybe I'm a seasoned programmer, let me go ahead
    • 1:12:44and do this.
    • 1:12:45Let me print out a square, the width, and the height of which is 3.
    • 1:12:48That's an abstraction.
    • 1:12:49I'm just taking for granted for a moment that there is already
    • 1:12:52a function called print square that's going to be with 3 and height 3
    • 1:12:56as well.
    • 1:12:57But someone's got to implement this, and at the moment,
    • 1:12:59there's only me at the keyboard, so let's go ahead
    • 1:13:01and implement that square.
    • 1:13:03Let me go ahead and define a function called
    • 1:13:05print square that takes in a specific size, both for height and for width.
    • 1:13:10And here's where we have an opportunity to use some of those loops.
    • 1:13:13And we can use those loops in a way we haven't yet.
    • 1:13:16If I want to print out all of these rows, but also, all of these columns,
    • 1:13:21I now have to think not just cyclically like a loop allows,
    • 1:13:24but I need to think two-dimensionally.
    • 1:13:26And if you're familiar with like an old school typewriter or even a printer
    • 1:13:30nowadays, it generally prints from top to bottom.
    • 1:13:33So even if you have multiple columns, you print out one line at a time,
    • 1:13:38and while you're on that line, the printer or the typewriter
    • 1:13:41prints from left to right.
    • 1:13:42And that's the mental model to have with your black and white terminal window.
    • 1:13:46All of the output for every example thus far starts at the top
    • 1:13:50and goes down to the bottom.
    • 1:13:52From top to bottom, left to right.
    • 1:13:54So we have to generate our output, our square in that same way.
    • 1:13:58So let me propose that we do this.
    • 1:14:01Let me propose that we know we need to iterate this many times, 3 or more
    • 1:14:04generally size.
    • 1:14:05So let me do this.
    • 1:14:06For i in the range of size, what do I need to do three times?
    • 1:14:12Well, I want to print out what?
    • 1:14:141, 2, 3 rows of bricks.
    • 1:14:17But within each row of bricks, what do I want to print?
    • 1:14:201, 2, 3 bricks specifically.
    • 1:14:24So if we go back to our diagram here and I
    • 1:14:26stipulate that it's indeed meant to be a 3-by-3 square, 3 wide and 3 tall,
    • 1:14:33what did I want to do to print the first row?
    • 1:14:35I want to print brick brick, brick.
    • 1:14:40What do I want to print on the second row? brick, brick, brick.
    • 1:14:42And the third row, brick, brick, brick.
    • 1:14:44So I'm doing three things three times.
    • 1:14:48There's a lot of printing that must happen.
    • 1:14:50So let me go back to my code here and let me propose now
    • 1:14:53that we think of this outer loop that I've just started
    • 1:14:57as representing each of our rows.
    • 1:15:00For i in range of size is going to ensure, no matter
    • 1:15:04what I do next, that I can print out 1, 2, 3 rows, or more generally,
    • 1:15:10size, where size could be 3, but it could be smaller or larger.
    • 1:15:15What do I want to do on each of the rows?
    • 1:15:17Well, just like an old school typewriter or printer, on each row,
    • 1:15:21I want to print out brick, brick, brick; brick, brick, brick; brick, brick,
    • 1:15:24brick.
    • 1:15:25Well, that sounds like a cycle, some kind of loop.
    • 1:15:28So maybe I can have inside of one loop another loop.
    • 1:15:31I don't want to use i again because I don't want to use the same variable
    • 1:15:35and mess up my counting.
    • 1:15:36So I'm going to by convention use j.
    • 1:15:38Very common to use i and then j-- maybe k,
    • 1:15:41but after that, you shouldn't keep nesting inside of each other.
    • 1:15:44Let me go ahead and say for j in range of size 2,
    • 1:15:47because it's a square, and then each of these rows,
    • 1:15:50let me print out a single hash, but no new line, but after each row,
    • 1:15:57let me print only a new line.
    • 1:16:00So there's a lot going on here, especially if you've never
    • 1:16:03touched Python, let alone loops, but notice what I've done here, too,
    • 1:16:08and I'll add some comments for clarity.
    • 1:16:10For each row in square, for each brick in row, print brick.
    • 1:16:22And here is where comments, and more generally,
    • 1:16:25pseudocode can really help explain to yourself and to others
    • 1:16:28what your lines of code are doing.
    • 1:16:30On line 8, I'm iterating from i equals 0 on up to size.
    • 1:16:35So 0, 1, 2.
    • 1:16:37On line 11, I'm doing the exact same thing, but using j from 0, 1, 2.
    • 1:16:41But that's good, because i represents how each of my rows.
    • 1:16:45And while I'm on each of those rows, inside of this outer loop,
    • 1:16:49I'm going to do brick, brick, brick; 1, 2, 3; 1, 2, 3; 1, 2, 3.
    • 1:16:53But I don't want my cursor to keep moving to the next line
    • 1:16:56while I'm on a row, so I'm just overriding that line ending.
    • 1:17:01But let me ask you a question of the group
    • 1:17:03now, why on line 16 do I have a print here all by itself?
    • 1:17:10Why do I have a print all by itself?
    • 1:17:13Notice that it's below the inner loop, but inside
    • 1:17:19of the outer loop, so to speak.
    • 1:17:22What is that loop on line 16 doing ultimately?
    • 1:17:26AUDIENCE: Every time you finish a line, you
    • 1:17:29have to add a new line at the end of it.
    • 1:17:33So print, it prints a new line.
    • 1:17:36DAVID MALAN: Perfect.
    • 1:17:37I don't want a new line after every brick.
    • 1:17:40I only want to do that at the end of the row,
    • 1:17:42and that's why my comments now are perhaps enlightening.
    • 1:17:45Notice that this loop here is just iterating for each brick in the row.
    • 1:17:51Once I'm done with that inner loop, so to speak,
    • 1:17:54once I'm done with these highlighted lines here, to Evelyn's point,
    • 1:17:57I need to print out one blank new line.
    • 1:17:59And we've not done this before, but when you call print with no arguments,
    • 1:18:03all you get is that automatic line ending,
    • 1:18:05the backslash n where the cursor moves to the next line.
    • 1:18:09So if I now go back to my terminal window and run mario.py,
    • 1:18:13I think I should get a 3-by-3 square.
    • 1:18:16And it doesn't quite look like a square on my screen
    • 1:18:18because these hashes are a little taller than they are wide, but it is, in fact,
    • 1:18:223-by-3.
    • 1:18:23But let me propose, as we've always done here, how
    • 1:18:26we might tighten up this code further.
    • 1:18:28Just for clarity's sake, let me get rid of my comments for a moment
    • 1:18:32just so we can see how many lines of code we have total.
    • 1:18:35And let me propose that we maybe do this.
    • 1:18:39Let me propose that, you know what, this inner loop,
    • 1:18:41especially if you're having trouble wrapping
    • 1:18:43your mind around one loop inside of another loop,
    • 1:18:46you don't strictly need it.
    • 1:18:47What if we do this trick again?
    • 1:18:49What if we print out inside of the outer and only loop each
    • 1:18:54of those hashes times the number of times we want them?
    • 1:18:57We draw inspiration from an earlier approach
    • 1:19:00and we run Python now of mario.py, same result,
    • 1:19:03but now, print square is really nice and compact.
    • 1:19:07It has one explicit loop, and it's still printing out
    • 1:19:10using string multiplication all of the hashes at once on that row.
    • 1:19:15If you like abstraction and you'd like to wrap your mind more around what
    • 1:19:19the code is doing, well, let's do this.
    • 1:19:21If you're not quite clear on what's going on,
    • 1:19:23let's propose that you implement a function called
    • 1:19:25print row, passing in size.
    • 1:19:28And let me propose that this print row function, it simply take in that width
    • 1:19:33and print out the individual hash times that many times.
    • 1:19:39In other words, here's an opportunity for abstraction, whereby, well, what
    • 1:19:43does it mean to print a row?
    • 1:19:45Well, when you're implementing print square,
    • 1:19:46I don't really care what it means to print a row,
    • 1:19:49I just need to know that someone's taking care of printing the row.
    • 1:19:53You can pass the buck to another function altogether.
    • 1:19:56And how does print row work?
    • 1:19:58Well, it could use a for loop, it could use this string multiplication trick.
    • 1:20:02This is a way to take a larger program-- and this is probably the most
    • 1:20:05complicated one we've looked at thus far--
    • 1:20:08and to decompose it into these smaller components, that once assembled,
    • 1:20:13achieve your final idea.
    • 1:20:16Seeing no questions, that's the end of our look at loops
    • 1:20:19in Python, this ability to do things cyclically again and again,
    • 1:20:22and when we combine those with conditionals, this ability
    • 1:20:25to ask and answer questions and combine them with our functions and variables,
    • 1:20:28we really now have most of the building blocks
    • 1:20:31we need to solve much larger, much more interesting, much
    • 1:20:34more personal questions.
    • 1:20:35So in the weeks to come, we'll start to see exactly what could go wrong,
    • 1:20:39though, when we do so, but we'll introduce you
    • 1:20:41to all the more tools via which you can troubleshoot those same problems.
  • 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