Advertising (This ad goes away for registered users. You can Login or Register)

[Tutorial] Learning Programming with Python, part 11

Discuss about your favorite (gaming...or not) devices here. The most popular ones will end up getting their own categories
Programming discussions for your favorite Device
Forum rules
Forum rule Nº 15 is strictly enforced in this subforum.
Locked
Acid_Snake
Retired Mod
Posts: 3100
Joined: Tue May 01, 2012 11:32 am
Location: Behind you!

[Tutorial] Learning Programming with Python, part 11

Post by Acid_Snake »

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:

Code: Select all

def some_function(some_variable):
   print some_variable
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

Code: Select all

def some_function(some_variable):
    return some_variable
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:

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!"
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:

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-1
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:

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
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:

Code: Select all

some_function(my_parameter)
if you want to store what this function returns, then it's as simple as this:

Code: Select all

x = some_function(my_parameter)
let's see a live sample using the above shown function in a python interpreter:

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
-1
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:

Code: Select all

def some_function():
    return
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:

Code: Select all

>>> def some_function():
...     return
... 
>>> x = some_function()
>>> print x
None
>>> 
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:

Code: Select all

def some_function():
    print ""
this other function doesn't have any return statement, yet it behaves similarly to a function with an empty return statement:

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()
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:

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()
but this doesn't work:

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()
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? :o
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"
You may ask, isn't it better to have a normal function and the if-elif-else statements inside this function? something like this:

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"
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:

Code: Select all

x = some_value
if x == 0: print "hello"
elif x == 1: print "Goodbye"
else:
    def some_funtion():
        some code here
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:

Code: Select all

def some_function():
    x = raw_input("Do you want to finish? y/n >")
    if x == "y": return
    else: some_function()
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:

Code: Select all

def some_function():
    x = "n"
    while x != "y":
       x = raw_input("o you want to finish? y/n >")
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:

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()
- dynamic functions:

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")
- recursivity:

Code: Select all

def some_function(n):

    if type(n) != int: return

    if n == 0: return 1
    else:
        return n * some_function(n-1)
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
Advertising
Tonakai
Posts: 594
Joined: Sun Aug 05, 2012 3:00 am
Location: United Kingdom.

Re: [Tutorial] Learning Programming with Python, part 11

Post by Tonakai »

Great to see you're still working on these tutorials - they've really helped me.
Advertising
bronywhocodes
Posts: 21
Joined: Mon Dec 07, 2015 7:19 am

Re: [Tutorial] Learning Programming with Python, part 11

Post by bronywhocodes »

BUT WAIT! The psn code is gone!

But still, this stuff is great. Python is my favourite code language, so the fact that you can use Python and a pygame "fork" to code for the psp is so... Woah!
I am a coder. Python is My favourite. Also, here's my consoles that I can hack

Wii [unhacked (plz tutorial on how to code for wii)]
Psp go (6.61 pro cfw unbridled)
ramagus
Posts: 1
Joined: Sat Aug 11, 2018 2:09 am

Re: [Tutorial] Learning Programming with Python, part 11

Post by ramagus »

good lessons :)
Locked

Return to “Programming and Security”