Hello, QTM151!
Lecture 07 - Custom Functions and Variable Scope
def and returnprint(), len(), str(), type(), etcnp.random.normal() expects two parameters: the mean (loc) and the standard deviation (scale). Size is an optional parameternp.random.normal(0, 1) takes two arguments and returns a random number from a normal distribution with mean 0 and standard deviation 1np.random.normal() will provide a sample of 1 number with mean 0 and standard deviation 1 if you don’t provide any argumentsHello, QTM151!
3.1415926536
3
So far, so good? 😊
[4.37622092e-01 1.01513996e+00 7.00305458e-01 5.32471134e-01
1.18685559e+00 1.77204365e-01 1.68540320e+00 1.95551140e-01
2.12538410e+00 1.16186348e-04]
[0.7695582 2.37614486 3.85655958 1.29520823 0.94802693 1.3603675
2.28118345 1.0192539 4.14558926 2.70249425]
[6.50701538 7.13033605 6.7428324 8.15282244 3.02765442 3.62617371
6.7797887 8.85941509 8.01647834 3.78707982]
What are the parameters, arguments, and return values in these examples? 🤓
def keyworddef keywordparameter (duh! 😅)None\[V=P\left(1+{\frac {r}{n}}\right)^{nt}\]
To know what each parameter means, click here: Appendix 01
# You can know compute the formula with different values
# Let's see how much one can gain by investing 50k and 100k
# Earning 10% a year for 10 years
V1 = fn_compound_interest(P = 50000, r = 0.10, n = 12, t = 10)
V2 = fn_compound_interest(100000, 0.10, 12, 10)
V3 = fn_compound_interest(r = 0.10, P = 100000, t = 10, n = 12)
print(V1)
print(V2)
print(V3)135352.0745431122
270704.1490862244
270704.1490862244
\(f(x) = x^2 + 2x + 1\)
numeric_gradestatus = passstatus = failstatusmy_function = lambda parameters: expression
fn_squared = lambda x: x**2fn_iseligible_voteFor loop + Functionslist_ages = [18,29,15,32,6]Most variables we have seen so far are in the global scope
They are stored in the global namespace and are accessible from anywhere in the code
Let’s create a function that sums 3 numbers
\(f(x,y,z) = x + y + z\)
We will pass the numbers as arguments to the function
8
13
NameErrorx is a local variable to the function print_x()global keywordglobal keyword tells Python that you want to use the global variable, not create a new local variableglobal?
global sparingly, if at all! 😉modify_x() again?global y inside fn_square?print(), len(), sum(), etc['ArithmeticError', 'AssertionError', 'AttributeError', 'BaseException', 'BaseExceptionGroup', 'BlockingIOError', 'BrokenPipeError', 'BufferError', 'BytesWarning', 'ChildProcessError', 'ConnectionAbortedError', 'ConnectionError', 'ConnectionRefusedError', 'ConnectionResetError', 'DeprecationWarning', 'EOFError', 'Ellipsis', 'EncodingWarning', 'EnvironmentError', 'Exception', 'ExceptionGroup', 'False', 'FileExistsError', 'FileNotFoundError', 'FloatingPointError', 'FutureWarning', 'GeneratorExit', 'IOError', 'ImportError', 'ImportWarning', 'IndentationError', 'IndexError', 'InterruptedError', 'IsADirectoryError', 'KeyError', 'KeyboardInterrupt', 'LookupError', 'MemoryError', 'ModuleNotFoundError', 'NameError', 'None', 'NotADirectoryError', 'NotImplemented', 'NotImplementedError', 'OSError', 'OverflowError', 'PendingDeprecationWarning', 'PermissionError', 'ProcessLookupError', 'PythonFinalizationError', 'RecursionError', 'ReferenceError', 'ResourceWarning', 'RuntimeError', 'RuntimeWarning', 'StopAsyncIteration', 'StopIteration', 'SyntaxError', 'SyntaxWarning', 'SystemError', 'SystemExit', 'TabError', 'TimeoutError', 'True', 'TypeError', 'UnboundLocalError', 'UnicodeDecodeError', 'UnicodeEncodeError', 'UnicodeError', 'UnicodeTranslateError', 'UnicodeWarning', 'UserWarning', 'ValueError', 'Warning', 'ZeroDivisionError', '_IncompleteInputError', '__IPYTHON__', '__build_class__', '__debug__', '__doc__', '__import__', '__loader__', '__name__', '__package__', '__spec__', 'abs', 'aiter', 'all', 'anext', 'any', 'ascii', 'bin', 'bool', 'breakpoint', 'bytearray', 'bytes', 'callable', 'chr', 'classmethod', 'compile', 'complex', 'copyright', 'credits', 'delattr', 'dict', 'dir', 'display', 'divmod', 'enumerate', 'eval', 'exec', 'execfile', 'filter', 'float', 'format', 'frozenset', 'get_ipython', 'getattr', 'globals', 'hasattr', 'hash', 'help', 'hex', 'id', 'input', 'int', 'isinstance', 'issubclass', 'iter', 'len', 'license', 'list', 'locals', 'map', 'max', 'memoryview', 'min', 'next', 'object', 'oct', 'open', 'ord', 'pow', 'print', 'property', 'range', 'repr', 'reversed', 'round', 'runfile', 'set', 'setattr', 'slice', 'sorted', 'staticmethod', 'str', 'sum', 'super', 'tuple', 'type', 'vars', 'zip']
Here’s how an inner function can access a variable from its enclosing (outer) function:
def outer_function():
outer_variable = "I'm from the outer function!" # Variable in outer_function's local scope
def inner_function():
# inner_function can 'see' and use outer_variable
# because outer_variable is in its enclosing scope.
print(f"Inner function says: {outer_variable}")
print("Calling inner_function from outer_function...")
inner_function() # Call the inner function
# Now, let's call the outer_function to see it in action
outer_function()Calling inner_function from outer_function...
Inner function says: I'm from the outer function!
In this example, outer_variable is “enclosing” for inner_function.
If the inner function defines a variable with the same name as one in the outer function, the inner function will use its own local variable. This is called “shadowing”.
def outer_function_shadow():
message = "This is the OUTER message." # Variable in outer_function_shadow's scope
def inner_function_shadow():
message = "This is the INNER message!" # This is a NEW, LOCAL variable for inner_function_shadow
# It "shadows" the outer 'message'
print(f"Inside inner_function_shadow: {message}")
print(f"Before calling inner, outer message is: {message}")
inner_function_shadow()
print(f"After calling inner, outer message is still: {message}") # Unchanged
outer_function_shadow()Before calling inner, outer message is: This is the OUTER message.
Inside inner_function_shadow: This is the INNER message!
After calling inner, outer message is still: This is the OUTER message.
The message inside inner_function_shadow is a completely separate variable from the message in outer_function_shadow.
Consider the following code:
a = 10 # Global variable
def func_one():
b = 20 # Local to func_one
print(f"Inside func_one: a = {a}, b = {b}")
def func_two():
c = 30 # Local to func_two
# 'a' is global, 'b' is from enclosing scope of func_one
print(f"Inside func_two: a = {a}, b = {b}, c = {c}")
func_two()
# print(f"Inside func_one, trying to print c: {c}") # What would happen here?
func_one()
# print(f"Outside all functions: a = {a}")
# print(f"Outside all functions, trying to print b: {b}") # What would happen here?
# print(f"Outside all functions, trying to print c: {c}") # What would happen here?print statement will output, or if it will cause an error.b and c outside their scopes) and observe the errors. Why do they occur?a, b, and c?9
16
pass
Age: 18 - Eligible to vote: True
Age: 29 - Eligible to vote: True
Age: 15 - Eligible to vote: False
Age: 32 - Eligible to vote: True
Age: 6 - Eligible to vote: False
Example 1:
100
5
100
a = 10 # Global variable
def func_one():
b = 20 # Local to func_one
print(f"Inside func_one: a = {a}, b = {b}")
def func_two():
c = 30 # Local to func_two
# 'a' is global, 'b' is from enclosing scope of func_one
print(f"Inside func_two: a = {a}, b = {b}, c = {c}")
func_two()
# print(f"Inside func_one, trying to print c: {c}") # What would happen here?
func_one()
print(f"Outside all functions: a = {a}")Inside func_one: a = 10, b = 20
Inside func_two: a = 10, b = 20, c = 30
Outside all functions: a = 10