Hi. Welcome to the second office hours.
Again we had a lot of really good questions in the forum, so let's get started.
The first question came from Matthew Atkinson.
He has heard that you shouldn't use functions like eval and exec,
which we did use in unit 2.
He wants to know why shouldn't we be using these functions,
and what's the problem with them.
That's a great question. There's a couple reason to avoid these.
On is for security, especially if you're going to be evaling
a string that somebody passes in to you, you don't know what it's going to be doing.
There are lots of dangerous commands that Python can execute like "delete all my files."
You don't want to be asking somebody to type something in and then go execute that
and allow them to do something dangerous. That's one reason.
The other is just in terms of program structure.
We like to write our programs so that the functions and variables and so on,
have a set scope.
This variable exists from here to here,
and eval kind of breaks all that structure
and goes outside of it and say now we're executing something right here,
but it's not executing with respect to where we are in the code.
It's executing someplace complete different. That makes it harder to follow the code.
There's nothing wrong in terms of do you get the right answer but harder to understand.
So we should minimize it.
I used it in the assignment for week 2, because there was no other way to easily get around it.
But you should minimize the use.
Thanks. The next question comes from Sasheen.
Sasheen want's to know a little bit more about this big-O notation
that we introduced and saw a little bit of in Unit 2.
Yeah. The answer to that question is a whole course in algorithms.
We can't do that right here.
But basically the idea is big O says approximately how many instructions
is it going to take to execute this.
Actually, big O is an upper bound on that.
There's another notation less widely used with big theta which gives a more exact bound,
but the idea is if I have a doubly nested loop that says for i = 1-n
and then inside of that is nest for j = 1-n then that's the order n-squared,
because we're going to n * n executions of the inner loop.
The basic idea is that's more than if we were just doing what are n executions of the loop.
So if you can get away with a single loop instead of a double loop, that's better.
That's really all you need to know about big O.
Alright. I should say there will be an algorithms class sometime in the near future
for those of you who want to learn more about this.
Thomas Grace had a question about these attributes you use--function attributes--
specifically in the C function that had c.starts and c.items. What's going on there?
So Dave Evans in CS101 chose not to really focus on Python classes,
which is probably a good choice, because it's a big topic.
The idea here is that classes of objects can have attributes.
These are parts or components of the object,
and they're named with this dot-notation--object, dot, then the name of a field
that's a component of that object.
In most languages you define all the fields ahead of time.
When you define what a class looks like, you say these are the fields that compose this object.
Python is a more dynamic language, and some classes of objects you're allowed to add
fields to them as you go, and functions are one of those types of dynamic objects
where you can at any you say I want to add a new attribute to this function.
Other objects have that same approach where you can add to it.
And so what was going on in the C function is that I needed two variables
that I wanted to keep track of something. I needed two counters.
I could have just used a global variable name, but that would be cluttering up the name space.
There'd be no way for you to, if I just made up a name like cstarts and citems--
by looking at the name of the variable you could figure out that they were related--
but there'd be no structural way to say that these are all related. They belong together.
You want to minimize the number of global variables, because people's memories are small.
By putting everything into one object, we say this belongs together.
Using c.start rather than a variable named cstart is a way of structuring things together.
In Python you can do that automatically. You don't have to have a declaration.
You can just say I want to add a new attribute to a function, and you go ahead and assign it.
Great. I had no idea you could do that either. I was very excited to see that.
Yeah. If you come from a language like Java or C, you're not used to that.
There you've got to declare ahead of time what your attributes are going to be.
Right. Next question comes from Tracy Zelman,
and she just wants to hear a little bit about when do we use lambdas.
How do you decide when to use a normal function versus lambda.
All a lambda is is a function definition without assigning a name to it.
In a normal function definition we say "def", then we say the function name,
the arguments, and the body of the function.
We're simultaneously doing two things.
We're defining what the function does, and we're giving it a name.
Now, what a lambda does is break those out
to say we're defining a function, but we're not giving it a name.
Why would you want to do that?
Well, we do it all the time.
If we have an expression--like say we have the arithmetic expression x + 1 * x - 1,
we didn't both to give names to those subcomponents--the x + 1 and the x - 1.
We just wrote them down. So a lambda is like that.
It's a function that's a small thing. We didn't want to bother giving it a name.
We just wanted to use it in place.
So that's the advantage of lambda that you aren't bothered with a name,
and you can just write it right there without having to define it at one point
and then use it at a second point. That's the good thing about it.
The bad thing about it is that it's limited.
In Python lambda can only have an expression.
It can't have statements in it, and it just doesn't really fit with the rest of the language.
Some languages are really designed around expressions like that, and they go really well.
In Python it doesn't fit that much.
I think mostly you should avoid it and just define a function with its name in the normal way,
but sometimes it's really convenient to put everything in one place
rather than having to define in one place and use in a second place.
Great. Udacer had some questions about the program design strategy that we've been using.
Namely, should we implement the strategy that we've been using
in every single problem we approach? Is there somewhere we don't really need it?
If we chose not to use the strategy, what are some of the disadvantages?
Well, whatever you can do to get your job done, go ahead and do it.
I've given you some approaches.
I wouldn't say that there is just one strategy, but rather there is a collection of strategies
that you want to be able to understand what's going on,
make your inventory of concepts,
build those up. You have a lot of choices within that.
Do I want to start top down, bottom up, middle out? That's all up to you.
As long as you arrive at the end of a description of the whole domain,
and the whole program and you get it right, then congratulations to you.
I think every body develops their own style for how they go about addressing this,
but there are ideas of what it means to have a high-quality program--
correctness, efficiency, and so on.
Then more driven by taste is what does it mean to be readable and extensible.
You'll learn that over time.
Great. For one last question, Takanzi wants to know if you have any good recommendations
for computer science, and specifically Python, books.
Oh, books. Okay.
Yes, I do have some recommendations.
If you search for Peter Norvig's library in Google Books, I have some there.
With this question maybe I'll go and update them some more.
I can mention a few.
In terms of general programming books, I really like The Practice of Programming.
I like The Elements of Programming Style, which is rather an old
and somewhat dated book now in terms of the examples it uses,
but still really up-to-date in terms of the advice.
I like Structure and Interpretation of Computer Programs,
which has been a standard textbook for introductory computer science.
I like Programming Pearls is a nice collection of short essays.
Then in Python books, there's a lot of them, and I haven't kept up with all the possibilities.
There's a nice online book of How To Think Like a Computer Scientist that has a Python version.
There's Python in a Nutshell, Python Cookbook, Learning Python.
Headfirst Python, I think, is an interesting, somewhat different approach.
There are a lot of them there, and I'll try to update my Google Books library
to give a little bit of commentary on each one.
Thank you. Thank you for all the question. Thank you for your answer.
Stay tuned for the next unit, which will be posted on Sunday
and also for a couple more editions to the Python glossary.
All right. See you in class.