[Tutorial] Learning Programming with Python, part 11
Posted: Wed Jun 05, 2013 5:36 pm
More on functions
We've already covered all the PSP-realated stuff and GUI-related stuff, so lets go back to the general language knowledge that applies to everything.
In part 4 I briefly explained functions, classes and modules, but I left it vague on purpose so I could later get more deeply with them.
Basics.
We already know how to declare functions: using the def statement, followed by the function name, the parameters and finally the code itself:
as we can see this function is pretty basic, it takes one parameter and prints it on-screen, but what if we want to return that parameter? we use the return statement
The return statement will, as the name implies, return the said value, but it will also terminate the function, so any code after that statement will never be executed.
But we don't want to call a function, pass a parameter, and then have that same parameter be returned to us, why would we want that? we want the function to either do something with that parameter and not return anything, or do something and return a modified version of the parameter, or do something and return something else.
Lets see the first example, the function takes a parameter and depending on the parameter does one thing or the other, but doesn't return anything:
nothing unusual here, we've already seen the if-elif-else statement.
On the second example, well have the function return a modified version of the parameter:
now this is different, not only the function does something, it also returns a modded version of our parameter to indicate us what it has done, this is a pretty common procedure, but even more common is returning error codes:
the function returns either 1, 2, or -1 depending on what situation has happened, it is up to the dev to know what these values actually mean, normally either reading the code or the docstring (more on that later) is enough to know how to interpret what the function returns.
How to store the return value of a function.
This is very basic knowledge you must already know, but in case you don't know, variables are used to store what a function returns by calling that function. This is how you normally call a function:
if you want to store what this function returns, then it's as simple as this:
let's see a live sample using the above shown function in a python interpreter:
Just as we intended, the function returns a value and that value is stored on our variable x, which we can later use as we please.
How about functions returning nothing?
It is very interesting to know that all python functions will always return something, even if not explicitly said, let's take this sample:
this function does absolutely nothing, it returns upon calling it and does not return any actual value, so what happens if I attempt to store this function's return value on a variable? let's see:
we get that the value of the variable is None, a python statement used for empty variables, similar in nature to C's NULL.
Now, you don't need the function to have a return statement in order for it to return None, even if the function has no return statement the variable gets set to None:
this other function doesn't have any return statement, yet it behaves similarly to a function with an empty return statement:
Nested Functions
A nested function is essentially a function within another function, in a way that we have:
- function A
--- (function A code)
--- function B
------ function B code
--- (function A code)
In C and C++, nested functions don't exist, but GCC allows for nested functions as an extension to C. In python, nested functions are a true thing, and as part of python's flexibility, there can be as many nested functions as you can.
Here's a live sample of how a nested function looks like:
nested functions are nothing special, they behave the same as any other function, but know that you can only call a nested function from within its parent function, the following code works:
but this doesn't work:
because a nested function is only visible within the scope of its parent function.
Dynamic functions.
A dynamic function is one that's declared at runtime only if a certain requirement is met. They are useful if you want a function to behave differently depending on some aspects of the environment, user input, etc, or you can have the function available only if a certain criteria is met. Usually these functions are declared within if-elif-else. A function declared by an if statement? what type of sorcery is this?
No sorcery, it's just part of python's flexibility. Here's a live example of a function that changes depending on the Operating System:
You may ask, isn't it better to have a normal function and the if-elif-else statements inside this function? something like this:
yeah it's essentially the same, but take into consideration that everytime you call getOS() it will do the checks again and again, while if using a dynamic function, the check is done only once at runtime and then the same function is used until the program ends, and there are some cases where you might not even want to declare the function at all, take this for example:
in this case, you might not want to always declare the function.
Dynamic functions are generally used to save memory (by having a function be declared only if needed) or by saving performance (you might not want to do the same check over and over again with variables that will never change anyways)
Recursivity
Recursivity is the act of a function calling itself. The methodology of recursivity is the same as calling any other function, but it produces a result similar to a while loop, here's an example:
it's simple, here we ask the user if he wants to end the program, if he chooses to then the function returns, otherwise the function calls itself, resulting in asking the same question over and over again until the user preses "y", this function can be rewritten by using a while loop:
the end result is the same
Live examples:
To conclude what we've learned, here's a few example functions using the different methods we've mentioned:
- nested functions:
- dynamic functions:
- recursivity:
As a learning exercise you have to figure out what each function does and explain how, please use spoilers.
Previous Lesson
You've come really far, here's a $10 PSN code: 74ML-FFNK-4772
We've already covered all the PSP-realated stuff and GUI-related stuff, so lets go back to the general language knowledge that applies to everything.
In part 4 I briefly explained functions, classes and modules, but I left it vague on purpose so I could later get more deeply with them.
Basics.
We already know how to declare functions: using the def statement, followed by the function name, the parameters and finally the code itself:
Code: Select all
def some_function(some_variable):
print some_variableCode: Select all
def some_function(some_variable):
return some_variableBut we don't want to call a function, pass a parameter, and then have that same parameter be returned to us, why would we want that? we want the function to either do something with that parameter and not return anything, or do something and return a modified version of the parameter, or do something and return something else.
Lets see the first example, the function takes a parameter and depending on the parameter does one thing or the other, but doesn't return anything:
Code: Select all
def some_function(some_variable):
if some_variable == 0: print "Hello"
elif some_variable == 1: print "Goodbye"
else: print "I don't know what you want!"On the second example, well have the function return a modified version of the parameter:
Code: Select all
def some_function(some_variable):
if some_variable == 0:
print "Hello"
return some_variable+1
elif some_variable == 1:
print "Goodbye"
return some_variable+2
else:
print "I don't know what you want!"
return some_variable-1Code: Select all
def some_function(some_variable):
if some_variable == 0:
print "Hello"
return 1
elif some_variable == 1:
print "Goodbye"
return 2
else:
print "I don't know what you want!"
return -1How to store the return value of a function.
This is very basic knowledge you must already know, but in case you don't know, variables are used to store what a function returns by calling that function. This is how you normally call a function:
Code: Select all
some_function(my_parameter)Code: Select all
x = some_function(my_parameter)Code: Select all
>>> def some_function(some_variable):
... if some_variable == 0:
... print "Hello"
... return 1
... elif some_variable == 1:
... print "Goodbye"
... return 2
... else:
... print "I don't know what you want!"
... return -1
...
>>> some_function(0)
Hello
1
>>> some_function(1)
Goodbye
2
>>> some_function(2)
I don't know what you want!
-1
>>> x = some_function(0)
Hello
>>> print x
1
>>> x = some_function(1)
Goodbye
>>> print x
2
>>> x = some_function(2)
I don't know what you want!
>>> print x
-1How about functions returning nothing?
It is very interesting to know that all python functions will always return something, even if not explicitly said, let's take this sample:
Code: Select all
def some_function():
returnCode: Select all
>>> def some_function():
... return
...
>>> x = some_function()
>>> print x
None
>>> Now, you don't need the function to have a return statement in order for it to return None, even if the function has no return statement the variable gets set to None:
Code: Select all
def some_function():
print ""Code: Select all
>>> def some_function():
... print ""
...
>>> x = some_function()
>>> print x
None
>>> Nested Functions
A nested function is essentially a function within another function, in a way that we have:
- function A
--- (function A code)
--- function B
------ function B code
--- (function A code)
In C and C++, nested functions don't exist, but GCC allows for nested functions as an extension to C. In python, nested functions are a true thing, and as part of python's flexibility, there can be as many nested functions as you can.
Here's a live sample of how a nested function looks like:
Code: Select all
def some_function():
def some_nested_function():
print "This is a nested function"
print "Now entering the nested function"
some_nested_funtion()Code: Select all
def some_function():
def some_nested_function():
print "This is a nested function"
print "Now entering the nested function"
some_nested_funtion()
some_function()Code: Select all
def some_function():
def some_nested_function():
print "This is a nested function"
print "Now entering the nested function"
some_nested_funtion()
some_function().some_nested_funtion()Dynamic functions.
A dynamic function is one that's declared at runtime only if a certain requirement is met. They are useful if you want a function to behave differently depending on some aspects of the environment, user input, etc, or you can have the function available only if a certain criteria is met. Usually these functions are declared within if-elif-else. A function declared by an if statement? what type of sorcery is this?
No sorcery, it's just part of python's flexibility. Here's a live example of a function that changes depending on the Operating System:
Code: Select all
import sys
if sys.platform.startswith("win"):
def getOS():
print "You are running windows"
elif sys.platform.startswith("linux"):
def getOS():
print "You are running linux"
elif sys.platform.startswith("darwin"):
def getOS():
print "You are running Mac OS"
else:
def getOS():
print "I don't know your OS"
Code: Select all
import sys
def getOS():
if sys.platform.startswith("win"):
print "You are running windows"
elif sys.platform.startswith("linux"):
print "You are running linux"
elif sys.platform.startswith("darwin"):
print "You are running Mac OS"
else:
print "I don't know your OS"Code: Select all
x = some_value
if x == 0: print "hello"
elif x == 1: print "Goodbye"
else:
def some_funtion():
some code hereDynamic functions are generally used to save memory (by having a function be declared only if needed) or by saving performance (you might not want to do the same check over and over again with variables that will never change anyways)
Recursivity
Recursivity is the act of a function calling itself. The methodology of recursivity is the same as calling any other function, but it produces a result similar to a while loop, here's an example:
Code: Select all
def some_function():
x = raw_input("Do you want to finish? y/n >")
if x == "y": return
else: some_function()Code: Select all
def some_function():
x = "n"
while x != "y":
x = raw_input("o you want to finish? y/n >")Live examples:
To conclude what we've learned, here's a few example functions using the different methods we've mentioned:
- nested functions:
Code: Select all
import os, shutil
def parent_function(src, dst):
def nested_function_1():
os.remove(src)
def nested_function_2():
shutil.copyfile(src, dst)
if src.endswith(".jpg") or src.endswith(".png"):
nested_funtion_2()
else:
nested_funtion_1()Code: Select all
import sys
if sys.platform.startswith("win"):
def some_function():
return "C:\", "//"
elif sys.platform.startswith("linux"):
def some_function():
return "/", "/"
elif sys.platform.startswith("darwin"):
def some_function():
return "/Mac HD/", "/"
elif sys.platform.startswith("psp"):
def some_function():
return "ms0:/", "/"
else:
raise SystemError("Can't detect OS")Code: Select all
def some_function(n):
if type(n) != int: return
if n == 0: return 1
else:
return n * some_function(n-1)Previous Lesson
You've come really far, here's a $10 PSN code: 74ML-FFNK-4772