# 3.2. Unpacking Parameters¶

## 3.2.1. Recap¶

• parameter - Receiving variable used within the function/block

• required parameters - Parameter which is necessary to call function

• optional parameters (with default value) - Parameter which is optional and has default value (if not specified at call time)

def echo(a, b=0):
print(a)
print(b)


Figure 3.15.

## 3.2.3. Positional Parameters¶

• * is used for positional parameters

• args is a convention, but you can use any name

• *args unpacks to tuple

def echo(*args):
print(args)

echo()                     # ()
echo(1)                    # (1,)
echo(2, 3)                 # (2, 3)
echo('a', 'b')             # ('a', 'b')
echo('a', 2, 3.3)          # ('a', 2, 3.3)

def echo(a, b, c=0, *args):
print(f'{a=}, {b=}, {c=}, {args=}')

echo(1, 2)
# a=1, b=2, c=0, args=()

echo(1, 2, 3)
# a=1, b=2, c=3, args=()

echo(1, 2, 3, 4)
# a=1, b=2, c=3, args=(4,)

echo(1, 2, 3, 4, 5, 6)
# a=1, b=2, c=3, args=(4, 5, 6)


## 3.2.4. Keyword Parameters¶

• ** is used for keyword parameters

• kwargs is a convention, but you can use any name

• **kwargs unpacks to dict

def echo(**kwargs):
print(kwargs)

echo(a=1)                                       # {'a': 1}
echo(color='red')                               # {'color': 'red'}
echo(firstname='Jan', lastname='Twardowski')    # {'firstname': 'Jan', 'lastname': Twardowski}

def echo(a, b, c=0, **kwargs):
print(f'{a=}, {b=}, {c=}, {kwargs=}')

echo(1, 2)
# a=1, b=2, c=0, kwargs={}

echo(1, 2, 3)
# a=1, b=2, c=3, kwargs={}

echo(1, 2, 3, d=7, e=8)
# a=1, b=2, c=3, kwargs={'d': 7, 'e': 8}

echo(1, 2, a=7)
# Traceback (most recent call last):
# TypeError: echo() got multiple values for argument 'a'


## 3.2.5. Positional and Keyword Parameters¶

def echo(a, b, c=0, *args, **kwargs):
print(f'{a=}, {b=}, {c=}, {args=}, {kwargs=}')

echo(1, 2)
# a=1, b=2, c=0, args=(), kwargs={}

echo(1, 2, 3, 4, 5, 6)
# a=1, b=2, c=3, args=(4, 5, 6), kwargs={}

echo(1, 2, 3, d=7, e=8)
# a=1, b=2, c=3, args=(), kwargs={'d': 7, 'e': 8}

echo(1, 2, 3, 4, 5, 6, d=7, e=8)
# a=1, b=2, c=3, args=(4, 5, 6), kwargs={'d': 7, 'e': 8}


## 3.2.6. Examples¶

Sum:

def sum(*values):
total = 0
for value in values:
total += value

sum()            # 0
sum(1)           # 1
sum(1, 4)        # 5
sum(3, 1)        # 4
sum(1, 2, 3, 4)  # 10


Kelvin to Celsius:

def kelvin_to_celsius(*degrees):
return [x+273.15 for x in degrees]

kelvin_to_celsius(1)
# [274.15]

kelvin_to_celsius(1, 2, 3, 4, 5)
# [274.15, 275.15, 276.15, 277.15, 278.15]


Generate HTML list:

def html_list(*fruits):
print('<ul>')
for fruit in fruits:
print(f'<li>{fruit}</li>')
print('</ul>')

html_list('apple', 'banana', 'orange')
# <ul>
# <li>apple</li>
# <li>banana</li>
# <li>orange</li>
# </ul>


Intuitive definition of print function:

def print(*values, sep=' ', end='\n', ...):
return sep.join(values) + end

print('a')
# a

print('a', 'b')
# 'a b'

print('a', 'b', 'c')
# 'a b c'

print('a', 'b', 'c', sep=',')
# 'a,b,c'

print('a', 'b', 'c', sep='|')
# 'a|b|c'


## 3.2.7. Assignments¶

"""
* Assignment: Unpacking Parameters Define
* Complexity: easy
* Lines of code: 4 lines
* Time: 5 min

English:
1. Create function mean(), which calculates arithmetic mean
2. Function can have arbitrary number of positional arguments
3. Do not import any libraries and modules
4. Compare result with "Tests" section (see below)

Polish:
1. Napisz funkcję mean(), wyliczającą średnią arytmetyczną
2. Funkcja przyjmuje dowolną ilość pozycyjnych argumentów
3. Nie importuj żadnych bibliotek i modułów
4. Porównaj wyniki z sekcją "Tests" (patrz poniżej)

Hints:
* sum(...) / len(...)

Tests:
>>> mean(1)
1.0
>>> mean(1, 3)
2.0
>>> mean()
Traceback (most recent call last):
ValueError: At least one argument is required
"""


"""
* Assignment: Unpacking Parameters Args
* Complexity: easy
* Lines of code: 7 lines
* Time: 5 min

English:
1. Create function isnumeric
2. Function can have arbitrary number of positional arguments
3. Arguments can be of any type
4. Return True if all arguments are int or float only
5. Return False if any argument is different type
6. Do not use all() and any()
7. Compare result with "Tests" section (see below)

Polish:
1. Stwórz funkcję isnumeric
2. Funkcja może przyjmować dowolną liczbę argumentów pozycyjnych
3. Podawane argumenty mogą być dowolnego typu
4. Zwróć True jeżeli wszystkie argumenty są tylko typów int lub float
5. Zwróć False jeżeli którykolwiek jest innego typu
6. Nie używaj all() oraz any()
7. Porównaj wyniki z sekcją "Tests" (patrz poniżej)

Hints:
* isinstance(obj, (type1, type2))
* type(obj)

Tests:
>>> isnumeric()
False
>>> isnumeric(0)
True
>>> isnumeric(1)
True
>>> isnumeric(-1)
True
>>> isnumeric(1.1)
True
>>> isnumeric('one')
False
>>> isnumeric([1, 1.1])
False
>>> isnumeric(1, 1.1)
True
>>> isnumeric(1, 'one')
False
>>> isnumeric(1, 'one', 'two')
False
>>> isnumeric(True)
False
"""


"""
* Assignment: Unpacking Parameters Kwargs
* Complexity: medium
* Lines of code: 8 lines
* Time: 5 min

English:
1. Create function isnumeric
2. Function can have arbitrary number of positional **and keyword arguments**
3. Arguments can be of any type
4. Return True if all arguments are int or float only
5. Return False if any argument is different type
6. Do not use all() and any()
7. Compare using type() and isinstance() passing True as an argument
8. Run the function without any arguments
9. Compare result with "Tests" section (see below)

Polish:
1. Stwórz funkcję isnumeric
2. Funkcja może przyjmować dowolną liczbę argumentów pozycyjnych **i nazwanych**
3. Podawane argumenty mogą być dowolnego typu
4. Zwróć True jeżeli wszystkie argumenty są tylko typów int lub float
5. Zwróć False jeżeli którykolwiek jest innego typu
6. Nie używaj all() oraz any()
7. Porównaj użycie type() i isinstance() podając argument do funkcji True
8. Uruchom funkcję bez podawania argumentów
9. Porównaj wyniki z sekcją "Tests" (patrz poniżej)

Hints:
* isinstance(obj, (type1, type2))
* type(obj)

Tests:
>>> isnumeric()
False
>>> isnumeric(0)
True
>>> isnumeric(1)
True
>>> isnumeric(-1)
True
>>> isnumeric(1.1)
True
>>> isnumeric('one')
False
>>> isnumeric([1, 1.1])
False
>>> isnumeric(1, 1.1)
True
>>> isnumeric(1, 'one')
False
>>> isnumeric(1, 'one', 'two')
False
>>> isnumeric(True)
False
>>> isnumeric(a=1)
True
>>> isnumeric(a=1.1)
True
>>> isnumeric(a='one')
False
"""