{
  "assessmentTests": {
    "python_test": {
      "name": "Test Python",
      "desc": "30 pytań scenariuszowych na temat składni, funkcji, struktur danych i zachowania obiektów — sprawdź, czy Twoja znajomość Pythona odpowiada temu, co rekruterzy rozumieją przez biegłość w Pythonie.",
      "recommendation": "Twój profil umiejętności Python",
      "results": {
        "beginner": {
          "name": "Początkujący",
          "desc": "Potrafisz śledzić krótki skrypt i zmieniać wartości w jego wnętrzu, ale pytania, które przegapiłeś, skupiają się wokół specyficznego dla języka zachowania — argument domyślny, który jest zbudowany raz i ponownie użyty, `is` versus `==` na dwóch wyglądających identycznie listach, zmienna, która staje się lokalna w momencie, gdy przypiszesz do niej wartość gdziekolwiek w funkcji. Nic z tego nie chodzi o bycie słabym programistą; to zasady specyficzne dla Pythona, które równie często wprawiają w trudności ludzi przychodzących z innych języków co osoby początkujące. Mają znaczenie w pracy, ponieważ każda z nich to miejsce, gdzie czai się błąd w kodzie, który na pierwszy rzut oka wygląda prawidłowo.",
          "recommendation": "Zacznij od trzech rzeczy, w tej kolejności: zmienne argumenty domyślne (dlaczego `basket=[]` jest niebezpieczne), różnica między `is` a `==`, i jak działa zakres zmiennych wewnątrz funkcji. Oficjalny samouczek Pythona na stronie docs.python.org obejmuje wszystkie trzy bezpośrednio, a termin \"Python gotchas\" prowadzi do pracowanych przykładów każdego z nich."
        },
        "intermediate": {
          "name": "Zaawansowany początkujący",
          "desc": "Komfortowo obsługujesz codzienne skrypty — struktury danych, przepływ sterowania, proste funkcje — i nie byłbyś spowolniony rutynową pracą konserwacyjną ani małą funkcją w istniejącej bazie kodu. Różnica między tym poziomem a Zaawansowanym polega głównie na tym, co dzieje się, gdy funkcje wygody Pythona wchodzą w interakcję ze sobą: płytka kopia pozostawiająca zagnieżdżone dane udostępnione, gdy spodziewałeś się duplikacji, wartość zwrotna generatora, która cicho nie staje się częścią jego wyniku, dekoratory ułożone w kolejności, którą łatwo źle zrozumieć. To są tego rodzaju błędy, które starszy recenzent zauważy w dziesięć sekund, a wszyscy inni spędzą godzinę na śledzeniu.",
          "recommendation": "Skoncentruj się na wewnętrznościach obiektów i iteracji: kopia płytka versus głęboka, co generator faktycznie robi z wartością zwrotną, i jak działa kolejność ułożenia dekoratorów. Następnie podstawy klasy, które większość samouczków pomija — domyślna równość bez `__eq__`, i dlaczego mutowalny atrybut klasy jest udostępniany każdej instancji."
        },
        "advanced": {
          "name": "Zaawansowany",
          "desc": "To jest poziom, który większość ofert pracy oznacza jako \"silny Python\". Sięgasz po właściwe narzędzie bez szukania, wiesz, dlaczego dany fragment współdzielonego stanu się zmienił, a nie tylko że się zmienił, i potrafisz przeczytać funkcję kogoś innego i prawidłowo przewidzieć jej wynik. To, co oddziela tę kategorię od najwyższej, to defensywna strona pracy: wiedza, które z dwóch wyglądających prawidłowo podejść będą się niewłaściwie zachowywać, gdy pojawi się atrybut klasy, argument tylko dla słów kluczowych czy hierarchia wyjątków.",
          "recommendation": "Zanurz się w części chroniące bazę kodu, którą dotykają też inne osoby: argumenty tylko dla słów kluczowych jako wybór projektowania API, a nie tylko ciekawość składni, hierarchia wyjątków (tak aby klauzule except łapały właściwą rodzinę błędów, nie tylko jedną klasę), i menedżery kontekstu jako standard gwarantujący czyszczenie. Artykuły pogłębiające na stronie Real Python to dobry następny krok dla wszystkich trzech."
        },
        "expert": {
          "name": "Ekspert",
          "desc": "Uzyskałeś maksymalne wyniki w każdej sekcji — składnia rdzenia, funkcje i zakres, struktury danych i idiomy obiektowo-orientowane. W praktyce oznacza to, że możesz dostać obcy plik i wyjaśnić, dlaczego daje konkretne wyniki, a nie tylko to, co składnia mówi, że powinna robić, co jest trudniejszą i bardziej wartościową umiejętnością. Na tym poziomie sam język jest rzadko czynnikiem limitującym w Twojej pracy; limit zwykle stanowi wielkość lub kształt systemu wokół kodu.",
          "recommendation": "Zwroty są teraz w narzędziach i przeglądach: statyczne sprawdzanie typów za pomocą mypy lub pyright, profilowanie przed optymalizacją, a nie zgadywanie, i czytanie pull requestów innych osób dokładnie w tej kategorii błędu — te, które przechodzą każdy test i wciąż robią złą rzecz przy określonym wejściu. Jeśli uczestniczysz w procesie rekrutacji, opisz błąd taki jak ten, który znaleźć, zamiast wymieniać funkcje języka — to pokazuje rozumowanie, a nie tylko słownictwo."
        }
      },
      "questions": [
        {
          "question": "Napiszesz `def add_item(item, basket=[]): basket.append(item); return basket`, następnie wywołasz `add_item('a')` i `add_item('b')`, oba razy pomijając basket. Co zwraca drugie wywołanie?",
          "options": [
            {"icon": "", "label": "`['b']` — każde wywołanie otrzymuje świeżą pustą listę domyślnie"},
            {"icon": "", "label": "`TypeError` — musisz podać argument basket"},
            {"icon": "", "label": "`['a', 'b']` — lista domyślna jest tworzona raz i ponownie użyta między wywołaniami"},
            {"icon": "", "label": "`['a']` a następnie `['b']` jako dwie niezależne listy jednoelementowe"}
          ]
        },
        {
          "question": "`a = [1, 2, 3]` i `b = [1, 2, 3]`. Co zwraca `a == b`, a co zwraca `a is b`?",
          "options": [
            {"icon": "", "label": "`True` dla obu — identyczne listy są zawsze tym samym obiektem"},
            {"icon": "", "label": "`True` dla `==`, `False` dla `is` — równe zawartości, ale różne obiekty w pamięci"},
            {"icon": "", "label": "`False` dla obu — oddzielne literały nigdy nie są równe w Pythonie"},
            {"icon": "", "label": "`True` dla `is`, `False` dla `==` — `is` sprawdza równość wartości dla list"}
          ]
        },
        {
          "question": "W Pythonie 3 na co oblicza się `7 / 2`, a na co `7 // 2`?",
          "options": [
            {"icon": "", "label": "`3.5`, następnie `3` — `/` zawsze zwraca liczbę zmiennoprzecinkową, `//` zaokrągla wynik w dół"},
            {"icon": "", "label": "`3`, następnie `3.5` — `/` skraca i `//` zwraca liczbę zmiennoprzecinkową"},
            {"icon": "", "label": "`3.5`, następnie `3.5` — oba operatory zwracają liczbę zmiennoprzecinkową w Pythonie 3"},
            {"icon": "", "label": "`3`, następnie `3` — oba operatory zaokrąglają wynik w dół w Pythonie 3"}
          ]
        },
        {
          "question": "`s = 'hello'`, następnie uruchamiasz `s[0] = 'H'`. Co się dzieje?",
          "options": [
            {"icon": "", "label": "`s` staje się `'Hello'`"},
            {"icon": "", "label": "`s` staje się `'Hhello'`, ponieważ znak jest wstawiany, a nie zastępowany"},
            {"icon": "", "label": "`TypeError` — napisy są niezmienne i nie obsługują przypisania elementu"},
            {"icon": "", "label": "Nic — przypisanie jest po cichu ignorowane i `s` pozostaje `'hello'`"}
          ]
        },
        {
          "question": "`x = [10, 20, 30, 40, 50]`. Co zwraca `x[1:4]`?",
          "options": [
            {"icon": "", "label": "`[20, 30, 40, 50]`"},
            {"icon": "", "label": "`[10, 20, 30, 40]`"},
            {"icon": "", "label": "`[20, 30, 40]`"},
            {"icon": "", "label": "`[30, 40]`"}
          ]
        },
        {
          "question": "`name = 'Ana'` i `age = 30`. Co produkuje `f'{name} is {age}'`?",
          "options": [
            {"icon": "", "label": "`{name} is {age}`"},
            {"icon": "", "label": "`Ana is 30`"},
            {"icon": "", "label": "`name is age`"},
            {"icon": "", "label": "`TypeError`, ponieważ f-stringi wymagają metody `format()`"}
          ]
        },
        {
          "question": "Na co oblicza się `1 < 2 < 3`?",
          "options": [
            {"icon": "", "label": "`True` — Python łańcuchuje porównania jako `(1 < 2) and (2 < 3)`"},
            {"icon": "", "label": "`False` — porównania łańcuchowe są obliczane od lewej do prawej bez short-circuitingu, dając `1 < 2 < 3 -> 1 < True -> False`"},
            {"icon": "", "label": "`SyntaxError` — porównania nie mogą być łańcuchowane"},
            {"icon": "", "label": "`3` — Python zwraca ostatnią wartość w łańcuchu"}
          ]
        },
        {
          "question": "Na co zwraca `bool([])` i na co zwraca `bool([0])`?",
          "options": [
            {"icon": "", "label": "`False`, następnie `False` — każda lista zawierająca tylko fałszywe wartości jest falszywą"},
            {"icon": "", "label": "`False`, następnie `True` — pusta lista jest falszywą, lista zawierająca jeden element (nawet `0`) jest prawdziwą"},
            {"icon": "", "label": "`True`, następnie `True` — obiekty inne niż `None` są zawsze prawdziwe"},
            {"icon": "", "label": "`True`, następnie `False` — lista jest prawdziwa tylko gdy jest pusta"}
          ]
        },
        {
          "question": "Istnieje `count = 0` na poziomie modułu. Wewnątrz `def increment(): count += 1; return count` wywołujesz `increment()`. Co się dzieje?",
          "options": [
            {"icon": "", "label": "`UnboundLocalError` — przypisanie do `count` gdziekolwiek w funkcji czyni ją lokalną, więc `count += 1` próbuje przeczytać zmienną lokalną przed przypisaniem"},
            {"icon": "", "label": "Zwraca `1` i inkrementuje `count` na poziomie modułu do `1`"},
            {"icon": "", "label": "Zwraca `1`, ale pozostawia `count` na poziomie modułu na `0`"},
            {"icon": "", "label": "Podnosi `NameError`, ponieważ `count` nigdy nie został zadeklarowany wewnątrz funkcji"}
          ]
        },
        {
          "question": "`def f(*args, **kwargs): return args, kwargs`. Co zwraca `f(1, 2, x=3)`?",
          "options": [
            {"icon": "", "label": "`([1, 2], {'x': 3})`"},
            {"icon": "", "label": "`((1, 2), {'x': 3})`"},
            {"icon": "", "label": "`(1, 2, {'x': 3})`"},
            {"icon": "", "label": "`TypeError` — argumenty pozycyjne i słowa kluczowe nie mogą być mieszane w jednym wywołaniu"}
          ]
        },
        {
          "question": "Budujesz `funcs = [lambda: i for i in range(3)]` w pętli. Co zwraca `[f() for f in funcs]`?",
          "options": [
            {"icon": "", "label": "`[2, 2, 2]` — każda lambda przeszukuje `i` gdy jest wywoływana, a wtedy pętla skończyła się z `i` równym `2`"},
            {"icon": "", "label": "`[0, 1, 2]` — każda lambda przechwytuje wartość `i` w momencie jej utworzenia"},
            {"icon": "", "label": "`[0, 0, 0]` — lambdy zawsze przechwytują pierwszą wartość przypisaną do zmiennej"},
            {"icon": "", "label": "`NameError`, ponieważ `i` już nie istnieje po zakończeniu pętli"}
          ]
        },
        {
          "question": "Funkcja jest zdefiniowana z `@a` bezpośrednio nad `@b`, która siedzi bezpośrednio nad `def f(): pass`. W jakiej kolejności dekoratory są stosowane do `f`?",
          "options": [
            {"icon": "", "label": "`b` opakowuje `f` pierwsze, następnie `a` opakowuje wynik `b` — dekorator najbliżej funkcji runs first"},
            {"icon": "", "label": "`a` opakowuje `f` pierwsze, następnie `b` opakowuje wynik — dekoratory stosują się od góry do dołu"},
            {"icon": "", "label": "Oba dekoratory opakują `f` niezależnie i tylko ostatnio zdefiniowany wchodzi w życie"},
            {"icon": "", "label": "To zależy od kolejności, w której dekoratory są importowane, a nie od ich pozycji w kodzie"}
          ]
        },
        {
          "question": "`def f(a, *, b): return a + b`. Które z tych wywołań działają?",
          "options": [
            {"icon": "", "label": "`f(1, b=2)` — `b` musi być przecięty przez słowo kluczowe, ponieważ pojawia się po nagim `*` w sygnaturze"},
            {"icon": "", "label": "`f(1, 2)` — argumenty pozycyjne wypełniają parametry od lewej do prawej niezależnie od `*`"},
            {"icon": "", "label": "`f(a=1, 2)` — argumenty słów kluczowych muszą być pierwsze"},
            {"icon": "", "label": "`f(1)` — `b` jest opcjonalne, ponieważ następuje `*`"}
          ]
        },
        {
          "question": "Funkcja generatora wykonuje `yield 1`, następnie `yield 2`, następnie `return 99`. Co zawiera `list(the_generator())`, a co się dzieje z `99`?",
          "options": [
            {"icon": "", "label": "`[1, 2, 99]` — `return` wewnątrz generatora zachowuje się jak jedno więcej `yield`"},
            {"icon": "", "label": "`[99]` — `return` natychmiast zastępuje wszystkie już wykonane wartości"},
            {"icon": "", "label": "`[1, 2]` — wartość zwrotna generatora staje się wartością dołączoną do `StopIteration`, którą podnosi, nie jest wykonana"},
            {"icon": "", "label": "`RuntimeError`, ponieważ generatory nie mogą zawierać instrukcji `return`"}
          ]
        },
        {
          "question": "W funkcji `outer()` ustawiona jest `x = 1`, następnie zagnieżdżony `inner()` robi `nonlocal x; x += 1`, i `outer()` wywoła `inner()` przed zwróceniem `x`. Co zwraca `outer()`?",
          "options": [
            {"icon": "", "label": "`1` — `inner()` operuje na własnej lokalnej kopii `x`, więc zmiana nie persystuje"},
            {"icon": "", "label": "`UnboundLocalError`, ponieważ `x` nie jest zadeklarowane wewnątrz `inner()` przed instrukcją `nonlocal`"},
            {"icon": "", "label": "`SyntaxError` — `nonlocal` można używać tylko wewnątrz klas"},
            {"icon": "", "label": "`2` — `nonlocal` pozwala `inner()` modyfikować `x` funkcji zewnętrznej zamiast tworzyć nową zmienną lokalną"}
          ]
        },
        {
          "question": "`d = {'a': 1, 'b': 2}`. Co zwraca `d.get('c', 0)`, i czy dodaje `'c'` do słownika?",
          "options": [
            {"icon": "", "label": "`0`, i nie — `get()` zwraca domyślną bez wstawiania klucza"},
            {"icon": "", "label": "`0`, i tak — `get()` wstawia klucz z wartością domyślną"},
            {"icon": "", "label": "`KeyError`, ponieważ `'c'` nie istnieje"},
            {"icon": "", "label": "`None`, i tak — `get()` zawsze dodaje brakujące klucze z wartością `None`"}
          ]
        },
        {
          "question": "`t = (1, 2, [3, 4])`. Czy możesz uruchomić `t[2].append(5)`, i czy możesz uruchomić `t[0] = 10`?",
          "options": [
            {"icon": "", "label": "Oba działają — zagnieżdżanie listy wewnątrz krotki czyni całą krotkę mutowalną"},
            {"icon": "", "label": "Oba podnoszą `TypeError` — nic wewnątrz krotki nigdy nie może być zmieniane"},
            {"icon": "", "label": "`t[2].append(5)` podnosi `TypeError`, ale `t[0] = 10` działa, ponieważ krotki pozwalają na reasygn ich pierwszego elementu"},
            {"icon": "", "label": "`t[2].append(5)` działa, ponieważ lista wewnątrz jest mutowalna; `t[0] = 10` podnosi `TypeError`, ponieważ sama krotka jest niezmienia"}
          ]
        },
        {
          "question": "Które z tych zwraca iterator, który oblicza wartości leniwie zamiast budować całą sekwencję w pamięci naraz: `[x*x for x in range(1000000)]` lub `(x*x for x in range(1000000))`?",
          "options": [
            {"icon": "", "label": "Ten z nawiasami, `(x*x for x in range(1000000))` — to jest wyrażenie generatora"},
            {"icon": "", "label": "Ten z nawiasami kwadratowymi — comprehenszje list są zawsze leniwe w Pythonie 3"},
            {"icon": "", "label": "Oba są leniwe — jedyną różnicą jest typ zwrócony na koniec"},
            {"icon": "", "label": "Żaden — oba budują pełną sekwencję w pamięci natychmiast"}
          ]
        },
        {
          "question": "Blok `try` dzieli przez zero, klauzula `except ZeroDivisionError` drukuje \"a\", a klauzula `finally` drukuje \"b\". Co drukuje i w jakiej kolejności?",
          "options": [
            {"icon": "", "label": "\"b\" następnie \"a\" — `finally` zawsze uruchamia się przed jakąkolwiek klauzulą `except`"},
            {"icon": "", "label": "\"a\" następnie \"b\" — pasująca klauzula `except` uruchamia się pierwszy, a `finally` zawsze uruchamia się potem niezależnie"},
            {"icon": "", "label": "Tylko \"b\" — wyjątek nie jest faktycznie łapany, więc \"a\" nigdy nie drukuje"},
            {"icon": "", "label": "Tylko \"a\" — `finally` jest pominięty, gdy wyjątek już został obsłużony"}
          ]
        },
        {
          "question": "`import copy; a = [[1, 2], [3, 4]]; b = copy.copy(a); b[0].append(99)`. Czy `a[0]` też się zmienia?",
          "options": [
            {"icon": "", "label": "Nie — `copy.copy()` zawsze duplikuje zagnieżdżone obiekty również"},
            {"icon": "", "label": "Nie — dodanie do `b[0]` tworzy zupełnie nową listę tylko dla `b[0]`"},
            {"icon": "", "label": "Tak, ale tylko dlatego, że `copy.copy()` został wywołany bez argumentu `deepcopy`"},
            {"icon": "", "label": "Tak — `copy.copy()` robi płytką kopię, więc zagnieżdżone listy są wciąż dzielone między `a` i `b`"}
          ]
        },
        {
          "question": "`d = {'x': 1, 'y': 2}`. Na co sprawdza `'x' in d` — klucze, wartości czy oba?",
          "options": [
            {"icon": "", "label": "Na wartości — `in` sprawdza czy `1` lub `2` równa się `'x'`"},
            {"icon": "", "label": "Zarówno klucze i wartości są sprawdzane"},
            {"icon": "", "label": "Żaden — `in` na słowniku zawsze podnosi `TypeError`"},
            {"icon": "", "label": "Na klucze — `in` na słowniku testuje członkostwo wśród jego kluczy, nie wartości"}
          ]
        },
        {
          "question": "`names = ['Al', 'Bo']` i `scores = [10, 20]`. Co zwraca `list(zip(names, scores))`?",
          "options": [
            {"icon": "", "label": "`[('Al', 'Bo'), (10, 20)]`"},
            {"icon": "", "label": "`['Al', 10, 'Bo', 20]`"},
            {"icon": "", "label": "`[('Al', 10), ('Bo', 20)]`"},
            {"icon": "", "label": "`ValueError`, ponieważ `zip` wymaga trzech lub więcej argumentów"}
          ]
        },
        {
          "question": "`class Dog: tricks = []` zawiera listę na poziomie klasy, a `add_trick` dodaje do `self.tricks`. `d1 = Dog()` i `d2 = Dog()` są tworzone, następnie `d1.add_trick('sit')` uruchamia się. Co zawiera `d2.tricks`?",
          "options": [
            {"icon": "", "label": "`[]` — każda instancja otrzymuje własną niezależną kopię `tricks`"},
            {"icon": "", "label": "`['sit']` — `tricks` to lista na poziomie klasy dzielona przez każdą instancję, więc zmiana `d1` jest widoczna na `d2` również"},
            {"icon": "", "label": "`TypeError` — instancje nie mogą dodawać do atrybutu klasy"},
            {"icon": "", "label": "`['sit']` tylko po ponownym uruchomieniu `d2 = Dog()`"}
          ]
        },
        {
          "question": "`class A` ma `def greet(self): return 'A'`. `class B(A)` ma `def greet(self): return 'B' + super().greet()`. Co zwraca `B().greet()`?",
          "options": [
            {"icon": "", "label": "`'AB'` — `super()` zawsze uruchamia się przed własnym kodem podklasy"},
            {"icon": "", "label": "`'B'` — `super().greet()` jest ignorowany, ponieważ `B` już przesłania `greet`"},
            {"icon": "", "label": "`'BA'` — `super().greet()` wzywa metodę `A` i jej wynik jest dołączony do `'B'`"},
            {"icon": "", "label": "`AttributeError`, ponieważ `A` nie ma metody `greet` widocznej dla `B`"}
          ]
        },
        {
          "question": "`class Point` przechowuje `self.x` w `__init__` i definiuje brak innych metod. `p1 = Point(1)` i `p2 = Point(1)`. Co zwraca `p1 == p2` domyślnie?",
          "options": [
            {"icon": "", "label": "`True` — Python domyślnie porównuje wszystkie pasujące atrybuty"},
            {"icon": "", "label": "`False` — bez custom `__eq__`, `==` wraca do porównania tożsamości, a `p1` i `p2` to różne obiekty"},
            {"icon": "", "label": "`True`, ale tylko dlatego, że oba obiekty były tworzone z tym samym argumentem"},
            {"icon": "", "label": "`TypeError`, ponieważ `Point` nie definiuje `__eq__`"}
          ]
        },
        {
          "question": "Która klauzula `except` poniżej będzie również łapać `ZeroDivisionError`: `except ArithmeticError`, `except ValueError`, czy `except KeyError`?",
          "options": [
            {"icon": "", "label": "`except ValueError` — błędy dzielenia są traktowane jako wartości nieważne"},
            {"icon": "", "label": "`except KeyError` — każdy błąd czasu wykonywania nie powiązany z określonym typem wraca do `KeyError`"},
            {"icon": "", "label": "Żaden z nich — tylko `except ZeroDivisionError` może go łapać"},
            {"icon": "", "label": "`except ArithmeticError` — `ZeroDivisionError` to podklasa `ArithmeticError`"}
          ]
        },
        {
          "question": "Otwierasz plik z `open('data.txt') as f:` i wyjątek jest podniesiony podczas czytania wewnątrz bloku. Czy plik jest wciąż zamykany?",
          "options": [
            {"icon": "", "label": "Nie — plik pozostaje otwarty, ponieważ blok nie zakończył się normalnie"},
            {"icon": "", "label": "Tylko jeśli dodasz również klauzulę `finally` wokół instrukcji `with`"},
            {"icon": "", "label": "Tak — instrukcja `with` wywoła metodę `__exit__` pliku, która go zamyka, nawet jeśli wyjątek występuje wewnątrz bloku"},
            {"icon": "", "label": "To zależy od typu wyjątku — tylko wyjątkami złapane w innym miejscu wyzwalają czyszczenie"}
          ]
        },
        {
          "question": "`x = [3, 1, 2]` i `y = x.sort()`. Co zawiera `y`?",
          "options": [
            {"icon": "", "label": "`[1, 2, 3]` — `sort()` zwraca nową posortowaną listę"},
            {"icon": "", "label": "`None` — `list.sort()` sortuje na miejscu i zwraca `None`; sam `x` staje się `[1, 2, 3]`"},
            {"icon": "", "label": "`[3, 1, 2]` — `sort()` zwraca oryginalną nieposortowaną listę i zmienia tylko wewnętrzną kolejność `x`"},
            {"icon": "", "label": "`TypeError`, ponieważ `sort()` nie może być przypisany do zmiennej"}
          ]
        },
        {
          "question": "Co się dzieje, gdy uruchamiasz `'Score: ' + 42`?",
          "options": [
            {"icon": "", "label": "`'Score: 42'` — Python konwertuje liczbę automatycznie wewnątrz wyrażenia `+`"},
            {"icon": "", "label": "`'Score: '` — liczba jest po cichu porzucana"},
            {"icon": "", "label": "`42` — napis jest zmuszony do liczby i dodany"},
            {"icon": "", "label": "`TypeError` — nie możesz bezpośrednio łączyć `str` i `int`, `42` musi być konwertowany z `str()` najpierw"}
          ]
        },
        {
          "question": "Musisz sprawdzić czy lista zwana `results` jest pusta. Jaki jest idiomatyczny sposób w Pythonie: `if results == []`:, `if len(results) == 0:`, czy `if not results:`?",
          "options": [
            {"icon": "", "label": "`if results == []`: — to jedyny niezawodny sposób na wykrycie pustej listy"},
            {"icon": "", "label": "`if len(results) == 0:` — to jest wymagane, ponieważ puste listy są prawdziwe w Pythonie"},
            {"icon": "", "label": "Wszystkie trzy są równo nigdy nie używane w praktyce; standardowe podejście to `if results is None:`"},
            {"icon": "", "label": "`if not results:` — idiom Pythona polega na prawdziwości, a pusta lista jest fałszywą"}
          ]
        }
      ],
      "optionOrderVersion": "92945565db6c55da"
    }
  }
}
