2.1. Arbitrary Number of Parameters

2.1.1. Recap information about function parameters

  • positional arguments

  • keyword (named) arguments

  • default values

  • keyword arguments must be on the right side

  • order of keyword arguments doesn't matter

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


echo(1, 2)       # positional arguments
echo(a=1, b=2)   # keyword arguments
echo(b=2, a=1)   # keyword arguments, order doesn't matter
echo(1, b=2)     # positional and keyword arguments
echo(a=1, 2)     # SyntaxError: positional argument follows keyword argument

2.1.2. Positional Parameters

  • * in this context, is not multiplication in mathematical sense

  • * is used for positional arguments

  • 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(a)       # 1
    print(b)       # 2
    print(c)       # 0
    print(args)    # ()


echo(1, 2)
def echo(a, b, c=0, *args):
    print(a)       # 1
    print(b)       # 2
    print(c)       # 3
    print(args)    # (4, 5, 6)


echo(1, 2, 3, 4, 5, 6)

2.1.3. Keyword Parameters

  • ** in this context, is not power in mathematical sense

  • ** is used for keyword arguments

  • 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(first_name='Jan', last_name='Twardowski')  # {'first_name': 'Jan', 'last_name': Twardowski}
def echo(a, b, c=0, **kwargs):
    print(a)       # 1
    print(b)       # 2
    print(c)       # 0
    print(kwargs)  # {}


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


echo(1, 2, 3, d=7, e=8)

2.1.4. Positional and Keyword Parameters

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


echo(1, 2)
def echo(a, b, c=0, *args, **kwargs):
    print(a)       # 1
    print(b)       # 2
    print(c)       # 3
    print(args)    # (4, 5, 6)
    print(kwargs)  # {}


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


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


echo(1, 2, 3, 4, 5, 6, d=7, e=8)

2.1.5. Examples

2.1.5.1. Sum

def add(*args):
    total = 0

    for arg in args:
        total += arg

    return total


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

2.1.5.2. Kelvin to Celsius

Listing 432. Converts arguments between different units
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]

2.1.5.3. HTML List Generator

Listing 433. Generate HTML list from function arguments
def html_list(*args):
    print('<ul>')

    for element in args:
        print(f'<li>{element}</li>')

    print('</ul>')


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

2.1.5.4. Print

Listing 434. Intuitive definition of print function
def print(*values, sep=' ', end='\n', ...):
    return sep.join(values) + end

2.1.5.5. Line Parser

def parse(line):
    mission, *crew = line.split(',')
    crew = ' and '.join(name.title() for name in crew)
    print(mission.upper(), crew)

parse('ares3,watney,lewis,vogel,johanssen')
# ARES3 Watney and Lewis and Vogel and Johanssen

parse('apollo18,twardowski,ivanovic')
# APOLLO18 Twardowski and Ivanovic

2.1.6. Assignments

2.1.6.1. Average

  • Complexity level: easy

  • Lines of code to write: 4 lines + doctests

  • Estimated time of completion: 5 min

  • Solution: solution/defining_average.py

English
  1. Create function average(), which calculates arithmetic mean

  2. Function can have arbitrary number of positional arguments

  3. Don't use neither numpy nor statistics

Polish
  1. Napisz funkcję average(), wyliczającą średnią arytmetyczną

  2. Funkcja przyjmuje dowolną ilość pozycyjnych argumentów

  3. Nie używaj numpy ani statistics

2.1.6.2. args

  • Complexity level: easy

  • Lines of code to write: 7 lines + doctests

  • Estimated time of completion: 10 min

  • Solution: solution/defining_args.py

English
  1. Create function is_numeric

  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 using type() and isinstance() passing True as an argument

  8. Run the function without any arguments

Polish
  1. Stwórz funkcję is_numeric

  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 użycie type() i isinstance() podając argument do funkcji True

  8. Uruchom funkcję bez podawania argumentów

The whys and wherefores
  • Defining and calling functions

  • Arbitrary number of positional arguments

  • Corner case checking

  • Function arguments checking

  • Type casting

2.1.6.3. args and kwargs

  • Complexity level: medium

  • Lines of code to write: 8 lines + doctests

  • Estimated time of completion: 10 min

  • Solution: solution/defining_kwargs.py

English
  1. Create function is_numeric

  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

Polish
  1. Stwórz funkcję is_numeric

  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

The whys and wherefores
  • Defining and calling functions

  • Arbitrary number of positional arguments

  • Corner case checking

  • Function arguments checking

  • Type casting