# 4.1. Parameter Syntax¶

## 4.1.1. Recap¶

def echo(a, b, c=3):
print(a, b, c)

echo(1, 2)              # 1 2 3
echo(1, b=2)            # 1 2 3
echo(1, c=3)            # TypeError: echo() missing 1 required positional argument: 'b'
echo(1, 2, 3)           # 1 2 3
echo(1, 2, c=3)         # 1 2 3
echo(1, b=2, c=3)       # 1 2 3
echo(a=1, b=2, c=3)     # 1 2 3


## 4.1.2. Keyword-only Parameters¶

• All parameters after * must be keyword-only

def echo(a, *, b, c=3):
print(a, b, c)

echo(1, 2)              # TypeError: echo() takes 1 positional argument but 2 were given
echo(1, b=2)            # 1 2 3
echo(1, c=3)            # TypeError: echo() missing 1 required keyword-only argument: 'b'
echo(1, 2, 3)           # TypeError: echo() takes 1 positional argument but 3 were given
echo(1, 2, c=3)         # TypeError: echo() takes 1 positional argument but 2 positional arguments (and 1 keyword-only argument) were given
echo(1, b=2, c=3)       # 1 2 3
echo(a=1, b=2, c=3)     # 1 2 3


## 4.1.3. Positional-only Parameters¶

• Since Python 3.8: PEP 570 -- Python Positional-Only Parameters

• All parameters before / must be positional-only

def echo(a, /, b, c=3):
print(a, b, c)

echo(1, 2)              # 1 2 3
echo(1, b=2)            # 1 2 3
echo(1, c=3)            # TypeError: echo() missing 1 required positional argument: 'b'
echo(1, 2, 3)           # 1 2 3
echo(1, 2, c=3)         # 1 2 3
echo(1, b=2, c=3)       # 1 2 3
echo(a=1, b=2, c=3)     # TypeError: echo() got some positional-only arguments passed as keyword arguments: 'a'


## 4.1.4. Positional and Keyword Parameters¶

def echo(a, /, b, *, c=3):
print(a, b, c)

echo(1, 2)              # 1 2 3
echo(1, b=2)            # 1 2 3
echo(1, c=3)            # TypeError: echo() missing 1 required positional argument: 'b'
echo(1, 2, 3)           # TypeError: echo() takes 2 positional arguments but 3 were given
echo(1, 2, c=3)         # 1 2 3
echo(1, b=2, c=3)       # 1 2 3
echo(a=1, b=2, c=3)     # TypeError: echo() got some positional-only arguments passed as keyword arguments: 'a'


## 4.1.5. Use Cases¶

sorted(iterable, *, key=None, reverse=False)

sum(iterable, /, start=0)

def add(a, b, /):
return a + b

def divmod(a, b, /):
return (a // b, a % b)

def quantiles(dist, /, *, n=4, method='exclusive')
...


## 4.1.6. Assignments¶

"""
* Assignment: Function Parameter Syntax Kwargs
* Complexity: easy
* Lines of code: 2 lines
* Time: 3 min

English:
1. Create function set_position
2. Function takes two arguments x, y and always returns None
3. Arguments must be passed only as keywords
4. Test function by running with keyword arguments
5. Test function by running with positional arguments
6. Compare result with "Tests" section (see below)

Polish:
1. Stwórz funkcję set_position
2. Funkcja przyjmuje dwa argumenty x, y i zawsze zwraca None
3. Argumenty można podawać tylko nazwanie (keyword)
4. Przetestuj funkcję uruchamiając z nazwanymi parametrami
5. Przetestuj funkcję uruchamiając z pozycyjnymi parametrami
6. Porównaj wyniki z sekcją "Tests" (patrz poniżej)

Tests:
>>> from inspect import isfunction
>>> assert callable(set_position)
>>> assert isfunction(set_position)

>>> set_position(x=1, y=2)

>>> set_position()
Traceback (most recent call last):
TypeError: set_position() missing 2 required keyword-only arguments: 'x' and 'y'

>>> set_position(1)
Traceback (most recent call last):
TypeError: set_position() takes 0 positional arguments but 1 was given

>>> set_position(1, 2)
Traceback (most recent call last):
TypeError: set_position() takes 0 positional arguments but 2 were given

>>> set_position(1, y=1)
Traceback (most recent call last):
TypeError: set_position() takes 0 positional arguments but 1 positional argument (and 1 keyword-only argument) were given

>>> set_position(x=1, 2)
Traceback (most recent call last):
SyntaxError: positional argument follows keyword argument
"""


"""
* Assignment: Function Parameter Syntax Args
* Complexity: easy
* Lines of code: 2 lines
* Time: 3 min
* Warning: This assignment will work only in Python 3.8+

English:
1. Create function take_damage
2. Function takes one argument dmg and always returns None
3. Argument must be passed only as positional
4. Test function by running with positional arguments
5. Test function by running with keyword arguments
6. Compare result with "Tests" section (see below)

Polish:
1. Stwórz funkcję take_damage
2. Funkcja przyjmuje jeden argument dmg i zawsze zwraca None
3. Argument można podawać tylko pozycyjnie
4. Przetestuj funkcję uruchamiając z pozycyjnymi parametrami
5. Przetestuj funkcję uruchamiając z nazwanymi parametrami
6. Porównaj wyniki z sekcją "Tests" (patrz poniżej)

Tests:
>>> from inspect import isfunction
>>> assert callable(take_damage)
>>> assert isfunction(take_damage)

>>> take_damage(1)
>>> take_damage(1, 2)
Traceback (most recent call last):
TypeError: take_damage() takes 1 positional argument but 2 were given
>>> take_damage()
Traceback (most recent call last):
TypeError: take_damage() missing 1 required positional argument: 'dmg'
>>> take_damage(dmg=1)
Traceback (most recent call last):
TypeError: take_damage() got some positional-only arguments passed as keyword arguments: 'dmg'
"""