?print-pdf
' Created for
### functions definitions
def sub_task_1():
pass
def sub_task_2():
pass
...
def sub_task_n():
pass
### main program
sub_task_1()
sub_task_2()
...
sub_task_n()
def function_name(param_list):
'''docstring'''
code block
return expression
def calculate_sum():
pass
def calculate_sum(number1, number2):
'''
Takes two numbers as parameters and returns their sum.
Parameters:
number1 (int/float): The first number.
number2 (int/float): The second number.
Returns:
int/float: The sum of number1 and number2.
'''
total_sum = number1 + number2
return total_sum
pass
statement for function body:
def do_task1():
pass
def do_task2():
pass
def do_task3():
pass
pass
statement anywhere in your code (if, for, while, etx. blocks), where you need a "do nothing" block!
def greet():
"""Just prints hello"""
print("Hello!")
Synonyms: Function Execution; Function Invocation
function_name(opt_arg_list)
### define greet() function
def greet():
"""Just prints hello"""
print("Hello!")
### execute the greet() function:
greet()
# execute the greet() function:
greet()
# define greet() function:
def greet():
print("Hello!")
# NameError: name 'greet' is not defined
# define greet() function:
def greet():
print("Hello!")
# execute the greet() function:
greet()
# Hello!
def add():
print(2+3)
add()
add()
add()
# OUTPUT:
# 5
# 5
# 5
# call add with different arguments:
add(20, 22)
add(123, 321)
add(16, 10)
# DESIRED OUTPUT:
# 42
# 444
# 26
def sub(x,y):
""" subtracts y from x and prints the result """
print(x - y)
sub(99)
# TypeError: sub() missing 1 required positional argument: 'y'
sub(99, 3, 3)
# TypeError: sub() takes 2 positional arguments but 3 were given
def greet(name="Nobody"):
""" greets a user """
print("Hello", name)
greet("Maria")
greet()
# Hello Maria
# Hello Nobody
def greet(msg="Hi", name):
print(f"{msg} {name}!")
greet("Maria")
# SyntaxError: non-default argument follows default argument
def greet(name, msg="Hi"):
print(f"{msg} {name}!")
greet("Maria")
# Hi Maria!
def greet(msg, name):
print(f"{msg} {name}!")
greet(name="Maria", msg="Hi")
def greet(msg, name):
print(f"{msg} {name}!")
greet(name="Maria", "Hi")
# SyntaxError: positional argument follows keyword argument
def greet(msg, name):
print(f"{msg} {name}!")
greet("Hi",name="Maria")
def greet(msg, name):
print(f"{msg} {name}!")
greet(name="Maria", msg="Hi")
*args
def foo(*args):
print(args)
foo(1)
foo(1,2)
foo(1,2,3)
#(1,)
#(1, 2)
#(1, 2, 3)
*args
is a special syntax that collects extra positional arguments into a tuple.args
can be any valid variable name, but its a convention to use *args
to denote that it contains the packed arguments.*args
must follow the positional parameters in definition (if any), or TypeError is raised:
def greet(*args, first_name):
print(f"Hello, {first_name}!")
for other_name in args:
print(f"Hello, {other_name}!")
# Example usage
greet("Alice", "Bob", "Charlie", "Diana")
# TypeError: greet() missing 1 required keyword-only argument: 'first_name'
def greet(first_name, *args, ):
print(f"Hello, {first_name}!")
for other_name in args:
print(f"Hello, {other_name}!")
# Example usage
greet("Alice", "Bob", "Charlie", "Diana")
# Hello, Alice!
# Hello, Bob!
# Hello, Charlie!
# Hello, Diana!
calculate_sum()
function, which will print the sum of variable number of numerical arguments
# calculate_sum() definition
# test your code:
calculate_sum(1)
#should print 1
calculate_sum(1,2)
#should print 3
calculate_sum(1,2,3)
#should print 6
**
(double stars) in front of parameter name which will collects a variable number of keyword arguments into a dictionary.
def foo(**kwargs):
print(kwargs)
foo(a=1, b=2)
# {'a': 1, 'b': 2}
def foo(**kwargs):
print(kwargs)
foo(a=1, b=2)
# {'a': 1, 'b': 2}
def print_user_data(**kwargs):
print(f'Data for user {kwargs['name']}: ')
for k,v in kwargs.items():
print(f'{k} - {v}')
print_user_data(name='Ada', age=28)
print_user_data(name='Maria', age=30, town='London')
# Data for user Ada:
# name - Ada
# age - 28
# Data for user Maria:
# name - Maria
# age - 30
# town - London
def configure_system(**kwargs):
print("System Configuration:")
for setting, value in kwargs.items():
print(f" - {setting}: {value}")
# Example usage
configure_system(resolution="1920x1080", brightness=75, volume=40)
# System Configuration:
# - resolution: 1920x1080
# - brightness: 75
# - volume: 40
*
operator
def my_func(p1,p2,p3):
print(p1, p2, p3)
args = [1,2,3]
my_func(*args)
# 1 2 3
Note, that if you miss the star in my_func(*[1,2,3])
, Python will assign the whole list [1,2,3]
to p1
, and the rest of parameters will receive no value. That will throw an error!
**
(double stars) to unpack dictionary into named arguments.
def menu_print(fruit, price):
print("{:.<20s}{:.2f}".format(fruit,price))
menu_print(**{
"price": 2.5,
"fruit": "apple"
})
# apple...............2.50
return
statementreturn
statement:
def f():
statements
return [expression]
def add(x,y):
return x+y
print(add(2,4)**2)
# 36
return
statementThe return statement exit the function! Any code after return
will never be executed:
def add(x,y):
return x+y
# next line will never be executed:
print("After return")
print(add(2,4))
return
statement, then the function return value is None.
def foo():
print("foo() was executed!")
def bar():
print("bar() was executed!")
return "End"
print( foo() )
print( bar() )
# OUTPUT:
# foo() was executed!
# None
# bar() was executed!
# End
def add(a, b):
return a + b
def div(a,b):
return a/b
res = add(2,3) + div(4,2)
print(res)
def greet(name):
print("Hello, {}".format(name))
#a function can be assigned to variable:
foo = greet
greet("Maria")
foo("Maria")
#OUTPUT
# Hello, Maria
# Hello, Maria
foo
holds a reference to the same function object in memory, so calling foo("Maria") is equivalent to calling greet("Maria")
def apply_function(func, value):
"""Applies a function to a value."""
return func(value)
def square(x):
"""Returns the square of x."""
return x * x
def cube(x):
"""Returns the cube of x."""
return x ** 3
# Passing the function 'square' to 'apply_function'
result_square = apply_function(square, 5)
print(result_square) # Output: 25
# Passing the function 'cube' to 'apply_function'
result_cube = apply_function(cube, 5)
print(result_cube) # Output: 125
def multiply_by(n):
"""Returns a function that multiplies its input by n."""
def multiply(x):
return x * n
return multiply
# Returning a function that multiplies by 2
double = multiply_by(2)
# Calling the returned function
result = double(5)
print(result) # Output: 10
lambda parameters: expression
double = lambda x: x * 2
print(double(5)) # 10
def double(x):
return x*2
print(double(5)) # 10
greet = lambda: "Hello, World!"
print(greet()) # Hello, World!
calc = {
'add': lambda x, y: x + y,
'sub': lambda x, y: x - y,
'mul': lambda x, y: x * y,
'div': lambda x, y: x / y if y != 0 else 'Error: Division by zero'
}
print( calc['add'](4,2) ) # 6
print( calc['sub'](4,2) ) # 2
print( calc['mul'](4,2) ) # 8
print( calc['div'](4,2) ) # 2.0
sorted()
function and the list.sort()
method both accept a key
parameter, where you can pass a lambda function to control the sorting criteria.
data = [(1, 'Z'), (2, 'Y'), (3, 'X')]
sorted_data = sorted(data, key=lambda t: t[1])
print(sorted_data)
# [(3, 'X'), (2, 'Y'), (1, 'Z')]
users = [
{'name': 'Alice', 'age': 30},
{'name': 'Bob', 'age': 25},
{'name': 'Charlie', 'age': 35}
]
sorted_users = sorted(users, key=lambda user: user['age'])
print(sorted_users)
# [{'name': 'Bob', 'age': 25}, {'name': 'Alice', 'age': 30}, {'name': 'Charlie', 'age': 35}]
products = {
'apple': 3,
'coffee': 2.5,
'beer': 4.20
}
sorted_products = sorted(products.items(), key=lambda item:item[1])
print(sorted_products)
# [('coffee', 2.5), ('apple', 3), ('beer', 4.2)]
def f1():
y = 2
print(f"y = {y} inside f1")
f1()
# y = 2 inside f1
print(f"y = {y} outside f1")
# NameError: name 'y' is not defined
x = 10
def foo():
print("x = {} inside foo()".format(x))
foo()
# x = 10 inside foo()
print("x = {} outside foo()".format(x))
# x = 10 outside foo()
locals()
and globals()
to print the local and global namespace, respectively.locals()
returns the namespace, containing the variables defined in the local scope.globals()
returns the namespace containing the variables defined in the global scope.
x = 10 # A global variable
def foo():
x = 20 # A local variable
print("Local Scope:", locals())
print("Global Scope:", globals())
foo()
# Local Scope: {'x': 20}
# Global Scope: {'__name__': '__main__', '__doc__': None, '__package__': None, '__loader__': <_frozen_importlib_external.SourceFileLoader object at 0x7f7bcb1d05c0>, '__spec__': None, '__annotations__': {}, '__builtins__': <module 'builtins' (built-in)>, '__file__': '/examples/tmp.py', '__cached__': None, 'x': 10, 'foo': <function my_function at 0x7f7bcb40a2a0>}
x = 1
def foo():
x = 99
print(f"x = {x} inside foo")
foo()
# x = 99 inside foo
print(f"x = {x} outside foo")
# x = 1 outside foo
Variables with same name, defined in different scopes are considered as different variables!
def outer():
x=2
def inner():
x = 3
print(f'x = {x} in inner')
inner()
print(f'x = {x} in outer')
x = 1
outer()
print(f'x = {x} in global')
#x = 3 in inner
#x = 2 in outer
#x = 1 in global
global
statementglobal
statement prefixglobal
statement causes the listed names to be interpreted as global names.
def outer():
x=2
def inner():
global x
x = 3 # we change the global x
print(f'x = {x} in inner')
inner()
print(f'x = {x} in outer')
x = 1
outer()
print(f'x = {x} in global')
#x = 3 in inner
#x = 2 in outer
#x = 3 in global
nonlocal
statementnonlocal
statement prefix
def outer():
x=2
def inner():
nonlocal x
x = 3 # we change the x in outer
print(f'x = {x} in inner')
inner()
print(f'x = {x} in outer')
x = 1
outer()
print(f'x = {x} in global')
#x = 3 in inner
#x = 2 in outer
#x = 1 in global
Although scopes are determined statically, they are used dynamically. I.e. a name is resolved searching in:
def get_user_data():
"""retrieves user data from the command line
Returns:
[dictionary] of the form:
{
"name" : "user_name",
"height": "user heigth in meters",
"weight": "user weight in kilograms"
}
"""
pass
def calc_BMI(w,h):
"""calculates the BMI
Arguments:
w {[float]} -- [weight]
h {[float]} -- [height]
Returns:
[float] -- [calculated BMI = w / (h*h)]
"""
pass
def calc_BMI_category(bmi):
"""Calculates the BMI category
Arguments:
bmi {[float]} -- [the bmi number index]
Returns:
[string] -- [bmi category]
"""
pass
def print_results(bmi_category):
"""[Prints the BMI category to the user ]
Arguments:
bmi_category {[string]} -- []
"""
pass
def cm_to_meters(cm):
"""converts centimetres to meters
Arguments:
cm {[int]}
Returns:
[float]
"""
pass
user_data = get_user_data()
bmi = calc_BMI(user_data["weight"],user_data["height"] )
bmi_category = calc_BMI_category(bmi)
print_results(bmi_category)
get_user_data()
defined in Task1, adding a check for valid user data:These slides are based on
customised version of
framework