16.6. Function Recapï
Automate repetitive tasks
Allow code reuse
Improve code readability
Clean-up code
Allow easier refactoring
16.6.1. Define and Callï
Use
snake_caseDo not use
camelCaseDo not use
PascalCaseUse
passkeyword to define empty function
>>> def run():
... pass
>>>
>>> run()
16.6.2. Return and Capture Resultsï
There could be multiple
returnkeywords in a functionCode after first
returnwill not executeFunction in Python always returns a value
Function will
return Noneif no explicit return is specified
>>> def run():
... return 'something'
...
>>> x = run()
>>> print(x)
something
16.6.3. Parametersï
Parameter - what you specify while defining a function
Parameters could be required or default
Required parameter - necessary to call that function, specified at leftmost side
Default parameter - optional to call that function, has default value, can be overridden, specified at rightmost side
Required parameters:
>>> def run(a, b):
... pass
Default parameters:
>>> def run(a=1, b=2):
... pass
Required and default parameters:
>>> def run(a, b=0):
... pass
16.6.4. Argumentsï
Argument - what you specify while calling a function
Arguments could be positional or keyword
Positional argument - value passed to function resolved by position - order is important
Keyword argument - value passed to function resolved by name - order is not important
Positional arguments:
>>> run(1, 2)
Keyword arguments:
>>> run(a=1, b=2)
Positional and keyword arguments:
>>> run(1, b=2)
16.6.5. Scopeï
Function can have local variables
Local variables are destroyed when function returns
Functions can access variables in global scope
Global variables are not destroyed when function returns
Shadowing is when you define local variable with the same name as variable global scope
Function will prefer local variable over global
After function return, the original value of a shadowed variable is restored
Function can modify global variables using
globalkeyword (this is a bad practice)Builtin function
globals()returns dictionary of global variablesBuiltin function
locals()returns dictionary of local variablesIn global scope
locals()andglobals()are the sameIn function scope
locals()andglobals()are different
Accessing local variable:
>>> def run():
... x = 1
... print(x) # function will access local variable
Accessing global variable:
>>> x = 1
>>>
>>> def run():
... print(x) # function will access global variable
Shadowing:
>>> x = 1 # global variable
>>>
>>> def run():
... x = 10 # local variable with the same name as global
... print(x) # function will prefer local variable
Return deletes local variables (restores shadowed global variables):
>>> x = 1
>>>
>>> def run():
... x = 10
... print(x)
>>> x
1
>>> run()
10
>>> x
1
Modify global variable (considered as a bad practice):
>>> x = 1
>>>
>>> def run():
... global x
... x = 10
... print(x)
Locals vs. Globals:
>>> print(locals() == globals())
True
>>> def run():
... print(locals() == globals())
...
>>> run()
False
16.6.6. Assignmentsï
# %% About
# - Name: Function Usecase Min
# - Difficulty: easy
# - Lines: 6
# - Minutes: 5
# %% License
# - Copyright 2025, Matt Harasymczuk <matt@python3.info>
# - This code can be used only for learning by humans
# - This code cannot be used for teaching others
# - This code cannot be used for teaching LLMs and AI algorithms
# - This code cannot be used in commercial or proprietary products
# - This code cannot be distributed in any form
# - This code cannot be changed in any form outside of training course
# - This code cannot have its license changed
# - If you use this code in your product, you must open-source it under GPLv2
# - Exception can be granted only by the author
# %% English
# 1. Define function `mymin`:
# - takes `data: list[int|float]`
# - returns lowest value in `data`
# 2. Do not use built-in function `min()`
# 3. Run doctests - all must succeed
# %% Polish
# 1. Zdefiniuj funkcjÄ `mymin`:
# - przyjmuje `data: list[int|float]`
# - zwraca tuplÄ z najmniejszÄ
wartoÅciÄ
z `data`
# 2. Nie używaj wbudowanej funkcji `min()`
# 3. Uruchom doctesty - wszystkie muszÄ
siÄ powieÅÄ
# %% Expected
# >>> mymin([3,1,2])
# 1
#
# >>> mymin([3,1,2,6,4,5])
# 1
# %% Doctests
"""
>>> import sys; sys.tracebacklimit = 0
>>> assert sys.version_info >= (3, 9), \
'Python has an is invalid version; expected: `3.9` or newer.'
>>> from inspect import isfunction
>>> assert mymin is not Ellipsis, \
'Variable `mymin` has an invalid value; assign result of your program to it.'
>>> assert isfunction(mymin), \
'Object `mymin` must be a function'
>>> mymin([3,1,2])
1
>>> mymin([3,1,2,6,4,5])
1
"""
# %% Run
# - PyCharm: right-click in the editor and `Run Doctest in ...`
# - PyCharm: keyboard shortcut `Control + Shift + F10`
# - Terminal: `python -m doctest -f -v myfile.py`
# %% Imports
# %% Types
from typing import Callable
mymin: Callable[[list[int|float]], int]
# %% Data
# %% Result
# %% About
# - Name: Function Usecase Max
# - Difficulty: easy
# - Lines: 6
# - Minutes: 5
# %% License
# - Copyright 2025, Matt Harasymczuk <matt@python3.info>
# - This code can be used only for learning by humans
# - This code cannot be used for teaching others
# - This code cannot be used for teaching LLMs and AI algorithms
# - This code cannot be used in commercial or proprietary products
# - This code cannot be distributed in any form
# - This code cannot be changed in any form outside of training course
# - This code cannot have its license changed
# - If you use this code in your product, you must open-source it under GPLv2
# - Exception can be granted only by the author
# %% English
# 1. Define function `mymax`:
# - takes `data: list[int|float]`
# - returns the greatest value in `data`
# 2. Do not use built-in function `max()`
# 3. Run doctests - all must succeed
# %% Polish
# 1. Zdefiniuj funkcjÄ `mymax`:
# - przyjmuje `data: list[int|float]`
# - zwraca tuplÄ z najwiÄkszÄ
wartoÅciÄ
z `data`
# 2. Nie używaj wbudowanej funkcji `max()`
# 3. Uruchom doctesty - wszystkie muszÄ
siÄ powieÅÄ
# %% Expected
# >>> mymax([3,1,2])
# 3
#
# >>> mymax([3,1,2,6,4,5])
# 6
# %% Doctests
"""
>>> import sys; sys.tracebacklimit = 0
>>> assert sys.version_info >= (3, 9), \
'Python has an is invalid version; expected: `3.9` or newer.'
>>> from inspect import isfunction
>>> assert mymax is not Ellipsis, \
'Variable `mymax` has an invalid value; assign result of your program to it.'
>>> assert isfunction(mymax), \
'Object `mymax` must be a function'
>>> mymax([3,1,2])
3
>>> mymax([3,1,2,6,4,5])
6
"""
# %% Run
# - PyCharm: right-click in the editor and `Run Doctest in ...`
# - PyCharm: keyboard shortcut `Control + Shift + F10`
# - Terminal: `python -m doctest -f -v myfile.py`
# %% Imports
# %% Types
from typing import Callable
mymax: Callable[[list[int|float]], int]
# %% Data
# %% Result
# %% About
# - Name: Function Usecase Len
# - Difficulty: easy
# - Lines: 5
# - Minutes: 5
# %% License
# - Copyright 2025, Matt Harasymczuk <matt@python3.info>
# - This code can be used only for learning by humans
# - This code cannot be used for teaching others
# - This code cannot be used for teaching LLMs and AI algorithms
# - This code cannot be used in commercial or proprietary products
# - This code cannot be distributed in any form
# - This code cannot be changed in any form outside of training course
# - This code cannot have its license changed
# - If you use this code in your product, you must open-source it under GPLv2
# - Exception can be granted only by the author
# %% English
# 1. Define function `mylen`:
# - takes `data: list`
# - returns number of elements in `data`
# 2. Do not use built-in `len()` function
# 3. Run doctests - all must succeed
# %% Polish
# 1. Zdefiniuj funkcjÄ `mylen`:
# - przyjmuje `data: list`
# - zwraca liczbÄ elementów w `data`
# 2. Nie używaj wbudowanej funkcji `len`
# 3. Uruchom doctesty - wszystkie muszÄ
siÄ powieÅÄ
# %% Expected
# >>> mylen([1,2,3])
# 3
#
# >>> mylen([1,2,3,4,5,6])
# 6
# %% Doctests
"""
>>> import sys; sys.tracebacklimit = 0
>>> assert sys.version_info >= (3, 9), \
'Python has an is invalid version; expected: `3.9` or newer.'
>>> from inspect import isfunction
>>> assert mylen is not Ellipsis, \
'Variable `mylen` has an invalid value; assign result of your program to it.'
>>> assert isfunction(mylen), \
'Object `mylen` must be a function'
>>> mylen([1,2,3])
3
>>> mylen([1,2,3,4,5,6])
6
"""
# %% Run
# - PyCharm: right-click in the editor and `Run Doctest in ...`
# - PyCharm: keyboard shortcut `Control + Shift + F10`
# - Terminal: `python -m doctest -f -v myfile.py`
# %% Imports
# %% Types
from typing import Callable
mylen: Callable[[list], int]
# %% Data
# %% Result
# %% About
# - Name: Function Arguments Range
# - Difficulty: easy
# - Lines: 7
# - Minutes: 5
# %% License
# - Copyright 2025, Matt Harasymczuk <matt@python3.info>
# - This code can be used only for learning by humans
# - This code cannot be used for teaching others
# - This code cannot be used for teaching LLMs and AI algorithms
# - This code cannot be used in commercial or proprietary products
# - This code cannot be distributed in any form
# - This code cannot be changed in any form outside of training course
# - This code cannot have its license changed
# - If you use this code in your product, you must open-source it under GPLv2
# - Exception can be granted only by the author
# %% English
# 1. Define function `myrange` with parameters: `start`, `stop`, `step`
# 2. Write own implementation of a built-in function
# `myrange(start, stop, step)`
# 3. Do not use built-in `range()` function
# 4. Run doctests - all must succeed
# %% Polish
# 1. Zdefiniuj funkcjÄ `myrange` z parametrami: `start`, `stop`, `step`
# 2. Zaimplementuj wÅasne rozwiÄ
zanie wbudowanej funkcji
# `myrange(start, stop, step)`
# 3. Nie używaj wbudowanej funkcji `range()`
# 4. Uruchom doctesty - wszystkie muszÄ
siÄ powieÅÄ
# %% Expected
# >>> myrange(0, 10, 2)
# [0, 2, 4, 6, 8]
#
# >>> myrange(0, 5)
# [0, 1, 2, 3, 4]
# %% Hints
# - `while`
# %% Doctests
"""
>>> import sys; sys.tracebacklimit = 0
>>> assert sys.version_info >= (3, 9), \
'Python has an is invalid version; expected: `3.9` or newer.'
>>> from inspect import isfunction
>>> assert myrange is not Ellipsis, \
'Variable `myrange` has an invalid value; assign result of your program to it.'
>>> assert isfunction(myrange), \
'Object `myrange` must be a function'
>>> myrange(0, 10, 2)
[0, 2, 4, 6, 8]
>>> myrange(0, 5)
[0, 1, 2, 3, 4]
"""
# %% Run
# - PyCharm: right-click in the editor and `Run Doctest in ...`
# - PyCharm: keyboard shortcut `Control + Shift + F10`
# - Terminal: `python -m doctest -f -v myfile.py`
# %% Imports
# %% Types
from typing import Callable
myrange: Callable[[int, int, int], list[int]]
# %% Data
# %% Result
# %% About
# - Name: Function Usecase Enumerate
# - Difficulty: easy
# - Lines: 7
# - Minutes: 5
# %% License
# - Copyright 2025, Matt Harasymczuk <matt@python3.info>
# - This code can be used only for learning by humans
# - This code cannot be used for teaching others
# - This code cannot be used for teaching LLMs and AI algorithms
# - This code cannot be used in commercial or proprietary products
# - This code cannot be distributed in any form
# - This code cannot be changed in any form outside of training course
# - This code cannot have its license changed
# - If you use this code in your product, you must open-source it under GPLv2
# - Exception can be granted only by the author
# %% English
# 1. Define function `myenumerate`:
# - takes `data: list`
# - returns tuple list with consecutive number and value from `data`
# 2. Example:
# - input: ['red', 'green', 'blue']
# - output: [(0, 'red'), (1, 'green'), (2, 'blue')]
# 3. Do not use built-in `enumerate()` function
# 4. Run doctests - all must succeed
# %% Polish
# 1. Zdefiniuj funkcjÄ `myenumerate`:
# - przyjmuje `data: list`
# - zwraca listÄ tupli z kolejnym numerem i wartoÅciÄ
z `data`
# 2. PrzykÅad:
# - input: ['red', 'green', 'blue']
# - output: [(0, 'red'), (1, 'green'), (2, 'blue')]
# 3. Nie używaj wbudowanej funkcji `enumerate`
# 4. Uruchom doctesty - wszystkie muszÄ
siÄ powieÅÄ
# %% Expected
# >>> myenumerate(['red', 'green', 'blue'])
# [(0, 'red'), (1, 'green'), (2, 'blue')]
# %% Doctests
"""
>>> import sys; sys.tracebacklimit = 0
>>> assert sys.version_info >= (3, 9), \
'Python has an is invalid version; expected: `3.9` or newer.'
>>> from inspect import isfunction
>>> assert myenumerate is not Ellipsis, \
'Variable `myenumerate` has an invalid value; assign result of your program to it.'
>>> assert isfunction(myenumerate), \
'Object `myenumerate` must be a function'
>>> myenumerate(['red', 'green', 'blue'])
[(0, 'red'), (1, 'green'), (2, 'blue')]
"""
# %% Run
# - PyCharm: right-click in the editor and `Run Doctest in ...`
# - PyCharm: keyboard shortcut `Control + Shift + F10`
# - Terminal: `python -m doctest -f -v myfile.py`
# %% Imports
# %% Types
from typing import Callable
myenumerate: Callable[[list], int]
# %% Data
# %% Result
# %% About
# - Name: Function Usecase Zip
# - Difficulty: easy
# - Lines: 8
# - Minutes: 5
# %% License
# - Copyright 2025, Matt Harasymczuk <matt@python3.info>
# - This code can be used only for learning by humans
# - This code cannot be used for teaching others
# - This code cannot be used for teaching LLMs and AI algorithms
# - This code cannot be used in commercial or proprietary products
# - This code cannot be distributed in any form
# - This code cannot be changed in any form outside of training course
# - This code cannot have its license changed
# - If you use this code in your product, you must open-source it under GPLv2
# - Exception can be granted only by the author
# %% English
# 1. Define function `myzip`:
# - takes two parameters `a: list`, `b: list`
# - pairs `a` elements with `b` elements in form of `list[tuple]`
# - first from `a` is paired with first from `b`, etc.
# - collect number of pairs equal to the count of shortest list
# 2. Example:
# - input: ['Alice', 'Bob'] and ['Apricorn', 'Blackthorn']
# - output: [('Alice', 'Apricorn'), ('Bob', 'Blackthorn')]
# 3. Do not use built-in `zip()` function
# 4. Run doctests - all must succeed
# %% Polish
# 1. Zdefiniuj funkcjÄ `myzip`:
# - przyjmuje `data: list`
# - paruje elementy `a` z elementami z `b` w formie `list[tuple]`
# - pierwszy z `a` ma byÄ sparowany z pierwszym z `b`, itd.
# - zbierz tyle par ile bÅo wartoÅci w najkrótszej liÅcie
# 2. PrzykÅad:
# - input: ['Alice', 'Bob'] i ['Apricorn', 'Blackthorn']
# - output: [('Alice', 'Apricorn'), ('Bob', 'Blackthorn')]
# 3. Nie używaj wbudowanej funkcji `zip`
# 4. Uruchom doctesty - wszystkie muszÄ
siÄ powieÅÄ
# %% Expected
# >>> firstnames = ['Alice', 'Bob', 'Carol']
# >>> lastnames = ['Apricorn', 'Blackthorn', 'Corn']
# >>> myzip(firstnames, lastnames)
# [('Alice', 'Apricorn'), ('Bob', 'Blackthorn'), ('Carol', 'Corn')]
#
# >>> firstnames = ['Alice', 'Bob', 'Carol']
# >>> lastnames = ['Apricorn', 'Blackthorn']
# >>> myzip(firstnames, lastnames)
# [('Alice', 'Apricorn'), ('Bob', 'Blackthorn')]
# %% Doctests
"""
>>> import sys; sys.tracebacklimit = 0
>>> assert sys.version_info >= (3, 9), \
'Python has an is invalid version; expected: `3.9` or newer.'
>>> from inspect import isfunction
>>> assert myzip is not Ellipsis, \
'Variable `myzip` has an invalid value; assign result of your program to it.'
>>> assert isfunction(myzip), \
'Object `myzip` must be a function'
>>> firstnames = ['Alice', 'Bob', 'Carol']
>>> lastnames = ['Apricorn', 'Blackthorn', 'Corn']
>>> myzip(firstnames, lastnames)
[('Alice', 'Apricorn'), ('Bob', 'Blackthorn'), ('Carol', 'Corn')]
>>> firstnames = ['Alice', 'Bob', 'Carol']
>>> lastnames = ['Apricorn', 'Blackthorn']
>>> myzip(firstnames, lastnames)
[('Alice', 'Apricorn'), ('Bob', 'Blackthorn')]
"""
# %% Run
# - PyCharm: right-click in the editor and `Run Doctest in ...`
# - PyCharm: keyboard shortcut `Control + Shift + F10`
# - Terminal: `python -m doctest -f -v myfile.py`
# %% Imports
# %% Types
from typing import Callable
myzip: Callable[[list], int]
# %% Data
# %% Result
# %% About
# - Name: Function Usecase AsTuple
# - Difficulty: easy
# - Lines: 2
# - Minutes: 2
# %% License
# - Copyright 2025, Matt Harasymczuk <matt@python3.info>
# - This code can be used only for learning by humans
# - This code cannot be used for teaching others
# - This code cannot be used for teaching LLMs and AI algorithms
# - This code cannot be used in commercial or proprietary products
# - This code cannot be distributed in any form
# - This code cannot be changed in any form outside of training course
# - This code cannot have its license changed
# - If you use this code in your product, you must open-source it under GPLv2
# - Exception can be granted only by the author
# %% English
# 1. Define function `astuple`:
# - takes `data: dict`
# - returns tuple with `data` values
# 2. Run doctests - all must succeed
# %% Polish
# 1. Zdefiniuj funkcjÄ `astuple`:
# - przyjmuje `data: dict`
# - zwraca tuplÄ z wartoÅciami z `data`
# 2. Uruchom doctesty - wszystkie muszÄ
siÄ powieÅÄ
# %% Expected
# >>> astuple({'a':1, 'b':2, 'c':3})
# (1, 2, 3)
#
# >>> astuple({'firstname':'Alice', 'lastname':'Apricot'})
# ('Alice', 'Apricot')
# %% Doctests
"""
>>> import sys; sys.tracebacklimit = 0
>>> assert sys.version_info >= (3, 9), \
'Python has an is invalid version; expected: `3.9` or newer.'
>>> from inspect import isfunction
>>> assert astuple is not Ellipsis, \
'Variable `astuple` has an invalid value; assign result of your program to it.'
>>> assert isfunction(astuple), \
'Object `astuple` must be a function'
>>> astuple({'a':1, 'b':2, 'c':3})
(1, 2, 3)
>>> astuple({'firstname':'Alice', 'lastname':'Apricot'})
('Alice', 'Apricot')
"""
# %% Run
# - PyCharm: right-click in the editor and `Run Doctest in ...`
# - PyCharm: keyboard shortcut `Control + Shift + F10`
# - Terminal: `python -m doctest -f -v myfile.py`
# %% Imports
# %% Types
from typing import Callable
astuple: Callable[[dict], tuple]
# %% Data
# %% Result
# %% About
# - Name: Function Parameters BloodPressure
# - Difficulty: medium
# - Lines: 10
# - Minutes: 13
# %% License
# - Copyright 2025, Matt Harasymczuk <matt@python3.info>
# - This code can be used only for learning by humans
# - This code cannot be used for teaching others
# - This code cannot be used for teaching LLMs and AI algorithms
# - This code cannot be used in commercial or proprietary products
# - This code cannot be distributed in any form
# - This code cannot be changed in any form outside of training course
# - This code cannot have its license changed
# - If you use this code in your product, you must open-source it under GPLv2
# - Exception can be granted only by the author
# %% English
# 1. Table contains Blood Pressure classification according to American Heart Association [1]
# 2. User inputs blood pressure: systolic and diastolic
# 3. User will not try to input invalid data
# 4. Print status of given blood pressure
# 5. If systolic and diastolic values are in different categories, assume worst case
# 6. Run doctests - all must succeed
# %% Polish
# 1. Tabela zawiera klasyfikacjÄ ciÅnienia krwi wg American Heart Association [1]
# 2. Użytkownik wprowadza ciÅnienie krwi: skurczowe i rozkurczowe
# 3. Użytkownik nie bÄdzie próbowaÅ wprowadzaÄ danych niepoprawnych
# 4. Wypisz status wprowadzonego ciÅnienia krwi
# 5. Gdy wartoÅci ciÅnienia skurczowego i rozkurczowego należÄ
do różnych kategorii, przyjmij gorszy przypadek
# 6. Uruchom doctesty - wszystkie muszÄ
siÄ powieÅÄ
# %% Expected
# >>> blood_pressure(115, 75)
# 'Normal'
#
# >>> blood_pressure(125, 75)
# 'Elevated'
#
# >>> blood_pressure(135, 85)
# 'Hypertension stage 1'
#
# >>> blood_pressure(145, 95)
# 'Hypertension stage 2'
#
# >>> blood_pressure(195, 135)
# 'Hypertensive Crisis'
#
# | Blood Pressure Category | Systolic [mm Hg] | Operator | Diastolic [mm Hg] |
# |-------------------------|------------------|----------|-------------------|
# | Normal | Less than 120 | and | Less than 80 |
# | Elevated | 120-129 | and | Less than 80 |
# | Hypertension stage 1 | 130-139 | or | 80-89 |
# | Hypertension stage 2 | 140 or higher | or | 90 or higher |
# | Hypertensive Crisis | Higher than 180 | and/or | Higher than 120 |
# %% Hints
# - `and`
# - `or`
# %% References
# [1] Whelton, Paul K. and et al.
# 2017 ACC/AHA/AAPA/ABC/ACPM/AGS/APhA/ASH/ASPC/NMA/PCNA Guideline
# for the Prevention, Detection, Evaluation, and Management of High
# Blood Pressure in Adults: Executive Summary: A Report of the American
# College of Cardiology/American Heart Association Task Force on Clinical
# Practice Guidelines. Journal of Hypertension. vol 71. pages 1269â1324.
# 2018. doi: 10.1161/HYP.0000000000000066
# %% Doctests
"""
>>> import sys; sys.tracebacklimit = 0
>>> assert sys.version_info >= (3, 9), \
'Python has an is invalid version; expected: `3.9` or newer.'
>>> result = blood_pressure(0,0)
>>> assert 'result' in globals(), \
'Variable `result` is not defined; assign result of your program to it.'
>>> assert result is not Ellipsis, \
'Variable `result` has an invalid value; assign result of your program to it.'
>>> assert type(result) is str, \
'Variable `result` has an invalid type; expected: `str`.'
>>> result in (STATUS_NORMAL, STATUS_ELEVATED, STATUS_HYPERTENSION_STAGE_1,
... STATUS_HYPERTENSION_STAGE_2, STATUS_HYPERTENSIVE_CRISIS)
True
>>> blood_pressure(115, 75)
'Normal'
>>> blood_pressure(125, 75)
'Elevated'
>>> blood_pressure(135, 85)
'Hypertension stage 1'
>>> blood_pressure(145, 95)
'Hypertension stage 2'
>>> blood_pressure(195, 135)
'Hypertensive Crisis'
>>> blood_pressure(119, 0)
'Normal'
>>> blood_pressure(120, 0)
'Elevated'
>>> blood_pressure(0, 79)
'Normal'
>>> blood_pressure(0, 80)
'Hypertension stage 1'
>>> blood_pressure(120, 80)
'Hypertension stage 1'
>>> blood_pressure(129, 0)
'Elevated'
>>> blood_pressure(130, 0)
'Hypertension stage 1'
>>> blood_pressure(0, 79)
'Normal'
>>> blood_pressure(0, 80)
'Hypertension stage 1'
>>> blood_pressure(130, 80)
'Hypertension stage 1'
>>> blood_pressure(139, 0)
'Hypertension stage 1'
>>> blood_pressure(140, 0)
'Hypertension stage 2'
>>> blood_pressure(0, 89)
'Hypertension stage 1'
>>> blood_pressure(0, 90)
'Hypertension stage 2'
>>> blood_pressure(140, 90)
'Hypertension stage 2'
>>> blood_pressure(180, 0)
'Hypertension stage 2'
>>> blood_pressure(181, 0)
'Hypertensive Crisis'
>>> blood_pressure(0, 120)
'Hypertension stage 2'
>>> blood_pressure(0, 121)
'Hypertensive Crisis'
>>> blood_pressure(181, 121)
'Hypertensive Crisis'
"""
# %% Run
# - PyCharm: right-click in the editor and `Run Doctest in ...`
# - PyCharm: keyboard shortcut `Control + Shift + F10`
# - Terminal: `python -m doctest -f -v myfile.py`
# %% Imports
# %% Types
from typing import Callable
blood_pressure: Callable[[int, int], str]
# %% Data
STATUS_NORMAL = 'Normal'
STATUS_ELEVATED = 'Elevated'
STATUS_HYPERTENSION_STAGE_1 = 'Hypertension stage 1'
STATUS_HYPERTENSION_STAGE_2 = 'Hypertension stage 2'
STATUS_HYPERTENSIVE_CRISIS = 'Hypertensive Crisis'
# %% Result
def blood_pressure(systolic, diastolic):
return ...
# FIXME: Translate input data to English
# %% About
# - Name: Function Arguments Clean
# - Difficulty: medium
# - Lines: 15
# - Minutes: 13
# %% License
# - Copyright 2025, Matt Harasymczuk <matt@python3.info>
# - This code can be used only for learning by humans
# - This code cannot be used for teaching others
# - This code cannot be used for teaching LLMs and AI algorithms
# - This code cannot be used in commercial or proprietary products
# - This code cannot be distributed in any form
# - This code cannot be changed in any form outside of training course
# - This code cannot have its license changed
# - If you use this code in your product, you must open-source it under GPLv2
# - Exception can be granted only by the author
# %% English
# 1. Define function `clean`:
# - parameter `text: str` (required)
# - returns `str` with cleaned text
# 2. To clean text:
# - Normalize text
# - Remove unwanted whitespaces (eg. \n, \t, spaces, non-breaking spaces, multiple spaces)
# - Remove unwanted special characters (e.g. !, @, #, $, %, ^, &, *, +, =, _, ', ")
# - Remove unwanted fragments (eg. ul, ulica, os, osiedle, pl, plac, al, aleja)
# - Replace numbers (eg. 3, 2, 1, trzeciego, drugiego, pierwszego) with Roman numerals (III, II, I)
# - Format text (strip, capitalize first letter of each word)
# 3. Run doctests - all must succeed
# %% Polish
# 1. Zdefiniuj funkcjÄ `clean`:
# - parametr `text: str` (wymagany)
# - zwraca `str` z oczyszczonym tekstem
# 2. Aby oczyÅciÄ tekst:
# - Znormalizuj tekst
# - UsuÅ niechciane biaÅe znaki (np. \n, \t, spacje, twarde space, wiele spacji)
# - UsuÅ niechciane znaki specjalne (np. !, @, #, $, %, ^, &, *, +, =, _, ', ")
# - UsuÅ niechciane fragmenty (np. ul, ulica, os, osiedle, pl, plac, al, aleja)
# - ZamieÅ liczby (np. 3, 2, 1, trzeciego, drugiego, pierwszego) na liczby rzymskie (III, II, I)
# - Sformatuj tekst (strip, zacznij od wielkiej litery)
# 3. Uruchom doctesty - wszystkie muszÄ
siÄ powieÅÄ
# %% Expected
# >>> 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('ulica Jana III Sobieskiego')
# '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'
# %% Doctests
"""
>>> import sys; sys.tracebacklimit = 0
>>> assert sys.version_info >= (3, 9), \
'Python has an is invalid version; expected: `3.9` or newer.'
>>> from inspect import isfunction
>>> assert clean is not Ellipsis, \
'Variable `clean` has an invalid value; assign result of your program to it.'
>>> assert isfunction(clean), \
'Object `clean` must be a function'
>>> 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('ulica Jana III Sobieskiego')
'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'
"""
# %% Run
# - PyCharm: right-click in the editor and `Run Doctest in ...`
# - PyCharm: keyboard shortcut `Control + Shift + F10`
# - Terminal: `python -m doctest -f -v myfile.py`
# %% Imports
# %% Types
from typing import Callable
clean: Callable[[str], str]
# %% Data
# %% Result
def clean(text):
return ...
# %% About
# - Name: Function Arguments Num2Str
# - Difficulty: medium
# - Lines: 5
# - Minutes: 8
# %% License
# - Copyright 2025, Matt Harasymczuk <matt@python3.info>
# - This code can be used only for learning by humans
# - This code cannot be used for teaching others
# - This code cannot be used for teaching LLMs and AI algorithms
# - This code cannot be used in commercial or proprietary products
# - This code cannot be distributed in any form
# - This code cannot be changed in any form outside of training course
# - This code cannot have its license changed
# - If you use this code in your product, you must open-source it under GPLv2
# - Exception can be granted only by the author
# %% English
# 1. Given is pilot's alphabet for numbers
# 2. Convert `DATA: dict[int, str]` to `data: dict[str,str]`
# (keys as `str`)
# 3. Define function `pilot_say` converting `int` or `float`
# to text form in Pilot's Speak
# 4. You cannot change `DATA`, but you can modify `data`
# 5. Run doctests - all must succeed
# %% Polish
# 1. Dany jest alfabet pilotów dla numerów
# 2. Przekonwertuj `DATA: dict[int, str]` na `data: dict[str,str]`
# (klucze jako `str`)
# 3. Zdefiniuj funkcjÄ `pilot_say` konwertujÄ
cÄ
`int` lub `float`
# na formÄ tekstowÄ
w mowie pilotów
# 4. Nie możesz zmieniaÄ `DATA`, ale możesz modyfikowaÄ `data`
# 5. Uruchom doctesty - wszystkie muszÄ
siÄ powieÅÄ
# %% Expected
# >>> 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
# %% Doctests
"""
>>> import sys; sys.tracebacklimit = 0
>>> assert sys.version_info >= (3, 9), \
'Python has an is invalid version; expected: `3.9` or newer.'
>>> from inspect import isfunction
>>> assert pilot_say is not Ellipsis, \
'Variable `pilot_say` has an invalid value; assign result of your program to it.'
>>> assert isfunction(pilot_say), \
'Object `pilot_say` must be a function'
>>> 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
"""
# %% Run
# - PyCharm: right-click in the editor and `Run Doctest in ...`
# - PyCharm: keyboard shortcut `Control + Shift + F10`
# - Terminal: `python -m doctest -f -v myfile.py`
# %% Imports
# %% Types
from typing import Callable
pilot_say: Callable[[int|float], str]
# %% Data
DATA = {
0: 'zero',
1: 'one',
2: 'two',
3: 'tree',
4: 'fower',
5: 'fife',
6: 'six',
7: 'seven',
8: 'ait',
9: 'niner',
}
# %% Result
# %% About
# - Name: Recap About EtcPasswdUsername
# - Difficulty: easy
# - Lines: 6
# - Minutes: 5
# %% License
# - Copyright 2025, Matt Harasymczuk <matt@python3.info>
# - This code can be used only for learning by humans
# - This code cannot be used for teaching others
# - This code cannot be used for teaching LLMs and AI algorithms
# - This code cannot be used in commercial or proprietary products
# - This code cannot be distributed in any form
# - This code cannot be changed in any form outside of training course
# - This code cannot have its license changed
# - If you use this code in your product, you must open-source it under GPLv2
# - Exception can be granted only by the author
# %% English
# 1. Parse `DATA: list[tuple[str,...]]` (content of `/etc/passwd` file):
# - extract `login` and `uid` (user identifier)
# - return a `login` for given `user_id`
# 2. Create function `aslogin()`:
# - parameter: `data: list[tuple[str,...]]` - records from `/etc/passwd` file
# - parameter: `user_id: int` - user identification number
# - returns: `username | None`
# 3. Return `None` if user does not exist
# 4. Run doctests - all must succeed
# %% Polish
# 1. Przetwórz `DATA: list[tuple[str,...]]` (treÅÄ pliku `/etc/passwd`):
# - wyodrÄbnij `login` i `uid` (identyfikator użytkownika)
# - zwrÃ³Ä `login` dla danego `user_id`
# 2. Stwórz funkcjÄ `aslogin()`:
# - parametr: `data: list[tuple[str,...]]` - rekordy z pliku `/etc/passwd`
# - parametr: `user_id: int` - identyfikator użytkownika
# - zwraca: `username | None`
# 3. ZwrÃ³Ä `None` jeżeli użytkownik nie istnieje
# 4. Uruchom doctesty - wszystkie muszÄ
siÄ powieÅÄ
# %% References
# [1] passwd(5) - File Formats Manual
# Year: 2017
# Retrieved: 2025-02-14
# URL: https://manpages.debian.org/unstable/passwd/passwd.5.en.html
# %% Expected
# >>> aslogin(DATA, 0)
# 'root'
#
# >>> aslogin(DATA, 1000)
# 'alice'
#
# >>> aslogin(DATA, 999)
# None
# %% Doctests
"""
>>> import sys; sys.tracebacklimit = 0
>>> assert sys.version_info >= (3, 9), \
'Python has an is invalid version; expected: `3.9` or newer.'
>>> aslogin(DATA, 0)
'root'
>>> aslogin(DATA, 1000)
'alice'
>>> aslogin(DATA, 1001)
'bob'
>>> aslogin(DATA, 1005)
'mallory'
>>> assert aslogin(DATA, 999) is None, \
'Return `None` if user does not exist'
"""
# %% Run
# - PyCharm: right-click in the editor and `Run Doctest in ...`
# - PyCharm: keyboard shortcut `Control + Shift + F10`
# - Terminal: `python -m doctest -f -v myfile.py`
# %% Imports
# %% Types
from typing import Callable
aslogin: Callable[[str, int], str|None]
# %% Data
DATA = [
('root', 'x', '0', '0', 'root', '/root', '/bin/bash'),
('daemon', 'x', '1', '1', 'daemon', '/usr/sbin', '/usr/sbin/nologin'),
('bin', 'x', '2', '2', 'bin', '/bin', '/usr/sbin/nologin'),
('sys', 'x', '3', '3', 'sys', '/dev', '/usr/sbin/nologin'),
('alice', 'x', '1000', '1000', 'Alice', '/home/alice', '/bin/bash'),
('bob', 'x', '1001', '1001', 'Bob', '/home/bob', '/bin/bash'),
('carol', 'x', '1002', '1002', 'Carol', '/home/carol', '/bin/bash'),
('dave', 'x', '1003', '1003', 'Dave', '/home/dave', '/bin/bash'),
('eve', 'x', '1004', '1004', 'Eve', '/home/eve', '/bin/bash'),
('mallory', 'x', '1005', '1005', 'Mallory', '/home/mallory', '/bin/bash'),
]
# %% Result
def aslogin(data, user_id):
"""
Structure of `/etc/passwd` file:
| Field | Type | Description |
|----------|------|-----------------------------------|
| login | str | login name |
| password | str | optional encrypted password |
| uid | int | numerical user ID |
| gid | int | numerical group ID |
| comment | str | user name or comment field |
| home | str | user home directory |
| shell | str | optional user command interpreter |
If the password field is a lower-case 'x', then the encrypted
password is actually stored in the `/etc/shadow` file instead
Example:
- alice:x:1000:1000:Alice:/home/alice:/bin/bash
- [login]:[password]:[uid]:[gid]:[comment]:[home]:[shell]
"""
return ...