1. Function Basics

1.1. Function definition

  • Wielokrotne używanie tego samego kodu
  • Poprawiają czytelność kodu
  • Porządkują kod
  • Pozwalają na łatwiejszy refactoring
def hello():
    print('My name... José Jiménez')

hello()     # My name... José Jiménez
hello()     # My name... José Jiménez
hello()     # My name... José Jiménez

1.2. Returning values

  • return wskazuje funkcji jaką wartość ma zwrócić
  • Kod po słowie kluczowym return się nie wykona
def hello():
    return 'ehlo world'

output = hello()

print(output)
# 'ehlo world'
def hello():
    return 'ehlo world'
    print('This will not be executed')

output = hello()

print(output)
# 'ehlo world'

1.2.1. Returning simple types

def function():
    return 42
def function():
    return 13.37
def function():
    return 'José Jiménez'
def function():
    return (42, 13.37, 'José Jiménez')
def function():
    return 42, 13.37, 'José Jiménez'
def function():
    return [42, 13.37, 'foobar']
def function():
    return {42, 13.37, 'José Jiménez'}
def function():
    return {'first_name': 'José', 'last_name': 'Jiménez'}
def function():
    return True
def function():
    return None
def function():
    print('ehlo world')
    # Python will ``return None`` if not specified
def function():
    pass
    # Python will ``return None`` if not specified

1.2.2. Returning nested types

def function():
    return [
        ('Mark', 'Watney'),
        {'Kowalski', 'Lewis'},
        {'astro': 'Иванович', 'agency': {'name': 'roscosmos'}},
        {'astro': 'Jiménez', 'missions': ('mercury', 'apollo')},
    ]

1.3. Function arguments

1.3.1. Passing arguments

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

add(1, 2)
# 3

1.3.2. Named arguments

def minus(a, b):
    return a - b

minus(2, 1)      # 1
minus(1, 2)      # -1
minus(a=2, b=1)  # 1
minus(b=1, a=2)  # 1
minus(2, b=1)    # 1
minus(a=2, 1)    # SyntaxError: positional argument follows keyword argument

1.3.3. Arguments with default value

  • Funkcja przyjmie wartość domyślną dla argumentu jeżeli użytkownik nie nadpisze
  • Argumenty z wartością domyślną muszą być skrajnie po prawej stronie
  • Kolejność podawania argumentów nazwanych nie ma znaczenia
  • Argumenty z wartościami domyślnymi nie muszą być podane
  • Arguemnty bez wartości domyślnych są wymagane
def hello(name='José Jiménez'):
     print(f'My name... {name}')


hello('Иван Иванович')        # My name... Иван Иванович
hello(name='Иван Иванович')   # My name... Иван Иванович
hello()                       # My name... José Jiménez
def server(username, password, host='127.0.0.1',
           port=80, ssl=False, keep_alive=1,
           persistent=False):
    print('Connecting...')


server('admin', 'admin', 'localhost', 80, False, 1, True)

server(host='localhost', username='admin', password='admin', ssl=True, keep_alive=1, persistent=True)

server(
    host='localhost',
    username='admin',
    password='admin',
    port=443,
    ssl=True,
    persistent=True,
)
# ``read_csv`` is a function from ``pandas`` library
read_csv(filepath_or_buffer, sep=', ', delimiter=None,
         header='infer', names=None, index_col=None,
         usecols=None, squeeze=False, prefix=None,
         mangle_dupe_cols=True, dtype=None, engine=None,
         converters=None, true_values=None, false_values=None,
         skipinitialspace=False, skiprows=None, nrows=None,
         na_values=None, keep_default_na=True, na_filter=True,
         verbose=False, skip_blank_lines=True, parse_dates=False,
         infer_datetime_format=False, keep_date_col=False,
         date_parser=None, dayfirst=False, iterator=False,
         chunksize=None, compression='infer', thousands=None,
         decimal=b'.', lineterminator=None, quotechar='"',
         quoting=0, escapechar=None, comment=None, encoding=None,
         dialect=None, tupleize_cols=None, error_bad_lines=True,
         warn_bad_lines=True, skipfooter=0, doublequote=True,
         delim_whitespace=False, low_memory=True, memory_map=False,
         float_precision=None)


data = read_csv(
    filepath_or_buffer='iris.csv',
    encoding='utf-8',
    usecols=['Petal lenght', 'Species']
)

1.4. Naming convention

1.4.1. Function name convention

  • It’s not Java, do not use camelCase

    def addNumbers(a, b):
        return a + b
    
  • It’s Python, use snake_case # Python - snake ;)

    def add_numbers(a, b):
        return a + b
    

1.4.2. Use better names, rather than comments

def cal_var(results):
    """Calculate variance"""
    return sum((Xi-m) ** 2 for Xi in results) / len(results)

def calculate_variance(results):
    return sum((Xi-m) ** 2 for Xi in results) / len(results)

1.4.3. Name collisions

  • _ at the end of name when name collision

    def print_(text):
        print(f'<strong>{text}</strong>')
    

1.4.4. System functions names

  • __ at the beginning and end of name

    def __import__(module_name):
        ...
    

1.5. Variable scope

  • function arguemnts and variables live only inside function scope
  • globals() - all variables in program (outside functions)
  • locals() - variables inside function
def add(a, b=2):
    c = 3
    print(locals())

add(1)
# {'a': 1, 'b': 2, 'c': 3}

1.6. More advanced topics

Note

The topic will be continued in Advanced Functions chapter

1.7. Assignments

1.7.1. Cleaning text input

  1. Napisz funkcję oczyszczającą, która podane niżej zmienne zamieni na ciąg “Jana III Sobieskiego”
expected = 'Jana III Sobieskiego'

a = '  Jana III Sobieskiego 1 apt 2'
b = 'ul Jana III SobIESkiego 1/2'
c = '\tul. Jana trzeciego Sobieskiego 1/2'
d = 'ulicaJana III Sobieskiego 1/2'
e = 'UL. JA\tNA 3 SOBIES\tKIEGO 1/2'
f = 'UL. III SOBiesKIEGO 1/2'
g = 'ULICA JANA III SOBIESKIEGO 1 /2  '
h = 'ULICA. JANA III SOBI'
i = ' Jana 3 Sobieskiego 1/2 '
j = 'Jana III Sobieskiego 1 m. 2'
k = 'ul.Jana III Sob\n\nieskiego 1/2'

print(f'{a == expected}\t a: "{a}"')
print(f'{b == expected}\t b: "{b}"')
print(f'{c == expected}\t c: "{c}"')
print(f'{d == expected}\t d: "{d}"')
print(f'{e == expected}\t e: "{e}"')
print(f'{f == expected}\t f: "{f}"')
print(f'{g == expected}\t g: "{g}"')
print(f'{h == expected}\t h: "{h}"')
print(f'{i == expected}\t i: "{i}"')
print(f'{j == expected}\t j: "{j}"')
print(f'{k == expected}\t k: "{k}"')
About:
  • Filename: functions_str_clean.py
  • Lines of code to write: 15 lines
  • Estimated time of completion: 15 min
The whys and wherefores:
 
  • Definiowanie i uruchamianie funkcji
  • Sprawdzanie przypadków brzegowych (niekompatybilne argumenty)
  • Parsowanie argumentów funkcji
  • Czyszczenie danych od użytkownika

1.7.2. Aviation numbers

  1. Napisz funkcję aviation_numbers
  2. Funkcja zamieni dowolnego int lub float na formę tekstową w mowie pilotów
Tab. 1.3. Aviation Phonetic Numbers
Letter Pronounce
0 zero
1 one
2 two
3 tree
4 fower
5 fife
6 six
7 seven
8 ait
9 niner
aviation_numbers(1969)       # 'one niner six niner'
aviation_numbers(31337)      # 'tree one tree tree seven'
aviation_numbers(13.37)      # 'one tree and tree seven'
aviation_numbers(31.337)     # 'tree one and tree tree seven'
aviation_numbers(-1969)      # 'minus one niner six niner'
aviation_numbers(-31.337)    # 'minus tree one and tree tree seven
aviation_numbers(-49.35)     # 'minus fower niner and tree fife'
About:
  • Filename: functions_aviation_numbers.py
  • Lines of code to write: 15 lines
  • Estimated time of completion: 15 min
The whys and wherefores:
 
  • Definiowanie i uruchamianie funkcji
  • Sprawdzanie przypadków brzegowych (niekompatybilne argumenty)
  • Parsowanie argumentów funkcji
  • Definiowanie i korzystanie z dict z wartościami
  • Przypadek zaawansowany: argumenty pozycyjne i domyślne
  • Rzutowanie i konwersja typów

1.7.3. Number to human readable

  1. Napisz funkcję number_to_str

  2. Funkcja zamieni dowolnego int lub float na formę tekstową

  3. Funkcja musi zmieniać wartości na poprawną gramatycznie formę

  4. Max 6 cyfr przed przecinkiem

  5. Max 5 cyfr po przecinku

    number_to_str(1969)      # 'one thousand nine hundred sixty nine'
    number_to_str(13.37)     # 'thirteen and thirty seven hundredths'
    number_to_str(31337)     # 'thirty one thousand three hundred thirty seven'
    number_to_str(31.337)    # 'thirty one three hundreds thirty seven thousands'
    number_to_str(-1969)     # 'minus one thousand nine hundred sixty nine'
    number_to_str(-31.337)   # 'minus thirty one three hundreds thirty seven thousands'
    
About:
  • Filename: functions_numstr_human.py
  • Lines of code to write: 15 lines
  • Estimated time of completion: 15 min
The whys and wherefores:
 
  • Definiowanie i uruchamianie funkcji
  • Sprawdzanie przypadków brzegowych (niekompatybilne argumenty)
  • Parsowanie argumentów funkcji
  • Definiowanie i korzystanie z dict z wartościami
  • Przypadek zaawansowany: argumenty pozycyjne i domyślne
  • Rzutowanie i konwersja typów

1.7.4. Roman numbers

  1. Napisz program, który przeliczy wprowadzoną liczbę rzymską na jej postać dziesiętną.
  2. Napisz drugą funkcję, która dokona procesu odwrotnego.
About:
  • Filename: functions_roman.py
  • Lines of code to write: 15 lines
  • Estimated time of completion: 15 min
The whys and wherefores:
 
  • Definiowanie i uruchamianie funkcji
  • Sprawdzanie przypadków brzegowych (niekompatybilne argumenty)
  • Parsowanie argumentów funkcji
  • Definiowanie i korzystanie z dict z wartościami
  • Sprawdzanie czy element istnieje w dict
  • Rzutowanie i konwersja typów