2. Pre-Intermediate

2.1. Create

  • Complexity level: easy

  • Lines of code to write: 13 lines

  • Estimated time of completion: 10 min

  • Filename: solution/tuple_create.py

English
  1. For given data input (see below)

  2. Create a tuple representing all Species

  3. Calculate mean for each numerical values column

  4. To convert table use multiline select with alt key in your IDE

Polish
  1. Dla danych wejściowych (patrz poniżej)

  2. Stwórz tuple z nazwami gatunków

  3. Wylicz średnią arytmetyczną dla każdej z kolumn numerycznych

  4. Do przekonwertowania tabelki wykorzystaj zaznaczanie wielu linijek za pomocą klawisza alt w Twoim IDE

Input
"Sepal length", "Sepal width", "Petal length", "Petal width", "Species"
"5.8", "2.7", "5.1", "1.9", "virginica"
"5.1", "3.5", "1.4", "0.2", "setosa"
"5.7", "2.8", "4.1", "1.3", "versicolor"
"6.3", "2.9", "5.6", "1.8", "virginica"
"6.4", "3.2", "4.5", "1.5", "versicolor"
"4.7", "3.2", "1.3", "0.2", "setosa"
"7.0", "3.2", "4.7", "1.4", "versicolor"
"7.6", "3.0", "6.6", "2.1", "virginica"
"4.9", "3.0", "1.4", "0.2", "setosa"
"4.9", "2.5", "4.5", "1.7", "virginica"
"7.1", "3.0", "5.9", "2.1", "virginica"
The whys and wherefores
  • Defining tuple

  • Learning IDE features

Hints
  • mean = sum(...) / len(...)

2.2. Select

  • Complexity level: easy

  • Lines of code to write: 6 lines

  • Estimated time of completion: 15 min

  • Filename: solution/nested_select.py

English
  1. For given data input (see below)

  2. Write header (first line) to header variable

  3. Convert to list data from row 2, 6, 9 and add to output

  4. Convert to tuple data from row 12, 15, 16 and add to output

  5. Convert to dict data from row 18, 21 and add to output:

    • key -> index number (18 or 21)

    • value -> species name

  6. Add empty set to output

  7. Use only indexes

  8. Do not use for, while or slice()

Polish
  1. Dla danych wejściowych (patrz poniżej)

  2. Zapisz nagłówek (pierwsza linia) do zmiennej header

  3. Przekonwertuj do list dane z wierszy 2, 6, 9 i dodaj do output

  4. Przekonwertuj do tuple dane z wierszy 12, 15, 16 i dodaj do output

  5. Przekonwertuj do dict dane z wierszy 18, 21 i dodaj do output:

    • klucz -> numer indeksu (18 or 21)

    • wartość -> nazwa gatunku

  1. Dodaj pusty set do output

  2. Użyj tylko indeksów

  3. Nie używaj for, while lub slice()

Input
INPUT = [
    ('Sepal length', 'Sepal width', 'Petal length', 'Petal width', 'Species'),
    (5.8, 2.7, 5.1, 1.9, 'virginica'),
    (5.1, 3.5, 1.4, 0.2, 'setosa'),
    (5.7, 2.8, 4.1, 1.3, 'versicolor'),
    (6.3, 2.9, 5.6, 1.8, 'virginica'),
    (6.4, 3.2, 4.5, 1.5, 'versicolor'),
    (4.7, 3.2, 1.3, 0.2, 'setosa'),
    (7.0, 3.2, 4.7, 1.4, 'versicolor'),
    (7.6, 3.0, 6.6, 2.1, 'virginica'),
    (4.9, 3.0, 1.4, 0.2, 'setosa'),
    (4.9, 2.5, 4.5, 1.7, 'virginica'),
    (7.1, 3.0, 5.9, 2.1, 'virginica'),
    (4.6, 3.4, 1.4, 0.3, 'setosa'),
    (5.4, 3.9, 1.7, 0.4, 'setosa'),
    (5.7, 2.8, 4.5, 1.3, 'versicolor'),
    (5.0, 3.6, 1.4, 0.3, 'setosa'),
    (5.5, 2.3, 4.0, 1.3, 'versicolor'),
    (6.5, 3.0, 5.8, 2.2, 'virginica'),
    (6.5, 2.8, 4.6, 1.5, 'versicolor'),
    (6.3, 3.3, 6.0, 2.5, 'virginica'),
    (6.9, 3.1, 4.9, 1.5, 'versicolor'),
    (4.6, 3.1, 1.5, 0.2, 'setosa'),
]
The whys and wherefores
  • Using nested data structures

  • Using indexes

  • Type casting

2.3. String cleaning

  • Complexity level: easy

  • Lines of code to write: 11 lines

  • Estimated time of completion: 15 min

  • Filename: solution/str_cleaning.py

English
  1. For input data (see below)

  2. Expected value is Jana III Sobieskiego

  3. Use only str methods to clean each variable

  4. Compare with output data (see below)

  5. Discuss how to create generic solution which fit all cases

  6. Implementation of such generic function will be in Function Basics chapter

Polish
  1. Dla danych wejściowych (patrz poniżej)

  2. Oczekiwana wartość Jana III Sobieskiego

  3. Wykorzystaj tylko metody str do oczyszczenia każdej zmiennej

  4. Porównaj wyniki z danymi wyjściowymi (patrz poniżej)

  5. Przeprowadź dyskusję jak zrobić rozwiązanie generyczne pasujące do wszystkich przypadków

  6. Implementacja takiej generycznej funkcji będzie w rozdziale Function Basics

Input
a = 'ul Jana III SobIESkiego'
b = '\tul. Jana trzeciego Sobieskiego'
c = 'ulicaJana III Sobieskiego'
d = 'UL. JANA 3 \nSOBIESKIEGO'
e = 'UL. jana III SOBiesKIEGO'
f = 'ULICA JANA III SOBIESKIEGO  '
g = 'ULICA. JANA III SOBIeskieGO'
h = ' Jana 3 Sobieskiego  '
i = 'Jana III Sobi\teskiego '
Output
expected = 'Jana III Sobieskiego'

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}"')
The whys and wherefores
  • Variable definition

  • Print formatting

  • Cleaning text input

2.4. /etc/hosts - parsing to List[dict]

  • Complexity level: medium

  • Lines of code to write: 15 lines

  • Estimated time of completion: 20 min

  • Filename: solution/file_parsing_advanced.py

English
  1. Copy input data from listing below and save to file hosts.txt

  2. Copy also comments and empty lines

  3. For each line in file:

    1. Skup line if it's empty, is whitespace or starts with comment #

    2. Remove leading and trailing whitespaces

    3. Split line by whitespace

    4. Separate IP address and hosts names

    5. Use one line if to check whether dot . is in the IP address

    6. If is present then protocol is IPv4 otherwise IPv6

    7. Append IP address and hosts names to OUTPUT

  4. Merge hostnames for the same IP

  5. OUTPUT must be list of dicts (List[dict])

Polish
  1. Skopiuj dane wejściowe z listingu poniżej i zapisz do pliku hosts.txt

  2. Skopiuj również komentarz i pustą linię

  3. Dla każdej lini w piku:

    1. Pomiń linię jeżeli jest pusta, jest białym znakiem lub zaczyna się od komentarza #

    2. Usuń białe znaki na początku i końcu linii

    3. Podziel linię po białych znakach

    4. Odseparuj adres IP i nazwy hostów

    5. Wykorzystaj jednolinikowego if do sprawdzenia czy jest kropka . w adresie IP

    6. Jeżeli jest obecna to protokół jest IPv4, w przeciwnym przypadku IPv6

    7. Dodaj adres IP i nazwy hostów do OUTPUT

  4. Scal nazwy hostów dla tego samego IP

  5. OUTPUT ma być listą dictów (List[dict])

Input
##
# ``/etc/hosts`` structure:
#   - IPv4 or IPv6
#   - Hostnames
##

127.0.0.1       localhost
127.0.0.1       astromatt
10.13.37.1      nasa.gov esa.int roscosmos.ru
255.255.255.255 broadcasthost
::1             localhost
Output
OUTPUT: List[Dict[str, Union[str, Set[str]]] = [
    {'ip': '127.0.0.1', 'protocol': 'ipv4', 'hostnames': {'localhost', 'astromatt'}},
    {'ip': '10.13.37.1', 'protocol': 'ipv4', 'hostnames': {'nasa.gov', 'esa.int', 'roscosmos.ru'}},
    {'ip': '255.255.255.255', 'protocol': 'ipv4', 'hostnames': {'broadcasthost'}},
    {'ip': '::1', 'protocol': 'ipv6', 'hostnames': {'localhost'}}
]
The whys and wherefores
  • czytanie i parsowanie pliku

  • nieregularne pliki konfiguracyjne (struktura może się zmieniać)

  • filtrowanie elementów

  • korzystanie z pętli i instrukcji warunkowych

  • parsowanie stringów

  • praca ze ścieżkami w systemie operacyjnym

Hints
  • str.isspace()

  • value = True if ... else False

2.5. Iris dataset

  • Complexity level: medium

  • Lines of code to write: 30 lines

  • Estimated time of completion: 20 min

  • Filename: solution/slice_iris.py

English
  1. For input data (see below)

  2. Use only slice

  3. Extract list features with measurements (every row must be tuple)

  4. Extract species name (every fifth element) and write to labels list

  5. Write unique species names to species set

Polish
  1. Dla danych wejściowych (patrz poniżej)

  2. Użyj tylko slice

  3. Wyodrębnij listę features w pomiarami (każdy wiersz ma być krotką)

  4. Wyodrębnij nazwę gatunku (co piąty element) i zapisz do listy labels

  5. Zapisz unikalne nazwy gatunków do zbioru species

Input
INPUT = (
    5.8, 2.7, 5.1, 1.9, 'virginica',
    5.1, 3.5, 1.4, 0.2, 'setosa',
    5.7, 2.8, 4.1, 1.3, 'versicolor',
    6.3, 2.9, 5.6, 1.8, 'virginica',
    6.4, 3.2, 4.5, 1.5, 'versicolor',
    4.7, 3.2, 1.3, 0.2, 'setosa',
)
Output
features = [
    (5.8, 2.7, 5.1, 1.9),
    (5.1, 3.5, 1.4, 0.2),
    (5.7, 2.8, 4.1, 1.3),
    (6.3, 2.9, 5.6, 1.8),
    (6.4, 3.2, 4.5, 1.5),
    (4.7, 3.2, 1.3, 0.2),
]

labels = [
    'virginica',
    'setosa',
    'versicolor',
    'virginica',
    'versicolor',
    'setosa',
]

species = {
    'versicolor',
    'setosa',
    'virginica',
}
The whys and wherefores
  • Defining and using list, tuple, set

  • Slicing sequences

2.6. List[tuple] to List[dict]

  • Complexity level: easy

  • Lines of code to write: 8 lines

  • Estimated time of completion: 20 min

  • Filename: solution/loop_dict_to_list.py

English
  1. For input data (see below)

  2. Separate header and data

  3. Print List[dict]

    • key - name from the header

    • value - measurement or species

Polish
  1. Dla danych wejściowych (patrz poniżej)

  2. Odseparuj nagłówek i dane

  3. Wypisz List[dict]

    • klucz: nazwa z nagłówka

    • wartość: wyniki pomiarów lub gatunek

Input
INPUT = [
    ('Sepal length', 'Sepal width', 'Petal length', 'Petal width', 'Species'),
    (5.8, 2.7, 5.1, 1.9, 'virginica'),
    (5.1, 3.5, 1.4, 0.2, 'setosa'),
    (5.7, 2.8, 4.1, 1.3, 'versicolor'),
    (6.3, 2.9, 5.6, 1.8, 'virginica'),
    (6.4, 3.2, 4.5, 1.5, 'versicolor'),
    (4.7, 3.2, 1.3, 0.2, 'setosa'),
    (7.0, 3.2, 4.7, 1.4, 'versicolor'),
    (7.6, 3.0, 6.6, 2.1, 'virginica'),
    (4.9, 3.0, 1.4, 0.2, 'setosa'),
    (4.9, 2.5, 4.5, 1.7, 'virginica'),
    (7.1, 3.0, 5.9, 2.1, 'virginica'),
    (4.6, 3.4, 1.4, 0.3, 'setosa'),
    (5.4, 3.9, 1.7, 0.4, 'setosa'),
    (5.7, 2.8, 4.5, 1.3, 'versicolor'),
    (5.0, 3.6, 1.4, 0.3, 'setosa'),
    (5.5, 2.3, 4.0, 1.3, 'versicolor'),
    (6.5, 3.0, 5.8, 2.2, 'virginica'),
    (6.5, 2.8, 4.6, 1.5, 'versicolor'),
    (6.3, 3.3, 6.0, 2.5, 'virginica'),
    (6.9, 3.1, 4.9, 1.5, 'versicolor'),
    (4.6, 3.1, 1.5, 0.2, 'setosa'),
]
Output
OUTPUT: List[dict] = [
    {'Sepal length': 5.8, 'Sepal width': 2.7, 'Petal length': 5.1, 'Petal width': 1.9, 'Species': 'virginica'},
    {'Sepal length': 5.1, 'Sepal width': 3.5, 'Petal length': 1.4, 'Petal width': 0.2, 'Species': 'setosa'},
    {'Sepal length': 5.7, 'Sepal width': 2.8, 'Petal length': 4.1, 'Petal width': 1.3, 'Species': 'versicolor'},
    ...
]
The whys and wherefores
  • Working with nested data structures

  • Iterating over dict and lists

2.7. Get elements from nested data structure

  • Complexity level: easy

  • Lines of code to write: 3 lines

  • Estimated time of completion: 10 min

  • Filename: solution/for_nested.py

English
  1. For input data (see below)

  2. Separate header from data

  3. Iterate over data

  4. Print species names ending with "ca" or "sa"

Polish
  1. Dla danych wejściowych (patrz poniżej)

  2. Oddziel nagłówek od danych

  3. Iteruj po danych

  4. Wypisz nazwy gatunków kończące się na "ca" lub "sa"

Input
INPUT = [
    ('Sepal length', 'Sepal width', 'Petal length', 'Petal width', 'Species'),
    (5.8, 2.7, 5.1, 1.9, {'virginica'}),
    (5.1, 3.5, 1.4, 0.2, {'setosa'}),
    (5.7, 2.8, 4.1, 1.3, {'versicolor'}),
    (6.3, 2.9, 5.6, 1.8, {'virginica'}),
    (6.4, 3.2, 4.5, 1.5, {'versicolor'}),
    (4.7, 3.2, 1.3, 0.2, {'setosa'}),
    (7.0, 3.2, 4.7, 1.4, {'versicolor'}),
    (7.6, 3.0, 6.6, 2.1, {'virginica'}),
    (4.6, 3.1, 1.5, 0.2, {'setosa'}),
]
The whys and wherefores
  • Accessing dict keys

  • Iterating over nested structure