LongCut logo

Names, Assignment, and User-Defined Functions

By John DeNero

Summary

Topics Covered

  • Imports Bind Built-in Names
  • Assignments Snapshot Values
  • Names Are Aliases to Objects
  • Defs Create Re-evaluable Functions

Full Transcript

PROFESSOR: Today we're going to talk about names and how they work.

So let me show you a quick demonstration to get us started.

I'll start up Python.

If I ever press Control-L, it clears the screen.

But I'm still in the same Python session.

Now, I showed you last time that Python can be used as a calculator.

That means it should know about important constants like pi.

Oh, name pi is not defined.

Well, it's not that Python has no idea what pi is.

It's just that most names aren't available unless you import them.

From math import pi is a statement that says make the name pi available.

And now it is.

I can use it in combination with other values however I want.

An import statement can also be used in order to get access to other functions, such as the sine function.

So sine is a built-in function that takes the sine of an angle.

So if I take the sine of pi over 2, I get 1.

Oh, it works.

Now, these are built-in functions and built-in names.

I didn't say what pi was.

I just looked it up.

But I can define my own names using an assignment statement.

An assignment statement has a name on the left-hand side.

It can be any name that you invent.

On the right-hand side, you could put any expression that you want.

And Python will evaluate that expression and bind it to the name.

So now radius is bound to the value 10.

2 times radius is 20.

I can use that name when I bind other names to other values.

And in fact, it's possible to bind multiple names to values in one single statement.

So if I say the area and circumference of a circle are pi times the radius times the radius and 2 times pi times the radius respectively, now I've defined the area and the circumference of a circle with radius 10.

Now, what happens is that these names are bound to these values.

They don't actually remember where those values came from.

So if I change radius to 20, and I check the area, the area is still 314, 10 times 10 times pi.

So these things are out of sync.

And that's how assignment works.

We are evaluating this expression to get a single value, 314.

And that's what gets bound to area.

It doesn't remember that area was once defined in terms of a radius.

Assignment statements can also be used to give names to functions.

Remember the max function?

It's built in.

Well, if I say f equals max, now f is the built-in max function.

What's exactly going on here?

F is a name.

Max is also a name.

And there's this thing called a function, which actually does stuff.

It takes the max of different arguments.

And that now has two names.

F and max are both names for the same function, which means I can write f 1, 2, 3 in order to apply this idea of maxing to the arguments 1, 2, and 3.

I can also change what the name max means.

Max is now 7.

I haven't broken the original max function, which is currently named f.

I've just made max mean something different.

So if I take f of 1, 2, and max, I'll get 7 because max is just the number 7.

Now, I haven't actually gotten into too much trouble.

If I want max to go back to being the max function, fortunately I have a name for that, f.

And so evaluating f gave me the built-in max function, which is now rebound to max.

And I can take max of 1, 2, and 3 and get the right answer again.

Last time I told you that there are function names for common infix operators such as plus and the time sign.

And they live in the operator module.

So if I write this, now I have access to the names add and mul.

So we know that one way to bind names to values is with an import statement.

But they have to be names that are built in.

A second way is with an assignment statement that lets us give a value to a new name or to change the value bound to a name.

Well, there's a third way to bind names to values.

And that's with a def statement.

A def statement lets us create our own functions.

So if I say def square x, indent the next line, and then write return the result of multiplying x and x together, I've now defined a new function called square.

And the square function takes in some number and squares it by multiplying it by itself.

I can square the result of adding together 3 and 4.

I can even square the result of squaring 3.

So I can use this function, which I created exactly as I would a built-in function.

I can even define a new function sum_squares, which sums the squares of x and y, by writing a return statement where I actually use the square function that I just defined.

Now, I could have put a plus sign here.

Or I could use the add function.

They both do the same thing.

If I write sum_squares 3 and 4, it will sum 9 and 16 together to get 25.

Now, remember when we had radius, which was 20, and area, which was not the area of a circle with radius 20 because these are out of sync.

How might we keep them in sync?

Well, a function can do that for us.

If instead of defining area like this, instead I say, area is a function which always returns pi times radius times radius, well, then area is a function which I can call by putting it in a call expression.

This is a call expression that just doesn't have any operands.

Now, area here when called is 1256.

What's that?

Well, that's 20 times 20 times pi.

If I change radius back to 10, and I call area again, area is updated.

It's now 314.

If I change radius to 1, then what's the area now?

Well, it's just pi.

So a function differs from just a name in that its return expression here gets re-evaluated every time it's called, meaning every time that it appears in the call expression.

So let's switch back to slides and just review what we've seen so far.

We're interested in expressions and how they evaluate to values.

The primitive expressions we've seen so far are the number or numeral, a name, and a string.

Strings I showed you last time.

They represent text.

We'll talk about them later in the course.

Call expressions look like this.

They have an operator, some parentheses, and then, separated by commas, some operands.

We just saw that you can have no operands at all and still have a valid call expression.

You can also have nested call expressions.

And operand can also be a call expression.

We're really interested now in how names work.

So let's go through a tricky case and see if you can figure out what happens.

What is the value of the final expression in the following sequence?

F equals min, f equals max, g comma h equals min comma max.

Then max equals g.

Then I compute the max of f of 2, g of h of 1 and 5.

G is also applied to 3.

And max is also applied to 4.

Think about it for a while.

The answer is either 1, 2, 3, 4, or 5.

You should pause the video now and try to work out what the real answer is.

Loading...

Loading video analysis...