Functions
The function has an optional return value; it's None by default. Just use the equal sign with a variable to its left to receive the return value from the function.
def my_night():
awake = "yes"
return awake
night_owl = my_night()
yes
If you don't know how many arguments are going to be passed in at any point in time on a function call, define the function for arbitrary arguments by just putting an asterisk to the left of the parameter. That will render the parameter to be of type tuple.
def eating(*food):
x = len(food)
print(x)
for i in food:
print(i)
eating("cake", "steak")
# results in
2
cake
steak
You can define an empty tuple variable in advance and pass it in with some actual values.
people = tuple()
def house(*people):
print(people)
house(("me", "her")) # notice double parentheses pairs - creating the tuple on the fly.
# output, the trailing commas indicates an arbitrary list ready to take more values if passed in.
# result is:
(('me', 'her'),)
Python will error check for duplicate parameters; it also traps for repeated keywords.
first = "steak"
second = "cake"
def eating(*food):
x = len(food)
print(x)
for i in food:
print(i)
eating(first, first) # error
eating(first, second) # valid
eating(second, first) # also valid
# output, note this prints the variable names and not their respective values
# In the "cake" and "steak" example before, the parameters of the function eating were explicit strings. Here they are the python variable names.
first
second
If you don't know how many key-value pairs are incoming as arguments at any point in time, you can define the key-value pairs as arbitrary. They'll be treated as a dictionary. If you don't know how many keyword value pairs in advance use a double asterisks to the left of the parameter name.
first = "steak"
second = "cake"
def eating(**food):
x = len(food)
print(x)
for i in food:
print(i)
print(food[i])
# first and second are the actual index values!!
eating(first = "salad", first = "bread") # error
eating(first = "salad", second = "bread") # valid
# the result is
2
first
salad
second
bread
# because you need two asterisks for arbitrary key-value pairs
Python permits global variables to have the same name as a function parameter without error or cross-referencing.
first = "soup"
second = "tuna"
def eating(**food):
x = len(food)
print(x)
for i in food:
print(i)
# first can be both a global variable and a
# function keyword parameter
eating(first = "carrot", next = second) # valid
However, you cannot mix global variables and key-value pairs in the syntax in a given function call. That is regardless of whether you use *, ** or exactly specify the parameters,
def eating(f,s):
def eating(*food):
def eating(**food):
eating(first = "carrot", second) # disallowed mixed syntax of strings with variables
# error for each of the 3 cases.
In order to help with avoiding run-time errors you can specify a key value pair in the function definition. In fact, you can have multiple ones and they'll all be treated as defaults. They will be lined up left to right as you pass in actual values from the calling function. This is useful when the calling function has fewer arguments then the function's inherent parameters.
def eating(f = "onion", s = "garlic"):
print("hard to eat " + f + " and " + s)
eating()
# results in
hard to eat onion and garlic
compare the example above to:
eating("mustard")# results in
hard to eat mustard and garlic
The pass keyword is allowed in functions; if you happen to include the pass keyword and actually have some commands inside the function the pass keyword is ignored.
You cannot utilize variables that are dependent upon recursive functions until the recursion is complete otherwise you will get a "local variable referenced before assignment error".
def recur(round):
if round == 4: result = 99999
if(round > 0):
print(result)
result = round + recur(round - 1)
else:
result = 0
return result
# ----------- program really starts here first ----------
round = 4
print("math results")
recur(round)
# output
math results
99999
error: "local variable 'result' referenced before assignment error"
-----------------------------------
Now move the print command until AFTER all possible recursive iterations are complete.
if round == 4: result = 99999 # this is "fool you" as the variable: result does not equal 99999 very long as it replaced by the recursion
if(round > 0):
result = round + recur(round - 1)
# calls itself based on def, the print command below # now waits until recursion is complete, i.e., round = 0
print(result)
else:
result = 0
return result # note that return has to line up with the first if
iterations = 4
print("math results")
last_return = recur(iterations)
print(last_return)
# output
math results
1
3
6
10
10
Program logic goes like this and is easier to understand using the Cntl-F5 "nicer" debugger of Thonny and using F7 to "Step In" each line of code.
Here is a step-by-step run through of how recursive function calls work in this example:
1. In the main section round = 4 and recur() is called for the first time.
2. Inside the recur function, result is set to 99999 as round =4 only at this recursion level.
3. result then relies on a recursive call to recur() with argument 3 to be added to the value of round at this level, which is 4.
4. Since at this inner level round is 3, it goes right on to the next update to the value of result by calling recur(2) to be added to the value of round at this level, which is 3.
5. result then relies on a recursive call to recur with argument 2 to be added to the value of round at this level, which is 3.
6. Since at this inner level round is 2, it goes right on to the next update to the value of result by calling recur(1) to be added to the value of round at this level, which is 2.
7. result then relies on a recursive call to recur() with argument 1 to be added to the value of round at this level, which is 2
8. Since at this inner level round is 1, it goes right on to the next update to the value of result by calling recur(0) to be added to the value of round at this level, which is 1.
9. At this deepest/innermost recursion level of the recur function, the if conditional fails since round = 0, and therefore the else clause kicks in so that result = 0. That value of result is then returned to the next instance upwards of the recur function. The print command is unreachable in the innermost function call (when round = 0).
10. Now back up to where the local variable for round is 1, the print command is reached for the first time, and prints the value of result which is 0 + 1 = 1.Then return result=1 to the next level up in function calls, when round =2.
11. In that function's local variable space round=2 and result gets that 2 added to the return value from the function nested underneath it with a value of 1. So result is 2+1 =3. That value of 3 is printed. and returned up the function recursion ladder again to where round = 3 locally there. round=3 + the return value of result =3 gives 6 and 6 is printed.
12. Finally, we backtrack all the way up to the top calling function of recur() by returning result=6 to its local variable space. Here round = 4. result is then 4 + 6 = 10 and gets printed. Remember, just like all the inner recur() function calls, this top level recur() still is obligated to return the value of result to the main program. So it does that with value 10, which gets printed once again to prove it.
END
No comments:
Post a Comment