Hello, and welcome to yet another worked
exercise for Python for Informatics: Exploring Information.
I'm your exercise worker Charles Severance, I'm the author of the book.
And as always, this material, as well
as the book itself, is Creative Commons attribution.
So this exercise assumes that you sort of know
how to edit files and have things set up.
If you if you need more help, go
with www.pythonlearn.com and go through the installation process.
So the exercise we're contemplating right now is Exercise 5.1.
We're going to read a list of numbers.
And deal with some bad data and ultimately
compute the average and finish when we're done.
And so, we're going to, we're going to do this stepwise like we always do.
We're not just going to write this and try
to, you know, imagine what the ultimate thing is.
So the first thing that I'm going to try to, to write, is.
So the first thing I'm going to try to write is entr, enter a number,
convert the number to a floating point, and then print it out, just for you.
So go ahead and get started on that.
Keep the copy that.
I've got a nice copy on paper here.
I'll refer back to my specifications.
So here I have TextWrangler up.
I will go, go into my desktop, I got this folder called Python for Informatics here.
So I go on to my desktop,
Desktop, cd Python for Informatics.
I'll to do an ls, and here's the,
some of the other exercises that I played with before.
So I'm going to make a new file.
I'll just say print hello.
Just yeah, I don't know, I always start this way.
That's how I do it.
Save As.
I'm just making sure I'm already in that, so I come in the right folder.
And I'll call this one numlist.
[BLANK_AUDIO]
dot p-y
If all goes well, you'll notice now it has the Python suffix, it's properly colored,
and son of a gun if I'm not in the correct directory.
So let's go ahead and run this thing numlist.py, hello.
So it's good stuff.
I'll make this a little smaller.
So there we go.
So let's get started.
So instead of saying hello, I'm going to just say
I'm going to get a string variable, in and say
raw input, enter a number, colon.
Then I'm going to add a space just to make it look a little prettier.
Then I'm going to convert that to a floating point number.
I'll call this thing num.
And I'll call float, because inp is a string.
And I want an integer number, floating point numbers so I can add them up.
And I'm just going to print num out, just to sort of be cool.
So I'm going to, on my Mac I can use a Command S instead of all the clicky stuff.
So Command S.
Now I'm in my terminal.
I hit up arrow, so I can run it again.
Enter a number, 79.
That's looking pretty good.
Enter a number.
That's looking pretty bad, but frankly
that's expect, exactly what we would expect.
If we're going to type garbage in, we're going to get a traceback.
We'll deal with that in a minute.
Okay, so.
[SOUND] So it looks like that part's pretty cool.
So our problem now is we want to take this no, let's, let's put that back in.
Let's put this, let's put this in a loop.
So how do we make a loop?
Well, I'll just make an infinite loop for
now, and I'm going to indent these four spaces.
Make sure you have spaces turned,
I mean tabs turned into spaces and it will all just be
[SOUND], and so I'm going to write this loop.
Right now we're writing an infinite loop because it's always going to be true.
So let's go ahead and save this one.
python numlist.py.
1-2-3; 4-5-6, that's another number.
Now we're supposed to be able type done.
Well, our program ended because the float
crashed, right? The float crashed on line three.
And so at least we killed our program.
Because we were in an infinite loop.
It would have been prompting us for
numbers forever, it would have never been done.
So the next thing we're going to need to do
is, we're going to need to get out of the loop.
Okay?
So I'm going to, I'm going to get out of the
loop by checking to see if inp is equal to done,
break.
So all that just basically says if the input the user types, I'm going to break out.
So let's run this again. 3, done.
Now at least it runs and it, it gets out of the of the loop. The break
comes down to here.
That much is pretty good.
Let me add a quick feature here that's not in the specification list.
We'll see if we get in trouble for this one.
I'm going to say if len of inp less than one, break.
This is actually kind of an idiom in here.
Check for empty line.
It's a bit of an idiom.
So, so basically, maybe the poor user would not
think to type done, because they didn't read the specifications.
So we'll save that one.
And you will see now that I can [SOUND].
just hit Enter key, and it sees that as done as well.
That's probably a more clever way to do it, and a more user-friendly way to do it.
Or maybe it's a violation of specifications,
but we're just going to treat that as [UNKNOWN].
We'll leave it in there for now.
But that's kind of Python idiom, that you know, ending on a empty line.
Just because it's natural for the user to
just hit Enter, and think is this thing is going to stop?
Okay.
So now our problem is, is we've got to count these things.
So we've got this loop body, and it's running a bunch of times.
And we want to count how many times it runs.
So we'll make a variable called count, set it to zero.
And then each time we come through we're going to add count equals count plus 1.
Now, oops.
Now, I did not put the count here.
And that's because I only want to count the numbers that I've actually read.
So I'm, I've read a number.
Because if I, if I increment my count here and I break, it'll be one too many.
Well let's just go ahead and do that.
Just say count equals and make that mistake.
Right?
So I'm going to, going to get rid of this, and I'll put it here.
Exactly where I say don't count here.
Right?
So I'm going to count here, and this is a bad place to count.
So I'm going to save that, and this loop is going to go until it's done
and then it's going to print out how many numbers we've got.
[SOUND] So you see here, it's got a mistake.
It's not a syntax error, it's a logic error.
Because we've got thr count up to 3, but that's because
the last time through the code, you know, count was zero.
We read a number, we added one to the count.
We read another number, added one to the count.
And then we read another bad number, we added a number to the count,
and then we end up with this break.
So the count is wrong, basically.
Okay?
And so, the key is that we've got to move
we've got to move the count down.
We only want to count the valid data, we don't want to count invalid data.
So what we were doing is we were counting the last non-data bit.
And so it's just, that's just, you know, another thing to look for.
You know, the, the pattern here is, you know, read your data,
decide if you've got bad data or good data, or you want to stop, or whatever.
And then do the work.
So I'll put a comment in here called do, oop, do the work.
So this is the work, and this is kind of handle the edge cases.
Right?
And this is get the data, handle the edge cases, then do the work.
And incrementing count is just part of the work.
Okay?
So let's keep going.
Now we've gotta make our, our average.
So average of course be the total.
And that's pretty easy, because we're going to
say total equals total plus num.
Simple enough?
So I'm going to print out num, total, and count.
Okay?
So we'll.
So now 12, 14.
So you see our number is 12, our total is 12, and our count's 1.
Number's 14, total 26, count of 2.
Looking pretty good.
Let's just hit Enter, and the count is 2.
So the only, so we got count.
So, let's change this to be what we're suppose to change it to.
Say average.
colon, then no space, because the comma adds a space,
and we're going to just say total over count.
So let's run that.
Run 10, 11, 10.5.
So our numbers are working.
So we're getting pretty close.
We really have one more problem to solve and that is [SOUND] that problem.
The problem when we have crappy data.
And we don't want to use traceback as
our mechanism, we just want to re-prompt the user.
So the key thing when you're dealing with this is, the first
thing to take a look at is the actual line in question.
The line that caused the error, line that caused the error
is line 11, and it's this line right here.
So, we can't control what the user types.
The simplest thing to do is to use the try-except
to put, take out some insurance on this particular line.
It's like, that's a dangerous line.
And then except tells us what to do.
So now the question is, well let's put out a print statement.
All right.
And print what we're supposed to say.
Invalid input.
Okay?
So here we go.
We've got invalid input, and so we've got an exception.
You know, I've made a mistake on purpose.
You can pause and try to figure out what the mistake is, but.
Okay, you got your chance to pause, so let's
go take a look at what the mistake is.
Let's come up with some evil data that causes the problem.
So 10 is our first number.
12 is our second number.
And now I'm going to say fred.
So now you should be able to see what's wrong here.
The problem is that basically fred indeed says invalid input.
That works because it runs down this line of code and it says invalid input.
The problem is, it's still executing this code right here.
So, the number actually the float failed.
We said fred but the number's 12 and that's
because it's 12 from the last time through the loop.
The last time through the loop, okay?
So it ends up adding 12 again, 22, then we have three numbers and
then we finish, oops, that wa in the wrong window there, and then when we finish,
the average is not 11, which is 10 plus 12, but it is indeed 11.3.
So the problem is when we have this exception, we can't run this code.
And of course there's a lovely, lovely bit of Python to fix this, solves this for us.
And that is the continue statement.
Continue statement says, I'm done with this iteration.
You entered a number.
It's crappy, I'm just not going to do anything.
So effectively instead of going down here to continue,
it goes up to here and prompts for the next one.
So it doesn't do this code, right? It does not do that code, and everything is cool.
And so that's the key.
When we say invalid input, we do not want to run this code.
Oops [SOUND] so let's save this.
So continue's our friend on this one.
So 10, 12.
I'm doing these just so I can know the average should be 11.
And then fred. Now you'll notice it says invalid input, but because of
continue, it doesn't fall through and do all the rest of that stuff.
And then let's hit Enter to finish and the average is indeed 11.0.
Okay?
So again, I think that's pretty much it.
Thanks for listening.
For more information Python for informatics, www.py4inf.com.
Thanks.