WEBVTT

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

00:00:02.450 --> 00:00:03.430 align:middle line:90%
[RUSTLING]

00:00:03.430 --> 00:00:05.390 align:middle line:90%
[CLICKING]

00:00:05.390 --> 00:00:11.270 align:middle line:90%


00:00:11.270 --> 00:00:12.200 align:middle line:90%
ANA BELL: OK.

00:00:12.200 --> 00:00:14.810 align:middle line:84%
So last lecture,
we started talking

00:00:14.810 --> 00:00:17.900 align:middle line:84%
about the idea of
decomposition and abstraction.

00:00:17.900 --> 00:00:19.940 align:middle line:84%
And we talked a little
bit about what that means

00:00:19.940 --> 00:00:22.940 align:middle line:84%
and how it ties into what
we've already been doing.

00:00:22.940 --> 00:00:25.250 align:middle line:84%
Today, we're going to
do a real-world example

00:00:25.250 --> 00:00:26.840 align:middle line:84%
of decomposition
and abstraction,

00:00:26.840 --> 00:00:28.550 align:middle line:84%
and then we'll see
exactly how we can

00:00:28.550 --> 00:00:31.080 align:middle line:90%
achieve this in programming.

00:00:31.080 --> 00:00:35.570 align:middle line:84%
So let's start by talking about
an example in the real world,

00:00:35.570 --> 00:00:37.360 align:middle line:90%
the smartphone.

00:00:37.360 --> 00:00:40.960 align:middle line:84%
So a lot of us have it,
but for a lot of us,

00:00:40.960 --> 00:00:43.000 align:middle line:90%
it's really just a black box.

00:00:43.000 --> 00:00:44.170 align:middle line:90%
For me, I know it is.

00:00:44.170 --> 00:00:46.450 align:middle line:84%
For most of the
people in the world,

00:00:46.450 --> 00:00:48.680 align:middle line:90%
the phone is a black box.

00:00:48.680 --> 00:00:52.090 align:middle line:84%
We basically view the phone
in terms of its inputs

00:00:52.090 --> 00:00:54.190 align:middle line:90%
and in terms of its outputs.

00:00:54.190 --> 00:00:57.070 align:middle line:90%
So the phone has some buttons.

00:00:57.070 --> 00:00:58.300 align:middle line:90%
You can scroll.

00:00:58.300 --> 00:01:00.110 align:middle line:90%
You can touch things.

00:01:00.110 --> 00:01:02.200 align:middle line:84%
But we don't really
know exactly how

00:01:02.200 --> 00:01:04.690 align:middle line:84%
all of these buttons
and scrolling and all

00:01:04.690 --> 00:01:07.880 align:middle line:84%
these internal workings
actually do their job.

00:01:07.880 --> 00:01:11.080 align:middle line:84%
And in fact, we don't need to
know how they do their job.

00:01:11.080 --> 00:01:13.180 align:middle line:84%
To us, as the
user, all we really

00:01:13.180 --> 00:01:15.490 align:middle line:84%
care about is the
interface between us

00:01:15.490 --> 00:01:18.550 align:middle line:84%
and what task we
want to achieve.

00:01:18.550 --> 00:01:21.460 align:middle line:84%
So what we need to
know, that interface,

00:01:21.460 --> 00:01:24.280 align:middle line:84%
is basically the relationship
between the input

00:01:24.280 --> 00:01:28.690 align:middle line:84%
we give to the phone
and the output we get.

00:01:28.690 --> 00:01:31.300 align:middle line:84%
So when we push that
button, the phone turns off.

00:01:31.300 --> 00:01:36.220 align:middle line:84%
When we push this other
button, the volume increases.

00:01:36.220 --> 00:01:38.470 align:middle line:84%
And so that's the
idea of abstraction.

00:01:38.470 --> 00:01:41.710 align:middle line:84%
The phone basically
abstracted away

00:01:41.710 --> 00:01:45.040 align:middle line:84%
all of those hardware details,
all of those implementations

00:01:45.040 --> 00:01:47.980 align:middle line:84%
that make it actually
work for the user.

00:01:47.980 --> 00:01:49.690 align:middle line:84%
So the user doesn't
need to know how

00:01:49.690 --> 00:01:51.460 align:middle line:90%
it works in order to use it.

00:01:51.460 --> 00:01:55.900 align:middle line:84%
Now, abstraction actually
enables the decomposition.

00:01:55.900 --> 00:01:57.170 align:middle line:90%
What does that mean?

00:01:57.170 --> 00:02:01.080 align:middle line:84%
Well, once we
abstract away details,

00:02:01.080 --> 00:02:04.140 align:middle line:84%
we can have different
manufacturers

00:02:04.140 --> 00:02:07.590 align:middle line:84%
working on different
components of the phone

00:02:07.590 --> 00:02:10.430 align:middle line:84%
to build these
different components.

00:02:10.430 --> 00:02:12.710 align:middle line:84%
And if different
manufacturers are

00:02:12.710 --> 00:02:15.230 align:middle line:84%
working to build these
hundreds of distinct parts

00:02:15.230 --> 00:02:17.480 align:middle line:84%
within the phone
separately, they

00:02:17.480 --> 00:02:21.080 align:middle line:84%
need to have some way to put
these parts back together.

00:02:21.080 --> 00:02:24.920 align:middle line:84%
And when they're working
on their pieces separately,

00:02:24.920 --> 00:02:27.050 align:middle line:84%
that's the idea
of decomposition.

00:02:27.050 --> 00:02:30.230 align:middle line:84%
How do they know that
what they're working on

00:02:30.230 --> 00:02:33.230 align:middle line:84%
will actually fit in with
the rest of the components?

00:02:33.230 --> 00:02:35.450 align:middle line:84%
Well, they use the
idea of decomposition.

00:02:35.450 --> 00:02:37.850 align:middle line:84%
They're basically
following a specification.

00:02:37.850 --> 00:02:40.340 align:middle line:84%
They're following
a set of inputs

00:02:40.340 --> 00:02:42.980 align:middle line:84%
that maybe come into
their component,

00:02:42.980 --> 00:02:46.130 align:middle line:84%
and a set of outputs that
maybe their component needs

00:02:46.130 --> 00:02:48.350 align:middle line:90%
to give to other components.

00:02:48.350 --> 00:02:51.530 align:middle line:84%
And all these
different manufacturers

00:02:51.530 --> 00:02:54.740 align:middle line:84%
that are building these
different parts need to know

00:02:54.740 --> 00:02:56.132 align:middle line:90%
is that interface bit.

00:02:56.132 --> 00:02:58.340 align:middle line:84%
They don't need to know how
other manufacturers build

00:02:58.340 --> 00:02:59.510 align:middle line:90%
their components.

00:02:59.510 --> 00:03:02.720 align:middle line:84%
All they need to know
is what functionality

00:03:02.720 --> 00:03:04.950 align:middle line:90%
those other components have.

00:03:04.950 --> 00:03:07.222 align:middle line:84%
And so all of these
different manufacturers

00:03:07.222 --> 00:03:08.930 align:middle line:84%
can build all these
different components.

00:03:08.930 --> 00:03:13.270 align:middle line:84%
The interfaces are going to
be standardized, so to speak.

00:03:13.270 --> 00:03:16.120 align:middle line:84%
And that's all that
they care about.

00:03:16.120 --> 00:03:18.420 align:middle line:84%
So once you know
the interface, you

00:03:18.420 --> 00:03:21.150 align:middle line:84%
can come together and put all
these different components

00:03:21.150 --> 00:03:23.610 align:middle line:84%
together to work
towards a common goal,

00:03:23.610 --> 00:03:26.410 align:middle line:90%
as in, to make a phone work.

00:03:26.410 --> 00:03:29.140 align:middle line:84%
So this is true for hardware,
as in the phone example,

00:03:29.140 --> 00:03:30.580 align:middle line:90%
but it's also true for software.

00:03:30.580 --> 00:03:32.260 align:middle line:84%
And that's exactly
what we will be doing

00:03:32.260 --> 00:03:34.750 align:middle line:90%
in this lecture on functions.

00:03:34.750 --> 00:03:37.990 align:middle line:84%
We're going to achieve
decomposition and abstraction

00:03:37.990 --> 00:03:41.740 align:middle line:84%
in programming, so treating
code as a black box

00:03:41.740 --> 00:03:46.630 align:middle line:84%
and making a large program,
kind of splitting it up

00:03:46.630 --> 00:03:50.350 align:middle line:84%
into these different
self-contained parts.

00:03:50.350 --> 00:03:54.590 align:middle line:84%
So in programming, we want
to suppress details as well,

00:03:54.590 --> 00:03:56.630 align:middle line:84%
not just in hardware,
like with the phone.

00:03:56.630 --> 00:03:59.720 align:middle line:84%
We want to suppress details
in programming as well.

00:03:59.720 --> 00:04:03.350 align:middle line:84%
And we do this using
this idea of abstraction.

00:04:03.350 --> 00:04:09.720 align:middle line:84%
So we will be writing code,
as we have already been doing,

00:04:09.720 --> 00:04:13.710 align:middle line:84%
with the thought that the code
we're writing will be done--

00:04:13.710 --> 00:04:15.180 align:middle line:90%
will be written only once.

00:04:15.180 --> 00:04:17.130 align:middle line:84%
We will have some
functional piece of code

00:04:17.130 --> 00:04:19.950 align:middle line:84%
that will do a very
useful task, and then,

00:04:19.950 --> 00:04:22.350 align:middle line:84%
after we've written that
code and debugged it and made

00:04:22.350 --> 00:04:25.720 align:middle line:84%
sure it works well, we'll
treat that code as a black box.

00:04:25.720 --> 00:04:27.630 align:middle line:84%
So from there on
out, as long as we

00:04:27.630 --> 00:04:29.760 align:middle line:84%
know what inputs that
piece of code needs

00:04:29.760 --> 00:04:31.410 align:middle line:84%
and what outputs
that piece of code

00:04:31.410 --> 00:04:33.690 align:middle line:84%
gives back to somebody
else or to us,

00:04:33.690 --> 00:04:35.800 align:middle line:84%
we don't care exactly
how it does it.

00:04:35.800 --> 00:04:40.320 align:middle line:84%
We just care that it is there,
and it is available for use.

00:04:40.320 --> 00:04:42.330 align:middle line:84%
So today's lecture,
we're going to be

00:04:42.330 --> 00:04:44.700 align:middle line:84%
seeing how we can actually
create these little

00:04:44.700 --> 00:04:46.770 align:middle line:90%
functional pieces of code.

00:04:46.770 --> 00:04:50.322 align:middle line:84%
We can then give these
pieces of code to ourselves.

00:04:50.322 --> 00:04:52.530 align:middle line:84%
We can definitely use these
functional pieces of code

00:04:52.530 --> 00:04:55.210 align:middle line:84%
that we've written, or we
can give them to other people

00:04:55.210 --> 00:04:58.500 align:middle line:84%
so that they can
use them as well.

00:04:58.500 --> 00:05:03.970 align:middle line:84%
So we're going to write these
functional pieces of code.

00:05:03.970 --> 00:05:05.260 align:middle line:90%
And we'll call the--

00:05:05.260 --> 00:05:08.080 align:middle line:84%
we'll call them
functions or procedures.

00:05:08.080 --> 00:05:11.080 align:middle line:84%
And in fact, we've already
been using functions,

00:05:11.080 --> 00:05:12.890 align:middle line:90%
believe it or not.

00:05:12.890 --> 00:05:16.630 align:middle line:84%
These three are examples
of functions we've already

00:05:16.630 --> 00:05:18.160 align:middle line:90%
been using in Python.

00:05:18.160 --> 00:05:20.440 align:middle line:90%
So max is a function.

00:05:20.440 --> 00:05:23.740 align:middle line:84%
It's some useful piece of
code that, when we use it

00:05:23.740 --> 00:05:28.480 align:middle line:84%
in this particular way, it
says it's taking in two inputs

00:05:28.480 --> 00:05:32.730 align:middle line:84%
and it gives me back the
biggest of those two inputs.

00:05:32.730 --> 00:05:36.180 align:middle line:84%
The middle one, abs, is the
absolute value function.

00:05:36.180 --> 00:05:40.020 align:middle line:84%
And its input is one
number, an integer,

00:05:40.020 --> 00:05:45.930 align:middle line:84%
and it gives back to me the
absolute value of that number.

00:05:45.930 --> 00:05:48.090 align:middle line:84%
And len is also a
really useful one

00:05:48.090 --> 00:05:50.430 align:middle line:84%
that we've been
using with strings.

00:05:50.430 --> 00:05:53.460 align:middle line:84%
And basically, its
input is a string,

00:05:53.460 --> 00:05:56.460 align:middle line:84%
and its output is going to
be how many characters are

00:05:56.460 --> 00:05:57.780 align:middle line:90%
in the string.

00:05:57.780 --> 00:06:00.030 align:middle line:84%
So we've already
been using functions.

00:06:00.030 --> 00:06:01.680 align:middle line:84%
The point of today's
lecture is you're

00:06:01.680 --> 00:06:06.150 align:middle line:84%
going to start to write
your own functions.

00:06:06.150 --> 00:06:09.860 align:middle line:90%
Hopefully, useful ones.

00:06:09.860 --> 00:06:13.730 align:middle line:84%
So the idea of a function is
that we want to abstract away

00:06:13.730 --> 00:06:16.310 align:middle line:84%
exactly how that function
achieves something

00:06:16.310 --> 00:06:18.350 align:middle line:90%
useful, some useful task.

00:06:18.350 --> 00:06:22.130 align:middle line:84%
And so the way that we're
going to tell other people how

00:06:22.130 --> 00:06:25.550 align:middle line:84%
to use our function is using
this idea of abstraction.

00:06:25.550 --> 00:06:29.240 align:middle line:84%
And we capture what the function
does with these things called

00:06:29.240 --> 00:06:31.400 align:middle line:90%
specifications.

00:06:31.400 --> 00:06:33.290 align:middle line:90%
They're also called docstrings.

00:06:33.290 --> 00:06:35.810 align:middle line:84%
And the docstring is
kind of like a contract

00:06:35.810 --> 00:06:38.390 align:middle line:84%
between somebody who
creates this useful function

00:06:38.390 --> 00:06:41.180 align:middle line:84%
and somebody who wants
to use the function.

00:06:41.180 --> 00:06:43.310 align:middle line:84%
The person who uses the
function might be you,

00:06:43.310 --> 00:06:46.070 align:middle line:84%
the person who wrote it, or
it might be somebody else.

00:06:46.070 --> 00:06:49.340 align:middle line:84%
And in the contract, the things
that we're going to mention

00:06:49.340 --> 00:06:51.680 align:middle line:84%
are, what are the
inputs to the function?

00:06:51.680 --> 00:06:56.300 align:middle line:84%
So in the length function,
it needs a string.

00:06:56.300 --> 00:06:58.190 align:middle line:90%
What is the function doing?

00:06:58.190 --> 00:07:01.170 align:middle line:84%
And what is the output
of the function?

00:07:01.170 --> 00:07:03.050 align:middle line:84%
What does the function
give back to somebody

00:07:03.050 --> 00:07:06.260 align:middle line:90%
who uses this function?

00:07:06.260 --> 00:07:09.230 align:middle line:84%
And we haven't actually
done this explicitly,

00:07:09.230 --> 00:07:12.690 align:middle line:84%
but you've probably seen this
as you type your code in.

00:07:12.690 --> 00:07:15.800 align:middle line:84%
So here's an example of the
absolute value function.

00:07:15.800 --> 00:07:18.170 align:middle line:84%
And it comes up
with this little pop

00:07:18.170 --> 00:07:19.740 align:middle line:90%
up here whenever you type it in.

00:07:19.740 --> 00:07:23.420 align:middle line:84%
So for example, abs,
parentheses, right here,

00:07:23.420 --> 00:07:26.570 align:middle line:84%
or if you hover over a
function in your file editor,

00:07:26.570 --> 00:07:28.940 align:middle line:84%
you'll see it pop
up this little text

00:07:28.940 --> 00:07:32.090 align:middle line:84%
box that says the
specification or the docstring.

00:07:32.090 --> 00:07:35.580 align:middle line:84%
And here, you see exactly the
signature of the function.

00:07:35.580 --> 00:07:38.690 align:middle line:84%
So it takes in one
input, the x, the value

00:07:38.690 --> 00:07:41.720 align:middle line:84%
you want to find the absolute
value of, and then, some text

00:07:41.720 --> 00:07:44.460 align:middle line:84%
here, which is what
the function does.

00:07:44.460 --> 00:07:46.220 align:middle line:84%
So the specification
of the docstring

00:07:46.220 --> 00:07:48.830 align:middle line:84%
is literally just a
multi-line comment.

00:07:48.830 --> 00:07:50.840 align:middle line:84%
There's nothing
special about it.

00:07:50.840 --> 00:07:53.450 align:middle line:84%
As long as you hit those
points, the inputs,

00:07:53.450 --> 00:07:57.360 align:middle line:84%
what the function does, and what
the function gives back to you,

00:07:57.360 --> 00:07:59.900 align:middle line:84%
you've written a
good specification.

00:07:59.900 --> 00:08:04.060 align:middle line:90%


00:08:04.060 --> 00:08:06.350 align:middle line:84%
Also, I should mention
that these contracts,

00:08:06.350 --> 00:08:07.990 align:middle line:84%
even though I call
them contracts,

00:08:07.990 --> 00:08:10.750 align:middle line:84%
they're not actually
enforced by Python.

00:08:10.750 --> 00:08:14.110 align:middle line:84%
So it's really just up to the
person who writes the code

00:08:14.110 --> 00:08:15.940 align:middle line:84%
to make sure that
their specification is

00:08:15.940 --> 00:08:19.630 align:middle line:84%
really detailed and
your function does

00:08:19.630 --> 00:08:21.490 align:middle line:90%
what you say you will.

00:08:21.490 --> 00:08:24.100 align:middle line:84%
So if your function can take
in both positive and negative

00:08:24.100 --> 00:08:25.840 align:middle line:84%
integers, for example,
then you better

00:08:25.840 --> 00:08:27.730 align:middle line:84%
make sure that the
function itself,

00:08:27.730 --> 00:08:29.410 align:middle line:84%
doing whatever task
it needs to do,

00:08:29.410 --> 00:08:33.789 align:middle line:84%
can handle both positive
and negative integers.

00:08:33.789 --> 00:08:35.860 align:middle line:84%
So once we write
these functions,

00:08:35.860 --> 00:08:38.970 align:middle line:84%
we now have these
little bits of code

00:08:38.970 --> 00:08:41.820 align:middle line:90%
that perform some useful task.

00:08:41.820 --> 00:08:43.830 align:middle line:84%
Given some input,
it'll perform this task

00:08:43.830 --> 00:08:45.970 align:middle line:90%
and give me back some output.

00:08:45.970 --> 00:08:49.110 align:middle line:84%
And now that we have these
different little pieces

00:08:49.110 --> 00:08:51.960 align:middle line:84%
of functionality,
we can go ahead

00:08:51.960 --> 00:08:55.590 align:middle line:84%
and take this
large file of code,

00:08:55.590 --> 00:08:57.480 align:middle line:84%
which you might
write from now on,

00:08:57.480 --> 00:09:00.670 align:middle line:84%
and see exactly
which pieces of code

00:09:00.670 --> 00:09:02.430 align:middle line:90%
maybe are getting repeated.

00:09:02.430 --> 00:09:04.080 align:middle line:84%
That's a clue that
that's something

00:09:04.080 --> 00:09:07.530 align:middle line:84%
that you can abstract away
into a little module, aka,

00:09:07.530 --> 00:09:08.640 align:middle line:90%
a function.

00:09:08.640 --> 00:09:11.640 align:middle line:84%
And then, you can just use
these functions to break up

00:09:11.640 --> 00:09:13.530 align:middle line:84%
the code, a very
large piece of code

00:09:13.530 --> 00:09:16.170 align:middle line:84%
into smaller, little
self-contained modules.

00:09:16.170 --> 00:09:19.860 align:middle line:84%
And then, maybe the bulk of
the work that the code is doing

00:09:19.860 --> 00:09:23.620 align:middle line:84%
is just saying,
hey, this module,

00:09:23.620 --> 00:09:24.870 align:middle line:90%
please give me this answer.

00:09:24.870 --> 00:09:26.662 align:middle line:84%
And then, this module,
give me this answer,

00:09:26.662 --> 00:09:31.060 align:middle line:84%
and then putting those
values back together again.

00:09:31.060 --> 00:09:33.250 align:middle line:84%
So these reusable
pieces of code are

00:09:33.250 --> 00:09:34.810 align:middle line:90%
called functions or procedures.

00:09:34.810 --> 00:09:36.610 align:middle line:84%
We're basically going
to try to capture

00:09:36.610 --> 00:09:40.720 align:middle line:84%
some sort of computation,
a very useful task

00:09:40.720 --> 00:09:43.130 align:middle line:84%
that you'd want to do
over and over again.

00:09:43.130 --> 00:09:47.330 align:middle line:84%
And we're going to see
some details about how

00:09:47.330 --> 00:09:49.370 align:middle line:84%
to write functions,
but essentially, it's

00:09:49.370 --> 00:09:52.610 align:middle line:84%
just going to be code that
you've already been writing,

00:09:52.610 --> 00:09:58.570 align:middle line:84%
just written in a special
way that makes it reusable.

00:09:58.570 --> 00:10:01.240 align:middle line:84%
So we're going to have
to switch the way we've

00:10:01.240 --> 00:10:02.985 align:middle line:84%
been thinking about
code for a bit now

00:10:02.985 --> 00:10:04.360 align:middle line:84%
that we're
introducing functions.

00:10:04.360 --> 00:10:06.527 align:middle line:84%
Because right now, when
we've been writing functions

00:10:06.527 --> 00:10:10.990 align:middle line:84%
in a file, we basically write
some code top to bottom,

00:10:10.990 --> 00:10:12.700 align:middle line:84%
and then, we think
about that code

00:10:12.700 --> 00:10:17.400 align:middle line:84%
as being executed line
by line, top to bottom.

00:10:17.400 --> 00:10:20.760 align:middle line:84%
But now that we're creating
these things called functions,

00:10:20.760 --> 00:10:23.610 align:middle line:84%
little blocks of code
that we can use many times

00:10:23.610 --> 00:10:25.660 align:middle line:84%
in many different
places in our code,

00:10:25.660 --> 00:10:27.510 align:middle line:84%
we're actually going
to introduce the idea

00:10:27.510 --> 00:10:29.080 align:middle line:90%
of defining a function.

00:10:29.080 --> 00:10:32.180 align:middle line:84%
So that means we're going
to write a piece of code,

00:10:32.180 --> 00:10:34.430 align:middle line:84%
and all that piece of
code is going to do

00:10:34.430 --> 00:10:37.760 align:middle line:84%
is tell Python that this is
a module or a function that

00:10:37.760 --> 00:10:41.020 align:middle line:90%
exists in my program.

00:10:41.020 --> 00:10:44.350 align:middle line:84%
All we're doing is
defining the function.

00:10:44.350 --> 00:10:46.750 align:middle line:84%
But we're not actually
going to run the function

00:10:46.750 --> 00:10:48.640 align:middle line:90%
when we define it.

00:10:48.640 --> 00:10:50.950 align:middle line:84%
And that's the
difference, the way

00:10:50.950 --> 00:10:53.180 align:middle line:84%
we're going to have to
shift our thinking here.

00:10:53.180 --> 00:10:55.150 align:middle line:84%
So when you define
a function, you just

00:10:55.150 --> 00:10:58.180 align:middle line:84%
tell Python that here is some
useful piece of code that

00:10:58.180 --> 00:11:01.480 align:middle line:84%
exists that does something,
but it doesn't actually

00:11:01.480 --> 00:11:04.580 align:middle line:90%
run until you call the function.

00:11:04.580 --> 00:11:06.470 align:middle line:84%
And the cool thing
about writing a function

00:11:06.470 --> 00:11:11.360 align:middle line:84%
is, once you wrote it once, you
can make 100 different function

00:11:11.360 --> 00:11:14.120 align:middle line:84%
calls to that one piece of
code that you wrote later

00:11:14.120 --> 00:11:15.800 align:middle line:90%
on in your program.

00:11:15.800 --> 00:11:17.770 align:middle line:84%
So you can call the
function many times

00:11:17.770 --> 00:11:19.960 align:middle line:84%
with different inputs to
give you different outputs,

00:11:19.960 --> 00:11:22.640 align:middle line:84%
but you only had to
write it one time.

00:11:22.640 --> 00:11:25.990 align:middle line:84%
So I would compare this to
when we write code in a file.

00:11:25.990 --> 00:11:28.870 align:middle line:84%
When we write code
in a file, yes, we

00:11:28.870 --> 00:11:30.280 align:middle line:84%
can write a whole
bunch of lines,

00:11:30.280 --> 00:11:34.150 align:middle line:84%
but this code isn't running
as we're writing it.

00:11:34.150 --> 00:11:38.790 align:middle line:84%
We have to actually push the
Run button to run that file.

00:11:38.790 --> 00:11:40.468 align:middle line:84%
So similarly, when
we're telling Python

00:11:40.468 --> 00:11:42.260 align:middle line:84%
that I'm going to create
this function that

00:11:42.260 --> 00:11:45.920 align:middle line:84%
does something useful, it's not
actually running those lines.

00:11:45.920 --> 00:11:52.250 align:middle line:84%
We have to tell Python that
we want to run this function.

00:11:52.250 --> 00:11:55.270 align:middle line:84%
So the first thing we're
going to do in this lecture

00:11:55.270 --> 00:11:57.070 align:middle line:84%
is just actually
create a function.

00:11:57.070 --> 00:11:59.260 align:middle line:84%
I'm going to show you how
to define a function, so

00:11:59.260 --> 00:12:01.000 align:middle line:84%
tell Python that
this function exists.

00:12:01.000 --> 00:12:03.490 align:middle line:84%
And then, we'll see how to
actually run the function

00:12:03.490 --> 00:12:05.810 align:middle line:90%
to give us some useful values.

00:12:05.810 --> 00:12:07.930 align:middle line:84%
So the function
characteristics are

00:12:07.930 --> 00:12:11.120 align:middle line:84%
going to be, the function
has to have a name.

00:12:11.120 --> 00:12:13.630 align:middle line:84%
So just like when
you create variables

00:12:13.630 --> 00:12:17.628 align:middle line:84%
that store some useful value,
like pi to 20 decimal digits

00:12:17.628 --> 00:12:19.420 align:middle line:84%
that you want to reuse
over and over again,

00:12:19.420 --> 00:12:21.440 align:middle line:84%
we're going to
create a function,

00:12:21.440 --> 00:12:25.120 align:middle line:84%
and that name is kind of
like a handle for us to refer

00:12:25.120 --> 00:12:29.740 align:middle line:84%
to this large chunk of code that
does something useful for us.

00:12:29.740 --> 00:12:33.040 align:middle line:84%
A function has some inputs
called parameters or arguments.

00:12:33.040 --> 00:12:37.180 align:middle line:84%
It can have no inputs,
or more, or one or more.

00:12:37.180 --> 00:12:39.470 align:middle line:84%
And a function should
have a docstring.

00:12:39.470 --> 00:12:41.050 align:middle line:90%
So this is the specification.

00:12:41.050 --> 00:12:44.860 align:middle line:84%
Again, just a multi-line comment
that tells the user, the person

00:12:44.860 --> 00:12:47.170 align:middle line:84%
who wants to use this
function, the inputs, what

00:12:47.170 --> 00:12:49.690 align:middle line:84%
the function does, and what
the output, or the return,

00:12:49.690 --> 00:12:53.000 align:middle line:84%
or whatever this
function will do for you.

00:12:53.000 --> 00:12:54.670 align:middle line:84%
And then, the body
of the function

00:12:54.670 --> 00:12:58.480 align:middle line:84%
is just Python code,
exactly the kind of code

00:12:58.480 --> 00:13:00.490 align:middle line:84%
we've already been
writing, except not

00:13:00.490 --> 00:13:01.522 align:middle line:90%
wrapped in a function.

00:13:01.522 --> 00:13:03.730 align:middle line:84%
So if you found yourself
writing a piece of code that

00:13:03.730 --> 00:13:06.010 align:middle line:84%
did something useful,
you can totally

00:13:06.010 --> 00:13:07.360 align:middle line:90%
wrap that in a function.

00:13:07.360 --> 00:13:10.340 align:middle line:84%
And we'll see how
to do that today.

00:13:10.340 --> 00:13:13.160 align:middle line:84%
So the body of the function is
just a bunch of lines of code

00:13:13.160 --> 00:13:14.960 align:middle line:90%
that do this useful task.

00:13:14.960 --> 00:13:18.170 align:middle line:84%
The only difference in the
body is that, at some point,

00:13:18.170 --> 00:13:19.850 align:middle line:90%
this function has to end.

00:13:19.850 --> 00:13:21.500 align:middle line:90%
It has finished its task.

00:13:21.500 --> 00:13:25.400 align:middle line:84%
It figured out a final value,
this useful thing that's

00:13:25.400 --> 00:13:27.740 align:middle line:84%
the result of your
task, and you want

00:13:27.740 --> 00:13:30.590 align:middle line:84%
to give this value
back to somebody

00:13:30.590 --> 00:13:32.100 align:middle line:90%
who's using this function.

00:13:32.100 --> 00:13:35.030 align:middle line:84%
And we do that using this
return keyword, as we're

00:13:35.030 --> 00:13:37.570 align:middle line:90%
going to see in the next slide.

00:13:37.570 --> 00:13:41.220 align:middle line:84%
So here's an example of
a really simple function.

00:13:41.220 --> 00:13:43.710 align:middle line:90%
So it's just a definition.

00:13:43.710 --> 00:13:46.840 align:middle line:84%
So again, these lines
of code do not run.

00:13:46.840 --> 00:13:49.330 align:middle line:84%
Here, we're just telling
Python that we're creating

00:13:49.330 --> 00:13:52.060 align:middle line:90%
a function that does something.

00:13:52.060 --> 00:13:55.877 align:middle line:84%
So we kick that off with
the def, define keyword.

00:13:55.877 --> 00:13:56.710 align:middle line:90%
So notice it's blue.

00:13:56.710 --> 00:14:00.500 align:middle line:84%
If you type it in your code,
you'll notice it changes color.

00:14:00.500 --> 00:14:03.550 align:middle line:84%
So def tells Python we're
defining a function.

00:14:03.550 --> 00:14:05.093 align:middle line:84%
The next is the name
of the function.

00:14:05.093 --> 00:14:06.760 align:middle line:84%
So this should be
something descriptive.

00:14:06.760 --> 00:14:09.220 align:middle line:84%
Usually, it's an action
word, because a function

00:14:09.220 --> 00:14:10.220 align:middle line:90%
does something.

00:14:10.220 --> 00:14:13.660 align:middle line:84%
So you want like,
an actiony-type name

00:14:13.660 --> 00:14:15.670 align:middle line:90%
for your function.

00:14:15.670 --> 00:14:18.240 align:middle line:90%
Then, we have parentheses.

00:14:18.240 --> 00:14:20.540 align:middle line:84%
And inside the
parentheses, you have

00:14:20.540 --> 00:14:23.330 align:middle line:84%
any of the inputs, the
parameters, the arguments

00:14:23.330 --> 00:14:24.650 align:middle line:90%
to the function.

00:14:24.650 --> 00:14:27.710 align:middle line:84%
So what should the user give
you as input to this function?

00:14:27.710 --> 00:14:30.030 align:middle line:90%
And then, of course, a colon.

00:14:30.030 --> 00:14:33.560 align:middle line:84%
So in that line right
there, the only thing

00:14:33.560 --> 00:14:35.810 align:middle line:84%
that is "customizable,"
quote unquote,

00:14:35.810 --> 00:14:38.690 align:middle line:84%
is the name of the function
and the parameters.

00:14:38.690 --> 00:14:41.070 align:middle line:84%
If there's zero parameters
you put nothing in there.

00:14:41.070 --> 00:14:44.900 align:middle line:84%
If there's more than one,
you separate them by commas.

00:14:44.900 --> 00:14:48.440 align:middle line:84%
Everything else should
be standard, the def,

00:14:48.440 --> 00:14:51.700 align:middle line:84%
the parentheses, and
the colon at the end.

00:14:51.700 --> 00:14:54.010 align:middle line:84%
Since we have a
colon at the end,

00:14:54.010 --> 00:14:58.330 align:middle line:84%
that means we have to
indent the next bit of code.

00:14:58.330 --> 00:15:01.090 align:middle line:84%
The indentation will tell
Python that the rest of this

00:15:01.090 --> 00:15:02.420 align:middle line:90%
is part of the function.

00:15:02.420 --> 00:15:04.390 align:middle line:84%
So everything from
here on out is part

00:15:04.390 --> 00:15:06.020 align:middle line:90%
of the function definition.

00:15:06.020 --> 00:15:08.780 align:middle line:84%
So we have our
docstring, of course.

00:15:08.780 --> 00:15:11.778 align:middle line:84%
You start with triple quotes and
you end it with triple quotes.

00:15:11.778 --> 00:15:13.570 align:middle line:84%
And in it, you can
write whatever you want.

00:15:13.570 --> 00:15:18.250 align:middle line:84%
Just treat it like a comment
that's on multiple lines.

00:15:18.250 --> 00:15:21.190 align:middle line:84%
And you can see here, I've
said that this function takes

00:15:21.190 --> 00:15:25.760 align:middle line:84%
in an input, i, which I restrict
to be a positive integer.

00:15:25.760 --> 00:15:29.820 align:middle line:84%
And then, I say what the
input gives back to the user.

00:15:29.820 --> 00:15:32.660 align:middle line:84%
So it will return true
if i is an even number,

00:15:32.660 --> 00:15:35.970 align:middle line:84%
and it will return
false otherwise.

00:15:35.970 --> 00:15:39.440 align:middle line:84%
So I've hit all the points, the
inputs, what the function does,

00:15:39.440 --> 00:15:41.330 align:middle line:84%
and what it gives
back to whoever

00:15:41.330 --> 00:15:42.530 align:middle line:90%
wants this function to run.

00:15:42.530 --> 00:15:45.920 align:middle line:90%


00:15:45.920 --> 00:15:48.810 align:middle line:84%
Beyond that, we have the
body of the function.

00:15:48.810 --> 00:15:51.537 align:middle line:84%
So here, you notice
it's just lines of code

00:15:51.537 --> 00:15:53.120 align:middle line:84%
that you would have
written otherwise.

00:15:53.120 --> 00:15:56.990 align:middle line:84%
If you were given the
problem on a quiz that said,

00:15:56.990 --> 00:15:59.810 align:middle line:84%
given i defined for
you, write some code

00:15:59.810 --> 00:16:04.485 align:middle line:84%
that prints true if the
number is even and false

00:16:04.485 --> 00:16:05.360 align:middle line:90%
if the number is odd.

00:16:05.360 --> 00:16:08.730 align:middle line:84%
This is basically lines of
code that you would type in.

00:16:08.730 --> 00:16:13.790 align:middle line:84%
The only difference is
this little return here.

00:16:13.790 --> 00:16:19.170 align:middle line:84%
The function is some lines
of code that do a task.

00:16:19.170 --> 00:16:24.290 align:middle line:84%
And that task, when it finishes,
has to give something back.

00:16:24.290 --> 00:16:27.050 align:middle line:84%
It can't just sit
there, I guess.

00:16:27.050 --> 00:16:31.070 align:middle line:84%
And the thing that it gives back
to whoever wants this function

00:16:31.070 --> 00:16:38.240 align:middle line:84%
to run is set up by this
return statement here.

00:16:38.240 --> 00:16:41.990 align:middle line:84%
So if the number is divisible
by 0, we return true,

00:16:41.990 --> 00:16:43.380 align:middle line:90%
and else, we return false.

00:16:43.380 --> 00:16:45.980 align:middle line:84%
So one of these either
true or false values

00:16:45.980 --> 00:16:48.030 align:middle line:84%
will be returned
by the function.

00:16:48.030 --> 00:16:50.143 align:middle line:84%
So this is you can think
of it like the output

00:16:50.143 --> 00:16:50.810 align:middle line:90%
of the function.

00:16:50.810 --> 00:16:55.640 align:middle line:90%


00:16:55.640 --> 00:16:57.180 align:middle line:90%
OK, questions so far?

00:16:57.180 --> 00:16:58.610 align:middle line:90%
Does this make sense?

00:16:58.610 --> 00:17:01.700 align:middle line:84%
Again, this is just us
creating this function

00:17:01.700 --> 00:17:04.520 align:middle line:84%
inside the computer,
inside Python.

00:17:04.520 --> 00:17:06.799 align:middle line:84%
We're not actually running
these lines of code yet.

00:17:06.799 --> 00:17:11.460 align:middle line:90%


00:17:11.460 --> 00:17:15.359 align:middle line:84%
So if you are given
a larger problem,

00:17:15.359 --> 00:17:16.980 align:middle line:84%
I just want to take
a couple slides

00:17:16.980 --> 00:17:20.560 align:middle line:84%
to talk about how you think
about writing the function.

00:17:20.560 --> 00:17:21.990 align:middle line:90%
This was a really easy one.

00:17:21.990 --> 00:17:26.819 align:middle line:84%
So obviously, it's not
that hard to write,

00:17:26.819 --> 00:17:30.180 align:middle line:84%
but what is the thought process
if you are given a larger

00:17:30.180 --> 00:17:32.370 align:middle line:84%
problem, like in English
or something like that,

00:17:32.370 --> 00:17:36.390 align:middle line:84%
and you wanted to translate
this into a piece of code that

00:17:36.390 --> 00:17:39.270 align:middle line:84%
does something
functionally interesting?

00:17:39.270 --> 00:17:41.610 align:middle line:84%
So you think about
what the problem is.

00:17:41.610 --> 00:17:44.310 align:middle line:84%
So our problem is,
given an integer,

00:17:44.310 --> 00:17:47.210 align:middle line:90%
figure out if it's even or odd.

00:17:47.210 --> 00:17:50.870 align:middle line:84%
So given this statement,
you could come up

00:17:50.870 --> 00:17:54.080 align:middle line:84%
with a name of
this piece of code

00:17:54.080 --> 00:17:55.490 align:middle line:90%
that's functionally interesting.

00:17:55.490 --> 00:18:00.906 align:middle line:90%
So is_even is a good name.

00:18:00.906 --> 00:18:04.650 align:middle line:84%
And we can also come up with
the inputs for this function.

00:18:04.650 --> 00:18:07.080 align:middle line:84%
So i, we are only
given one number,

00:18:07.080 --> 00:18:08.580 align:middle line:84%
so there's no need
for this function

00:18:08.580 --> 00:18:11.220 align:middle line:90%
to take in any other inputs.

00:18:11.220 --> 00:18:13.860 align:middle line:84%
And then, using that
description, we can now

00:18:13.860 --> 00:18:15.670 align:middle line:84%
start to fill in the
docstring that says,

00:18:15.670 --> 00:18:18.570 align:middle line:84%
well, our input is going
to be a positive integer.

00:18:18.570 --> 00:18:22.380 align:middle line:84%
We could use math to figure
out restrictions on the inputs.

00:18:22.380 --> 00:18:24.900 align:middle line:84%
And then, we can write the
rest of the docstring that

00:18:24.900 --> 00:18:27.360 align:middle line:84%
tells us what to
return and when,

00:18:27.360 --> 00:18:30.550 align:middle line:90%
what the function is doing.

00:18:30.550 --> 00:18:34.660 align:middle line:84%
And once you have that, you
can just solve the problem.

00:18:34.660 --> 00:18:37.440 align:middle line:84%
So for us, we solve
the problem by saying,

00:18:37.440 --> 00:18:40.800 align:middle line:84%
if the remainder when we divide
i by 2 is 0, we return true,

00:18:40.800 --> 00:18:43.440 align:middle line:90%
and otherwise, we return false.

00:18:43.440 --> 00:18:48.030 align:middle line:84%
So that's code that you could
have already written without,

00:18:48.030 --> 00:18:49.890 align:middle line:90%
actually, this function lecture.

00:18:49.890 --> 00:18:52.830 align:middle line:84%
But now, we're putting it
in the context of a function

00:18:52.830 --> 00:18:53.553 align:middle line:90%
definition.

00:18:53.553 --> 00:18:55.470 align:middle line:84%
So we're going to be
able to run this function

00:18:55.470 --> 00:18:57.615 align:middle line:84%
with many different
inputs to give us

00:18:57.615 --> 00:18:59.490 align:middle line:84%
a bunch of different
outputs, whether a bunch

00:18:59.490 --> 00:19:02.820 align:middle line:84%
of these different
numbers are even or not.

00:19:02.820 --> 00:19:06.380 align:middle line:90%


00:19:06.380 --> 00:19:08.380 align:middle line:84%
So when we're writing
the body of the code,

00:19:08.380 --> 00:19:10.390 align:middle line:84%
the only difference from
what you've been doing

00:19:10.390 --> 00:19:12.100 align:middle line:90%
is the return statement.

00:19:12.100 --> 00:19:14.720 align:middle line:84%
Instead of printing
something out to the console,

00:19:14.720 --> 00:19:17.680 align:middle line:84%
we're going to return
a value to somebody

00:19:17.680 --> 00:19:22.380 align:middle line:84%
who wants to know whether
the number i is even or odd.

00:19:22.380 --> 00:19:25.050 align:middle line:84%
The function can also
print stuff to the console.

00:19:25.050 --> 00:19:26.940 align:middle line:84%
But the key thing
here is you want

00:19:26.940 --> 00:19:30.210 align:middle line:90%
to return a value to the user.

00:19:30.210 --> 00:19:32.732 align:middle line:84%
And after you wrote
code, right off the bat,

00:19:32.732 --> 00:19:34.440 align:middle line:84%
and you tested it and
made sure it works,

00:19:34.440 --> 00:19:37.240 align:middle line:84%
you can improve the
code a little bit.

00:19:37.240 --> 00:19:45.120 align:middle line:84%
So here, we're improving it by
noticing that i%2==0 here is

00:19:45.120 --> 00:19:47.700 align:middle line:90%
actually already a boolean.

00:19:47.700 --> 00:19:52.260 align:middle line:90%
If i is even, 3% 2==0 is true.

00:19:52.260 --> 00:19:54.370 align:middle line:84%
And otherwise,
it's already false.

00:19:54.370 --> 00:19:58.510 align:middle line:84%
So these four lines of code
basically say, if true,

00:19:58.510 --> 00:19:59.910 align:middle line:90%
return true.

00:19:59.910 --> 00:20:02.920 align:middle line:90%
Else, return false.

00:20:02.920 --> 00:20:08.100 align:middle line:84%
So our improvement can just be
to return whether i%2==0 right

00:20:08.100 --> 00:20:09.780 align:middle line:90%
off the bat.

00:20:09.780 --> 00:20:12.390 align:middle line:84%
So here, we're going
to return either true

00:20:12.390 --> 00:20:15.220 align:middle line:84%
or return false
based on what i is.

00:20:15.220 --> 00:20:17.840 align:middle line:90%


00:20:17.840 --> 00:20:19.430 align:middle line:90%
So at this point--

00:20:19.430 --> 00:20:21.860 align:middle line:84%
again, sorry I'm
stressing this enough--

00:20:21.860 --> 00:20:22.520 align:middle line:90%
too much.

00:20:22.520 --> 00:20:24.350 align:middle line:84%
But it's really
important to understand

00:20:24.350 --> 00:20:27.140 align:middle line:84%
that once we write
these lines of code

00:20:27.140 --> 00:20:31.010 align:middle line:84%
in the context of a function
definition, these lines of code

00:20:31.010 --> 00:20:32.870 align:middle line:90%
do not run.

00:20:32.870 --> 00:20:37.230 align:middle line:84%
They basically
just sit in Python

00:20:37.230 --> 00:20:40.320 align:middle line:84%
saying that there are
these lines of code that

00:20:40.320 --> 00:20:45.000 align:middle line:84%
correspond to some function
object whose name is even.

00:20:45.000 --> 00:20:47.600 align:middle line:90%
That's it.

00:20:47.600 --> 00:20:50.800 align:middle line:84%
So what we need to do now
is to actually tell Python

00:20:50.800 --> 00:20:53.540 align:middle line:90%
to run these lines of code.

00:20:53.540 --> 00:20:56.030 align:middle line:84%
To do that, we make
a function call.

00:20:56.030 --> 00:20:58.910 align:middle line:84%
And again, we've already been
doing function calls, just

00:20:58.910 --> 00:21:01.790 align:middle line:84%
to functions that
already exist in Python,

00:21:01.790 --> 00:21:06.180 align:middle line:84%
just Python itself, max,
absolute, len, all that stuff.

00:21:06.180 --> 00:21:08.450 align:middle line:84%
But now, we're making a
function call to something

00:21:08.450 --> 00:21:12.530 align:middle line:84%
that we wrote, this
nice piece of code that

00:21:12.530 --> 00:21:16.970 align:middle line:84%
tells us if a number, the
input, is even or not.

00:21:16.970 --> 00:21:23.490 align:middle line:84%
So here, I'm going to invoke
the name of my function, aka,

00:21:23.490 --> 00:21:25.240 align:middle line:84%
I'm going to call the
name of my function.

00:21:25.240 --> 00:21:26.800 align:middle line:84%
I'm basically just
typing in the name

00:21:26.800 --> 00:21:28.510 align:middle line:90%
of my function in the code.

00:21:28.510 --> 00:21:31.570 align:middle line:84%
Parentheses, and then, the
inputs the function expects.

00:21:31.570 --> 00:21:33.850 align:middle line:84%
There's only one, the
number I want to figure out

00:21:33.850 --> 00:21:35.410 align:middle line:90%
if it's even or odd.

00:21:35.410 --> 00:21:37.810 align:middle line:90%
And then, that's it.

00:21:37.810 --> 00:21:39.520 align:middle line:84%
So I've got the
name of my function,

00:21:39.520 --> 00:21:41.980 align:middle line:84%
and then all the
inputs, the parameters

00:21:41.980 --> 00:21:44.460 align:middle line:90%
that this function expects.

00:21:44.460 --> 00:21:47.670 align:middle line:84%
At this point, Python goes
into the function body,

00:21:47.670 --> 00:21:52.390 align:middle line:84%
it runs the function, and
it returns back a value.

00:21:52.390 --> 00:21:57.330 align:middle line:84%
So whatever the value is
associated with the return is,

00:21:57.330 --> 00:21:59.910 align:middle line:84%
that value will
immediately be given back

00:21:59.910 --> 00:22:01.650 align:middle line:90%
to whoever called it.

00:22:01.650 --> 00:22:03.040 align:middle line:90%
What does that mean?

00:22:03.040 --> 00:22:06.390 align:middle line:84%
Well, that return
value will completely

00:22:06.390 --> 00:22:08.325 align:middle line:90%
replace this function call.

00:22:08.325 --> 00:22:14.200 align:middle line:90%


00:22:14.200 --> 00:22:15.688 align:middle line:90%
Let's think back to expressions.

00:22:15.688 --> 00:22:17.230 align:middle line:84%
Do you remember when
we were learning

00:22:17.230 --> 00:22:19.600 align:middle line:84%
about Python
expressions and I said

00:22:19.600 --> 00:22:22.810 align:middle line:84%
you have something like object,
operator, object, like 3 plus

00:22:22.810 --> 00:22:23.440 align:middle line:90%
2?

00:22:23.440 --> 00:22:24.820 align:middle line:90%
That was an expression.

00:22:24.820 --> 00:22:27.250 align:middle line:84%
And Python went in,
evaluated that expression,

00:22:27.250 --> 00:22:32.710 align:middle line:84%
and replaced that entire
expression by the value, 5.

00:22:32.710 --> 00:22:34.460 align:middle line:90%
This is exactly the same thing.

00:22:34.460 --> 00:22:37.360 align:middle line:84%
In fact, functions are kind
of like Python expressions.

00:22:37.360 --> 00:22:39.610 align:middle line:90%
They do something useful.

00:22:39.610 --> 00:22:41.920 align:middle line:84%
It's just that it's
not math or something

00:22:41.920 --> 00:22:43.240 align:middle line:90%
like that that gets evaluated.

00:22:43.240 --> 00:22:46.780 align:middle line:84%
It's a bunch of lines of
code that get evaluated.

00:22:46.780 --> 00:22:53.370 align:middle line:84%
But in the end, that function
returns back only one value.

00:22:53.370 --> 00:22:57.250 align:middle line:84%
And that value replaces
the entire function call.

00:22:57.250 --> 00:22:59.040 align:middle line:84%
So this entire
function call is going

00:22:59.040 --> 00:23:02.490 align:middle line:84%
to be, basically,
replaced by false,

00:23:02.490 --> 00:23:04.400 align:middle line:90%
because it's an odd number.

00:23:04.400 --> 00:23:09.200 align:middle line:84%
And the next one is going to
be replaced by true, the return

00:23:09.200 --> 00:23:09.950 align:middle line:90%
from the function.

00:23:09.950 --> 00:23:12.510 align:middle line:90%


00:23:12.510 --> 00:23:15.080 align:middle line:84%
So the way that the
code looks, just

00:23:15.080 --> 00:23:18.590 align:middle line:84%
this definition of is even and
then running a function call

00:23:18.590 --> 00:23:19.205 align:middle line:90%
is this.

00:23:19.205 --> 00:23:22.940 align:middle line:84%
This is all that we
would have in our file.

00:23:22.940 --> 00:23:25.370 align:middle line:84%
So here, we have our
function definition,

00:23:25.370 --> 00:23:27.800 align:middle line:84%
and then, at the same
indentation level,

00:23:27.800 --> 00:23:29.150 align:middle line:90%
we have a function call.

00:23:29.150 --> 00:23:31.700 align:middle line:84%
Because the call is not
part of the function.

00:23:31.700 --> 00:23:36.470 align:middle line:84%
The call is just making use
of the function that we wrote.

00:23:36.470 --> 00:23:37.908 align:middle line:90%
So what exactly happens?

00:23:37.908 --> 00:23:39.450 align:middle line:84%
We'll do a little
bit of step-by-step

00:23:39.450 --> 00:23:41.533 align:middle line:84%
now going a little bit
into more detail as to what

00:23:41.533 --> 00:23:45.630 align:middle line:84%
exactly happens when we
make the function call.

00:23:45.630 --> 00:23:47.660 align:middle line:84%
So when we make
the function call--

00:23:47.660 --> 00:23:49.280 align:middle line:90%
again, function definition.

00:23:49.280 --> 00:23:53.000 align:middle line:84%
This just tells Python we
have this function that

00:23:53.000 --> 00:23:56.870 align:middle line:84%
does something in our
program, and then, here, we

00:23:56.870 --> 00:23:59.640 align:middle line:90%
have the function call.

00:23:59.640 --> 00:24:02.250 align:middle line:84%
As soon as Python sees
the function call,

00:24:02.250 --> 00:24:05.400 align:middle line:84%
that's when it starts
doing something useful.

00:24:05.400 --> 00:24:08.410 align:middle line:84%
Up here, it just sort of
stores this in memory.

00:24:08.410 --> 00:24:11.640 align:middle line:84%
So as soon as it sees the
function call is even 3,

00:24:11.640 --> 00:24:15.700 align:middle line:84%
it looks at the input
parameter to the function call.

00:24:15.700 --> 00:24:18.470 align:middle line:84%
And here, you see
we have a value.

00:24:18.470 --> 00:24:21.190 align:middle line:90%
It's an actual, tangible object.

00:24:21.190 --> 00:24:23.320 align:middle line:90%
It's not some random variable.

00:24:23.320 --> 00:24:24.800 align:middle line:90%
It's not something abstract.

00:24:24.800 --> 00:24:27.490 align:middle line:90%
It's a number 3.

00:24:27.490 --> 00:24:30.100 align:middle line:84%
The i up here from our
function definition

00:24:30.100 --> 00:24:31.990 align:middle line:90%
is called a formal parameter.

00:24:31.990 --> 00:24:33.370 align:middle line:90%
It's abstract.

00:24:33.370 --> 00:24:35.980 align:middle line:84%
We wrote the body of the
function assuming the user

00:24:35.980 --> 00:24:38.440 align:middle line:84%
will eventually give
us a value for i.

00:24:38.440 --> 00:24:41.140 align:middle line:84%
But in the actual
body of the function,

00:24:41.140 --> 00:24:43.150 align:middle line:84%
i is just a variable
we're using.

00:24:43.150 --> 00:24:44.740 align:middle line:90%
Kind of like in the quizzes.

00:24:44.740 --> 00:24:47.140 align:middle line:84%
For now, I've been
saying, assume

00:24:47.140 --> 00:24:50.170 align:middle line:84%
you're given some number
n that's defined for you.

00:24:50.170 --> 00:24:52.150 align:middle line:84%
Write the code
assuming this number.

00:24:52.150 --> 00:24:53.590 align:middle line:90%
It's the exact same thing.

00:24:53.590 --> 00:24:56.380 align:middle line:84%
We write the code at the
body of the function assuming

00:24:56.380 --> 00:24:59.460 align:middle line:90%
we know a value for i.

00:24:59.460 --> 00:25:02.370 align:middle line:84%
So when Python sees this
function call with 3,

00:25:02.370 --> 00:25:05.423 align:middle line:84%
it goes into the body of
the function and says,

00:25:05.423 --> 00:25:06.840 align:middle line:84%
all right, what
are my parameters?

00:25:06.840 --> 00:25:07.620 align:middle line:90%
There's only one.

00:25:07.620 --> 00:25:08.490 align:middle line:90%
It's i.

00:25:08.490 --> 00:25:11.040 align:middle line:84%
And it's going to
map them one by one

00:25:11.040 --> 00:25:14.320 align:middle line:84%
to all the actual parameters
given in the function call.

00:25:14.320 --> 00:25:17.740 align:middle line:90%
So basically just maps i to 3.

00:25:17.740 --> 00:25:20.570 align:middle line:84%
And then, it executes
the body of the function.

00:25:20.570 --> 00:25:22.840 align:middle line:84%
So it replaces
everywhere you see i.

00:25:22.840 --> 00:25:25.287 align:middle line:84%
So it might have a
longer bit of code here,

00:25:25.287 --> 00:25:26.620 align:middle line:90%
but here, we just have one line.

00:25:26.620 --> 00:25:30.090 align:middle line:90%
It replaces i with 3.

00:25:30.090 --> 00:25:32.670 align:middle line:90%
So we have 3%2==0.

00:25:32.670 --> 00:25:36.750 align:middle line:84%
Now, we have a
tangible value, false.

00:25:36.750 --> 00:25:39.830 align:middle line:84%
So this expression is
replaced with false.

00:25:39.830 --> 00:25:43.680 align:middle line:84%
And so this line of code
here will return false.

00:25:43.680 --> 00:25:46.610 align:middle line:84%
And as soon as Python
sees that return value,

00:25:46.610 --> 00:25:48.740 align:middle line:84%
it immediately
exits the function

00:25:48.740 --> 00:25:51.260 align:middle line:84%
and gives back the
value that you're

00:25:51.260 --> 00:25:53.310 align:middle line:90%
returning to whoever called it.

00:25:53.310 --> 00:25:57.440 align:middle line:84%
So this entire function call
here will be replaced by false.

00:25:57.440 --> 00:26:01.220 align:middle line:90%


00:26:01.220 --> 00:26:05.980 align:middle line:84%
That was very step-by-step,
but does it make sense?

00:26:05.980 --> 00:26:06.940 align:middle line:90%
OK.

00:26:06.940 --> 00:26:11.140 align:middle line:84%
So this is a program
that doesn't do anything.

00:26:11.140 --> 00:26:14.170 align:middle line:84%
If somebody were to write
this program and run it,

00:26:14.170 --> 00:26:17.980 align:middle line:84%
it doesn't actually show
anything to the user.

00:26:17.980 --> 00:26:20.470 align:middle line:84%
That's because, in
our program, it's

00:26:20.470 --> 00:26:23.920 align:middle line:84%
like we had just written a
line of code that said false.

00:26:23.920 --> 00:26:26.990 align:middle line:84%
Does that get printed
to the output?

00:26:26.990 --> 00:26:28.100 align:middle line:90%
No, right?

00:26:28.100 --> 00:26:31.190 align:middle line:84%
What we need to do is
do something useful now

00:26:31.190 --> 00:26:34.740 align:middle line:84%
that we have the result
of a function call.

00:26:34.740 --> 00:26:38.540 align:middle line:84%
So one useful thing we can do
is to actually print the result

00:26:38.540 --> 00:26:40.220 align:middle line:90%
of the function call.

00:26:40.220 --> 00:26:43.190 align:middle line:84%
So here, we have
print, and then, I

00:26:43.190 --> 00:26:45.380 align:middle line:84%
have my function
call I had up here.

00:26:45.380 --> 00:26:48.180 align:middle line:84%
I'm just sticking it
inside the print statement.

00:26:48.180 --> 00:26:52.100 align:middle line:84%
And Python will, as before,
evaluate is_even(3).

00:26:52.100 --> 00:26:54.560 align:middle line:84%
This is replaced with false,
and this line essentially

00:26:54.560 --> 00:26:55.535 align:middle line:90%
becomes print false.

00:26:55.535 --> 00:26:59.240 align:middle line:90%


00:26:59.240 --> 00:27:03.200 align:middle line:84%
And so the way this looks
in our actual code is this.

00:27:03.200 --> 00:27:10.570 align:middle line:84%
So here, I have this is_even
function, the inefficient way

00:27:10.570 --> 00:27:12.260 align:middle line:90%
of writing it.

00:27:12.260 --> 00:27:14.020 align:middle line:84%
I've got two
function calls here.

00:27:14.020 --> 00:27:18.170 align:middle line:84%
But if I run the code, it
doesn't print anything.

00:27:18.170 --> 00:27:20.000 align:middle line:84%
I need to do something
useful with them.

00:27:20.000 --> 00:27:21.800 align:middle line:84%
And one useful
thing we can do is

00:27:21.800 --> 00:27:24.060 align:middle line:84%
to print the result of
these function calls.

00:27:24.060 --> 00:27:26.720 align:middle line:84%
So now that I've wrapped these
calls inside a print statement,

00:27:26.720 --> 00:27:28.370 align:middle line:90%
I see the output in my console.

00:27:28.370 --> 00:27:31.870 align:middle line:90%


00:27:31.870 --> 00:27:35.650 align:middle line:84%
So we're writing-- so we're
kind of separating ourselves

00:27:35.650 --> 00:27:37.390 align:middle line:90%
when we're writing code now.

00:27:37.390 --> 00:27:39.730 align:middle line:84%
One, we're defining
a function, some code

00:27:39.730 --> 00:27:41.330 align:middle line:90%
that does something useful.

00:27:41.330 --> 00:27:44.920 align:middle line:84%
And then, two, we're
using this function

00:27:44.920 --> 00:27:47.950 align:middle line:84%
that we wrote to
make function calls.

00:27:47.950 --> 00:27:49.900 align:middle line:84%
And the beauty about
writing the function

00:27:49.900 --> 00:27:52.090 align:middle line:84%
is we only write it
once and debug it once,

00:27:52.090 --> 00:27:56.020 align:middle line:84%
but now, we can run it as
many times as we'd like.

00:27:56.020 --> 00:28:00.280 align:middle line:84%
Without functions, we'd find
ourselves copying and pasting

00:28:00.280 --> 00:28:01.990 align:middle line:84%
that piece of code
that does something

00:28:01.990 --> 00:28:04.480 align:middle line:84%
useful in many places
in our code, which

00:28:04.480 --> 00:28:05.560 align:middle line:90%
could lead to errors.

00:28:05.560 --> 00:28:07.000 align:middle line:90%
The code is hard to modify.

00:28:07.000 --> 00:28:09.520 align:middle line:84%
It's hard to debug,
all that stuff.

00:28:09.520 --> 00:28:13.260 align:middle line:90%


00:28:13.260 --> 00:28:15.940 align:middle line:84%
I'll give you a chance to try
this out for about a minute.

00:28:15.940 --> 00:28:17.710 align:middle line:84%
So let's have you
write this code.

00:28:17.710 --> 00:28:20.220 align:middle line:84%
So here, I'm giving you
the function specification.

00:28:20.220 --> 00:28:22.800 align:middle line:84%
Most of the time, I'll give
it to you even in quizzes.

00:28:22.800 --> 00:28:26.610 align:middle line:84%
I want you to write for me
a function called div_by.

00:28:26.610 --> 00:28:30.730 align:middle line:84%
This one takes in
two parameters,

00:28:30.730 --> 00:28:33.880 align:middle line:84%
both integers
greater than 0 and d.

00:28:33.880 --> 00:28:37.870 align:middle line:84%
And this function will return
true if d divides n evenly,

00:28:37.870 --> 00:28:44.560 align:middle line:84%
and false if it does
not divide n evenly.

00:28:44.560 --> 00:28:46.910 align:middle line:84%
So if you test it out
with those two values,

00:28:46.910 --> 00:28:48.610 align:middle line:84%
the first one should
give us false,

00:28:48.610 --> 00:28:51.510 align:middle line:84%
and the second one
should give us true.

00:28:51.510 --> 00:28:55.830 align:middle line:84%
So as usual, this is
down in the Python file.

00:28:55.830 --> 00:28:57.987 align:middle line:84%
Around line 28 is
where you should

00:28:57.987 --> 00:28:59.070 align:middle line:90%
start typing in your code.

00:28:59.070 --> 00:29:02.510 align:middle line:90%


00:29:02.510 --> 00:29:04.955 align:middle line:90%
Does anyone have a start for me?

00:29:04.955 --> 00:29:08.370 align:middle line:90%


00:29:08.370 --> 00:29:11.490 align:middle line:84%
Should be very similar
to what we just-- yeah?

00:29:11.490 --> 00:29:16.070 align:middle line:84%
AUDIENCE: e%n==0,
then print true.

00:29:16.070 --> 00:29:27.260 align:middle line:90%


00:29:27.260 --> 00:29:31.670 align:middle line:90%
ANA BELL: Else, print false.

00:29:31.670 --> 00:29:34.260 align:middle line:90%


00:29:34.260 --> 00:29:37.110 align:middle line:90%
So let's run the function.

00:29:37.110 --> 00:29:38.360 align:middle line:90%
Oh, let's just do it with one.

00:29:38.360 --> 00:29:40.525 align:middle line:84%
So the first one, I'm
expecting to print false.

00:29:40.525 --> 00:29:44.790 align:middle line:90%


00:29:44.790 --> 00:29:48.450 align:middle line:84%
It does print false, but it also
prints this weird none right

00:29:48.450 --> 00:29:49.080 align:middle line:90%
after it.

00:29:49.080 --> 00:29:50.538 align:middle line:84%
Actually, this is
something we want

00:29:50.538 --> 00:29:52.950 align:middle line:84%
we're going to talk
about next lecture.

00:29:52.950 --> 00:29:55.500 align:middle line:84%
But does anyone
know an improvement

00:29:55.500 --> 00:29:57.580 align:middle line:90%
we can make to the code?

00:29:57.580 --> 00:29:58.420 align:middle line:90%
Yes.

00:29:58.420 --> 00:30:01.230 align:middle line:90%
AUDIENCE: [INAUDIBLE]

00:30:01.230 --> 00:30:02.428 align:middle line:90%
ANA BELL: Yes, actually.

00:30:02.428 --> 00:30:02.970 align:middle line:90%
You're right.

00:30:02.970 --> 00:30:07.140 align:middle line:84%
So instead of printing true,
remember, it's a function.

00:30:07.140 --> 00:30:10.830 align:middle line:84%
We want it to give us back
the value true, right?

00:30:10.830 --> 00:30:15.180 align:middle line:84%
So instead of printing,
we'll do a return true.

00:30:15.180 --> 00:30:18.490 align:middle line:84%
And we don't need the
parentheses in this case.

00:30:18.490 --> 00:30:20.380 align:middle line:84%
And then, we'll
do a return false.

00:30:20.380 --> 00:30:28.130 align:middle line:90%


00:30:28.130 --> 00:30:31.220 align:middle line:84%
So now, we don't have that
weird none right after it.

00:30:31.220 --> 00:30:33.930 align:middle line:84%
That's something I was going
to talk about in next lecture.

00:30:33.930 --> 00:30:38.120 align:middle line:84%
But basically, when
we had print here,

00:30:38.120 --> 00:30:39.920 align:middle line:90%
what did the function return?

00:30:39.920 --> 00:30:43.670 align:middle line:84%
Did it have a return
statement inside it?

00:30:43.670 --> 00:30:44.600 align:middle line:90%
No, right?

00:30:44.600 --> 00:30:47.960 align:middle line:84%
And so if there's no return
statement inside the function,

00:30:47.960 --> 00:30:51.388 align:middle line:84%
Python automatically
returns the special none.

00:30:51.388 --> 00:30:53.680 align:middle line:84%
This is something we'll talk
about in next lecture more

00:30:53.680 --> 00:30:54.180 align:middle line:90%
in detail.

00:30:54.180 --> 00:30:58.240 align:middle line:84%
But the return true, return
false is correct here.

00:30:58.240 --> 00:30:59.000 align:middle line:90%
Yes?

00:30:59.000 --> 00:31:00.940 align:middle line:84%
AUDIENCE: Do you
need the details,

00:31:00.940 --> 00:31:02.750 align:middle line:90%
or do you just return--

00:31:02.750 --> 00:31:03.700 align:middle line:90%
ANA BELL: Yeah.

00:31:03.700 --> 00:31:04.270 align:middle line:90%
Yeah.

00:31:04.270 --> 00:31:05.590 align:middle line:90%
You don't need the return.

00:31:05.590 --> 00:31:07.270 align:middle line:90%
The if else, just like before.

00:31:07.270 --> 00:31:12.655 align:middle line:84%
So we can just do
return this directly.

00:31:12.655 --> 00:31:15.778 align:middle line:90%


00:31:15.778 --> 00:31:17.320 align:middle line:84%
And we can run it
with the other one.

00:31:17.320 --> 00:31:21.520 align:middle line:90%


00:31:21.520 --> 00:31:25.460 align:middle line:84%
So the second one should
actually return true.

00:31:25.460 --> 00:31:26.412 align:middle line:90%
But it returned false.

00:31:26.412 --> 00:31:27.620 align:middle line:90%
Does anyone know the problem?

00:31:27.620 --> 00:31:28.401 align:middle line:90%
Yeah?

00:31:28.401 --> 00:31:30.760 align:middle line:90%
AUDIENCE: It has a remainder.

00:31:30.760 --> 00:31:32.110 align:middle line:90%
ANA BELL: Yes, exactly.

00:31:32.110 --> 00:31:34.510 align:middle line:84%
So actually, we
want the remainder

00:31:34.510 --> 00:31:38.440 align:middle line:90%
when we divide n by d.

00:31:38.440 --> 00:31:42.730 align:middle line:84%
So this is just flipped
around and %d==0.

00:31:42.730 --> 00:31:45.510 align:middle line:90%
Yeah.

00:31:45.510 --> 00:31:48.060 align:middle line:84%
So it's a good thing we had two
test cases to test for that.

00:31:48.060 --> 00:31:50.310 align:middle line:84%
And you don't have to test
them with such big numbers.

00:31:50.310 --> 00:31:53.010 align:middle line:84%
You could obviously test them
with some smaller numbers

00:31:53.010 --> 00:31:54.580 align:middle line:90%
as well.

00:31:54.580 --> 00:31:57.720 align:middle line:84%
So let's zoom out a little
bit and talk about how exactly

00:31:57.720 --> 00:31:59.190 align:middle line:90%
functions are stored in memory.

00:31:59.190 --> 00:32:02.250 align:middle line:84%
Because I mentioned this thing
about defining a function,

00:32:02.250 --> 00:32:05.010 align:middle line:84%
and that just doesn't
do anything really

00:32:05.010 --> 00:32:06.430 align:middle line:90%
that we can see.

00:32:06.430 --> 00:32:08.260 align:middle line:84%
But what exactly
happens in memory?

00:32:08.260 --> 00:32:10.680 align:middle line:84%
Well, let's think
about what happens

00:32:10.680 --> 00:32:13.380 align:middle line:90%
when we create variables.

00:32:13.380 --> 00:32:18.740 align:middle line:84%
So when we create a is equal to
3 inside memory, or the program

00:32:18.740 --> 00:32:19.370 align:middle line:90%
scope--

00:32:19.370 --> 00:32:21.273 align:middle line:84%
again, we'll talk about
this next lecture.

00:32:21.273 --> 00:32:22.940 align:middle line:84%
But you can think of
this as the memory.

00:32:22.940 --> 00:32:25.580 align:middle line:84%
What happens is a
becomes a variable

00:32:25.580 --> 00:32:27.080 align:middle line:90%
that's bound to value 3.

00:32:27.080 --> 00:32:30.260 align:middle line:84%
b equals 4 is a variable
b bound to value 4.

00:32:30.260 --> 00:32:32.600 align:middle line:84%
And c is going to
be bound to value 7.

00:32:32.600 --> 00:32:33.530 align:middle line:90%
Clear, right?

00:32:33.530 --> 00:32:35.630 align:middle line:90%
We already know this.

00:32:35.630 --> 00:32:37.980 align:middle line:84%
What happens when we
create a function?

00:32:37.980 --> 00:32:41.330 align:middle line:84%
So again, this is something
I might write in a code file.

00:32:41.330 --> 00:32:43.980 align:middle line:84%
The top bit is my
function definition.

00:32:43.980 --> 00:32:47.740 align:middle line:84%
So as soon as Python
sees this def keyword,

00:32:47.740 --> 00:32:50.110 align:middle line:84%
everything that's
indented, that's part

00:32:50.110 --> 00:32:52.920 align:middle line:84%
of the function
definition in the body

00:32:52.920 --> 00:32:55.755 align:middle line:90%
is essentially just some code.

00:32:55.755 --> 00:32:58.700 align:middle line:90%


00:32:58.700 --> 00:33:02.630 align:middle line:84%
To Python, it does not care at
this point what that code is

00:33:02.630 --> 00:33:04.580 align:middle line:90%
or what that code does.

00:33:04.580 --> 00:33:08.420 align:middle line:84%
All it knows is that there
is a function object--

00:33:08.420 --> 00:33:11.060 align:middle line:84%
and functions are actually
objects in Python.

00:33:11.060 --> 00:33:15.110 align:middle line:84%
There is a function
object whose name is even.

00:33:15.110 --> 00:33:19.070 align:middle line:84%
That is all it knows when we get
to this point here in the code,

00:33:19.070 --> 00:33:20.960 align:middle line:84%
right after we
define the function,

00:33:20.960 --> 00:33:23.690 align:middle line:90%
right before a equals.

00:33:23.690 --> 00:33:27.980 align:middle line:84%
So we think about the function
as kind of like a "variable,"

00:33:27.980 --> 00:33:28.640 align:middle line:90%
quote unquote.

00:33:28.640 --> 00:33:30.223 align:middle line:84%
It's not actually a
variable, but it's

00:33:30.223 --> 00:33:32.960 align:middle line:84%
like a variable
whose name is even,

00:33:32.960 --> 00:33:36.620 align:middle line:84%
and it points to-- it's
bound to some code in memory.

00:33:36.620 --> 00:33:39.290 align:middle line:84%
And we don't care what that
code is right now because we

00:33:39.290 --> 00:33:40.370 align:middle line:90%
might never use it.

00:33:40.370 --> 00:33:44.570 align:middle line:84%
We only care what the code is
when we make function calls.

00:33:44.570 --> 00:33:47.320 align:middle line:84%
So down here is where
the action actually

00:33:47.320 --> 00:33:50.140 align:middle line:84%
happens when we make
our function calls.

00:33:50.140 --> 00:33:54.170 align:middle line:84%
I have a is going to be,
as usual, a variable.

00:33:54.170 --> 00:33:58.550 align:middle line:84%
That's going to be
bound to some value.

00:33:58.550 --> 00:34:02.230 align:middle line:84%
So the function definition is
kind of just like a black box.

00:34:02.230 --> 00:34:04.270 align:middle line:84%
Once you wrote it
once and it works,

00:34:04.270 --> 00:34:08.530 align:middle line:84%
you don't care anymore how it
actually achieves its task.

00:34:08.530 --> 00:34:11.949 align:middle line:84%
All you care is that it takes
in a number and tells you

00:34:11.949 --> 00:34:16.449 align:middle line:84%
whether that number is
even or odd via true false.

00:34:16.449 --> 00:34:18.969 align:middle line:84%
So down here where we
make our function calls,

00:34:18.969 --> 00:34:22.630 align:middle line:90%
we're just using our black box.

00:34:22.630 --> 00:34:25.909 align:middle line:84%
And we're using the black
box by making function calls.

00:34:25.909 --> 00:34:29.080 align:middle line:84%
So a is going to be
a variable that's

00:34:29.080 --> 00:34:32.170 align:middle line:84%
bound to the value
returned by is even.

00:34:32.170 --> 00:34:36.775 align:middle line:84%
So it's going to be based
on the function call, false.

00:34:36.775 --> 00:34:38.650 align:middle line:84%
And then, here, I have
another function call.

00:34:38.650 --> 00:34:42.100 align:middle line:84%
I'm using this useful piece
of code that I wrote up here.

00:34:42.100 --> 00:34:45.940 align:middle line:84%
And b is going to be a
variable that's bound to true.

00:34:45.940 --> 00:34:49.389 align:middle line:84%
And c is going to be a
variable that's bound to true.

00:34:49.389 --> 00:34:52.340 align:middle line:90%


00:34:52.340 --> 00:34:53.360 align:middle line:90%
Does that make sense?

00:34:53.360 --> 00:34:55.670 align:middle line:84%
Kind of separating
the code we write

00:34:55.670 --> 00:34:59.600 align:middle line:84%
which doesn't run until we
actually make function calls.

00:34:59.600 --> 00:35:01.280 align:middle line:84%
That's the thing
about functions.

00:35:01.280 --> 00:35:05.510 align:middle line:84%
And that's how it helps
us write more robust code.

00:35:05.510 --> 00:35:08.090 align:middle line:90%


00:35:08.090 --> 00:35:12.400 align:middle line:84%
So now, here, we can have a
more complex piece of code

00:35:12.400 --> 00:35:15.670 align:middle line:84%
where we're using the
function that we wrote.

00:35:15.670 --> 00:35:18.850 align:middle line:84%
Not just making a function
call and printing the result,

00:35:18.850 --> 00:35:22.480 align:middle line:84%
but we're actually using it
inside a more interesting

00:35:22.480 --> 00:35:23.390 align:middle line:90%
program.

00:35:23.390 --> 00:35:25.270 align:middle line:84%
So here, I've got
a program that will

00:35:25.270 --> 00:35:27.610 align:middle line:84%
print for me the numbers
between 1 and 10,

00:35:27.610 --> 00:35:30.820 align:middle line:84%
and it'll print whether
that number is odd or even.

00:35:30.820 --> 00:35:34.960 align:middle line:84%
So if you were just to read this
code, it's pretty easy to read,

00:35:34.960 --> 00:35:35.650 align:middle line:90%
right?

00:35:35.650 --> 00:35:38.620 align:middle line:84%
You have a loop that goes
through the numbers 1 to 10,

00:35:38.620 --> 00:35:45.110 align:middle line:84%
not including 10, and then,
I have this if is_even.

00:35:45.110 --> 00:35:45.920 align:middle line:90%
Well, that's cool.

00:35:45.920 --> 00:35:48.740 align:middle line:84%
Here, I'm using the function
that I wrote kind of just

00:35:48.740 --> 00:35:53.870 align:middle line:84%
in the middle of
another piece of code.

00:35:53.870 --> 00:35:54.830 align:middle line:90%
Which is fine.

00:35:54.830 --> 00:35:58.010 align:middle line:84%
Because as I said
a few slides ago,

00:35:58.010 --> 00:36:02.480 align:middle line:84%
function calls are
basically just expressions.

00:36:02.480 --> 00:36:03.350 align:middle line:90%
They get run.

00:36:03.350 --> 00:36:04.370 align:middle line:90%
They get evaluated.

00:36:04.370 --> 00:36:06.540 align:middle line:90%
You one value back out of them.

00:36:06.540 --> 00:36:09.690 align:middle line:84%
And then, that value
replaces the function call.

00:36:09.690 --> 00:36:10.610 align:middle line:90%
So that's fine.

00:36:10.610 --> 00:36:14.930 align:middle line:84%
Let's use the is_even result,
the return from the is_even

00:36:14.930 --> 00:36:17.270 align:middle line:90%
method inside a conditional.

00:36:17.270 --> 00:36:20.574 align:middle line:90%


00:36:20.574 --> 00:36:23.630 align:middle line:84%
If calling is_even
with i returns true,

00:36:23.630 --> 00:36:25.100 align:middle line:84%
that means if the
number is even,

00:36:25.100 --> 00:36:27.380 align:middle line:90%
we print that value, comma even.

00:36:27.380 --> 00:36:29.990 align:middle line:84%
Else, we print that
value, comma odd.

00:36:29.990 --> 00:36:32.150 align:middle line:84%
So here, I'm not
defining a function.

00:36:32.150 --> 00:36:34.700 align:middle line:84%
Notice, it's not wrapped in
a def or anything like that.

00:36:34.700 --> 00:36:38.240 align:middle line:84%
I'm just using a function
that I already wrote.

00:36:38.240 --> 00:36:41.080 align:middle line:90%
So inside here.

00:36:41.080 --> 00:36:44.210 align:middle line:90%
I'll just comment that out.

00:36:44.210 --> 00:36:46.045 align:middle line:84%
This is the code we
just had on the slide.

00:36:46.045 --> 00:36:47.420 align:middle line:84%
So again, notice
it's not within.

00:36:47.420 --> 00:36:48.950 align:middle line:84%
It's not wrapped
within a function.

00:36:48.950 --> 00:36:52.850 align:middle line:84%
It's just a loop that tells
me the numbers 1 at a time,

00:36:52.850 --> 00:36:54.320 align:middle line:90%
whether they're odd or even.

00:36:54.320 --> 00:36:55.815 align:middle line:90%
So prints 1, comma--

00:36:55.815 --> 00:36:56.947 align:middle line:90%
yeah?

00:36:56.947 --> 00:36:59.280 align:middle line:84%
AUDIENCE: What are you doing
when you select [INAUDIBLE]

00:36:59.280 --> 00:37:00.530 align:middle line:90%
comment and you make it like--

00:37:00.530 --> 00:37:02.160 align:middle line:84%
ANA BELL: Oh, when
I select everything.

00:37:02.160 --> 00:37:05.700 align:middle line:84%
I just use spider-like
ability to--

00:37:05.700 --> 00:37:09.420 align:middle line:84%
so I do Control 1, or Command
1, probably, on a Mac.

00:37:09.420 --> 00:37:13.070 align:middle line:84%
And it just comments and
uncomments things in batch.

00:37:13.070 --> 00:37:13.570 align:middle line:90%
Yeah.

00:37:13.570 --> 00:37:14.200 align:middle line:90%
Very useful.

00:37:14.200 --> 00:37:16.020 align:middle line:90%
Yeah.

00:37:16.020 --> 00:37:18.810 align:middle line:84%
And so this code is now
very easy to modify.

00:37:18.810 --> 00:37:21.310 align:middle line:84%
I can just choose 100 and
then I can run it again.

00:37:21.310 --> 00:37:24.600 align:middle line:84%
And it gives me the numbers 1
through hundreds odd or even.

00:37:24.600 --> 00:37:26.700 align:middle line:84%
And you can imagine using
your is_even function

00:37:26.700 --> 00:37:29.100 align:middle line:90%
in a more complex setting.

00:37:29.100 --> 00:37:32.813 align:middle line:84%
And is_even is a really
simple function too write,

00:37:32.813 --> 00:37:34.230 align:middle line:84%
but again, you can
imagine writing

00:37:34.230 --> 00:37:35.550 align:middle line:90%
a more complex function.

00:37:35.550 --> 00:37:39.480 align:middle line:84%
And then, that complex function
isn't a whole chunk of code

00:37:39.480 --> 00:37:42.240 align:middle line:84%
that just gets stuck into
this program, this loop.

00:37:42.240 --> 00:37:43.740 align:middle line:84%
It's going to be a
function that you

00:37:43.740 --> 00:37:47.070 align:middle line:84%
call that you can just easily
read the specification for

00:37:47.070 --> 00:37:50.790 align:middle line:84%
and you don't need to
completely understand how

00:37:50.790 --> 00:37:52.410 align:middle line:90%
it works in order to use it.

00:37:52.410 --> 00:37:58.330 align:middle line:90%


00:37:58.330 --> 00:38:01.150 align:middle line:84%
So we're going to go
through one other example

00:38:01.150 --> 00:38:03.140 align:middle line:90%
to write a little function.

00:38:03.140 --> 00:38:06.670 align:middle line:84%
And this will also
showcase the best practices

00:38:06.670 --> 00:38:08.980 align:middle line:84%
for writing a
function and writing

00:38:08.980 --> 00:38:10.990 align:middle line:84%
code, especially maybe
in a quiz situation

00:38:10.990 --> 00:38:12.040 align:middle line:90%
or something like that.

00:38:12.040 --> 00:38:13.690 align:middle line:84%
How to write
incremental code, how

00:38:13.690 --> 00:38:16.370 align:middle line:84%
to test it a little bit
at a time, and so on.

00:38:16.370 --> 00:38:18.490 align:middle line:84%
So the last example
I want to go through

00:38:18.490 --> 00:38:22.660 align:middle line:84%
is I want to write some code
that adds all the odd integers

00:38:22.660 --> 00:38:25.580 align:middle line:90%
between and including a and b.

00:38:25.580 --> 00:38:27.335 align:middle line:84%
Might be something
you're asked on a quiz.

00:38:27.335 --> 00:38:30.560 align:middle line:90%


00:38:30.560 --> 00:38:33.440 align:middle line:84%
The first thing you do when
you're faced with such a task

00:38:33.440 --> 00:38:36.360 align:middle line:84%
is to think about a nice
name for the function.

00:38:36.360 --> 00:38:39.350 align:middle line:84%
So sum_odd or sum_odds
is a reasonable name.

00:38:39.350 --> 00:38:42.170 align:middle line:84%
The inputs to the function,
well, I've got two endpoints.

00:38:42.170 --> 00:38:43.890 align:middle line:84%
I want to sum odd
numbers in between.

00:38:43.890 --> 00:38:47.270 align:middle line:84%
So the inputs might well
be my two endpoints.

00:38:47.270 --> 00:38:51.260 align:middle line:84%
And then, what is the thing
your function achieves?

00:38:51.260 --> 00:38:53.710 align:middle line:84%
Well, in the end, it's
going to give me some sum.

00:38:53.710 --> 00:38:57.687 align:middle line:84%
So let's call that sum
a variable sum_of_odds,

00:38:57.687 --> 00:38:59.645 align:middle line:84%
and we'll return it at
the end of our function.

00:38:59.645 --> 00:39:02.280 align:middle line:90%


00:39:02.280 --> 00:39:04.500 align:middle line:84%
And in between, we're
going to have some code.

00:39:04.500 --> 00:39:07.330 align:middle line:90%


00:39:07.330 --> 00:39:10.080 align:middle line:84%
So first thing to do is to
not write code right away.

00:39:10.080 --> 00:39:11.670 align:middle line:84%
When you're faced
with a task, again,

00:39:11.670 --> 00:39:13.230 align:middle line:84%
on a quiz or
something like that,

00:39:13.230 --> 00:39:15.450 align:middle line:84%
it's best to take
a piece of paper,

00:39:15.450 --> 00:39:18.150 align:middle line:84%
write a little bit,
one example, and try

00:39:18.150 --> 00:39:21.720 align:middle line:84%
to think about how you'd solve
it, not like a human would.

00:39:21.720 --> 00:39:25.260 align:middle line:84%
Because for us, we would
immediately know the sum.

00:39:25.260 --> 00:39:28.020 align:middle line:84%
It's very easy for humans
to identify the solutions

00:39:28.020 --> 00:39:29.010 align:middle line:90%
to these problems.

00:39:29.010 --> 00:39:31.320 align:middle line:84%
But try to think about
how you would write--

00:39:31.320 --> 00:39:33.840 align:middle line:84%
what kind of a recipe
would work for this?

00:39:33.840 --> 00:39:34.830 align:middle line:90%
Would you loop?

00:39:34.830 --> 00:39:36.390 align:middle line:90%
Would you have a conditional?

00:39:36.390 --> 00:39:37.890 align:middle line:84%
Would you use a for
loop, or a while

00:39:37.890 --> 00:39:40.800 align:middle line:84%
loop, and a bunch
of other concepts

00:39:40.800 --> 00:39:43.530 align:middle line:84%
that we'll learn about in
the following lectures.

00:39:43.530 --> 00:39:46.840 align:middle line:84%
But the key thing is to just
not write code right away.

00:39:46.840 --> 00:39:49.890 align:middle line:84%
So if we start with a really
simple example on paper,

00:39:49.890 --> 00:39:55.960 align:middle line:84%
we can say, let's choose end
points a is 2 and b is 4.

00:39:55.960 --> 00:39:59.600 align:middle line:84%
On paper, I would probably
write out 2, 3, 4 in a row.

00:39:59.600 --> 00:40:02.140 align:middle line:84%
So I know the numbers
I need to look at.

00:40:02.140 --> 00:40:04.360 align:middle line:84%
I would say 2 is
my a, 4 is my b.

00:40:04.360 --> 00:40:08.830 align:middle line:84%
I need to look at every one of
these numbers one at a time.

00:40:08.830 --> 00:40:10.030 align:middle line:90%
Reasonable.

00:40:10.030 --> 00:40:11.450 align:middle line:90%
I can do another example.

00:40:11.450 --> 00:40:11.950 align:middle line:90%
Sorry.

00:40:11.950 --> 00:40:13.807 align:middle line:84%
And I know what the
answer should be.

00:40:13.807 --> 00:40:15.640 align:middle line:84%
So I figure out what
the answer should be so

00:40:15.640 --> 00:40:17.182 align:middle line:84%
that when I write
my code, I actually

00:40:17.182 --> 00:40:19.540 align:middle line:90%
know what I'm looking for.

00:40:19.540 --> 00:40:21.940 align:middle line:84%
I look at another example,
let's say a little bit more

00:40:21.940 --> 00:40:23.560 align:middle line:90%
complicated, a bigger range.

00:40:23.560 --> 00:40:24.610 align:middle line:90%
a is 2, b is 7.

00:40:24.610 --> 00:40:26.740 align:middle line:84%
I try to use the
same strategy I used,

00:40:26.740 --> 00:40:30.650 align:middle line:84%
same recipe I used to solve that
simpler example in this harder

00:40:30.650 --> 00:40:31.150 align:middle line:90%
one.

00:40:31.150 --> 00:40:33.150 align:middle line:84%
So again, I'm going to
write out all the numbers

00:40:33.150 --> 00:40:34.910 align:middle line:90%
between 2 and 7 inclusive.

00:40:34.910 --> 00:40:37.270 align:middle line:84%
This is my first,
this is my last.

00:40:37.270 --> 00:40:40.760 align:middle line:84%
And my strategy was to
go through one at a time,

00:40:40.760 --> 00:40:43.570 align:middle line:84%
and if it's odd, I take
it to my running sum,

00:40:43.570 --> 00:40:46.150 align:middle line:84%
add it to my running sum,
and if it's even, I don't.

00:40:46.150 --> 00:40:48.130 align:middle line:90%
I ignore it.

00:40:48.130 --> 00:40:51.290 align:middle line:84%
And again, I know the answer
for this should be 50.

00:40:51.290 --> 00:40:54.740 align:middle line:84%
So with these two examples in
mind, I can start writing code.

00:40:54.740 --> 00:40:58.490 align:middle line:84%
But instead of writing code
for the big problem that

00:40:58.490 --> 00:41:00.860 align:middle line:84%
might include some nuances
or some edge cases,

00:41:00.860 --> 00:41:03.740 align:middle line:84%
I can actually try to
solve a similar problem.

00:41:03.740 --> 00:41:06.980 align:middle line:84%
So instead of summing all the
odd numbers between a and b,

00:41:06.980 --> 00:41:09.680 align:middle line:84%
let's just sum all the
numbers between a and b

00:41:09.680 --> 00:41:12.140 align:middle line:84%
and see if we can get
code working for that.

00:41:12.140 --> 00:41:14.570 align:middle line:84%
Once we do, figuring
out the odd ones

00:41:14.570 --> 00:41:18.230 align:middle line:84%
should be a small
tweak to our code.

00:41:18.230 --> 00:41:21.350 align:middle line:84%
So if we start with figuring out
the sum of all the odd numbers

00:41:21.350 --> 00:41:24.560 align:middle line:84%
between and including a and
b, that sounds like a loop.

00:41:24.560 --> 00:41:27.020 align:middle line:84%
Because I knew, when I
wrote my example on paper,

00:41:27.020 --> 00:41:30.920 align:middle line:84%
I'd have to touch each number
between and including a and b.

00:41:30.920 --> 00:41:35.680 align:middle line:84%
So I know I need to loop through
every one of these values.

00:41:35.680 --> 00:41:37.030 align:middle line:90%
While or a for loop?

00:41:37.030 --> 00:41:38.110 align:middle line:90%
Your choice.

00:41:38.110 --> 00:41:41.540 align:middle line:84%
In the slides, I'll do both,
just to see what it looks like.

00:41:41.540 --> 00:41:43.220 align:middle line:90%
So with a for loop, it's easy.

00:41:43.220 --> 00:41:44.650 align:middle line:90%
It's just for i in range a b.

00:41:44.650 --> 00:41:48.130 align:middle line:84%
But with a while loop, remember,
we have to initialize our loop

00:41:48.130 --> 00:41:49.840 align:middle line:90%
variable, if we have one.

00:41:49.840 --> 00:41:50.830 align:middle line:90%
i equals a.

00:41:50.830 --> 00:41:55.000 align:middle line:84%
Our loop condition is while
i is less than or equal to b.

00:41:55.000 --> 00:41:56.830 align:middle line:84%
So we're going to
loop through while I'm

00:41:56.830 --> 00:41:59.560 align:middle line:84%
looking at all these values
up to and including b.

00:41:59.560 --> 00:42:02.110 align:middle line:84%
And I need to remember
to increment my loop

00:42:02.110 --> 00:42:04.210 align:middle line:90%
variable within the loop.

00:42:04.210 --> 00:42:05.860 align:middle line:90%
By one each time, in this case.

00:42:05.860 --> 00:42:08.770 align:middle line:90%


00:42:08.770 --> 00:42:10.750 align:middle line:84%
And then, what do I
do within my loop?

00:42:10.750 --> 00:42:12.397 align:middle line:84%
Well, I'm going
to-- remember, we're

00:42:12.397 --> 00:42:13.480 align:middle line:90%
solving a similar problem.

00:42:13.480 --> 00:42:15.320 align:middle line:90%
I'm going to keep a running sum.

00:42:15.320 --> 00:42:20.400 align:middle line:84%
So as soon as I see a new i,
I'm going to add it to my sum.

00:42:20.400 --> 00:42:23.040 align:middle line:84%
I realize here, probably
my id would show me

00:42:23.040 --> 00:42:24.088 align:middle line:90%
that there's an error.

00:42:24.088 --> 00:42:25.380 align:middle line:90%
I didn't initialize sum of odd.

00:42:25.380 --> 00:42:28.360 align:middle line:84%
So I remember to initialize sum
of odds right before the loop.

00:42:28.360 --> 00:42:30.150 align:middle line:84%
And then, this is a
good place to test

00:42:30.150 --> 00:42:31.450 align:middle line:90%
the code for a little bit.

00:42:31.450 --> 00:42:36.300 align:middle line:84%
So we'll test it with a really
simple example, 2, comma 4.

00:42:36.300 --> 00:42:39.960 align:middle line:84%
If we test it with 2, comma
4, the for loop gives me a 5,

00:42:39.960 --> 00:42:42.930 align:middle line:90%
but the while loop gives me a 9.

00:42:42.930 --> 00:42:46.110 align:middle line:84%
So you guys might have
noticed what the problem is.

00:42:46.110 --> 00:42:48.630 align:middle line:84%
My for loop goes through
up to but not including

00:42:48.630 --> 00:42:51.660 align:middle line:90%
the n variable, the b.

00:42:51.660 --> 00:42:55.230 align:middle line:84%
So we can add a print
statement, in case you

00:42:55.230 --> 00:42:57.210 align:middle line:84%
didn't figure that out,
and the print statement

00:42:57.210 --> 00:42:58.830 align:middle line:90%
would actually tell us.

00:42:58.830 --> 00:43:00.720 align:middle line:84%
It tells us what
we're incrementing.

00:43:00.720 --> 00:43:05.400 align:middle line:84%
First, it's 2, then, it's
3, but I never hit the 4.

00:43:05.400 --> 00:43:09.970 align:middle line:84%
So the fix is to just change
my end range to be plus 1.

00:43:09.970 --> 00:43:14.020 align:middle line:84%
And then, we run it again,
and we see the answers match.

00:43:14.020 --> 00:43:16.880 align:middle line:84%
And this solves
the bigger problem.

00:43:16.880 --> 00:43:18.850 align:middle line:84%
So now, all we need
to do is adding

00:43:18.850 --> 00:43:23.030 align:middle line:84%
the nuance, the piece where we
just grabbed the odd numbers.

00:43:23.030 --> 00:43:25.960 align:middle line:84%
And here, we say, well, if I'm
just grabbing the odd numbers,

00:43:25.960 --> 00:43:30.520 align:middle line:84%
I only want to add
i to my sum of odds

00:43:30.520 --> 00:43:32.270 align:middle line:90%
when I see an odd number.

00:43:32.270 --> 00:43:35.560 align:middle line:84%
So here, I could use my is_even
function that I already wrote.

00:43:35.560 --> 00:43:39.730 align:middle line:84%
I would say if not is_even, or
I can just do it all over again.

00:43:39.730 --> 00:43:44.170 align:middle line:90%
If i%2==1, then we do this.

00:43:44.170 --> 00:43:47.830 align:middle line:84%
And now, we can run it again,
and hopefully, this now

00:43:47.830 --> 00:43:49.840 align:middle line:84%
matches with the
example I had on paper.

00:43:49.840 --> 00:43:51.700 align:middle line:90%
And it does.

00:43:51.700 --> 00:43:54.760 align:middle line:84%
So the idea here is to try to
solve a simpler problem first,

00:43:54.760 --> 00:43:57.310 align:middle line:84%
and then, as you see more
nuances to the problem,

00:43:57.310 --> 00:43:59.660 align:middle line:84%
add in the functionality
just a little bit at a time

00:43:59.660 --> 00:44:04.000 align:middle line:84%
so you don't actually get bogged
down by a whole bunch of issues

00:44:04.000 --> 00:44:07.920 align:middle line:84%
that might come up when you
wrote a whole bunch of code.

00:44:07.920 --> 00:44:10.440 align:middle line:84%
The last step is just to
test it on the other example,

00:44:10.440 --> 00:44:12.840 align:middle line:84%
just to make sure
that it still works.

00:44:12.840 --> 00:44:15.960 align:middle line:84%
And so if we print sum_of_odds
between 2 and 7 again,

00:44:15.960 --> 00:44:20.250 align:middle line:84%
this matches what I had
written down on paper.

00:44:20.250 --> 00:44:22.000 align:middle line:84%
If you don't want to
use print statements,

00:44:22.000 --> 00:44:26.400 align:middle line:84%
the Python tutor is also
a great debugging tool.

00:44:26.400 --> 00:44:28.957 align:middle line:84%
So testing code
often, very useful.

00:44:28.957 --> 00:44:31.290 align:middle line:84%
I think I've stressed this
in previous lectures as well.

00:44:31.290 --> 00:44:35.790 align:middle line:84%
Using print or the Python tutor
to debug is also very useful.

00:44:35.790 --> 00:44:38.420 align:middle line:84%
I don't actually intend
to go through this try it,

00:44:38.420 --> 00:44:44.060 align:middle line:84%
but this, along with a
bunch of other examples,

00:44:44.060 --> 00:44:46.460 align:middle line:84%
things to try at home
are in the Python file.

00:44:46.460 --> 00:44:50.300 align:middle line:84%
So just functions you
can write is palindrome,

00:44:50.300 --> 00:44:52.490 align:middle line:84%
this keep consonants,
this first_to_last_diff.

00:44:52.490 --> 00:44:54.650 align:middle line:84%
Read the function
specification and try

00:44:54.650 --> 00:44:58.250 align:middle line:84%
to write code that
matches the specification.

00:44:58.250 --> 00:45:01.070 align:middle line:84%
And as usual, the answers
are in the Python file but,

00:45:01.070 --> 00:45:03.110 align:middle line:84%
please, please, try to
do them on your own first

00:45:03.110 --> 00:45:04.670 align:middle line:90%
before looking at the answers.

00:45:04.670 --> 00:45:07.700 align:middle line:90%


00:45:07.700 --> 00:45:10.190 align:middle line:90%
A quick summary.

00:45:10.190 --> 00:45:11.870 align:middle line:90%
Functions are very useful.

00:45:11.870 --> 00:45:14.960 align:middle line:84%
Allows us to abstract
certain useful tasks.

00:45:14.960 --> 00:45:16.940 align:middle line:84%
Basically, abstract
away functionality

00:45:16.940 --> 00:45:19.670 align:middle line:84%
that we might reuse many
times in our program.

00:45:19.670 --> 00:45:21.620 align:middle line:90%
Functions take in inputs.

00:45:21.620 --> 00:45:23.512 align:middle line:90%
They have something to return.

00:45:23.512 --> 00:45:25.220 align:middle line:84%
We're going to see
next time what happens

00:45:25.220 --> 00:45:28.610 align:middle line:90%
when we don't return anything.

00:45:28.610 --> 00:45:30.920 align:middle line:84%
Creating the function is
different than running

00:45:30.920 --> 00:45:32.330 align:middle line:90%
the function.

00:45:32.330 --> 00:45:34.760 align:middle line:84%
So you create the
function once, but you

00:45:34.760 --> 00:45:36.570 align:middle line:90%
can run it many, many times.

00:45:36.570 --> 00:45:38.800 align:middle line:84%
And that's what makes
functions useful.

00:45:38.800 --> 00:45:42.700 align:middle line:84%
It makes code easy to
write, read, debug, modify.

00:45:42.700 --> 00:45:45.560 align:middle line:84%
Leads to a very
nice robust code.

00:45:45.560 --> 00:45:53.000 align:middle line:90%