8.4. Function Arguments

8.4.1. Rationale

argument

Value/variable/reference being passed to the function

positional argument

Value passed to function - order is important

keyword argument

Value passed to function resolved by name - order is not important

8.4.2. Syntax

Function definition with parameters:

myfunction(<arguments>)
>>> add(1, 2)
>>> add(a=1, b=2)
>>> add(1, b=2)

8.4.3. Positional Arguments

  • Order of positional arguments has significance

    >>> def subtract(a, b):
    ...    return a - b
    >>>
    >>>
    >>> subtract(2, 1)
    1
    >>> subtract(1, 2)
    -1
    

8.4.4. Keyword Arguments

  • Order of keyword arguments has no significance

    >>> def subtract(a, b):
    ...     return a - b
    >>>
    >>>
    >>> subtract(a=2, b=1)
    1
    >>> subtract(b=1, a=2)
    1
    

8.4.5. Positional and Keyword Arguments

  • Positional arguments must be at the left side

  • Keyword arguments must be at the right side

    >>> def subtract(a, b):
    ...     return a - b
    >>>
    >>>
    >>> subtract(2, b=1)
    1
    >>> subtract(a=2, 1)
    Traceback (most recent call last):
    SyntaxError: positional argument follows keyword argument
    >>> subtract(2, a=1)
    Traceback (most recent call last):
    TypeError: subtract() got multiple values for argument 'a'
    

8.4.6. Examples

Example 1:

>>> def hello(name='José Jiménez'):
...      print(f'My name... {name}')
>>>
>>>
>>> hello('Mark Watney')
My name... Mark Watney
>>> hello(name='Mark Watney')
My name... Mark Watney
>>> hello()
My name... José Jiménez

Example 2:

>>> connect('myusername', 'mypassword')
>>> connect('myusername', 'mypassword', 'example.com', 443, False, 1, True)
>>> connect(host='example.com', username='myusername', password='mypassword')
>>> connect(
...     host='example.com',
...     username='myusername',
...     password='mypassword',
...     port=443,
...     ssl=True,
...     persistent=True)

Example 3:

>>> read_csv('iris.csv')
>>> read_csv('iris.csv', encoding='utf-8')
>>> read_csv('iris.csv', encoding='utf-8', parse_dates=['date_of_birth'])
>>> read_csv('iris.csv', skiprows=3, delimiter=';')
>>> read_csv('iris.csv',
...     encoding='utf-8',
...     skiprows=3,
...     delimiter=';',
...     usecols=['Sepal Length', 'Species'],
...     parse_dates=['date_of_birth'])

8.4.7. Assignments

Code 8.6. Solution
"""
* Assignment: Function Arguments Sequence
* Complexity: easy
* Lines of code: 2 lines
* Time: 3 min

English:
    1. Define function which takes sequence of integers as an argument
    2. Sum only even numbers
    3. Print returned value

Polish:
    1. Zdefiniuj funkcję biorącą sekwencję liczb całkowitych jako argument
    2. Zsumuj tylko parzyste liczby
    3. Wypisz zwróconą wartość

Tests:
    >>> from inspect import isfunction
    >>> isfunction(total)
    True
    >>> total([1,2,3,4])
    6
    >>> total([2,-1,0,2])
    4
    >>> total(range(0,101))
    2550
"""


Code 8.7. Solution
"""
* Assignment: Function Arguments Divide
* Complexity: easy
* Lines of code: 4 lines
* Time: 3 min

English:
    1. Define function `divide`
    2. Function takes two arguments
    3. Function returns result of the division of both arguments
    4. If division cannot be made, raise `ValueError` with "Argument `b` cannot be negative"

Polish:
    1. Zdefiniuj funkcję `divide`
    2. Funkcja przyjmuje dwa argumenty
    3. Funkcja zwraca wynik dzielenia dwóch argumentów
    4. Jeżeli nie można podzielić, podnieś `ValueError` z "Argument `b` cannot be negative"

Tests:
    >>> from inspect import isfunction
    >>> isfunction(divide)
    True
    >>> divide(4, 0)
    Traceback (most recent call last):
    ValueError: Argument `b` cannot be negative
    >>> divide(4, 2)
    2.0
"""


Code 8.8. Solution
"""
* Assignment: Function Arguments Power
* Complexity: easy
* Lines of code: 4 lines
* Time: 3 min

English:
    1. Define function `power`
    2. Function takes two arguments
    3. Second argument is optional
    4. Function returns power of the first argument to the second
    5. If only one argument was passed, consider second equal to the first one
    6. Print returned values
    7. Compare result with "Tests" section (see below)

Polish:
    1. Zdefiniuj funkcję `power`
    2. Funkcja przyjmuje dwa argumenty
    3. Drugi argument jest opcjonalny
    4. Funkcja zwraca wynik pierwszego argumentu do potęgi drugiego
    5. Jeżeli tylko jeden argument był podany, przyjmij drugi równy pierwszemu
    6. Wypisz zwracane wartości
    7. Porównaj wyniki z sekcją "Tests" (patrz poniżej)

Tests:
    >>> from inspect import isfunction
    >>> isfunction(power)
    True
    >>> power(4, 3)
    64
    >>> power(3)
    27
"""


Code 8.9. Solution
"""
* Assignment: Function Arguments Translate
* Complexity: easy
* Lines of code: 2 lines
* Time: 5 min

English:
    1. Define function `translate` with parameter `text`
    2. Use `str.join()` with generator expression to iterate over `text`
    3. If letter is in `PL` then use conversion value as letter, otherwise take letter
    4. Return from function translated `text`
    5. Compare result with "Tests" section (see below)

Polish:
    1. Zdefiniuj funkcję `translate` przyjmującą parametr `text`
    2. Użyj `str.join()` z wyrażeniem generatorowym do iteracji po `text`
    3. Jeżeli litera jest w `PL` to użyj skonwertowanej wartości jako litera, w przeciwnym przypadku to weź literę
    4. Zwróć z funkcji przetłumaczony `text`
    5. Porównaj wyniki z sekcją "Tests" (patrz poniżej)

Tests:
    >>> from inspect import isfunction
    >>> isfunction(translate)
    True
    >>> translate('zażółć')
    'zazolc'
    >>> translate('gęślą')
    'gesla'
    >>> translate('jaźń')
    'jazn'
    >>> translate('zażółć gęślą jaźń')
    'zazolc gesla jazn'
"""


# Given
PL = {'ą': 'a', 'ć': 'c', 'ę': 'e',
      'ł': 'l', 'ń': 'n', 'ó': 'o',
      'ś': 's', 'ż': 'z', 'ź': 'z'}


Code 8.10. Solution
"""
* Assignment: Function Arguments Clean
* Complexity: medium
* Lines of code: 15 lines
* Time: 13 min

English:
    1. Write function cleaning up data
    2. Function takes one argument of type `str`
    3. Function returns cleaned text
    4. Compare result with "Tests" section (see below)

Polish:
    1. Napisz funkcję czyszczącą dane
    2. Funkcja przyjmuje jeden argument typu `str`
    3. Funkcja zwraca oczyszczony tekst
    4. Porównaj wyniki z sekcją "Tests" (patrz poniżej)

Tests:
    >>> from inspect import isfunction
    >>> isfunction(clean)
    True
    >>> clean('ul.Mieszka II')
    'Mieszka II'
    >>> clean('UL. Zygmunta III WaZY')
    'Zygmunta III Wazy'
    >>> clean('  bolesława chrobrego ')
    'Bolesława Chrobrego'
    >>> clean('ul Jana III SobIESkiego')
    'Jana III Sobieskiego'
    >>> clean('\tul. Jana trzeciego Sobieskiego')
    'Jana III Sobieskiego'
    >>> clean('ulicaJana III Sobieskiego')
    'Jana III Sobieskiego'
    >>> clean('UL. JA    NA 3 SOBIES  KIEGO')
    'Jana III Sobieskiego'
    >>> clean('ULICA JANA III SOBIESKIEGO  ')
    'Jana III Sobieskiego'
    >>> clean('ULICA. JANA III SOBIeskieGO')
    'Jana III Sobieskiego'
    >>> clean(' Jana 3 Sobieskiego  ')
    'Jana III Sobieskiego'
    >>> clean('Jana III Sobi  eskiego ')
    'Jana III Sobieskiego'

TODO: Translate input data to English
"""


Code 8.11. Solution
"""
* Assignment: Function Arguments Numbers to Str
* Complexity: medium
* Lines of code: 5 lines
* Time: 8 min

English:
    1. Use data from "Given" section (see below)
    2. Given is pilot's alphabet for numbers
    3. Convert `DATA: dict[int, str]` to `data: dict[str, str]` (keys as `str`)
    4. Define function `pilot_say` converting `int` or `float` to text form in Pilot's Speak
    5. You cannot change `DATA`, but you can modify `data`
    6. Compare result with "Tests" section (see below)

Polish:
    1. Użyj danych z sekcji "Given" (patrz poniżej)
    2. Dany jest alfabet pilotów dla numerów
    3. Przekonwertuj `DATA: dict[int, str]` na `data: dict[str, str]` (klucze jako `str`)
    4. Zdefiniuj funkcję `pilot_say` konwertującą `int` lub `float` na formę tekstową w mowie pilotów
    5. Nie możesz zmieniać `DATA`, ale możesz modyfikować `data`
    6. Porównaj wyniki z sekcją "Tests" (patrz poniżej)

Tests:
    >>> from inspect import isfunction
    >>> isfunction(pilot_say)
    True
    >>> pilot_say(1)
    'one'
    >>> pilot_say(+1)
    'one'
    >>> pilot_say(-1)
    'minus one'
    >>> pilot_say(1+1)
    'two'
    >>> pilot_say(1-1)
    'zero'
    >>> pilot_say(1969)
    'one niner six niner'
    >>> pilot_say(31337)
    'tree one tree tree seven'
    >>> pilot_say(13.37)
    'one tree and tree seven'
    >>> pilot_say(31.337)
    'tree one and tree tree seven'
    >>> pilot_say(-1969)
    'minus one niner six niner'
    >>> pilot_say(-31.337)
    'minus tree one and tree tree seven'
    >>> pilot_say(-49.35)
    'minus fower niner and tree fife'
    >>> pilot_say(1.0)
    'one and zero'
    >>> pilot_say(1.)
    'one and zero'
    >>> pilot_say(123.)
    'one two tree and zero'
    >>> pilot_say(123.0)
    'one two tree and zero'
    >>> pilot_say(.44)
    'zero and fower fower'
    >>> pilot_say(1-)
    Traceback (most recent call last):
    SyntaxError: invalid syntax
"""


# Given
DATA = {
    0: 'zero',
    1: 'one',
    2: 'two',
    3: 'tree',
    4: 'fower',
    5: 'fife',
    6: 'six',
    7: 'seven',
    8: 'ait',
    9: 'niner',
}


Code 8.12. Solution
"""
* Assignment: Function Arguments Numbers to Human
* Complexity: hard
* Lines of code: 15 lines
* Time: 21 min

English:
    1. Define function converting `int` or `float` to text form
    2. Text form must be in proper grammar form
    3. Max 6 digits before decimal separator (point `.`)
    4. Max 5 digits after decimal separator (point `.`)
    5. Compare result with "Tests" section (see below)

Polish:
    1. Zdefiniuj funkcję konwertującą `int` lub `float` na formę tekstową
    2. Forma tekstowa musi być poprawna gramatycznie
    3. Max 6 cyfr przed separatorem dziesiętnym (point `.`)
    4. Max 5 cyfr po separatorze dziesiętnym (point `.`)
    5. Porównaj wyniki z sekcją "Tests" (patrz poniżej)

Tests:
    >>> from inspect import isfunction
    >>> isfunction(number_to_str)
    True
    >>> number_to_str(1969)
    'one thousand nine hundred sixty nine'
    >>> number_to_str(31337)
    'thirty one thousand three hundred thirty seven'
    >>> number_to_str(13.37)
    'thirteen and thirty seven hundredths'
    >>> number_to_str(31.337)
    'thirty one and three hundreds thirty seven thousands'
    >>> number_to_str(-1969)
    'minus one thousand nine hundred sixty nine'
    >>> number_to_str(-31.337)
    'minus thirty one and three hundreds thirty seven thousands'
    >>> number_to_str(-49.35)
    'minus forty nine and thirty five hundreds'
"""


# Given
NUMBER = {
    '0': 'zero',
    '1': 'one',
    '2': 'two',
    '3': 'three',
    '4': 'four',
    '5': 'five',
    '6': 'six',
    '7': 'seven',
    '8': 'eight',
    '9': 'nine',
    '.': 'and',
    '-': 'minus'}


def number_to_str(number):
    return