Hello and welcome to Chapter 5, loops and iteration.
As always, this lecture is copyright Creative Commons Attribution, including
the audio and video and, and the slides, and the book even.
So, now we're getting to our fourth basic pattern.
We've talked about sequential, where steps happen one after another.
We've talked about conditional, where steps may or may not happen.
In Chapter Four we talked about the store and retrieve pattern.
And now we're going to talk about the looping pattern.
And the looping pattern is the last of our really foundational ones, and
it potentially is the most important one, because it's the thing that allows us
to get computers to do lots of things that, say,
humans might get tired of, but computers don't tire of.
And so after this we'll start sort of becoming a little more
skilled in the basic language capabilities.
We'll talk about strings and, and then start to talk about files.
Add start doing some real work after we get done with this, so bear with us.
It's going to be a while, but we'll get there.
We'll get there. So, welcome to repeated steps.
This is the example that I had in the first, first lecture, Chapter 1.
And the basic idea, just to review,
is that you have this while keyword.
The while keyword sort of functions like an if in that
it implicitly has a decision that it's going to make.
And it's either going to do the code in the
indented block or not do it, or skip it basically.
Alright? So you either do it or you skip it.
The difference between the while and the if is that it's going
to do it many times, as long as this question that we have remains true.
Okay?
And so, in this case, n is 5, while n greater than 0 functions like an if.
So yes, it's going to run it. Prints out 5, subtracts 1, so it's 4.
Goes back up.
Goes back up and asks the question again, is n still greater than 0?
Well, since it's 4, yes, we'll continue on.
Out comes 4 then n gets subtracted. 3, 2, 3, 2, and then
we come through, we print 1. Print 1.
We subtract n to 0. We go up, we go back up.
n is now not greater than 0, so we come
up and we execute outside the loop, we leave the loop.
And that really means in the Python code we
skip to whatever is lined with the while statement.
The same indent level as the while statement.
And so that's how it works, and
I just print n at the end here to remind ourselves that n ended up at 0, not at 1,
the last thing we printed out in the loop. The last thing we
printed out in the loop was the 1, but n ended up at 0 because
it was, this loop was going to run as long as n was greater than 0,
so n had to sort of be not greater than 0 to get out of the loop.
Okay?
So that's basically a review of what we've done.
Now, oh, wait, wait, wait, wait,
wait, something else. Iteration variables.
Okay, so the key to this is these loops can't run forever.
We don't want them to run forever.
We want them to run until, as long as we want them to run.
They may run a very long time, but not forever.
There's got to be a way to get out of them, otherwise we
call them infinite loops, which we'll talk about in the next slide.
And so the iteration variable is generally some variable
that is changing each
time through the loop, and we're changing it by subtracting 1 to it, from it.
And so this thing is going to keep running, and we
can pretty much see that Oh, this is going to exit, right?
Whatever n is, it could be a large number, but eventually it's going to get to 0.
Right?
So the iteration variable controls how many times the loop runs.
And it also allows us to do something different inside the loop.
And, of course, this is like a trivial
loop, where we're just printing the iteration variable.
But it just means that this loop is going to run
five times and it's going to do something potentially different each time.
If you just ran the loop that did the same thing over
and over and over again, with no data changing, that's kind of dull and pointless.
So just because you have an iteration variable
doesn't mean that you've properly constructed your loop.
It's a, it's a common problem or something we want to avoid,
is an infinite loop. And here is a, a carefully constructed loop.
We start n at 5 at the beginning.
We have a good question at the end, while n greater than 0.
It's going to run this
as long as n is greater than 0.
But the problem is, is we don't change in the little block.
We don't change the n.
Which means it's going to come back and n is going to be 5.
And it's going to run this and n is going to be 5.
And so this is an infinite loop, which means this loop will never exit.
It will never get out,
it's just going to run forever in here, because n is not changing.
Neither of these statements change n.
So part of the iteration variable is there needs to be something that changes
so that the loop will ultimately make progress to
accomplish what it is and know when to stop.
So this is an infinite loop and, of course,
Lather, Rinse, Repeat is commonly put on shampoo and conditioner.
And so you know, you can, next time you are
in the shower, take a look at your shampoo and
conditioner and find the infinite loop that's,
that's on most bottles of shampoo and conditioner.
Now here is another loop,
just to emphasize that it's possible to structure
these loops in a way that they never run.
So this function is, is an if.
The while functions as an if.
And so when n is set to 0 and we ask the question,
it is literally going to make the decision based on n greater than 0.
Well it is not greater than 0, so it's going to go right by it, over
here it's going to come in here and go right to there and never run these
lines of code. And that's, we call this a zero trip loop.
And that's okay. I mean, this is a silly one, of course.
It just shows that the test, the question that's being asked is
above the lines that make up the body of the loop.
And if it's false, the loop never runs.
So it's possible that these loops have zero trips.
Okay?
So, that's a loop.
Now, there are more than one way to sort of control the flow
of a loop.
The basic flow of the loop is when it gets to the
bottom, it goes back up to the while, and does the check.
This is a different way of getting out of
a loop or controlling the execution of a loop.
There is a keyword or a part of the Python language called...
What color do I got?
No, green's over here. Called break.
If you look back at the reserved words, break was one of the reserved words.
Break says,
hey, if I'm in a loop, stop the loop. All right?
Get out of this loop.
I'm done with this loop.
And so here's this loop.
Now the interesting thing we've done is I've
just got done talking to you about infinite loops.
We have just constructed an "infinite loop", because the
question is right there, and the answer is yes.
True.
And that's a way to construct an infinite loop.
We've done this because we have a different
way of getting out of the loop, so we've
constructed a loop that, just on the face of it,
just looking at that line, looks like an infinite loop.
So what this loop does is it reads a line of input,
checks to see if the string that we've entered is done.
And if it is, we're going to skip out with this break
and get out of the loop, otherwise we're going to print it.
So at a high level, what this loop is
going to do is prompt for strings of characters
until we enter done.
And that's exactly what it does.
It prompts, we say hello there, it prints that out.
We say, we say finished, it prints that out.
We say done, and it's done.
So it, when we say done, it comes out and
finishes the loop, and, and that's the end of the program.
Okay?
So, to look at this in some more detail.
The first time, it comes in, does the raw input.
Because True is true, so it's going to run it.
And then we enter hello there.
It checks to see if what we entered is equal to the string done.
It is not, so it skips and it does the print.
And we do this one more time, we type finished.
And then the line is not done, that variable
line does not have the value done in it.
So we print that. We come in
one more time, but this time this is true, so it
goes in and executes the break and then it escapes the loop.
And so you can think of...
Right?
Here is the body of this loop,
because that's where the indentation starts and ends.
The break says, break me out of the current loop that I am in
and get to that next line that has the same indent as the while.
So, whatever it is, break says, we are done with this loop.
When that statement executes, we are done with the loop.
We're finished with the loop.
It'll run until that executes because we got this set to be while True.
Okay, so there's a simpler, I mean this is sort of a simple way to draw this.
Break is sort of a jump to the statement immediately following the loop.
If you really want to picture this, I think
of this as a kind of like a Star Trek transporter.
Where you kind of come into break and then [SOUND] your molecules are sent
to the four corners of the universe, and you reassemble outside of the loop.
And so if we look at this in sort of my little road map
version of these things, right?
The while loop is going to run for a while, yada, yada.
There can actually be more than one break
as long as they only get this. But the moment that somehow, some if or
whatever hits the break, then it gets out completely and so it escapes the loop.
And so it sort of like you, you, you're zoom, zoom,
zoom, zoom, zoom, zoom, you come in here and then you are,
you are re-materialized outside the loop. That's what the break does, okay?
So, break is one way to control the execution of loops.
Now, another way to control the execution of
loops, that doesn't actually exit the loop, is called continue.
Continue basically says, hey, I'm done with this iteration of the loop.
Now each time through the loop, we call that an iteration.
Continue says, I don't want to stop the loop, but I
want to stop this iteration and advance to the next iteration.
And so what we have here is we have the same basic loop,
a while True which kind of makes us an infinite loop.
We're going to read a line prompting with a less than sign.
And if it's done, we are going to break, that code is
down here, and we are going to print it if we fall through.
So normally we'll be reading and
printing, and if the line is done, we are going to break out.
That's we just got done doing. But the new part is right here.
And this is, we'll learn this in the next chapter.
If line sub 0, if the first character of
the line, is a pound sign, we're going to continue.
And what continue says is it doesn't actually get us out of the loop.
It jumps back up to the top of the loop.
Which means that it ignores, for that iteration,
the rest of the loop. Right?
So if execution comes in here.
I'm going to clear that.
If execution comes in here and hits this line, it goes back up to the while.
Okay?
Which means it, whatever this is, it's not coming out of this if.
It's going back up to the while.
Okay?
So continue ends the current iteration and jumps to
the top of the loop, and starts the next iteration.
And so if we look at how the code runs,
hello there prints, pound sign with the first character
doesn't print, so there is no printout right here.
Print this is not done. And we enter done, and then the loop ends.
Now another way to sort of draw this is
the continued jumps to the top of the loop.
It, it does run the question, right? It does check the question.
So here is another way to, to draw
that picture. And so here again we have a loop and it's happily running.
And there can be breaks in there and there could
be continues in there, and as long as we don't
hit a break or continue, the loop just sort of
runs and goes up to the top. And at some point, some if,
we hit the continue. And like a transporter, instead of
going out of the loop, we go to the top of the loop.
But it's important that we go and we check the question, right?
So the continue is
not likely to exit the loop unless the question has become false.
So the continue is likely to come up here,
run some more, then hit the continue. It comes up here.
Oops! Oops, it did that backwards.
Run some more.
Clear this out.
So, the continue could run many times, right?
So we have the loop.
Loop runs a bunch of times, then finally we hit the continue.
Continue goes up to the top.
If it's still true, we'll run the loop some more.
Then you might hit the continue.
Then you might go up to the top, come
down, round and round and round and round, hit the continue again.
Go up to the top, yada, yada.
Now in this, in this particular loop, this break eventually
is down here and that's how we get out, okay?
So the continue goes back up to the top of the loop.
So these loops that we construct with the
while keyword are what we call indefinite loops.
I mean, looking at the ones that we've
written, which are two lines or six lines,
we can kind of inspect them and understand when they are going
to stop, and we are going to know that they're possible to stop them.
A loop that won't stop is an infinite loop.
Sometimes these loops can be rather [COUGH] complex and you may not actually be able to
look at them, because there are many lines and, and so we don't know.
And so, so if you, you have to be real careful when you
construct these to make sure that they stop as, as things get more complicated.
Now the cousin to indefinite loops are definite loops.
And definite loops is something where we have a list of things or a set
of things that are kind of a known set of things, a finite set of things.
And we are going to write a loop that's going to go through that set of things
and do something to each thing in that set of things.
And the keyword that we use for this is the for.
So we use the Python for keyword that says we are going to write a loop, but
instead of it just running until some condition
becomes true or false or we hit a break,
we're actually going to know how many times this is going to run.
Now you can actually use break and continue in for loops.
We call these definite loops because the, how long
they're going to run is kind of well known, basically.
So here's a simple definite loop, and it's kind of like that while loop
that we just got done looking at
where it's counting down and then saying blastoff.
And so the way we construct this loop is we have the for keyword,
it's part of Python language,
the in keyword, and then we have an iteration variable.
I've chosen i as my iteration variable.
And basically what we're saying is, dear Python,
run this indented block, and there's only one line in the indented block.
Run it once for each of the values in this little list.
This is a Python list, square brackets make Python lists.
Comma-separated values.
So it says, I would like i to be 5, then run this code.
Then I would like i to be 4, then run this code.
Then I would like i to be 3, then run this code.
i should be 2, then run this code. And i should be 1, then run this code.
And so this is pretty clear, and I like this word in.
It says you know, doop, doop, doop, doop, doop, and then run this each time.
And so out of that comes 5, 4, 3, 2, 1, and then the loop is done.
Python is doing all the tricky bits
here, Python's figuring all these things out for us
and handling all this, and then we're done. And so it's, it's, if you look at it,
we have an iteration variable, but we didn't have to increment it,
we didn't have to do anything. Python took care of a lot of things for us.
And so when we're looping through a known list of things,
or later when we read a file,
we're going to loop through the lines in the file.
And so the for loop is a really nice powerful.
And it's syntactically cleaner, it's really quite nice.
Now it's important to realize that you
don't have to just loop through numbers. I did that one with the set of
descending numbers, so that it was equivalent to the
while loop that I started at the beginning.
But this is a loop where what it's going to loop through is a list.
Closed square brackets are a list in Python.
This is a list of three strings, Joseph, Glenn, and Sally.
They're string constants, and then commas are how we make lists.
And so friends
is a mnemonic variable.
Python doesn't know anything about friends in particular,
but I've chosen this variable name to be friends.
And it's a list of three people, Joseph, Glenn, and Sally.
And so I have an iteration variable called friend.
And I'm going to loop through the set of friends.
Now Python doesn't know anything about singular.
Python doesn't know anything about plural.
I'm just choosing these variable names because it makes a lot of sense.
This is a set of friends. Because it has three of them in it.
And this is a single friend.
What it's really going to do is friend is going to take on the successive
of values Joseph, Glenn, and Sally, and this little block of code
is going to once for each of those three items in the set, and
the variable friend is going to take on the successive values of that set.
So out of this comes three lines of printout.
Happy New Year Joseph, Happy New Year Glenn, Happy New Year Sally.
Of course this is the i bit right down here, but we just
made it so, hey Python, look, how ever many friends they are, run this
code one time for each one, change this variable friend to be each
of the successive ones in order, and then we print that we're done.
Okay?
So the for loop.
Sort of if we go and try to make a picture of the for loop.
The for loop is kind of a powerful thing. It's does, it does two things.
It decides if we're done or not.
Do we keep going in the loop?
Or, well I mean as long as we keep
going, we're going to advance the i value, the iteration variable.
It takes care of the responsibility of changing the iteration variable.
We do not have to add lines of code in that change the iteration variable, okay?
And so if we take a look, you know, we come in.
Are we done? We're not done.
Set i to the right thing, then print it.
Out comes 5. Advance i,
advance i, print it. Advance it.
Print it. Advance it. Print it.
Oh, now we're done.
Right?
i was not the thing that decided when we were done.
The for loop just keeps track internally as i moves
through these things and it goes like oh, I'm all done.
I'll take care of that, you finished.
So it doesn't, there's no if in here, so it's not like like if i equals 1, stop.
No, no, no, it just says you told me to do five things.
I'm going to do five things
and then we're going to stop.
And so again the for loop, the for loop here has got sort of two functions.
It decides how long the loop is going to run, and changes the
iteration variable based on what you've told it to, in this in clause.
Okay?
So I think in is a real elegant construct.
It's just a keyword, but it's sort of, if you think about math,
if you're familiar with sets,
it's like something inside of a set of something.
I think it's a real pretty way to think about it.
And you can kind of think of it a little more abstractly.
That you say, well here's a little indented block of code.
Right?
And I want it to run some number of times for each
of the i values in the set 5, 4, 3, 2, 1.
That's how I kind of think of it.
So I think that this is a real pretty syntax.
Different languages have different looping syntax.
I think this is really a very expressive, very pretty one.
Yeah.
So another way to, so, so, so one way to
think about this picture is that, you know, the for loop
causes sort of repeated execution in that we're
driving in the circle and then we stop, right?
The other way to think about is to, to
not, to think about a little more abstractly, right?
To say, hmm, you know, at the end of the day, all I'm
really telling Python is, I want to execute this block of code five times,
then I want the variable i to change from, to these three values.
So in a way, you could think of this as expanded
is the for loop sets it to 5, then runs your code.
The for loop then sets it to 4, runs your code.
The for loop sets it to 3, runs your code.
For loop sets it to 2, runs your code. Sets it to 1, runs your code.
These two ways of looking at it are the same
from your perspective, because you're just asking Python
to do something.
Whether it does it this way, or whether it does it this way,
you hardly can tell the difference. It's probably going to do it this way.
But logically it's not that different. It's not different from doing it this way.
You're saying, run this block of code, change i in the following way.
Cool. It's like, we don't have to worry.
I mean, we can use, mentally, either model of what's
going on inside, because it doesn't matter, because they're the same.
Okay, so these definite loops are really cool.
Starting in a couple of chapters we'll mostly use definite
loops to go through lists or dictionaries or tuples or files.
And so that's a finite set of things.
It can be a large set of things, but it's a finite set of things.
Okay. So now I want to talk about loop idioms.
Loop idioms are how we construct loops.
And we're going to, the loops kind of have some kind of a goal in mind.
Finding the largest, we played with that.
Finding the smallest, counting the number of things,
looking for lines that start with pound signs, something like that.
They, they have a kind of a high-level view of what they're supposed to do,
and then we have to kind of build a loop to accomplish that.
And and this goes back to how we have to think like a computer, right?
We have to say, hey computer,
do this over and over and over again, and then I'll
get what I want once you've done that over and over again.
You have to do something a million times.
I'm not going to sit here and wait.
At the end, I'll get what I want.
So I call these kind of "smart loops",
or how to kind of build intelligence into loops.
So, for example, we want the largest number.
Right?
But we have to construct a loop that will
get us the largest number thinking like a computer.
Okay? Thinking computationally.
Thinking like a computer.
So the idea is that we have some kind
of a loop and we're going to go through this list,
some list of things, and this is going to run a bunch of times.
And, but the way we're going to do it is
we're going to set something up before the loop starts.
We're going to do something to each of the things that's being looked at,
and at the end, we're going to get the result we're looking for.
Okay?
And so in the middle it's kind of like working.
It's in the middle working, da, da, da, da, da.
And then here is the payoff.
The payoff is at the end when we get the information that we're interested in.
So I will sort of use in the next few examples
this simple loop,
and right now it doesn't do much.
It does a print Before and it has this variable
thing that goes through the successive values of these numbers.
And it prints it out, right? So that middle part says
run this six times, once for each of those values.
And then After. Okay?
And so we will add some intelligence at the beginning, we'll add
some intelligence in the middle, and we'll add some intelligence at the end.
And then the whole thing will accomplish what we want.
Right now this is kind of not that intelligent.
So now what I want to do, is I want to review the thing we did, and I want you
to remember what the largest number is, and I'm going to
show you a sequence of numbers in order.
Ready?
One, I'll do it kind of quickly, because you've seen this before.
So, I'm only showing you one number at a time.
So you want to tell me what the largest number is.
So here we go. The first number is 9.
The second number is 41.
The third number is 12. The fourth number is 3.
The fifth number is 74. And the sixth number is 15.
So what was the largest number?
Did you have to go back? Or did you remember how to do it?
Okay, well, I will give you a clue. It was 74.
Okay? That's because I know.
Okay, now if you did that and you had to do that for 20 or 30 numbers,
you'd have to create a mental algorithm in
your head to approach it and stay concentrated, focused.
So, you would've created a variable in your head
called largest_so_far.
I would show you the first number, which would be 9, and you would go hmm.
Well, 9 is larger than 1, negative 1.
So I will keep that. That's the new largest I've seen so far.
That's pretty awesome, because it's way better than negative 1.
41? I thought 9 was good. But 41, that is a lot better.
So I'm going to keep that one.
That's the, that's the best. It's the largest we've seen so far.
We've only seen two numbers.
But the best we've so far is 41.
So 12 is not larger. Who, who cares about that?
It's not as big as 41 so we'll just go right on to the next, on to the next.
3, that's lame when we are looking for large numbers.
So we skip, oh, 74. 74, that's a rockingly large number.
So we're going to, that's a lot.
That's actually the largest we've seen so far
because it's bigger than 41, and 41 was the former champion
largest we've seen so far. And there's 74, so we keep that one.
I don't know how many letters, of these things you're going to see, right?
We could see lots of them. But the next one we see 15.
Well, that's no good.
We've got 74 already. 74's like totally awesome.
Right?
So now, oh, we're done.
So, hey, we're done and so 74 is the champion.
That is the largest.
It's not even the largest so far any more, it's actually the largest.
It's the largest.
So again, we had this thing at the top, we had this loop in
the middle, and at the bottom is where you kind of get the payoff.
And the payoff is
not in the middle.
while we're largest so far, largest so far, largest so far,
but at the end it turned out
once you've looked at all the variables,
all the values, the largest so far is indeed the largest.
Okay.
So here's the algorithm for this.
I have some variables, and remember
that underscores are valid characters in variables.
Now [COUGH] I'm being a little over-explicit in this.
So I have a variable called largest_so_far.
Then what I do is I set it to 1, negative 1.
Then I print Before so we can see that largest_so_far is negative 1.
Then we have a for loop and my variable iteration variable is the_num.
So that's going to take on the successive values: 9, 41, 12, 3, 74, 15,
and run this indented loop of code, okay?
And so the_num will be 9, first time through.
If the_num, 9, is greater than
largest_so_far, then grab the_num and assign
it into largest_so_far. Then print at the end of each loop,
largest_so_far and the_num. So, so, in effect, the_num is 9.
We compare it to negative 1, and negative 1, 9 is higher.
So we make largest_so_far be 9.
Next time through the loop, next time through the loop, num is 41.
So we compare largest_so_far with 41, and we like it, so we store it.
So we like it, we run it, and we print our 41 is the largest we've seen so far.
And we run again.
We come in, the_num now points to 12. the_num, 12, is
not greater than 41, and so we skip. So, the largest
so far stays 41, and we see 12. Similarly, the_num advances to 3.
We skip.
So we saw 3, but the largest so far is still 41.
Continuing, the_num is now 74. It runs, 74 is
greater than 41, and so we run this code. And so we say 74
is stuck in largest_so_far, and indeed, then we print
it out, and largest so far is now 74.
We continue on.
We go up one more time.
The_num points to 15, but 15 is not larger than 74.
And so we skip.
We print out 15 and 74, and then we come out and
at the end, at the end, we get the largest so far.
It, the name no matter, no longer,
I mean it's kind of the largest
so far at the end is the largest, but the variable name.
Okay? Got it?
That's one idiom. So let's just switch to another idiom.
Now counting, how many things are we
going to, how many times is loop going to execute?
How things are we going to find in the loop?
It's all kind of the same notion.
And the pattern is really simple. We start some variable zork.
A better name for this would be count.
But I want to call it zork.
And then we have a loop, and then in the loop we just add 1 to zork,
and at the end, zork.
That should be light blue right there. zork should be the total count.
Now of course we can look at it and say it's going to be 6, but
assume this loop is looping through a million
lines in the file or something like that.
So it's [SOUND], so it's cheating to kind of look at it and say, ooh, it's 6,
because we want to actually compute it. So it's really simple.
You know, zork starts at 0. It's going to run zork is 1 now, and
2, 3, 4, 5, 6, and then we've run out of stuff and then we print out 6.
Okay?
So that's kind of the idiom, right?
Before, during, and after, right? We do something before, we do
something during, and, and in a sense this zork here is the number we've seen so far.
And at the end it becomes kind of the total number.
Summing in a loop, very similar.
Again, you have to think of this is, there is a whole bunch of variables here.
We start a variable at 0.
Each time through the loop, we add whatever it is that we're seeing.
Instead of adding 1 we're adding 9, 41, 12, 3, 74, 15.
And zork would be best thought of as running total.
So, zork is the running total.
And so if we look at the numbers 9,
running total's 9, running total's 50, running total's 62, 65, 139, 154.
And then we skip out and at the end, the running total becomes the total.
Okay?
So, that's another of these patterns that, sort of,
we do something at the beginning, we
do something in the middle, and we have
something very nice for ourselves at the end.
Finding the average of a sequence of values
is the combination of the two previous patterns.
This time I am going to use more mnemonic variables.
A variable called count.
Everyone calls this count.
Sum, now total would maybe be a better word for this.
The running total. And then, so the count and the sum start out at 0, and
then each time through the loop, count equals count plus 1, so we're adding 1 to count.
Sum equal sum plus value, so we're adding 1 to to sum.
I mean adding the value.
Value of course being 9, 41, 12, 3, 74, 15.
And then at the very end we can print out the number.
We have six things with a total of 154, and then we calculate the average.
Of course these are integer numbers, and so this is a truncating division.
So 154 over 6 equals 25 and
not 25 point something.
In Python 3000, Python 3, it'd be better.
But so the average, the integer average is of the numbers we just looked at, is 25.
So sometimes we're searching, like for a needle in a haystack.
Looking for something and again you have to think of like
you're handed some amount of data and you gotta hunt for something.
And there might be a million things and you might only want five of them.
And you can either look by hand or you can write
a loop that's got an if statement that says found it.
Maybe I found it at line seven or found it wherever.
So this is filtering or finding or searching, looking
for a needle in a haystack, in a loop.
And so the, the idea basically is that we have this loop,
it's going to go through all the values, 9, 41, 12, 3, 74.
But we put in the loop, we embed an if statement.
If the value we're looking at is greater than 20, print I found it.
So when value is 9, this is going to do nothing and just go and make value be 41.
And then value 41, oop, yep, there we go, print Large number, so off this comes.
Then value becomes 12, nothing happens, value becomes 3, nothing happens,
value becomes 74, oops, this time it's going to happen.
So out comes Large number 74.
Then value becomes 15, nothing happens, and then value is all done,
and so it comes and finishes.
So this is the searching or filtering or catching or, or whatever.
Okay?
We can also sort of, if we don't just want
to print everything out, we want to say is something in there.
Go look through this million things and
tell me if blah exists.
And in this we're going to introduce the notion of Boolean variable.
A Boolean is a true-false.
It only has two values and we've already used it in the while True.
So that capital True, that is a constant, just like 7 or 42 or 99, or "Sam".
And so we're going to make this variable called found.
Now found is a mnemonic value, variable. It's just a name I picked.
So found equals False.
This is going to be false, until we find what
we're looking for and then it's going to switch to true.
So it starts out and it's false.
Then we're going to run this bit of code three times.
And if the value that we are looking at is 3, then we're going
to set found to be true, and we'll print found value each time through.
So value's going to take on 9, 41, 12, 3, 74, so we get a line
of output for each one. And the first time through
it's not yet found, because we're looking at a 9.
Second time, it's not yet found.
We looked at 41, still false. So it could stay false for long time.
Oh, we found a true.
And then that means that this code is going to run once.
And so you can kind of think of this found variable as sticky.
It's going to stay false, and then the rest of the loop
it's going to stay true, and at the end it is true.
Now the way we usually do these kinds of things
is we don't bother with this print statement,
so we wouldn't see all this stuff.
All we'd see is Before False, After True.
And After would just tell us that yeah, we found it.
There was a 3 somewhere in that long list of numbers.
Okay? I am just adding this print statement so we can
kind of trace it. But basically this loop, sort of from here to here, is asking
the question, is there the number 3 in the list that we're about to go through?
Okay? Now...
How could, I'll just give you a second and ask you a quick question.
You can pause if you want.
How could you improve this loop using the break?
Where might you put a break to make this loop smarter?
[SOUND].
It's okay if you didn't, if it doesn't jump out at you.
So, if you think about it.
Once you hit true, there's really little point in looking at the rest of them.
There just is no point. So we could put a break right here.
Inside this block. You'd say, look, I'm looking for a 3.
All I care is whether I found it or not.
If I find it, I mark it to true that I found it, and I get out of the loop.
Why bother?
Why do all these things?
Right, just get out. Okay?
So don't worry about it.
I'm just pointing that out, that's one of the places where break could be used.
The loop functions either way it just, it just loops through all the rest
of them as well.
Okay. So.
Here's this largest value one I've used before and you know, away we go.
We, you know, we have largest_so_far, we check to see
if the one we're looking at is better
and if it is we keep it and then away we go and we find that the largest is 17.
What if...
What would you have to change in this
code to make this search for the smallest of all the values?
Like point, point where in the screen.
Where, what would you have to change to
make this look for the smallest in the list of values?
What is the nature of what's making this about being largest?
What would you change? Okay.
Pause if you like.
So here is some things that you might do to make it work about the smallest.
So, hey, one thing we would do.
Let's change the name of the variable. We had a variable named largest_so_far.
And now we'll change it to be called smallest_so_far.
Changing the variable name doesn't change the program at all.
But it makes the program easier to read.
If the program works.
So, it's like smallest so far.
Okay, but that didn't make it about being small.
The thing that made it about being small
is change this greater than to a less than.
Because we're kind of thinking when we're doing largest so far, if the
number we're looking at is bigger than the largest so far, we keep it.
If the number we're looking at in the smallest is
smaller than the smallest so far, then we want to keep it.
So this is like,
this line here is the keeping line and this is the when line.
When to keep.
We'll keep it if it's smaller.
Okay?
So that's the key, and so yeah, so I name it smallest_so_far,
whoop de do. That's good. But the real thing that
had this being about largeness and smallness was whether this, this less
than and greater than and this was the repeated code that got re-checked
over and over again. So, but this still has a bug in it.
So let's run this visually.
Okay.
So now we've got a variable called smallest so far.
We are going to check to see if a series of numbers that
I'm about to show you are smaller than the smallest so far.
So the first number is 9. Is that smaller than negative 1?
No, it's not. Negative 1 is smaller.
The second number is 41. Is that smaller than negative 1?
No, it is not.
The next number is 12. Is that smaller than negative 1?
No.
Negative 1 is smaller than 12.
3? No, not smaller.
74? No, not smaller.
15? Not smaller.
So, we're all done.
Yay, and the smallest number we saw in the list is...
Negative 1? Negative 1 wasn't even in the list.
So that's not a very good program.
So let's take a look at what went wrong with this program.
So we fixed it, we fixed it as best we could. Right?
We made it, we changed the words largest to smallest and yay, that'll fix.
Just makes it more readable, doesn't actually change the program.
And we made this less than, so now what happens is it comes in,
if 3 is less than negative 1, smallest so far of course is negative 1.
It, this just never runs.
This never runs. And so
as we print, smallest_so_far stays negative 1 and oops, that
should be negative 1, right there. [LAUGH] I'm sorry, I forgot to fix that.
Here, let me magically fix that.
Boom. [SNAP]
So let's take a look at what went wrong with this.
So here we have the code. smallest_so_far is negative 1.
We have it fixed so we're checking, looking for smaller
numbers rather than larger numbers, by turning this to less than.
But the first time through, smallest_so_far is negative 1 and the_num is 3.
3 is not less than negative 1, so we skip through and the printout of the
first line is negative 1 3.
And it doesn't take long to realize that it's just going to keep doing this.
smallest_so_far is going to stay negative 1,
no matter what we look at on this side.
And then we're going to come out at the end.
And we end up with negative 1 as the answer. Not very good.
[SIGH].
So the question is...
What should we make this value be? Negative 1?
It barely worked in the largest because we were working with positive
numbers and so starting with negative 1 as the largest so far
was a reasonable assumption as long as the numbers were all positive.
[SOUND].
But what would be the number to choose here?
Think about that for a second.
Pause if you have to.
Let me clear it. Let me make it real clear.
[SOUND]. What's the right thing
to put here? Okay.
So, what? A million?
That might work, a million might work. But what if this number, you know,
was, you know, what if, what if all these numbers were larger
than a million, okay? Then, then that wouldn't work.
So the problem is there's no real good value, unless you could make this be
somehow infinity, okay? You could make this be infinity.
But there is a way to do this in Python. And it's a really kind of cool technique.
It's sort of a way we signal ourselves,
and that is we're going to use a special value.
Not negative 1.
It's not a number. And the special value we're going to use is None.
It's a different type. It's not a number, it's itself its own type.
So what we're going to do is mark smallest as "None".
And, and, and sort of at a high level what
we're really saying is we haven't seen anything so far.
The smallest we've seen so far is none.
We've not seen anything so far.
Now we have to change our loop, our little if inside the loop.
This is this intelligence in the middle.
First we say if smallest is None.
is is an operator, part of the Python language.
If smallest is None, exactly the same as None,
then the smallest we've seen so far is the value.
Now this is going to happen the first time [SOUND].
Because smallest starts out None and then as soon as we set smallest
to the value, it's going to be that first number, so it's going to be 9.
Okay? So the smallest is quickly going to become 9.
Then we print out the new, the smallest is 9 after we've seen the 9.
Then we go up to the top and we say, is smallest None?
And the answer is no it is not, because smallest is now 9.
Then this else-if is going to ask, is the value we're looking at, which is 41,
is the value less than smallest? Well, no, it is not.
9 is smaller than 41.
And, so in a sense, after the first time it's executed,
after the first time the statement is executed,
this is going to always be false, right?
Because smallest is no longer None and this is going to be
the thing that really is operating.
And then it's going to work.
And when we, you know, smallest will become 9.
The smallest so far is 9, but then we see
the 3 finally, and the value of the 3 is less than 9.
And so then we take 3 and we stick it into
smallest and we end up with this, and then the loop
runs some more times, and when we're all done we have 3.
So the trick here is we put this None in, and we have a
little more if code to check to see if we haven't seen anything so far.
This is what, you can think of this
as a way to trigger on the first, first iteration.
Special code that's really going to, it could, it looks at it
on each iteration, but it's never true after the first iteration.
Okay? So that's just a technique.
So this is and the is not operator, I think it's a real elegant thing.
Don't start overusing it. It's, at a low level
its real meaning is exactly the same as in type and value.
There's an is and there's an is not, but don't, like,
say, like, if, don't do things like saying if i equals.
Oops. I won't even let myself type the bad code.
if i is 4.
Don't say that, okay? Don't say that.
Don't do if i is 4.
It may work in certain situations. It's really best used in very limited
situations where you're checking for some of these
special values like None and False.
Okay.
The problem is if you use equality here, it tries to kind of
convert values and it may end up giving you a false yes.
And so is is a stronger equality than simple equals.
Equals is same value, same numeric value, whereas is is exactly the same thing.
But don't, don't overuse is. Use double equals
95% of the time and use is when you're
checking if it's one of these special constants like True or False.
Okay?
Okay. So this is a iterations.
I mean our loops are going to get more sophisticated and
we have more interesting things to do, but we,
you know, we talked about some
indefinite loops, definite loops, iteration variables.
Some patterns like maximum, minimum, summing, averaging, you know.
We introduced the concept of None, you know, and, and so this is.
We're getting there, we've got a couple more chapters before we really
start hitting the data analysis, so see you in the next lecture.