WEBVTT

00:00:00.000 --> 00:00:01.968 align:middle line:90%
[SQUEAKING]

00:00:01.968 --> 00:00:03.936 align:middle line:90%
[RUSTLING]

00:00:03.936 --> 00:00:04.920 align:middle line:90%
[CLICKING]

00:00:04.920 --> 00:00:11.330 align:middle line:90%


00:00:11.330 --> 00:00:13.850 align:middle line:84%
ANA BELL: So today,
we're going to wrap up

00:00:13.850 --> 00:00:15.830 align:middle line:84%
talking about
functions by talking

00:00:15.830 --> 00:00:18.290 align:middle line:84%
about these things called
lambda functions as a way for us

00:00:18.290 --> 00:00:20.450 align:middle line:90%
to create anonymous functions.

00:00:20.450 --> 00:00:23.810 align:middle line:84%
And that will pretty much
finish our exploration

00:00:23.810 --> 00:00:27.110 align:middle line:90%
into creating functions.

00:00:27.110 --> 00:00:29.250 align:middle line:84%
And the last part
of the lecture,

00:00:29.250 --> 00:00:33.120 align:middle line:84%
we're going to introduce new
object types, tuples and lists.

00:00:33.120 --> 00:00:38.150 align:middle line:84%
So let's remember
what we did last time.

00:00:38.150 --> 00:00:39.780 align:middle line:90%
We ended with this example.

00:00:39.780 --> 00:00:41.600 align:middle line:90%
We created a function.

00:00:41.600 --> 00:00:42.950 align:middle line:90%
You guys wrote it for me.

00:00:42.950 --> 00:00:45.350 align:middle line:84%
And then we wrote it and
debugged it together.

00:00:45.350 --> 00:00:47.970 align:middle line:84%
But we created this
function called apply.

00:00:47.970 --> 00:00:50.120 align:middle line:84%
So what was interesting
about this function

00:00:50.120 --> 00:00:55.100 align:middle line:84%
is that one of its
parameters was a function

00:00:55.100 --> 00:00:56.870 align:middle line:84%
and the other one
was an integer.

00:00:56.870 --> 00:00:58.910 align:middle line:84%
And that seemed a
little strange at first,

00:00:58.910 --> 00:01:02.810 align:middle line:84%
but not when we realized
that functions in Python

00:01:02.810 --> 00:01:04.670 align:middle line:90%
are actually just objects.

00:01:04.670 --> 00:01:07.820 align:middle line:84%
And so they have a name, which
means that anywhere where

00:01:07.820 --> 00:01:11.720 align:middle line:84%
we use other kinds of objects,
like integers, floats,

00:01:11.720 --> 00:01:13.520 align:middle line:84%
we can use them as
parameters to functions,

00:01:13.520 --> 00:01:17.960 align:middle line:84%
we can use other functions
as parameters to functions

00:01:17.960 --> 00:01:18.810 align:middle line:90%
as well.

00:01:18.810 --> 00:01:21.770 align:middle line:84%
So here, criteria,
we had just used it

00:01:21.770 --> 00:01:25.430 align:middle line:84%
as a variable name assuming
that the type of criteria

00:01:25.430 --> 00:01:27.050 align:middle line:90%
is a function.

00:01:27.050 --> 00:01:29.630 align:middle line:84%
According to this
documentation, we

00:01:29.630 --> 00:01:32.870 align:middle line:84%
assume that it takes in a
number and returns a Boolean.

00:01:32.870 --> 00:01:34.910 align:middle line:84%
So we just wrote the
body of the function

00:01:34.910 --> 00:01:36.970 align:middle line:90%
assuming that that is true.

00:01:36.970 --> 00:01:42.030 align:middle line:84%
So right here, is where we used
this function named criteria.

00:01:42.030 --> 00:01:44.380 align:middle line:84%
We assumed that it
takes in an integer.

00:01:44.380 --> 00:01:47.490 align:middle line:84%
So we passed in the loop
variable I as an integer.

00:01:47.490 --> 00:01:49.380 align:middle line:84%
And we assumed it
returns a Boolean.

00:01:49.380 --> 00:01:52.950 align:middle line:84%
So we were able to use
the return of criteria(i)

00:01:52.950 --> 00:01:56.370 align:middle line:84%
just as a Boolean inside
as my condition for this if

00:01:56.370 --> 00:01:57.253 align:middle line:90%
statement.

00:01:57.253 --> 00:01:59.670 align:middle line:84%
So hopefully you got a chance
to look through this example

00:01:59.670 --> 00:02:01.360 align:middle line:90%
from last lecture.

00:02:01.360 --> 00:02:03.663 align:middle line:84%
So that's the definition
of this function

00:02:03.663 --> 00:02:05.580 align:middle line:84%
that takes in another
function as a parameter.

00:02:05.580 --> 00:02:08.889 align:middle line:84%
And then the way we use
the function is down here.

00:02:08.889 --> 00:02:12.390 align:middle line:84%
So "apply" is us making
our function call.

00:02:12.390 --> 00:02:15.000 align:middle line:84%
And then, the first parameter
is the name of a function.

00:02:15.000 --> 00:02:17.020 align:middle line:84%
And the second
parameter is an integer.

00:02:17.020 --> 00:02:19.110 align:middle line:84%
So the name of the
function we're running

00:02:19.110 --> 00:02:23.940 align:middle line:84%
is this object that
we defined over here.

00:02:23.940 --> 00:02:26.750 align:middle line:90%
Hopefully this is just review.

00:02:26.750 --> 00:02:29.810 align:middle line:84%
Now, what's interesting
about this example

00:02:29.810 --> 00:02:34.025 align:middle line:84%
is that this is_even
function is pretty simple.

00:02:34.025 --> 00:02:35.960 align:middle line:90%
It's basically a one-liner.

00:02:35.960 --> 00:02:39.470 align:middle line:84%
It doesn't do any computations
inside the function body.

00:02:39.470 --> 00:02:43.760 align:middle line:84%
It basically just takes
in a value, an input,

00:02:43.760 --> 00:02:46.700 align:middle line:90%
and returns something.

00:02:46.700 --> 00:02:50.860 align:middle line:84%
And so we didn't really
need to create a function,

00:02:50.860 --> 00:02:53.140 align:middle line:84%
a full-fledged function
definition just

00:02:53.140 --> 00:02:55.180 align:middle line:90%
to do this really simple task.

00:02:55.180 --> 00:02:58.030 align:middle line:84%
And in fact, that's what
a Lambda function is.

00:02:58.030 --> 00:03:01.510 align:middle line:84%
It's basically a way for us to
create an anonymous function,

00:03:01.510 --> 00:03:04.450 align:middle line:84%
a function that does
something really simple,

00:03:04.450 --> 00:03:07.420 align:middle line:84%
but we just don't
give it a name.

00:03:07.420 --> 00:03:10.000 align:middle line:84%
And so here is the
function that we

00:03:10.000 --> 00:03:13.480 align:middle line:84%
created with an actual
definition up here.

00:03:13.480 --> 00:03:16.150 align:middle line:84%
We can create an equivalent
anonymous function

00:03:16.150 --> 00:03:17.660 align:middle line:90%
that looks like this.

00:03:17.660 --> 00:03:20.290 align:middle line:84%
So this is a much more
concise way for us

00:03:20.290 --> 00:03:23.200 align:middle line:84%
to create a really simple
function that we only

00:03:23.200 --> 00:03:24.980 align:middle line:90%
need to use one time.

00:03:24.980 --> 00:03:26.740 align:middle line:90%
So here is--

00:03:26.740 --> 00:03:29.230 align:middle line:84%
I'm going to just
map out, one by one,

00:03:29.230 --> 00:03:31.520 align:middle line:84%
the important pieces
of the Lambda function.

00:03:31.520 --> 00:03:36.695 align:middle line:84%
So the Lambda keyword starts
out the anonymous function.

00:03:36.695 --> 00:03:38.320 align:middle line:84%
And it tells Python
that we're creating

00:03:38.320 --> 00:03:39.770 align:middle line:90%
this anonymous function.

00:03:39.770 --> 00:03:41.785 align:middle line:84%
So lambda is not the
name of the function,

00:03:41.785 --> 00:03:44.410 align:middle line:84%
it just tells Python we're going
to create this function in one

00:03:44.410 --> 00:03:47.240 align:middle line:90%
line that is nameless.

00:03:47.240 --> 00:03:49.760 align:middle line:84%
x is going to be any
parameters that we

00:03:49.760 --> 00:03:51.120 align:middle line:90%
expect this function to take.

00:03:51.120 --> 00:03:53.870 align:middle line:84%
So if we have more than one, we
just separate them with commas.

00:03:53.870 --> 00:03:55.730 align:middle line:90%
Colon is, again, the same.

00:03:55.730 --> 00:03:57.770 align:middle line:84%
And then, the body
of the function,

00:03:57.770 --> 00:04:01.640 align:middle line:84%
if you can write it in one liner
that's not too complicated,

00:04:01.640 --> 00:04:03.480 align:middle line:84%
you can make a Lambda
function out of it.

00:04:03.480 --> 00:04:05.690 align:middle line:84%
So here, notice,
we don't actually

00:04:05.690 --> 00:04:08.600 align:middle line:84%
have a return keyword when we're
creating the Lambda function.

00:04:08.600 --> 00:04:11.090 align:middle line:84%
We're just doing the
operation that we

00:04:11.090 --> 00:04:14.250 align:middle line:90%
wish to return the value from.

00:04:14.250 --> 00:04:18.720 align:middle line:84%
So the x%2=0 is basically the
body of my Lambda function over

00:04:18.720 --> 00:04:20.040 align:middle line:90%
here.

00:04:20.040 --> 00:04:22.079 align:middle line:84%
So the key thing
about Lambda functions

00:04:22.079 --> 00:04:24.960 align:middle line:84%
is that it allows you to
create a really quick Function

00:04:24.960 --> 00:04:27.790 align:middle line:84%
object that you basically
want to use only one time.

00:04:27.790 --> 00:04:30.100 align:middle line:84%
And so we're not
giving it a name.

00:04:30.100 --> 00:04:32.260 align:middle line:90%
So let's look at the code.

00:04:32.260 --> 00:04:35.700 align:middle line:84%
So here is my Apply function
that we've seen before.

00:04:35.700 --> 00:04:37.260 align:middle line:90%
Here is us--

00:04:37.260 --> 00:04:38.550 align:middle line:90%
I showed you this last time.

00:04:38.550 --> 00:04:41.640 align:middle line:84%
I created another definition
for another simple function

00:04:41.640 --> 00:04:44.010 align:middle line:84%
that takes in an integer
and returns a Boolean.

00:04:44.010 --> 00:04:46.170 align:middle line:84%
In this case, this
function just tells me

00:04:46.170 --> 00:04:48.900 align:middle line:84%
whether that input
is equal to 5.

00:04:48.900 --> 00:04:52.410 align:middle line:84%
And this is where we
left off last time we ran

00:04:52.410 --> 00:04:55.710 align:middle line:90%
apply with this is_5 function.

00:04:55.710 --> 00:04:58.980 align:middle line:84%
So that prints apply
with is_5 is 1.

00:04:58.980 --> 00:05:01.620 align:middle line:84%
There's only one
integer between 0 and 10

00:05:01.620 --> 00:05:06.640 align:middle line:84%
where applying
this returns true.

00:05:06.640 --> 00:05:08.800 align:middle line:84%
Now, with an anonymous
function, just

00:05:08.800 --> 00:05:12.880 align:middle line:84%
to show you how we would write
a Lambda function for this is_5,

00:05:12.880 --> 00:05:14.047 align:middle line:90%
it would look like this.

00:05:14.047 --> 00:05:16.630 align:middle line:84%
So again, we tell Python we're
creating an anonymous function.

00:05:16.630 --> 00:05:20.500 align:middle line:84%
It has just the one input
x, colon, no return,

00:05:20.500 --> 00:05:22.780 align:middle line:84%
and just the body of the
function is going to be

00:05:22.780 --> 00:05:27.320 align:middle line:84%
the thing that we would
like to return, x==5.

00:05:27.320 --> 00:05:30.980 align:middle line:84%
So again, this notice, we're not
actually passing in the name.

00:05:30.980 --> 00:05:33.350 align:middle line:84%
There is no name for
this anonymous function.

00:05:33.350 --> 00:05:35.420 align:middle line:84%
But it works in
the exact same way

00:05:35.420 --> 00:05:38.450 align:middle line:84%
as if we had created
this function over here.

00:05:38.450 --> 00:05:42.350 align:middle line:90%


00:05:42.350 --> 00:05:43.760 align:middle line:90%
And I can run it again.

00:05:43.760 --> 00:05:47.540 align:middle line:84%
And you can see "apply with"
the function name is 1.

00:05:47.540 --> 00:05:50.150 align:middle line:84%
And obviously, apply with
this anonymous function also

00:05:50.150 --> 00:05:52.410 align:middle line:90%
returns 1.

00:05:52.410 --> 00:05:54.810 align:middle line:84%
So just to bring
the point home, I

00:05:54.810 --> 00:05:57.450 align:middle line:84%
want to show you one
other way to think

00:05:57.450 --> 00:05:59.710 align:middle line:90%
of these anonymous functions.

00:05:59.710 --> 00:06:07.140 align:middle line:84%
So here is me calling my is_even
function with a parameter 8.

00:06:07.140 --> 00:06:12.240 align:middle line:84%
Now, in order for me to
actually run this line here,

00:06:12.240 --> 00:06:15.180 align:middle line:84%
I had to have the function
definition way up here.

00:06:15.180 --> 00:06:17.280 align:middle line:84%
But again, it's a
really simple function.

00:06:17.280 --> 00:06:19.320 align:middle line:84%
If I only want to
use it one time,

00:06:19.320 --> 00:06:21.600 align:middle line:90%
I can create a Lambda function.

00:06:21.600 --> 00:06:28.260 align:middle line:84%
And this, over here, is
equivalent to this function

00:06:28.260 --> 00:06:31.710 align:middle line:84%
definition and a function
definition over here.

00:06:31.710 --> 00:06:36.270 align:middle line:90%


00:06:36.270 --> 00:06:39.510 align:middle line:84%
So you can think of this
line over here, so the part

00:06:39.510 --> 00:06:42.600 align:middle line:84%
that I've highlighted, as
creating the definition

00:06:42.600 --> 00:06:45.940 align:middle line:84%
all in one line, not
giving it a name.

00:06:45.940 --> 00:06:48.150 align:middle line:84%
And then, the
parentheses here is

00:06:48.150 --> 00:06:52.080 align:middle line:84%
us calling those lines of code
for that function definition

00:06:52.080 --> 00:06:55.320 align:middle line:90%
with that parameter 8.

00:06:55.320 --> 00:06:57.570 align:middle line:84%
And so the usefulness
of Lambda functions

00:06:57.570 --> 00:07:01.800 align:middle line:84%
is when you want to create these
really quick functions that you

00:07:01.800 --> 00:07:02.790 align:middle line:90%
don't want to reuse.

00:07:02.790 --> 00:07:07.110 align:middle line:84%
Obviously, if we wanted
to reuse the functionality

00:07:07.110 --> 00:07:11.290 align:middle line:84%
of the is_even, but we created
it using a Lambda function,

00:07:11.290 --> 00:07:13.800 align:middle line:84%
we would have to
basically copy this line

00:07:13.800 --> 00:07:15.870 align:middle line:90%
and paste it all over again.

00:07:15.870 --> 00:07:19.530 align:middle line:84%
So we'd have to take this,
copy it, paste it, and give it

00:07:19.530 --> 00:07:24.690 align:middle line:84%
another input because this
Lambda function does not

00:07:24.690 --> 00:07:27.550 align:middle line:84%
actually create it in
memory with a name.

00:07:27.550 --> 00:07:31.515 align:middle line:84%
There's no way for us to access
the body because it's nameless.

00:07:31.515 --> 00:07:34.140 align:middle line:90%


00:07:34.140 --> 00:07:42.970 align:middle line:84%
OK, so just to finish how
we call lambda functions,

00:07:42.970 --> 00:07:47.500 align:middle line:84%
so basically when we called
the apply (is_even , 10),

00:07:47.500 --> 00:07:52.030 align:middle line:84%
the equivalent to calling that
function name but with a Lambda

00:07:52.030 --> 00:07:55.930 align:middle line:84%
function is basically putting
in the entire body of the Lambda

00:07:55.930 --> 00:07:59.240 align:middle line:84%
function inside this
other function call.

00:07:59.240 --> 00:08:03.362 align:middle line:84%
So here, we're both defining
and then telling Python

00:08:03.362 --> 00:08:04.945 align:middle line:84%
that this is my input
to the function.

00:08:04.945 --> 00:08:08.490 align:middle line:90%


00:08:08.490 --> 00:08:12.130 align:middle line:84%
OK, so I know this
is a You Try It.

00:08:12.130 --> 00:08:13.980 align:middle line:84%
But I thought that
we would actually

00:08:13.980 --> 00:08:18.550 align:middle line:84%
run through it together step
by step on the next few slides.

00:08:18.550 --> 00:08:20.940 align:middle line:84%
So let's try to understand
what this is doing.

00:08:20.940 --> 00:08:23.940 align:middle line:84%
I've got a function
definition named do_twice.

00:08:23.940 --> 00:08:27.640 align:middle line:84%
It takes in one
input, another input.

00:08:27.640 --> 00:08:30.900 align:middle line:84%
But if we look at the
body here, this fn--

00:08:30.900 --> 00:08:33.720 align:middle line:84%
that's the input-- is
actually being called

00:08:33.720 --> 00:08:37.695 align:middle line:90%
a function inside the body.

00:08:37.695 --> 00:08:40.590 align:middle line:84%
So we can immediately
tell that fn

00:08:40.590 --> 00:08:43.559 align:middle line:84%
is going to be a
function when we actually

00:08:43.559 --> 00:08:45.660 align:middle line:90%
make the call to do_twice.

00:08:45.660 --> 00:08:49.170 align:middle line:84%
And indeed, when we make the
call to do_twice down here,

00:08:49.170 --> 00:08:54.000 align:middle line:84%
n is mapped to 3 and the
second parameter, fn,

00:08:54.000 --> 00:08:56.565 align:middle line:84%
is mapped to this
anonymous Lambda function.

00:08:56.565 --> 00:08:59.430 align:middle line:90%


00:08:59.430 --> 00:09:02.430 align:middle line:84%
So let's step through
one a little by little

00:09:02.430 --> 00:09:04.920 align:middle line:84%
in the same manner that we
learned last lecture, so

00:09:04.920 --> 00:09:07.770 align:middle line:84%
creating actual environments
whenever we see a Function

00:09:07.770 --> 00:09:10.890 align:middle line:84%
call, mapping parameters--
actual parameters

00:09:10.890 --> 00:09:13.500 align:middle line:84%
to formal parameters,
and following through

00:09:13.500 --> 00:09:19.230 align:middle line:84%
on what exactly happens
within each function body.

00:09:19.230 --> 00:09:22.130 align:middle line:84%
So when we first make the
Function call, right--

00:09:22.130 --> 00:09:24.020 align:middle line:84%
or sorry, when we
first run this program,

00:09:24.020 --> 00:09:28.220 align:middle line:84%
if it has these three
lines of code inside it,

00:09:28.220 --> 00:09:30.530 align:middle line:84%
Python creates our
global environment.

00:09:30.530 --> 00:09:33.620 align:middle line:84%
Inside the environment, we've
got one Function definition

00:09:33.620 --> 00:09:34.170 align:middle line:90%
here.

00:09:34.170 --> 00:09:37.300 align:middle line:84%
So this is going to be
this Function object.

00:09:37.300 --> 00:09:41.690 align:middle line:84%
And then I've got the thing
that actually kicks off

00:09:41.690 --> 00:09:44.170 align:middle line:90%
my Function calls, my program.

00:09:44.170 --> 00:09:46.240 align:middle line:84%
So I've got a Print
statement that will print

00:09:46.240 --> 00:09:49.020 align:middle line:90%
the result of doing something.

00:09:49.020 --> 00:09:51.200 align:middle line:84%
So the first thing
I can see here

00:09:51.200 --> 00:09:53.970 align:middle line:84%
is that I've got a
function call to do_twice.

00:09:53.970 --> 00:09:55.490 align:middle line:90%
So I'm going left to right.

00:09:55.490 --> 00:09:58.010 align:middle line:84%
The first thing I do when
I have a Function call

00:09:58.010 --> 00:10:00.700 align:middle line:90%
is I create a new environment.

00:10:00.700 --> 00:10:03.400 align:middle line:84%
Inside this environment
of do_twice,

00:10:03.400 --> 00:10:05.380 align:middle line:90%
I have to see what it takes in.

00:10:05.380 --> 00:10:07.090 align:middle line:90%
What are its formal parameters?

00:10:07.090 --> 00:10:10.360 align:middle line:84%
There's one called
n and one called fn.

00:10:10.360 --> 00:10:13.450 align:middle line:84%
So there's one parameter
n and the other one, fn.

00:10:13.450 --> 00:10:18.640 align:middle line:84%
And now, I basically map, one
by one, the formal parameter

00:10:18.640 --> 00:10:20.170 align:middle line:90%
to the actual parameter.

00:10:20.170 --> 00:10:22.690 align:middle line:84%
So the n gets mapped
to the 3 because that's

00:10:22.690 --> 00:10:24.250 align:middle line:90%
the first parameter of do_twice.

00:10:24.250 --> 00:10:28.780 align:middle line:84%
And the fn gets mapped to
this Function object here.

00:10:28.780 --> 00:10:31.495 align:middle line:84%
So the fn gets mapped to
this Lambda function here.

00:10:31.495 --> 00:10:34.720 align:middle line:90%


00:10:34.720 --> 00:10:36.100 align:middle line:90%
OK, that's exactly what I said.

00:10:36.100 --> 00:10:37.540 align:middle line:90%
So we've done the mapping.

00:10:37.540 --> 00:10:39.580 align:middle line:84%
And now that we've
done the mapping,

00:10:39.580 --> 00:10:41.560 align:middle line:90%
we can do the body of do_twice.

00:10:41.560 --> 00:10:44.110 align:middle line:84%
So the body of
do_twice says "return."

00:10:44.110 --> 00:10:47.980 align:middle line:84%
And then I have to
replace everywhere I

00:10:47.980 --> 00:10:52.070 align:middle line:84%
see "fn" with this
Lambda function

00:10:52.070 --> 00:10:57.620 align:middle line:84%
and everywhere I
see "n" with this 3.

00:10:57.620 --> 00:11:01.670 align:middle line:84%
Well, fn is going to
be a Function call.

00:11:01.670 --> 00:11:03.590 align:middle line:84%
Whenever we see a
function call, we

00:11:03.590 --> 00:11:05.270 align:middle line:90%
need to create a Function scope.

00:11:05.270 --> 00:11:09.080 align:middle line:84%
So before I can do the return,
before this do_twice can

00:11:09.080 --> 00:11:13.410 align:middle line:84%
terminate, can return its
value, it sees a Function call.

00:11:13.410 --> 00:11:15.140 align:middle line:84%
So when there's a
Function call, we

00:11:15.140 --> 00:11:19.350 align:middle line:84%
need to create another
scope, another environment.

00:11:19.350 --> 00:11:24.150 align:middle line:84%
This environment belongs to the
function call of lambda x colon

00:11:24.150 --> 00:11:26.220 align:middle line:90%
x squared.

00:11:26.220 --> 00:11:28.680 align:middle line:84%
Now, this function, of
course, doesn't have a name.

00:11:28.680 --> 00:11:31.920 align:middle line:84%
Normally I would say
this is the f environment

00:11:31.920 --> 00:11:34.530 align:middle line:84%
or this is the g environment
or the is_even environment.

00:11:34.530 --> 00:11:36.250 align:middle line:84%
But there's no
name for this one.

00:11:36.250 --> 00:11:40.910 align:middle line:84%
So I'm just going to write up
here the body of that function.

00:11:40.910 --> 00:11:43.070 align:middle line:84%
All right, well,
in this function,

00:11:43.070 --> 00:11:46.670 align:middle line:84%
again, following the rules
one by one, what we need to do

00:11:46.670 --> 00:11:51.030 align:middle line:84%
is figure out what are the
parameters of this function.

00:11:51.030 --> 00:11:53.860 align:middle line:90%
Well, there's one called x.

00:11:53.860 --> 00:11:56.140 align:middle line:90%
So here is my parameter x.

00:11:56.140 --> 00:12:00.130 align:middle line:84%
And then I need to figure
out, what does this map to.

00:12:00.130 --> 00:12:05.900 align:middle line:84%
Well, what it maps to is
the parameter inside it.

00:12:05.900 --> 00:12:08.180 align:middle line:84%
But the parameter
inside it is fn(n).

00:12:08.180 --> 00:12:11.500 align:middle line:90%


00:12:11.500 --> 00:12:14.710 align:middle line:84%
Do we have a return
value for this yet?

00:12:14.710 --> 00:12:18.650 align:middle line:84%
No, because this is
another function call.

00:12:18.650 --> 00:12:22.750 align:middle line:84%
So what ends up happening
is this environment

00:12:22.750 --> 00:12:26.560 align:middle line:84%
gets put on hold, as well,
because we can't figure out

00:12:26.560 --> 00:12:29.470 align:middle line:84%
what parameter this
Lambda function takes in,

00:12:29.470 --> 00:12:30.920 align:middle line:90%
what is its value.

00:12:30.920 --> 00:12:35.820 align:middle line:84%
So we create another
scope, another environment.

00:12:35.820 --> 00:12:37.950 align:middle line:84%
And in this particular
case, this one

00:12:37.950 --> 00:12:46.070 align:middle line:84%
is going to belong to this
inside bit here fn(n).

00:12:46.070 --> 00:12:49.370 align:middle line:84%
So this lambda x
x squared is going

00:12:49.370 --> 00:12:52.590 align:middle line:84%
to be the exact same function
again, being called again.

00:12:52.590 --> 00:12:54.320 align:middle line:84%
And in this particular
environment,

00:12:54.320 --> 00:12:57.390 align:middle line:90%
we need to map x to its input.

00:12:57.390 --> 00:13:03.970 align:middle line:84%
So the input to this lambda
x x squared is going to be n.

00:13:03.970 --> 00:13:06.730 align:middle line:84%
Well, this environment
doesn't know about n.

00:13:06.730 --> 00:13:08.410 align:middle line:90%
So we pop up one level.

00:13:08.410 --> 00:13:10.180 align:middle line:90%
This environment knows about n.

00:13:10.180 --> 00:13:10.900 align:middle line:90%
It's 3.

00:13:10.900 --> 00:13:18.340 align:middle line:84%
So it passes that value along
down to this Lambda call.

00:13:18.340 --> 00:13:24.160 align:middle line:84%
So now that this inner
highlight yellow over here

00:13:24.160 --> 00:13:27.250 align:middle line:84%
knows what it needs to do,
it needs to take in this x

00:13:27.250 --> 00:13:28.700 align:middle line:90%
and return x squared.

00:13:28.700 --> 00:13:33.760 align:middle line:84%
So it calculates 9 and then
returns 9 to whoever called it.

00:13:33.760 --> 00:13:42.390 align:middle line:84%
That 9 gets replaced now as
the input to this outer fn.

00:13:42.390 --> 00:13:44.700 align:middle line:84%
So just to show you
exactly what gets replaced,

00:13:44.700 --> 00:13:49.810 align:middle line:84%
that entire Function call
there gets replaced with 9.

00:13:49.810 --> 00:13:52.090 align:middle line:84%
All right, as soon as
we've done the return,

00:13:52.090 --> 00:13:54.530 align:middle line:90%
that environment goes away.

00:13:54.530 --> 00:13:58.120 align:middle line:84%
And at this point,
this call to lambda

00:13:58.120 --> 00:14:00.400 align:middle line:84%
x x squared can terminate
as well because it

00:14:00.400 --> 00:14:05.180 align:middle line:84%
takes in the number 9
and it returns 9 squared.

00:14:05.180 --> 00:14:07.340 align:middle line:90%
So this one returns 81.

00:14:07.340 --> 00:14:11.590 align:middle line:84%
So this entire
Function call is 81.

00:14:11.590 --> 00:14:15.040 align:middle line:84%
And as soon as it returns,
that environment goes away.

00:14:15.040 --> 00:14:20.500 align:middle line:84%
And now do_twice can finally
finish its job and return 81.

00:14:20.500 --> 00:14:23.560 align:middle line:84%
It just basically passes
this value along back up.

00:14:23.560 --> 00:14:25.590 align:middle line:90%
So that returns 81.

00:14:25.590 --> 00:14:31.260 align:middle line:84%
So this entire do_twice
call is going to be 81.

00:14:31.260 --> 00:14:32.520 align:middle line:90%
AUDIENCE: Why does lambda--

00:14:32.520 --> 00:14:34.980 align:middle line:84%
why were there
two of them again?

00:14:34.980 --> 00:14:38.520 align:middle line:84%
ANA BELL: There were two of
them because this outer fn

00:14:38.520 --> 00:14:40.978 align:middle line:90%
calls an inner fn, so we--

00:14:40.978 --> 00:14:41.520 align:middle line:90%
AUDIENCE: Oh.

00:14:41.520 --> 00:14:42.500 align:middle line:90%
ANA BELL: Yeah, OK.

00:14:42.500 --> 00:14:45.680 align:middle line:90%


00:14:45.680 --> 00:14:49.160 align:middle line:84%
OK, so that wraps up our
discussion on functions.

00:14:49.160 --> 00:14:52.610 align:middle line:84%
And there's a couple exercises
in the Python file associated

00:14:52.610 --> 00:14:54.830 align:middle line:84%
with this lecture
with Lambda functions

00:14:54.830 --> 00:14:58.225 align:middle line:84%
just so you can give
it a try with those.

00:14:58.225 --> 00:14:58.850 align:middle line:90%
Yeah, question.

00:14:58.850 --> 00:15:01.490 align:middle line:84%
AUDIENCE: With lambda functions,
so we use print or apply,

00:15:01.490 --> 00:15:05.470 align:middle line:90%
because if we [INAUDIBLE]?

00:15:05.470 --> 00:15:09.970 align:middle line:84%
ANA BELL: Well, apply was
just a function that I wrote.

00:15:09.970 --> 00:15:12.010 align:middle line:84%
So in this new
example, I was just

00:15:12.010 --> 00:15:14.628 align:middle line:84%
printing the result of
calling that function.

00:15:14.628 --> 00:15:15.170 align:middle line:90%
AUDIENCE: OK.

00:15:15.170 --> 00:15:17.260 align:middle line:90%
ANA BELL: Yeah.

00:15:17.260 --> 00:15:19.510 align:middle line:84%
So again, this kind
of trace of what

00:15:19.510 --> 00:15:22.600 align:middle line:84%
happens throughout the program
is really, really useful.

00:15:22.600 --> 00:15:26.320 align:middle line:84%
So if you have some time
to try to get that down,

00:15:26.320 --> 00:15:27.880 align:middle line:84%
it'll be very,
very helpful as you

00:15:27.880 --> 00:15:31.370 align:middle line:90%
trace through some programs.

00:15:31.370 --> 00:15:35.930 align:middle line:84%
OK, so that ends our
discussion on functions.

00:15:35.930 --> 00:15:37.940 align:middle line:84%
And really, the
only syntax we've

00:15:37.940 --> 00:15:39.920 align:middle line:84%
introduced in the
past couple lectures

00:15:39.920 --> 00:15:42.050 align:middle line:84%
were just about how to
wrap code we've already

00:15:42.050 --> 00:15:44.030 align:middle line:90%
been using in a function.

00:15:44.030 --> 00:15:45.290 align:middle line:90%
So not much new syntax.

00:15:45.290 --> 00:15:50.030 align:middle line:84%
But today, we're going to
introduce some new syntax along

00:15:50.030 --> 00:15:52.320 align:middle line:84%
with the introduction
of two new data types.

00:15:52.320 --> 00:15:53.720 align:middle line:90%
One is called a tuple.

00:15:53.720 --> 00:15:56.370 align:middle line:84%
And the other one
is called a list.

00:15:56.370 --> 00:15:59.090 align:middle line:84%
So what are the data
types we've seen so far?

00:15:59.090 --> 00:16:01.310 align:middle line:90%
We've seen integers, floats--

00:16:01.310 --> 00:16:02.450 align:middle line:90%
basically numbers.

00:16:02.450 --> 00:16:04.580 align:middle line:84%
We've seen Booleans
as truth values.

00:16:04.580 --> 00:16:08.360 align:middle line:84%
We've seen this none type,
type which has one value none.

00:16:08.360 --> 00:16:11.840 align:middle line:84%
And we actually also saw
the string data type.

00:16:11.840 --> 00:16:13.820 align:middle line:84%
We could think of
the string data type

00:16:13.820 --> 00:16:18.320 align:middle line:84%
as a compound data type, like a
sequence of single characters.

00:16:18.320 --> 00:16:21.980 align:middle line:84%
And in fact, we were using
that string in that way

00:16:21.980 --> 00:16:24.080 align:middle line:84%
because we were able to
index into the string

00:16:24.080 --> 00:16:27.050 align:middle line:84%
to grab the
character at index 0,

00:16:27.050 --> 00:16:31.000 align:middle line:84%
sort of slice the substring to
get the length of the string.

00:16:31.000 --> 00:16:33.460 align:middle line:84%
Today, we're going to introduce
two more compound data

00:16:33.460 --> 00:16:35.890 align:middle line:84%
types, so these things called
tuples and these things

00:16:35.890 --> 00:16:36.640 align:middle line:90%
called lists.

00:16:36.640 --> 00:16:40.180 align:middle line:84%
And throughout the
lecture, you should really

00:16:40.180 --> 00:16:45.340 align:middle line:84%
think about how it's very,
very similar to the strings

00:16:45.340 --> 00:16:46.820 align:middle line:90%
that we've already seen.

00:16:46.820 --> 00:16:51.070 align:middle line:84%
So a lot of the operations,
I'm actually going to skip.

00:16:51.070 --> 00:16:56.860 align:middle line:84%
Aside from the syntax of how
we denote a tuple or a list,

00:16:56.860 --> 00:16:59.350 align:middle line:84%
really, the operations that
we do with tuples and lists

00:16:59.350 --> 00:17:01.420 align:middle line:84%
are going to be exactly
the same as the ones

00:17:01.420 --> 00:17:02.980 align:middle line:90%
that we did with strings.

00:17:02.980 --> 00:17:06.252 align:middle line:84%
So if you understand indexing
and slicing and getting

00:17:06.252 --> 00:17:07.960 align:middle line:84%
the length of the
string, all that stuff,

00:17:07.960 --> 00:17:12.150 align:middle line:84%
you'll understand how to do
that for tuples and lists.

00:17:12.150 --> 00:17:14.190 align:middle line:84%
All right, so
tuples are indexable

00:17:14.190 --> 00:17:16.020 align:middle line:90%
ordered sequences of objects.

00:17:16.020 --> 00:17:17.490 align:middle line:90%
That's kind of a lot.

00:17:17.490 --> 00:17:19.599 align:middle line:90%
So we can break that down.

00:17:19.599 --> 00:17:21.599 align:middle line:84%
So first of all, it's
a sequence of objects,

00:17:21.599 --> 00:17:26.160 align:middle line:84%
just like a string was a
sequence of single characters.

00:17:26.160 --> 00:17:29.730 align:middle line:84%
A tuple is going to be a
sequence of not just characters

00:17:29.730 --> 00:17:32.190 align:middle line:90%
but any kind of object.

00:17:32.190 --> 00:17:34.500 align:middle line:84%
Ordered sequence
means that there will

00:17:34.500 --> 00:17:36.580 align:middle line:90%
be an order to this sequence.

00:17:36.580 --> 00:17:39.540 align:middle line:84%
So there's going to be an
object at the first position

00:17:39.540 --> 00:17:42.320 align:middle line:84%
in my tuple, an object at the
second position in my tuple,

00:17:42.320 --> 00:17:44.070 align:middle line:84%
and so on, just like
there was a character

00:17:44.070 --> 00:17:46.403 align:middle line:84%
at the first position, character
at the second position,

00:17:46.403 --> 00:17:47.010 align:middle line:90%
and so on.

00:17:47.010 --> 00:17:50.100 align:middle line:84%
And indexable ordered
sequence means that we

00:17:50.100 --> 00:17:52.210 align:middle line:90%
can index into this object.

00:17:52.210 --> 00:17:54.900 align:middle line:84%
So we can grab the
element at index 0,

00:17:54.900 --> 00:17:59.240 align:middle line:84%
grab the element index
1, and so on and so on.

00:17:59.240 --> 00:18:02.980 align:middle line:84%
So how do we create
these tuples?

00:18:02.980 --> 00:18:05.320 align:middle line:84%
I should note that some
people call them "tup-ples"

00:18:05.320 --> 00:18:09.230 align:middle line:84%
because they're just kind of
like an n-tuple kind of thing.

00:18:09.230 --> 00:18:11.260 align:middle line:84%
So you can call them
"too-ples" or "tup-ples,"

00:18:11.260 --> 00:18:13.010 align:middle line:90%
however you'd like.

00:18:13.010 --> 00:18:17.060 align:middle line:84%
All right, so how do we
create these tuple objects?

00:18:17.060 --> 00:18:22.160 align:middle line:84%
Well, we can create a tuple
object that's empty using just

00:18:22.160 --> 00:18:24.050 align:middle line:90%
open and closed parentheses.

00:18:24.050 --> 00:18:28.310 align:middle line:84%
So we could create strings
using just the open and closed

00:18:28.310 --> 00:18:29.480 align:middle line:90%
quotation marks.

00:18:29.480 --> 00:18:31.310 align:middle line:84%
We create an empty
tuple by doing

00:18:31.310 --> 00:18:33.150 align:middle line:90%
open and closed parentheses.

00:18:33.150 --> 00:18:36.050 align:middle line:84%
Now, this is different
than functions.

00:18:36.050 --> 00:18:37.580 align:middle line:90%
This is a little bit similar.

00:18:37.580 --> 00:18:39.950 align:middle line:84%
It might be a bit confusing
because we use parentheses

00:18:39.950 --> 00:18:41.480 align:middle line:90%
to make Function calls.

00:18:41.480 --> 00:18:44.630 align:middle line:84%
But notice, it's just the
parentheses by themselves.

00:18:44.630 --> 00:18:46.550 align:middle line:84%
There's no function
name, nothing

00:18:46.550 --> 00:18:48.240 align:middle line:90%
preceding the parentheses.

00:18:48.240 --> 00:18:50.930 align:middle line:84%
So to Python, it's not
going to be confusing

00:18:50.930 --> 00:18:53.320 align:middle line:90%
when you just do this.

00:18:53.320 --> 00:18:56.050 align:middle line:84%
You can create a tuple
with one element in it

00:18:56.050 --> 00:19:00.220 align:middle line:84%
by putting open closed
parentheses, that element

00:19:00.220 --> 00:19:01.780 align:middle line:84%
that you want to
add to your tuple,

00:19:01.780 --> 00:19:04.320 align:middle line:90%
and then a comma right after it.

00:19:04.320 --> 00:19:10.490 align:middle line:84%
Now, the comma is
there to differentiate

00:19:10.490 --> 00:19:16.310 align:middle line:84%
a tuple with one element from
using parentheses as precedence

00:19:16.310 --> 00:19:17.840 align:middle line:90%
over an operation.

00:19:17.840 --> 00:19:22.850 align:middle line:84%
So just as an example, if
I create a is equal to 5,

00:19:22.850 --> 00:19:26.630 align:middle line:84%
like this, I'm using
parentheses around an integer.

00:19:26.630 --> 00:19:30.410 align:middle line:84%
But the type of a
is still an integer.

00:19:30.410 --> 00:19:32.690 align:middle line:84%
I'm basically just using
the parentheses to say,

00:19:32.690 --> 00:19:37.730 align:middle line:84%
I want to do this 5 before
doing anything else, which

00:19:37.730 --> 00:19:39.140 align:middle line:90%
is a little strange to do.

00:19:39.140 --> 00:19:42.220 align:middle line:90%
And write the value of a is 5.

00:19:42.220 --> 00:19:46.900 align:middle line:84%
But if I do b is equal
to the tuple 4 comma,

00:19:46.900 --> 00:19:50.590 align:middle line:84%
this tells Python that this
is now a sequence of objects,

00:19:50.590 --> 00:19:53.420 align:middle line:84%
but there's just one
object in my sequence.

00:19:53.420 --> 00:19:57.595 align:middle line:84%
So the type of b is a
tuple, not an integer.

00:19:57.595 --> 00:20:00.710 align:middle line:90%


00:20:00.710 --> 00:20:03.335 align:middle line:84%
And if I ask what
b is, you can see

00:20:03.335 --> 00:20:07.950 align:middle line:90%
it's 4 comma in parentheses.

00:20:07.950 --> 00:20:09.980 align:middle line:84%
It's a tuple with
one object in it.

00:20:09.980 --> 00:20:13.420 align:middle line:90%


00:20:13.420 --> 00:20:16.600 align:middle line:84%
OK, so to create a tuple
with many objects in it,

00:20:16.600 --> 00:20:19.210 align:middle line:84%
we basically put in
parentheses all the objects

00:20:19.210 --> 00:20:21.920 align:middle line:84%
I want to add in my tuple
separated by commas.

00:20:21.920 --> 00:20:24.640 align:middle line:84%
So here, I've got
my first element

00:20:24.640 --> 00:20:27.220 align:middle line:84%
in my tuple, integer
2, second element

00:20:27.220 --> 00:20:29.920 align:middle line:84%
in the tuple, the string
mit, and the third element

00:20:29.920 --> 00:20:32.110 align:middle line:90%
in my tuple being the integer 3.

00:20:32.110 --> 00:20:35.830 align:middle line:84%
And notice, we can mix and match
now objects of different types

00:20:35.830 --> 00:20:37.820 align:middle line:90%
within my tuple object.

00:20:37.820 --> 00:20:40.510 align:middle line:84%
So here, I've got
integers and strings.

00:20:40.510 --> 00:20:42.820 align:middle line:84%
And integers, I can even
add floats and Booleans.

00:20:42.820 --> 00:20:44.620 align:middle line:84%
And whatever object
types I'd like,

00:20:44.620 --> 00:20:46.840 align:middle line:84%
I can make them elements
to my tuple, which

00:20:46.840 --> 00:20:47.800 align:middle line:90%
is pretty cool, right?

00:20:47.800 --> 00:20:49.990 align:middle line:84%
Different than strings
in that respect,

00:20:49.990 --> 00:20:55.170 align:middle line:84%
but still in order
within my tuple.

00:20:55.170 --> 00:20:58.380 align:middle line:84%
And so the rest of this
is actually operations

00:20:58.380 --> 00:21:00.700 align:middle line:84%
that we've already
seen on strings.

00:21:00.700 --> 00:21:03.390 align:middle line:84%
So I'm not going to go through
them in too much detail.

00:21:03.390 --> 00:21:06.730 align:middle line:84%
We can use the square bracket
to index into the tuple,

00:21:06.730 --> 00:21:09.600 align:middle line:84%
so to grab the element
at a particular index.

00:21:09.600 --> 00:21:12.230 align:middle line:90%
Again, indexing starts from 0.

00:21:12.230 --> 00:21:16.130 align:middle line:84%
We can use the plus operator to
concatenate two tuples together

00:21:16.130 --> 00:21:21.300 align:middle line:84%
to create one larger tuple with
all those elements in a row.

00:21:21.300 --> 00:21:24.090 align:middle line:90%
We can slice down here.

00:21:24.090 --> 00:21:26.130 align:middle line:84%
We can get the length
of the tuple, which

00:21:26.130 --> 00:21:30.180 align:middle line:84%
tells us how many elements
are in it, so three elements.

00:21:30.180 --> 00:21:34.560 align:middle line:84%
We can use the max, min,
some sum things like that

00:21:34.560 --> 00:21:37.530 align:middle line:84%
to grab the maximum
element, minimum element,

00:21:37.530 --> 00:21:40.380 align:middle line:84%
sum all the elements of my
tuple and things like that.

00:21:40.380 --> 00:21:43.530 align:middle line:84%
Notice that here I've got
parentheses for the max

00:21:43.530 --> 00:21:47.940 align:middle line:84%
function call and then another
set of parentheses here

00:21:47.940 --> 00:21:50.130 align:middle line:84%
to denote that I
have one tuple object

00:21:50.130 --> 00:21:51.772 align:middle line:90%
I'd like to grab the max of.

00:21:51.772 --> 00:21:54.610 align:middle line:90%


00:21:54.610 --> 00:21:57.310 align:middle line:84%
And then, the last
bit here is something

00:21:57.310 --> 00:21:59.980 align:middle line:84%
that we're going to see
that's different with lists

00:21:59.980 --> 00:22:01.900 align:middle line:90%
in next lecture, not today.

00:22:01.900 --> 00:22:05.860 align:middle line:84%
But basically, you might
think that once you create

00:22:05.860 --> 00:22:09.970 align:middle line:84%
this tuple object in memory,
that has 2, mit, 3 as its three

00:22:09.970 --> 00:22:12.280 align:middle line:84%
elements in it, you
can go into memory

00:22:12.280 --> 00:22:14.363 align:middle line:90%
and modify one of the elements.

00:22:14.363 --> 00:22:16.280 align:middle line:84%
If I don't want the
middle one to be a string,

00:22:16.280 --> 00:22:17.655 align:middle line:84%
I want it to be
a common integer,

00:22:17.655 --> 00:22:20.530 align:middle line:84%
you might think that you
should be able to change it.

00:22:20.530 --> 00:22:23.660 align:middle line:84%
You can with lists, as we'll
see in the next lecture.

00:22:23.660 --> 00:22:25.840 align:middle line:84%
But you cannot do
this with tuples.

00:22:25.840 --> 00:22:30.820 align:middle line:84%
Just like once we created
an integer 5 inside memory,

00:22:30.820 --> 00:22:35.320 align:middle line:84%
we can't go into memory and tell
Python to change this 5 to a 6.

00:22:35.320 --> 00:22:36.820 align:middle line:90%
It's just not allowed.

00:22:36.820 --> 00:22:39.040 align:middle line:84%
Or once we created a
string abc in memory,

00:22:39.040 --> 00:22:42.010 align:middle line:84%
you can't go into memory
and change the string.

00:22:42.010 --> 00:22:43.930 align:middle line:84%
You can certainly
create new objects

00:22:43.930 --> 00:22:45.940 align:middle line:90%
that are based on this string.

00:22:45.940 --> 00:22:49.940 align:middle line:84%
But you can't go in and modify
that object once it's created.

00:22:49.940 --> 00:22:51.880 align:middle line:84%
So once you've made
your sequence of tuples,

00:22:51.880 --> 00:22:54.470 align:middle line:90%
you cannot go in and change it.

00:22:54.470 --> 00:22:57.070 align:middle line:90%


00:22:57.070 --> 00:22:57.670 align:middle line:90%
Yeah?

00:22:57.670 --> 00:22:58.837 align:middle line:90%
AUDIENCE: I have a question.

00:22:58.837 --> 00:23:02.890 align:middle line:84%
So if you just rewrote t equals,
and then [INAUDIBLE] different,

00:23:02.890 --> 00:23:05.140 align:middle line:90%
it would be like an error?

00:23:05.140 --> 00:23:07.820 align:middle line:84%
ANA BELL: If you wrote t equals
and then something different?

00:23:07.820 --> 00:23:10.150 align:middle line:84%
AUDIENCE: Yeah, [INAUDIBLE]
you can't modify one thing.

00:23:10.150 --> 00:23:12.910 align:middle line:84%
ANA BELL: Yeah, that's
a good question.

00:23:12.910 --> 00:23:17.530 align:middle line:84%
So the variable t, so the name
t and the object it's bound to

00:23:17.530 --> 00:23:19.100 align:middle line:90%
are two different things.

00:23:19.100 --> 00:23:22.120 align:middle line:84%
So the object it's bound to
will still sit in memory.

00:23:22.120 --> 00:23:24.230 align:middle line:84%
We're just going to lose
the binding from it.

00:23:24.230 --> 00:23:26.620 align:middle line:84%
So that t initially
points to this one.

00:23:26.620 --> 00:23:29.590 align:middle line:84%
But then if you say t equals
something else later on,

00:23:29.590 --> 00:23:30.940 align:middle line:90%
this one still stays there.

00:23:30.940 --> 00:23:34.190 align:middle line:84%
But that t is going to
point to this new thing.

00:23:34.190 --> 00:23:36.580 align:middle line:84%
So the object itself
is still in memory.

00:23:36.580 --> 00:23:38.510 align:middle line:84%
We've just lost
the binding to it.

00:23:38.510 --> 00:23:40.330 align:middle line:84%
And that's something
we did way back

00:23:40.330 --> 00:23:42.970 align:middle line:84%
in the first early lectures
where we kind of rebound

00:23:42.970 --> 00:23:45.760 align:middle line:90%
variables, yeah.

00:23:45.760 --> 00:23:47.815 align:middle line:90%
So yeah, it's the same idea.

00:23:47.815 --> 00:23:50.490 align:middle line:90%


00:23:50.490 --> 00:23:53.190 align:middle line:84%
One interesting thing that
we can do now with tuples

00:23:53.190 --> 00:23:58.000 align:middle line:84%
that we couldn't with strings
is to have elements of a tuple

00:23:58.000 --> 00:24:00.790 align:middle line:90%
be another tuple.

00:24:00.790 --> 00:24:03.350 align:middle line:84%
And that's what this example
is going to showcase.

00:24:03.350 --> 00:24:07.030 align:middle line:84%
So here, I've got an integer
2 as my first element.

00:24:07.030 --> 00:24:08.770 align:middle line:84%
My second element
is the string a.

00:24:08.770 --> 00:24:11.050 align:middle line:84%
My third element
is my integer 4.

00:24:11.050 --> 00:24:14.440 align:middle line:84%
And my fourth element
is a tuple object

00:24:14.440 --> 00:24:19.180 align:middle line:84%
that just happens to have
two elements inside it.

00:24:19.180 --> 00:24:24.880 align:middle line:84%
But this tuple object that
I'm referencing by seq,

00:24:24.880 --> 00:24:28.070 align:middle line:84%
seq only has four
elements in it.

00:24:28.070 --> 00:24:31.120 align:middle line:84%
It just so happens that
the last one is a tuple.

00:24:31.120 --> 00:24:33.700 align:middle line:84%
But I'm not going
to dive further down

00:24:33.700 --> 00:24:36.550 align:middle line:84%
to figure out if I have
tuples that have subtuples

00:24:36.550 --> 00:24:38.140 align:middle line:90%
that have subtuples and so on.

00:24:38.140 --> 00:24:43.210 align:middle line:84%
Only top level I care about
how many elements I have.

00:24:43.210 --> 00:24:45.495 align:middle line:84%
And so when I print
the length of seq,

00:24:45.495 --> 00:24:47.550 align:middle line:84%
it's going to be 4
because I have 1,

00:24:47.550 --> 00:24:51.480 align:middle line:84%
2, 3, and then this last
object is just one object

00:24:51.480 --> 00:24:52.920 align:middle line:90%
that takes up one slot.

00:24:52.920 --> 00:24:57.370 align:middle line:84%
It happens to have
elements within it.

00:24:57.370 --> 00:24:59.580 align:middle line:84%
And so the rest of
these are basically

00:24:59.580 --> 00:25:03.330 align:middle line:84%
what we've seen with strings
except for this one here.

00:25:03.330 --> 00:25:07.320 align:middle line:84%
If we were to index into
the last element here

00:25:07.320 --> 00:25:11.530 align:middle line:84%
of seq, 1 comma 2, well,
this is another tuple, right?

00:25:11.530 --> 00:25:14.190 align:middle line:84%
So it should follow
that I can then

00:25:14.190 --> 00:25:18.010 align:middle line:84%
take that tuple and
further index into it.

00:25:18.010 --> 00:25:21.570 align:middle line:84%
And so that's what this
line here is doing.

00:25:21.570 --> 00:25:24.700 align:middle line:84%
When we read an expression,
we go left to right.

00:25:24.700 --> 00:25:29.220 align:middle line:84%
So basically, seq at index 3
grabs for me the 1 comma 2.

00:25:29.220 --> 00:25:33.660 align:middle line:84%
And then if I further index
into 1 comma 2 at index 0,

00:25:33.660 --> 00:25:37.110 align:middle line:90%
I'm going to grab the number 1.

00:25:37.110 --> 00:25:40.675 align:middle line:84%
So I'm basically chaining
all these indexing operations

00:25:40.675 --> 00:25:41.175 align:middle line:90%
together.

00:25:41.175 --> 00:25:44.940 align:middle line:90%


00:25:44.940 --> 00:25:48.352 align:middle line:84%
And then this is,
again, very similar to

00:25:48.352 --> 00:25:49.560 align:middle line:90%
what we've seen from strings.

00:25:49.560 --> 00:25:53.220 align:middle line:84%
So it's just slicing instead
of indexing into the tuple.

00:25:53.220 --> 00:25:56.160 align:middle line:84%
I'm not going to go
through it today.

00:25:56.160 --> 00:25:58.710 align:middle line:84%
But I encourage you to
type them in and type

00:25:58.710 --> 00:26:04.490 align:middle line:84%
in some other things as you
might have done with strings.

00:26:04.490 --> 00:26:07.400 align:middle line:84%
One thing that I
do want to mention

00:26:07.400 --> 00:26:11.000 align:middle line:84%
is that we can
iterate over a tuple

00:26:11.000 --> 00:26:13.670 align:middle line:84%
just like we could
iterate over a string.

00:26:13.670 --> 00:26:15.500 align:middle line:90%
I don't mean over indices.

00:26:15.500 --> 00:26:18.090 align:middle line:84%
But I mean over the
elements directly.

00:26:18.090 --> 00:26:20.060 align:middle line:84%
So when we iterated
over a string directly,

00:26:20.060 --> 00:26:24.260 align:middle line:84%
we were able to grab
in our loop variable

00:26:24.260 --> 00:26:27.990 align:middle line:90%
the characters at each index.

00:26:27.990 --> 00:26:30.480 align:middle line:84%
Similarly, we can
iterate over a tuple

00:26:30.480 --> 00:26:33.430 align:middle line:84%
to grab the elements
at each index directly.

00:26:33.430 --> 00:26:37.140 align:middle line:84%
So here, I've got
for e in seq is

00:26:37.140 --> 00:26:39.420 align:middle line:84%
going to make my
Loop variable e take

00:26:39.420 --> 00:26:43.670 align:middle line:84%
on each element of
the tuple directly,

00:26:43.670 --> 00:26:45.720 align:middle line:90%
not the index but each element.

00:26:45.720 --> 00:26:49.280 align:middle line:84%
So as I'm looping through,
e will first have a value 2,

00:26:49.280 --> 00:26:52.580 align:middle line:84%
then it'll have a value a,
then it'll have a value 4,

00:26:52.580 --> 00:26:55.670 align:middle line:84%
and lastly, it'll have
this value 1 comma 2.

00:26:55.670 --> 00:26:57.530 align:middle line:84%
And so if I just print
that out directly,

00:26:57.530 --> 00:27:00.170 align:middle line:84%
you'll see these
values printed out.

00:27:00.170 --> 00:27:04.470 align:middle line:90%


00:27:04.470 --> 00:27:07.650 align:middle line:84%
So very, very similar to
some of the operations

00:27:07.650 --> 00:27:08.650 align:middle line:90%
we've done with strings.

00:27:08.650 --> 00:27:10.067 align:middle line:84%
The only difference
is we just now

00:27:10.067 --> 00:27:13.740 align:middle line:84%
have to be careful that our
tuples can have elements

00:27:13.740 --> 00:27:19.070 align:middle line:84%
that are other tuples or
basically any object in Python.

00:27:19.070 --> 00:27:21.170 align:middle line:90%
So what do we use tuples for?

00:27:21.170 --> 00:27:23.630 align:middle line:84%
Well, there was this one
example we did way back

00:27:23.630 --> 00:27:29.450 align:middle line:84%
at the beginning of 6.100L where
we tried to swap variables.

00:27:29.450 --> 00:27:31.220 align:middle line:84%
And we basically
said that this way

00:27:31.220 --> 00:27:34.370 align:middle line:84%
didn't work because we
overwrote the variable.

00:27:34.370 --> 00:27:35.990 align:middle line:84%
We overwrote the
variable, and then we

00:27:35.990 --> 00:27:39.420 align:middle line:84%
weren't able to get back to
the value that was overwritten.

00:27:39.420 --> 00:27:42.980 align:middle line:84%
So our solution was to create
this temporary variable

00:27:42.980 --> 00:27:45.740 align:middle line:84%
to save the value
before we overwrote it,

00:27:45.740 --> 00:27:49.520 align:middle line:84%
then overwrite the variable, and
then use the temporary variable

00:27:49.520 --> 00:27:52.450 align:middle line:90%
to grab back that saved value.

00:27:52.450 --> 00:27:54.220 align:middle line:84%
Well, it turns out
tuples actually

00:27:54.220 --> 00:27:58.300 align:middle line:84%
allow us to do these three lines
of code in one line of code

00:27:58.300 --> 00:28:00.010 align:middle line:90%
here.

00:28:00.010 --> 00:28:05.500 align:middle line:84%
So we can say x comma
y equals y comma x.

00:28:05.500 --> 00:28:07.390 align:middle line:90%
So this is an assignment.

00:28:07.390 --> 00:28:10.960 align:middle line:84%
And it's allowed because the
left-hand side is basically

00:28:10.960 --> 00:28:15.720 align:middle line:90%
a set of variables in sequence.

00:28:15.720 --> 00:28:18.690 align:middle line:84%
And the right-hand side
gets evaluated first

00:28:18.690 --> 00:28:20.950 align:middle line:84%
as we would an
assignment statement.

00:28:20.950 --> 00:28:24.360 align:middle line:84%
So y gets the value 2 because
that's what it is up here.

00:28:24.360 --> 00:28:25.920 align:middle line:90%
And x gets the value 1.

00:28:25.920 --> 00:28:29.280 align:middle line:84%
So y is 2, x is 1 over here
on the right-hand side.

00:28:29.280 --> 00:28:32.610 align:middle line:84%
And then Python, one at a
time, matches the values

00:28:32.610 --> 00:28:36.490 align:middle line:84%
on the right to the values on
the left separated by commas.

00:28:36.490 --> 00:28:39.960 align:middle line:84%
So basically what we have
here is x is equal to 2,

00:28:39.960 --> 00:28:43.155 align:middle line:84%
y is equal to 1, and then
the values have been rebound.

00:28:43.155 --> 00:28:46.810 align:middle line:90%


00:28:46.810 --> 00:28:50.930 align:middle line:90%
So very, very, very useful--

00:28:50.930 --> 00:28:53.640 align:middle line:90%
very good use of tuples here.

00:28:53.640 --> 00:28:58.560 align:middle line:84%
Now, this idea can actually
be taken one step further.

00:28:58.560 --> 00:29:02.880 align:middle line:84%
And we can use tuples to
return more than one value

00:29:02.880 --> 00:29:04.950 align:middle line:90%
from a function.

00:29:04.950 --> 00:29:09.480 align:middle line:84%
Now, I know in the past
couple lectures I said,

00:29:09.480 --> 00:29:14.520 align:middle line:84%
basically you can't return more
than one thing from a function.

00:29:14.520 --> 00:29:16.170 align:middle line:84%
A function returns
only one thing.

00:29:16.170 --> 00:29:18.370 align:middle line:84%
As soon as it sees
a return statement,

00:29:18.370 --> 00:29:22.110 align:middle line:84%
it takes the value associated
with that return and returns it

00:29:22.110 --> 00:29:24.700 align:middle line:90%
back to whoever called it.

00:29:24.700 --> 00:29:27.730 align:middle line:90%
But tuples are one object.

00:29:27.730 --> 00:29:30.940 align:middle line:84%
They just so happen
to have elements

00:29:30.940 --> 00:29:32.767 align:middle line:90%
that can have different values.

00:29:32.767 --> 00:29:34.600 align:middle line:84%
You can have a tuple
with 10 elements in it.

00:29:34.600 --> 00:29:37.600 align:middle line:84%
You can have a tuple
with two elements in it.

00:29:37.600 --> 00:29:40.690 align:middle line:84%
Using a tuple, we
can actually return

00:29:40.690 --> 00:29:43.300 align:middle line:90%
one object, the tuple itself.

00:29:43.300 --> 00:29:46.300 align:middle line:84%
It just so happens to have
a whole bunch of values

00:29:46.300 --> 00:29:49.210 align:middle line:84%
that my function
might calculate.

00:29:49.210 --> 00:29:51.340 align:middle line:84%
And so by way of the
tuple, I'm actually

00:29:51.340 --> 00:29:54.970 align:middle line:84%
able to return a whole
bunch of different values

00:29:54.970 --> 00:29:57.100 align:middle line:90%
through this one object tuple.

00:29:57.100 --> 00:29:58.840 align:middle line:84%
And so in this
particular example,

00:29:58.840 --> 00:30:00.970 align:middle line:84%
I have a function
that calculates

00:30:00.970 --> 00:30:05.210 align:middle line:84%
the quotient and the remainder
when x is divided by y.

00:30:05.210 --> 00:30:12.590 align:middle line:84%
Yeah, so the function
itself uses integer division

00:30:12.590 --> 00:30:15.170 align:middle line:84%
to find the quotient and
uses the remainder operator

00:30:15.170 --> 00:30:17.660 align:middle line:84%
to find the
remainder, and then it

00:30:17.660 --> 00:30:21.230 align:middle line:84%
returns that q
calculation, some number,

00:30:21.230 --> 00:30:25.190 align:middle line:84%
and that r calculation, another
number, as elements to a tuple.

00:30:25.190 --> 00:30:28.010 align:middle line:84%
And Python returns
this one tuple

00:30:28.010 --> 00:30:34.000 align:middle line:84%
object using this line
here returning this object.

00:30:34.000 --> 00:30:37.920 align:middle line:84%
And so when I make this Function
call to quotient and remainder

00:30:37.920 --> 00:30:40.890 align:middle line:84%
10 comma 3, it's
going to go in, it's

00:30:40.890 --> 00:30:44.250 align:middle line:84%
going to calculate the quotient
to be 3, the remainder to be 1,

00:30:44.250 --> 00:30:48.300 align:middle line:84%
and it's going to return
one object, 3 comma 1.

00:30:48.300 --> 00:30:51.837 align:middle line:84%
And then that gets
assigned to this variable,

00:30:51.837 --> 00:30:53.670 align:middle line:84%
that I named "both" in
this particular case.

00:30:53.670 --> 00:30:57.090 align:middle line:90%


00:30:57.090 --> 00:30:59.660 align:middle line:84%
If I wanted to access the
quotient part of both,

00:30:59.660 --> 00:31:01.760 align:middle line:84%
I would do both
square brackets 0.

00:31:01.760 --> 00:31:05.090 align:middle line:84%
And the remainder part of both
would be both square bracket 1,

00:31:05.090 --> 00:31:07.310 align:middle line:84%
accessing the zeroth element
and the first element

00:31:07.310 --> 00:31:08.970 align:middle line:90%
of the return.

00:31:08.970 --> 00:31:12.690 align:middle line:84%
Now, if I wanted to explicitly
save the quotient and remainder

00:31:12.690 --> 00:31:16.150 align:middle line:84%
as variables after
they got returned,

00:31:16.150 --> 00:31:19.568 align:middle line:84%
I can actually do the trick
we saw on the previous slide.

00:31:19.568 --> 00:31:21.360 align:middle line:84%
The trick that we saw
on the previous slide

00:31:21.360 --> 00:31:24.510 align:middle line:84%
was x comma y equals
some other tuple.

00:31:24.510 --> 00:31:26.350 align:middle line:84%
Well, that's what
I'm doing here.

00:31:26.350 --> 00:31:29.130 align:middle line:84%
I'm making a function called a
quotient and remainder 5 comma

00:31:29.130 --> 00:31:29.700 align:middle line:90%
2.

00:31:29.700 --> 00:31:32.870 align:middle line:84%
That's going to
return 2 comma 1.

00:31:32.870 --> 00:31:38.210 align:middle line:84%
And then I'm going to have quote
comma rem equals 2 comma 1.

00:31:38.210 --> 00:31:40.100 align:middle line:84%
So Python, one at
a time, is going

00:31:40.100 --> 00:31:44.420 align:middle line:84%
to map the quote to
2 and the rem to 1.

00:31:44.420 --> 00:31:47.000 align:middle line:84%
And so what that means for
us in terms of the code

00:31:47.000 --> 00:31:51.800 align:middle line:84%
is we can then do whatever
we'd like in the remaining

00:31:51.800 --> 00:31:55.850 align:middle line:84%
part of the code, code assuming
that quote and rem are just

00:31:55.850 --> 00:31:57.150 align:middle line:90%
regular variables.

00:31:57.150 --> 00:31:59.930 align:middle line:84%
So here, I'm just showing
that you can print them out

00:31:59.930 --> 00:32:01.650 align:middle line:90%
in these print statements.

00:32:01.650 --> 00:32:04.250 align:middle line:84%
So here, I have quotient
is 2 and remainder

00:32:04.250 --> 00:32:07.100 align:middle line:84%
is 1 as these two
lines of code here.

00:32:07.100 --> 00:32:13.060 align:middle line:90%


00:32:13.060 --> 00:32:16.600 align:middle line:84%
OK, so the big idea of
tuples and the reason why

00:32:16.600 --> 00:32:21.100 align:middle line:84%
we use them is you
can use them to return

00:32:21.100 --> 00:32:27.380 align:middle line:84%
more than one value via this one
tuple object from a function.

00:32:27.380 --> 00:32:29.500 align:middle line:84%
And so in this way, we
can have a function that

00:32:29.500 --> 00:32:31.660 align:middle line:84%
does a whole bunch
of calculations,

00:32:31.660 --> 00:32:35.350 align:middle line:84%
returns this one object
that might contain

00:32:35.350 --> 00:32:37.450 align:middle line:84%
all of these different
values as the elements

00:32:37.450 --> 00:32:40.070 align:middle line:90%
to this tuple object.

00:32:40.070 --> 00:32:43.920 align:middle line:84%
So let's have you work on
this for a couple of minutes.

00:32:43.920 --> 00:32:46.150 align:middle line:84%
Write a function that
meets the specification.

00:32:46.150 --> 00:32:48.270 align:middle line:90%
So it's called char_counts.

00:32:48.270 --> 00:32:52.500 align:middle line:84%
I've got an input that is a
string s, lowercase characters.

00:32:52.500 --> 00:32:54.840 align:middle line:84%
Assume it's just got
vowels and consonants.

00:32:54.840 --> 00:32:58.140 align:middle line:84%
Return for me a tuple where
the first element in the tuple

00:32:58.140 --> 00:32:59.370 align:middle line:90%
is how many vowels are in s.

00:32:59.370 --> 00:33:01.140 align:middle line:84%
And the second
element of the tuple

00:33:01.140 --> 00:33:03.320 align:middle line:90%
is how many consonants are in s.

00:33:03.320 --> 00:33:06.340 align:middle line:84%
So it should be pretty
straightforward.

00:33:06.340 --> 00:33:08.460 align:middle line:84%
A hint I have here,
if you don't remember,

00:33:08.460 --> 00:33:10.230 align:middle line:84%
that will make
your life easier is

00:33:10.230 --> 00:33:14.650 align:middle line:84%
try to remember how to check
if a character is in a string,

00:33:14.650 --> 00:33:19.020 align:middle line:90%
so using the special n keyword.

00:33:19.020 --> 00:33:21.580 align:middle line:84%
We saw an example of
this probably back

00:33:21.580 --> 00:33:22.830 align:middle line:90%
when we learned about strings.

00:33:22.830 --> 00:33:26.870 align:middle line:90%


00:33:26.870 --> 00:33:31.413 align:middle line:84%
So you can try to write your
code around line 65-ish.

00:33:31.413 --> 00:33:32.830 align:middle line:84%
And then we can
write it together.

00:33:32.830 --> 00:33:36.130 align:middle line:90%


00:33:36.130 --> 00:33:38.990 align:middle line:84%
All right, so how would
you approach this problem?

00:33:38.990 --> 00:33:42.570 align:middle line:90%


00:33:42.570 --> 00:33:45.210 align:middle line:90%
So what's the first step here?

00:33:45.210 --> 00:33:46.480 align:middle line:90%
Yeah.

00:33:46.480 --> 00:33:49.300 align:middle line:84%
AUDIENCE: Make a string that
contains all the vowels?

00:33:49.300 --> 00:33:51.250 align:middle line:84%
ANA BELL: Yep, we
can make a string

00:33:51.250 --> 00:33:53.080 align:middle line:90%
that contains all the vowels.

00:33:53.080 --> 00:33:57.180 align:middle line:84%
Vowels equals
aeiou in lowercase.

00:33:57.180 --> 00:33:58.925 align:middle line:90%
Yep, nice.

00:33:58.925 --> 00:34:02.690 align:middle line:90%


00:34:02.690 --> 00:34:03.190 align:middle line:90%
Next?

00:34:03.190 --> 00:34:06.770 align:middle line:90%


00:34:06.770 --> 00:34:08.030 align:middle line:90%
Yeah.

00:34:08.030 --> 00:34:14.100 align:middle line:84%
AUDIENCE: If the [INAUDIBLE]
in that list, then

00:34:14.100 --> 00:34:17.909 align:middle line:84%
we could have a number
[INAUDIBLE] track,

00:34:17.909 --> 00:34:19.679 align:middle line:90%
like plus equals [INAUDIBLE]?

00:34:19.679 --> 00:34:20.270 align:middle line:90%
ANA BELL: Yep.

00:34:20.270 --> 00:34:24.860 align:middle line:90%
Yep, vowels plus equals 1.

00:34:24.860 --> 00:34:25.850 align:middle line:90%
And else?

00:34:25.850 --> 00:34:27.530 align:middle line:84%
We know it's not
a vowel, so we'll

00:34:27.530 --> 00:34:32.270 align:middle line:84%
keep a consonants
count plus equals 1.

00:34:32.270 --> 00:34:34.380 align:middle line:90%
So this is the consonant count.

00:34:34.380 --> 00:34:35.989 align:middle line:90%
And this is the vowels count.

00:34:35.989 --> 00:34:41.550 align:middle line:90%


00:34:41.550 --> 00:34:46.297 align:middle line:84%
What is char in
this case though?

00:34:46.297 --> 00:34:49.010 align:middle line:84%
AUDIENCE: [INAUDIBLE]
char In that?

00:34:49.010 --> 00:34:50.120 align:middle line:90%
ANA BELL: Yeah, exactly.

00:34:50.120 --> 00:34:54.227 align:middle line:84%
We have to loop,
so for char in s.

00:34:54.227 --> 00:34:58.160 align:middle line:84%
So we need to look at
every character inside s.

00:34:58.160 --> 00:35:03.610 align:middle line:84%
And this is where, now that
we're dealing with things that

00:35:03.610 --> 00:35:06.640 align:middle line:84%
might be non integers
in my for loops,

00:35:06.640 --> 00:35:09.010 align:middle line:84%
we can write little notes for
ourselves that's something

00:35:09.010 --> 00:35:14.710 align:middle line:84%
like "char is a then b
then c," or something like

00:35:14.710 --> 00:35:18.730 align:middle line:84%
that to remind us that
char is not the index,

00:35:18.730 --> 00:35:22.320 align:middle line:90%
but it's an actual thing.

00:35:22.320 --> 00:35:26.934 align:middle line:84%
And then what else
we need to do?

00:35:26.934 --> 00:35:28.742 align:middle line:90%
AUDIENCE: [INAUDIBLE]

00:35:28.742 --> 00:35:31.810 align:middle line:90%


00:35:31.810 --> 00:35:33.850 align:middle line:84%
ANA BELL: Yeah, we can
initiate c and v 0.

00:35:33.850 --> 00:35:38.860 align:middle line:84%
We can use the trick where you
do c comma v equals 0 comma 0.

00:35:38.860 --> 00:35:43.460 align:middle line:84%
Or we can just do it on
separate lines, all good.

00:35:43.460 --> 00:35:46.520 align:middle line:84%
And then lastly, this
does the work for us.

00:35:46.520 --> 00:35:50.220 align:middle line:84%
But the function needs to
have something to show for it.

00:35:50.220 --> 00:35:51.420 align:middle line:90%
AUDIENCE: [INAUDIBLE]?

00:35:51.420 --> 00:35:54.060 align:middle line:84%
ANA BELL: Yeah,
after the loop, we'll

00:35:54.060 --> 00:35:58.840 align:middle line:90%
return the tuple c comma v--

00:35:58.840 --> 00:36:00.090 align:middle line:90%
sorry, v comma c probably.

00:36:00.090 --> 00:36:03.290 align:middle line:90%


00:36:03.290 --> 00:36:08.440 align:middle line:84%
And if we run it, it
matches what we expected.

00:36:08.440 --> 00:36:10.410 align:middle line:90%
So 1, 3 and 0, 5.

00:36:10.410 --> 00:36:12.930 align:middle line:84%
And you can imagine adding
a couple more test cases,

00:36:12.930 --> 00:36:16.410 align:middle line:84%
maybe something with an empty
string that should return 0 0,

00:36:16.410 --> 00:36:19.020 align:middle line:84%
and maybe something with
all vowels, which should

00:36:19.020 --> 00:36:21.030 align:middle line:90%
return some number comma 0.

00:36:21.030 --> 00:36:27.820 align:middle line:90%


00:36:27.820 --> 00:36:30.520 align:middle line:84%
OK, so one other thing
we can do with tuples

00:36:30.520 --> 00:36:32.590 align:middle line:84%
is to create these
functions that

00:36:32.590 --> 00:36:36.530 align:middle line:84%
take a variable number of
arguments is in as a parameter.

00:36:36.530 --> 00:36:38.560 align:middle line:84%
So remember, when
we define functions,

00:36:38.560 --> 00:36:40.330 align:middle line:84%
we basically tell
Python how many

00:36:40.330 --> 00:36:43.120 align:middle line:90%
parameter we expect it to take.

00:36:43.120 --> 00:36:46.660 align:middle line:84%
But it's possible to have some
functions, for example, max

00:36:46.660 --> 00:36:49.960 align:middle line:84%
or min, that can take
in two parameters here.

00:36:49.960 --> 00:36:52.540 align:middle line:84%
And notice, there's
no extra parentheses.

00:36:52.540 --> 00:36:56.120 align:middle line:84%
Or we can just add as
many numbers as we'd like

00:36:56.120 --> 00:36:59.020 align:middle line:84%
and it will still work
to take the max of all

00:36:59.020 --> 00:37:00.410 align:middle line:90%
of these sets of numbers.

00:37:00.410 --> 00:37:03.790 align:middle line:84%
And again, we didn't
make this inner thing

00:37:03.790 --> 00:37:08.840 align:middle line:84%
a tuple, although it works even
with the tuple as an object.

00:37:08.840 --> 00:37:11.680 align:middle line:84%
But our goal here is to try
to write a function that

00:37:11.680 --> 00:37:15.780 align:middle line:84%
can take in a variable number
of arguments, either two

00:37:15.780 --> 00:37:19.570 align:middle line:84%
or three or 10 or 20,
and it should still work.

00:37:19.570 --> 00:37:23.380 align:middle line:84%
And the way we do that is using
a parameter that's defined

00:37:23.380 --> 00:37:25.250 align:middle line:90%
using the star notation.

00:37:25.250 --> 00:37:29.660 align:middle line:84%
So as soon as you create a
function and its parameter

00:37:29.660 --> 00:37:32.300 align:middle line:84%
is star and then the
name of your input,

00:37:32.300 --> 00:37:34.700 align:middle line:84%
Python basically
takes that input

00:37:34.700 --> 00:37:37.580 align:middle line:84%
and assigns it to a
tuple behind the scenes.

00:37:37.580 --> 00:37:39.770 align:middle line:90%
So you don't have to.

00:37:39.770 --> 00:37:42.080 align:middle line:84%
And so, in this
particular case, we're

00:37:42.080 --> 00:37:44.510 align:middle line:84%
not writing our own
max or min or some,

00:37:44.510 --> 00:37:48.170 align:middle line:84%
we're writing our
own mean function.

00:37:48.170 --> 00:37:51.860 align:middle line:84%
And this mean function will
take in a variable number

00:37:51.860 --> 00:37:53.180 align:middle line:90%
of arguments.

00:37:53.180 --> 00:37:56.780 align:middle line:84%
And it's going to figure out
the mean of all of these values.

00:37:56.780 --> 00:37:59.630 align:middle line:84%
The way it does that
is pretty simple now

00:37:59.630 --> 00:38:01.850 align:middle line:84%
that we know that we
can just treat args

00:38:01.850 --> 00:38:05.640 align:middle line:84%
as a tuple of a
bunch of numbers.

00:38:05.640 --> 00:38:09.170 align:middle line:84%
So we just loop through all
of the elements in args,

00:38:09.170 --> 00:38:12.440 align:middle line:84%
we add up this running
total, and at the end,

00:38:12.440 --> 00:38:16.160 align:middle line:84%
we return the total divided by
how many arguments were given,

00:38:16.160 --> 00:38:19.260 align:middle line:84%
so return total divided
by the length of the args.

00:38:19.260 --> 00:38:21.110 align:middle line:84%
And then, when we
make a Function call

00:38:21.110 --> 00:38:26.840 align:middle line:84%
to the function we
just wrote mean here,

00:38:26.840 --> 00:38:29.090 align:middle line:84%
args will become
a tuple that's all

00:38:29.090 --> 00:38:33.170 align:middle line:90%
of the parameters inside there.

00:38:33.170 --> 00:38:36.040 align:middle line:84%
And so here is
that example, which

00:38:36.040 --> 00:38:38.020 align:middle line:84%
means that we can use
our function to get

00:38:38.020 --> 00:38:41.710 align:middle line:90%
the mean of 1, 2, 3, 4, 5, 6.

00:38:41.710 --> 00:38:43.930 align:middle line:84%
But we can use the
exact same function

00:38:43.930 --> 00:38:46.580 align:middle line:84%
to get the mean of
6, 0, 9 for example.

00:38:46.580 --> 00:38:49.610 align:middle line:84%
So first case, I have six
parameters as my input.

00:38:49.610 --> 00:38:52.270 align:middle line:84%
But in the second case, I've
got only three parameters

00:38:52.270 --> 00:38:53.230 align:middle line:90%
as my input.

00:38:53.230 --> 00:39:00.580 align:middle line:84%
And that little star in my
arguments allows me to do this.

00:39:00.580 --> 00:39:04.180 align:middle line:84%
Now, I did write a version
of this mean for you guys

00:39:04.180 --> 00:39:08.940 align:middle line:84%
down here where I'm
assuming that mean

00:39:08.940 --> 00:39:11.050 align:middle line:84%
doesn't have the
star, so assuming

00:39:11.050 --> 00:39:13.190 align:middle line:90%
that args is a tuple itself.

00:39:13.190 --> 00:39:17.530 align:middle line:84%
And in that case, you would
have to call the mean function

00:39:17.530 --> 00:39:21.920 align:middle line:84%
by explicitly passing in only
one argument that is a tuple.

00:39:21.920 --> 00:39:26.120 align:middle line:84%
So this extra set of parentheses
makes my argument the tuple.

00:39:26.120 --> 00:39:29.830 align:middle line:84%
So take a closer look at
that if you're interested.

00:39:29.830 --> 00:39:32.360 align:middle line:90%


00:39:32.360 --> 00:39:35.950 align:middle line:84%
So I want to
introduce lists today.

00:39:35.950 --> 00:39:40.750 align:middle line:84%
And a lot of the slides here
are basically copy and paste

00:39:40.750 --> 00:39:42.700 align:middle line:90%
from the tuple slides.

00:39:42.700 --> 00:39:44.920 align:middle line:84%
The only difference
in these slides

00:39:44.920 --> 00:39:50.240 align:middle line:84%
that I have regarding lists
is the way we define a list.

00:39:50.240 --> 00:39:55.630 align:middle line:84%
So in terms of defining a tuple,
we were using parentheses.

00:39:55.630 --> 00:39:59.680 align:middle line:84%
But to define a list, we use
open closed square brackets.

00:39:59.680 --> 00:40:02.170 align:middle line:84%
But otherwise, a lot
of the operations

00:40:02.170 --> 00:40:06.310 align:middle line:84%
are exactly the same as
tuples and as strings.

00:40:06.310 --> 00:40:09.970 align:middle line:84%
We're not going to look at
what it means for lists to be

00:40:09.970 --> 00:40:11.050 align:middle line:90%
mutable this lecture.

00:40:11.050 --> 00:40:14.500 align:middle line:84%
But next lecture will
be all about mutability.

00:40:14.500 --> 00:40:18.980 align:middle line:84%
But today, I just want to give
you a sense of what a list is.

00:40:18.980 --> 00:40:23.210 align:middle line:84%
So as I said, this is copy and
paste from the tuple slide.

00:40:23.210 --> 00:40:27.500 align:middle line:84%
When I create a list, I just use
open and close square brackets.

00:40:27.500 --> 00:40:31.350 align:middle line:84%
This creates a list for me
with no elements within it.

00:40:31.350 --> 00:40:32.970 align:middle line:84%
Creating a list with
one element in it

00:40:32.970 --> 00:40:35.460 align:middle line:84%
doesn't need that extra
comma because there's

00:40:35.460 --> 00:40:38.760 align:middle line:84%
no confusion with
operation precedence

00:40:38.760 --> 00:40:40.300 align:middle line:90%
with square brackets.

00:40:40.300 --> 00:40:41.950 align:middle line:90%
So there's no need for that.

00:40:41.950 --> 00:40:44.370 align:middle line:84%
But otherwise,
everything else here

00:40:44.370 --> 00:40:46.530 align:middle line:84%
is exactly the same
as with tuples.

00:40:46.530 --> 00:40:50.820 align:middle line:84%
We're just using square
brackets instead of parentheses.

00:40:50.820 --> 00:40:54.590 align:middle line:84%
So remember, strings and
tuples, it's the same.

00:40:54.590 --> 00:40:57.530 align:middle line:84%
What I do want to mention
and talk a little bit about,

00:40:57.530 --> 00:40:59.810 align:middle line:84%
now that we've introduced
tuples and lists,

00:40:59.810 --> 00:41:04.310 align:middle line:84%
is the idea of having our
loops iterate over elements

00:41:04.310 --> 00:41:05.855 align:middle line:90%
of tuples and lists directly.

00:41:05.855 --> 00:41:07.730 align:middle line:84%
And I'm going to basically
write these slides

00:41:07.730 --> 00:41:09.180 align:middle line:90%
in the context of lists.

00:41:09.180 --> 00:41:13.450 align:middle line:84%
But the exact same thing is
applicable to tuples, as well.

00:41:13.450 --> 00:41:17.710 align:middle line:84%
So here is an
example of us wanting

00:41:17.710 --> 00:41:19.930 align:middle line:84%
to find the sum of the
elements in a list.

00:41:19.930 --> 00:41:23.650 align:middle line:84%
The code on the left is a
little bit hard to parse, right?

00:41:23.650 --> 00:41:28.060 align:middle line:84%
We've got a loop variable
going through range length n.

00:41:28.060 --> 00:41:30.880 align:middle line:84%
And then I have to
keep my running total.

00:41:30.880 --> 00:41:34.840 align:middle line:84%
But I have to index into
the list at that index here.

00:41:34.840 --> 00:41:36.460 align:middle line:84%
And it's really
hard to tell what's

00:41:36.460 --> 00:41:38.630 align:middle line:90%
going on at a quick glance.

00:41:38.630 --> 00:41:40.960 align:middle line:84%
And so luckily for
us, the way that we

00:41:40.960 --> 00:41:44.140 align:middle line:84%
were able to iterate over
string characters directly,

00:41:44.140 --> 00:41:47.800 align:middle line:84%
we can iterate over tuple
and list elements directly.

00:41:47.800 --> 00:41:52.630 align:middle line:84%
So the right-hand
side here is code

00:41:52.630 --> 00:41:55.450 align:middle line:84%
that does exactly the same
thing as the one on the left,

00:41:55.450 --> 00:41:59.050 align:middle line:84%
except that our loop variable
i, in this particular case,

00:41:59.050 --> 00:42:06.060 align:middle line:84%
will take on the values
of my list directly.

00:42:06.060 --> 00:42:09.210 align:middle line:90%
And so if we take that code--

00:42:09.210 --> 00:42:10.920 align:middle line:84%
yes, and I guess we
call this version

00:42:10.920 --> 00:42:13.510 align:middle line:84%
more "Pythonic" because
it's a lot easier to read.

00:42:13.510 --> 00:42:18.280 align:middle line:84%
So if we take that code and
wrap it around the function

00:42:18.280 --> 00:42:21.010 align:middle line:84%
to make this piece
of code be something

00:42:21.010 --> 00:42:23.200 align:middle line:84%
that we can reuse in a
whole bunch of places

00:42:23.200 --> 00:42:26.080 align:middle line:84%
to grab the sum of all
the elements of a list,

00:42:26.080 --> 00:42:27.320 align:middle line:90%
we can do that.

00:42:27.320 --> 00:42:30.700 align:middle line:84%
So here, I've taken the
code that does the work,

00:42:30.700 --> 00:42:34.000 align:middle line:84%
I've plopped it inside this
function, I've named list sum,

00:42:34.000 --> 00:42:35.980 align:middle line:84%
I've taken a list
as a parameter,

00:42:35.980 --> 00:42:40.090 align:middle line:84%
and instead of printing the
total, I'm returning the total.

00:42:40.090 --> 00:42:43.240 align:middle line:90%
So very useful function now.

00:42:43.240 --> 00:42:48.070 align:middle line:84%
This loop variable i will
take on the values 8, then 3,

00:42:48.070 --> 00:42:52.240 align:middle line:84%
then 5, if that's the list
I called this function with,

00:42:52.240 --> 00:42:55.960 align:middle line:84%
so a lot nicer than
iterating over the index

00:42:55.960 --> 00:42:58.690 align:middle line:84%
and then indexing into the
list with the square brackets

00:42:58.690 --> 00:43:01.350 align:middle line:90%
at that index.

00:43:01.350 --> 00:43:03.375 align:middle line:84%
What I do want to
mention is something,

00:43:03.375 --> 00:43:04.740 align:middle line:90%
when you're writing code--

00:43:04.740 --> 00:43:07.650 align:middle line:84%
and this is
something that I used

00:43:07.650 --> 00:43:09.930 align:middle line:84%
to do when I first
started out-- is

00:43:09.930 --> 00:43:11.640 align:middle line:84%
to write a little
comment for yourself

00:43:11.640 --> 00:43:13.200 align:middle line:90%
right underneath for loop.

00:43:13.200 --> 00:43:16.470 align:middle line:84%
Now, I know it's
a little tedious,

00:43:16.470 --> 00:43:19.740 align:middle line:84%
but it does help you keep
track of-- especially

00:43:19.740 --> 00:43:22.170 align:middle line:84%
now that we're iterating
over tuples or over lists

00:43:22.170 --> 00:43:23.910 align:middle line:84%
or over string
elements directly,

00:43:23.910 --> 00:43:25.680 align:middle line:84%
or even over the
indices, it helps

00:43:25.680 --> 00:43:28.830 align:middle line:84%
you keep track of what this
loop variable's value is

00:43:28.830 --> 00:43:29.485 align:middle line:90%
going to be.

00:43:29.485 --> 00:43:31.860 align:middle line:84%
And then you don't have to
keep track of it in your mind.

00:43:31.860 --> 00:43:32.790 align:middle line:90%
It's on paper.

00:43:32.790 --> 00:43:35.470 align:middle line:84%
And you can use your mind to
keep track of other things.

00:43:35.470 --> 00:43:38.100 align:middle line:84%
So if you just write a little
comment for yourself there,

00:43:38.100 --> 00:43:41.940 align:middle line:84%
it helps you debug
along the way.

00:43:41.940 --> 00:43:46.880 align:middle line:84%
So once we iterate over
list elements directly,

00:43:46.880 --> 00:43:50.190 align:middle line:84%
it makes code that we
write really easy to read.

00:43:50.190 --> 00:43:52.310 align:middle line:84%
So here, the code
on the left is going

00:43:52.310 --> 00:43:54.680 align:middle line:84%
to iterate over the
elements directly and get

00:43:54.680 --> 00:43:56.420 align:middle line:90%
the running total.

00:43:56.420 --> 00:44:00.380 align:middle line:84%
But we can make a really small
change to the input list.

00:44:00.380 --> 00:44:03.560 align:middle line:84%
Let's say our input list no
longer takes in just numbers,

00:44:03.560 --> 00:44:08.840 align:middle line:90%
but it can take in strings.

00:44:08.840 --> 00:44:14.710 align:middle line:84%
We can make one small
change to our loop body.

00:44:14.710 --> 00:44:17.530 align:middle line:84%
Our loop variable
still iterates over

00:44:17.530 --> 00:44:19.780 align:middle line:90%
all the elements in the list l.

00:44:19.780 --> 00:44:21.615 align:middle line:84%
And then if we write
the note for ourselves

00:44:21.615 --> 00:44:25.860 align:middle line:84%
that s is going to be
a, b, then def, then g,

00:44:25.860 --> 00:44:29.100 align:middle line:84%
if we wanted to write code
that grabbed the sum of all

00:44:29.100 --> 00:44:33.400 align:middle line:84%
of the lengths of the
list, the total plus

00:44:33.400 --> 00:44:37.225 align:middle line:84%
equals e on the left-hand side
becomes total plus equal length

00:44:37.225 --> 00:44:39.500 align:middle line:90%
of s on the right-hand side.

00:44:39.500 --> 00:44:43.420 align:middle line:84%
So length of s, one at a
time, will take on the value 2

00:44:43.420 --> 00:44:47.320 align:middle line:84%
because a, b has length
2, and then 3 because def

00:44:47.320 --> 00:44:51.550 align:middle line:84%
has length 3, and then 1
because g has length 1.

00:44:51.550 --> 00:44:53.680 align:middle line:84%
So the code looks
very similar, but they

00:44:53.680 --> 00:44:55.900 align:middle line:84%
have different
functionalities depending

00:44:55.900 --> 00:44:57.430 align:middle line:90%
on what we want to do.

00:44:57.430 --> 00:45:00.450 align:middle line:90%


00:45:00.450 --> 00:45:04.950 align:middle line:84%
OK, we don't have time to
go through this to try it.

00:45:04.950 --> 00:45:08.860 align:middle line:84%
But definitely try it
on your own at home.

00:45:08.860 --> 00:45:09.850 align:middle line:90%
It's very useful.

00:45:09.850 --> 00:45:11.640 align:middle line:84%
Plus a whole bunch
of other functions

00:45:11.640 --> 00:45:13.440 align:middle line:84%
that I've put in
this Python file

00:45:13.440 --> 00:45:15.090 align:middle line:84%
for you to get a
lot of experience

00:45:15.090 --> 00:45:18.590 align:middle line:90%
with tuples and lists, OK.

00:45:18.590 --> 00:45:26.000 align:middle line:90%