- [Instructor] In this video, we're going to
take a look at defining your own custom function.
Now up to this point, whenever we've used any functions,
we've specifically taken advantage
of functions that were already built into Python.
Things like print function or the int function
to convert a value to an integer,
or the float function to convert a value
to a floating point number
and we also took advantage of the sum function
to add together all of the elements in a list
and the len function to calculate the length
of a list as well.
Of course, many of the things
that you'll want to do in programming
will involve packaging up your own code
and one of the key ways to do that
is by creating a function
that you can then reuse.
So our key goal in this particular video
is to just introduce the basic syntax
of a function in Python
and the terminology associated with it,
show you how to call the function
and also introduce a couple of other things
that are specific to functions in the context of Python.
Now to save me a little bit of typing pain,
I'm going to paste in a function definition
for a function that we're going to talk about.
We are defining here a function named square
and the purpose of this function,
as you can see in the next line here,
is to calculate the square of a number.
Now, for those of you who might be coming from
other programming languages,
you'll notice that the definition of a function in Python
is somewhat different from various
other programming languages,
especially C-based programming languages
where you're typically required
to specify the types of everything.
That is not how Python works.
Python is much more flexible than that.
It is a scripting language first
and as a general purpose,
scripting language not only enables you
to be quite expressive,
but enables you to do some very powerful things
as you're going to see through the next many lessons.
Now, every function definition
begins with the keyword D-E-F,
which is short for definition.
The name of the function is next,
and of course, as you define a function,
you should give it a name that this understandable,
something that has to do with the purpose of that function
and then following the function name
will always be a set of parentheses,
which defines what is known as the parameter list.
In the parameter list, you specify variable names
that will receive any information that the function needs
in order to perform its task.
And in the case of our square function,
it needs to receive some number
that it can then square and return the result.
So we have one parameter in this case,
but if we had multiple parameters,
they would be separated by commas.
Notice we say nothing at all
about the type of that parameter
which means this function actually could be used
for example with integers,
but it could also be used with floating point numbers.
If you happen to pass into this function,
something for which we cannot use
the exponentiation operator,
well, then you'll wind up with a syntax error
when the interpreter tries to define the function
based on the code that you've provided.
Now just like when you have a control statement,
the first line of a function definition
ends with a colon.
In the context of a control statement,
we call the lines that are indented
within the control statement a suite.
In the context of a function,
we call those lines a block of code.
So a block of code is basically a suite
that belongs to a function for the moment.
And we'll see that classes also have blocks of code as well
when we get to that concept in lesson 10.
So we have the colon, we drop to the next line and indent.
Again, four spaces are the default indentation
and the style guide for Python code
specifically recommends that the very first thing
you place inside the body of your function
is a doc string.
Now you may recall when I introduced triple-quoted strings
that one of the cases for triple-quoted strings
is a documentation string
and this is an example of such a string.
This is a particularly short example.
Sometimes when you have more complex functionality
or functions that you're defining,
you'll have possible paragraphs of text
or much more detail about what a given function does
in a multi-line triple-quoted string
and towards the end of this video,
I'm going to show you how you can access that doc string
through the documentation capabilities
of the Interactive Python interpreter
and in fact, those same capabilities
are available to you through Jupyter Notebooks as well
so here, we have a simply documentation string,
notice the three double-quote characters
on either end here.
Calculate the square of number
and then we have a one additional statement in the body,
a return statement which is going to give a value back
to whoever calls this function.
So just like when we called the sum function
in the preceding lesson to calculate
the sum of the numbers inside of a list,
and it gave us back the total, the sum,
this return statement is going to take
whatever number the square function receives
and it will use that value
and it will square that value
and then give back that value that it calculates
to whoever calls that function.
Now, when you execute a snippet that defines a function,
executing that literally just brings the function to life.
It is now something that can be executed.
It exists at this point.
But until you actually call it, nothing happens.
So for example, if I go ahead and say square
and I give it the value seven, woops,
sorry about that,
I give it the value seven and then I press enter,
you can see that I get, as a result, 49.
Now, I could have assigned that result to a variable.
In this case I simply at IPython display the value
and this is a really handy way to develop a function
and test it out before you incorporate it
into a more robust application.
As I mentioned, this function does not care
what type of number you give it, so, for example,
I can say square and give it 2.5,
which is a floating point number
and it will happily give me back
a floating point number as well.
So if I give it an integer,
it will give me back and integer.
If it give it a floating point number,
it'll give me back a floating point number
and by the way, if I give it a decimal,
it will calculate the square of that decimal value
and give me back the squared decimal value
in that case as well.
Anything that supports this exponentiation operator
can be passed into the square function
as an argument to the function.
Each argument you pass to a function
gets assigned to a corresponding parameter,
so when I pass the argument seven to the square function,
number gets assigned the value seven,
so I'm doing seven squared down here
and when this return statement executes
the value is returned back
to the snippet number two,
where the IPython Interpreter
then uses that value as the output result
and the same basic thing is happening down here
in snippet three as well.
Now, one thing to know about Python
that's a little different from other languages
is that when you return from a function
to the caller of that function,
something is always returned back to the caller,
whether you have a return statement or not.
If you have a return statement,
then the expression to the right of the return
is what is going to be given back to the caller.
If there is no expression,
there's actually a value in Python called None
that gets returned, so that's actually an object
that represents nothing
and you can actually use that in your code
to test and see whether a function
returns something or not,
if you need to test for things like that
and we'll use the None value in later lessons.
So if I have an empty return statement,
the value None gets returned to the caller,
or if I have no return statement whatsoever,
the value None also gets turned to the caller as well.
Now, the variable number, the parameter number
that we defined back here in the square function
exists only for the lifetime of the function's call
so when you call the function,
the variable number is now available for use.
It receives the argument that you pass.
When the return statement finishes executing,
then the variable number goes away
and I would not be able tot use that down here
in my subsequent snippets of code.
So if I try to go ahead
and auto-complete or tab-complete the word number,
it's not doing anything as I type the tab character here
because it doesn't know what number is
and if by any chance I were to try to evaluate number,
you'll see that you get a NameError
because number does not exist
once a given function call to the square function
completes execution.
It only exists during the call.
Now, another thing I wanna talk about
is, again, this doc string here.
So it turns out that in IPython,
there's a handy character that you can attach to something
to look at its help documentation
and that character is a question mark.
So I can go ahead and type square
followed by a question mark,
square being the name of my function,
and automatically, the IPython Interpreter
will display information like what you see here.
The first piece of information that gives me
is the signature of the function.
The signature is the name of the function
and what parameters it expects to receive.
So, that is something that as we'll talk about
in more detail later, is important
because it helps Python decide which function gets called
when you have an expression like here in snippet two
or snippet three.
So it's going to look, in particular,
for a function with the name square
that takes one argument in each of these cases
and we have a square function that takes one argument
or one parameter, I should say, called number
in this particular case.
The next thing it shows you is the doc string
associated with that function
so even for example using the sum function
that's built into Python,
I can go ahead and say sum question mark
and get details about that function
that's built into the language.
I won't go into the details of what's going on here,
but you can see that it's giving me the doc string,
which for the sum function, is a little bit more elaborate
than what I had for my square function up above.
It also tells you the type of that item
is a built-in function or method,
something that's built into Python
as opposed to a function that I defined myself
back up above in this session.
If the source code for the function
is available to you,
you can also take this a step further
and use two question marks,
in which case, not only will it give you
the signature of the function,
it will give you the full source definition
of that function as well.
So here is the actual definition of the function.
By the way, up above, it did this as well.
It's telling me where this function is defined.
In my case, I'm working in the Chapter Four folder
which is the set of examples
that correspond to Lesson Four of these videos
and it's telling me that the function was defined
in IPython input number one,
which was snippet number one back up here,
so that's what this information means.
This last piece is actually a hexadecimal,
unique id code that just identifies the function in memory
and that's something you can simply ignore
in any messages where you see something like this.
But again, it says the type of that thing is function
and I don't believe the sum function is available to us
but we can do ahead and check
and what you see here is it did not give us
the details of the sum function,
so what happens when you use two question marks
and the source code is not available
is it simply gives you the same result
as using a single question mark
to access the health information about that function.
So those are a couple of nice little tricks
that you can use the learn about things.
When you start importing other libraries,
so for example, we had imported the statistics library
back in the preceding lesson, so,
woops, I didn't spell it correctly, there we go.
So if I import the statistics library
and I want to know more about it,
I can go ahead and,
apparently I can't type very well here,
I can learn about the statistics library
by simply typing its name in a question mark
and now it starts giving me more detailed information
about the statistics library.
So as you can see, it's actually not done
giving me information about the statistics library.
When it is done, I'll get my next input prompt back
but I can now simply use the arrow key to move down
or I can press the Space key
to move down in bigger chunks at a time.
Now you can see end at the end here
and, excuse me,
when the end is displayed,
you can go ahead and type a Q
and it will return you back to prompt
so that you can input your next snippet of code
in the current IPython session.
So if the full documentation can be displayed all at once,
it will automatically give you your input prompt back
if the full documentation cannot be displayed
in the vertical amount of space
available to you on your screen.
Then you'll simply see a colon,
until eventually the documentation has been full displayed.
Then you'll see that word end
and you just press the Q to quit from the Help system.