Przejdź do treści

Kategoria: Python

25 artykułów oznaczonych „Python".

Gdy kod sam się dubluje – sprzątanie pod osłoną testów

PythonDjangoJavaScript

W dużym projekcie nie da się pamiętać, że gdzieś już jest funkcja licząca to samo – więc pisze się ją drugi i trzeci raz. To nie lenistwo, to koszt pamięci. Problem w tym, że kopie z czasem się rozchodzą: ta sama najlepsza próba ucznia potrafiła być inna na ekranie i w PDF-ie, a w aplikacji mobilnej ten sam egzamin pokazywał czas raz jako 12:05, raz jako 12 min 5 s. Ta sama choroba złapała niezależnie backend Django i aplikację w React Native. O tym, dlaczego duplikacja to fabryka takich rozjazdów, i jak posprzątać ją bezpiecznie: najpierw dopisać testy, potem scalać, a zielona suita ma świecić tak samo przed i po.

Czytaj dalej →

Ile testów ma produkcyjna aplikacja? Liczby z zawodowe.edu.pl

testyPythonDjango

Po serii o testowaniu czas na dowód z produkcji, policzony co do sztuki: backend Django z ponad 100 tysiącami linii kodu i 6,6 tysiąca testów, mobilka React Native z 44 tysiącami linii i ponad 1600 testami, do tego 298 testów Playwright, 7 przepływów Maestro i bramka w GitHub Actions, która nie raz zatrzymała zepsute wdrożenie przed produkcją. Z metodą liczenia, proporcjami kodu do testów i uczciwym rozdziałem o tym, czego wciąż nie pokrywam.

Czytaj dalej →

Testy przepływów: Playwright i Maestro, czyli E2E bez dawnego bólu

testyPython

Testy end-to-end miały u mnie zasłużenie złą opinię: Selenium z ręcznymi sleepami i łamliwymi XPathami, Appium z konfiguracją trudniejszą niż same testy. Dlatego latami ich unikałem – i to był błąd, tylko że wtedy racjonalny. Dziś flow na webie klika Playwright, a na mobile Maestro w kilkunastu linijkach YAML-a. Co konkretnie się zmieniło, tabela stare kontra dziś i uczciwy rozdział o tym, czemu E2E wciąż jest drogie.

Czytaj dalej →

Co testować i gdzie – piramida testów w praktyce, bez religii pokrycia

testyPythonDjango

Skoro testować, to co dokładnie i na którym poziomie? Piramida testów opowiedziana po ludzku: testy jednostkowe w pytest, integracyjne z bazą i widokami Django, testy przepływów na samej górze. Skąd naprawdę biorą się luki w pokryciu, dlaczego sto procent pokrycia niczego nie gwarantuje – i dlaczego moje testy pilnują nie tylko kodu, ale też treści tego bloga.

Czytaj dalej →

Jak liczyć pieniądze w kodzie – żeby grosze się zgadzały

bazy danychPythonphp

0,1 + 0,2 to nie 0,3 – a to znaczy, że typu float nie wolno używać do pieniędzy. Nie chodzi o ostrożniejsze zaokrąglanie, tylko o inny typ danych. Przegląd tego, jak liczy się kwoty poprawnie: grosze jako liczby całkowite, DECIMAL w bazie, decimal w Pythonie, BigDecimal w Javie, BCMath w PHP i BigInt w JavaScripcie. Do tego zaokrąglenie bankierskie i słynny spór o VAT liczony od pozycji czy od sumy.

Czytaj dalej →

Grafy w praktyce: BFS, DFS, Dijkstra i A*, czyli jak wyznacza się trasę

algorytmyPython

Ostatnia część serii o strukturach danych. Trzy algorytmy przeszukiwania na jednej mapie: BFS liczy kroki, Dijkstra koszt, A* dokłada heurystykę i przestaje błądzić. Do tego reprezentacja grafu, DFS i sortowanie topologiczne, struktura zbiorów rozłącznych z odwrotną funkcją Ackermanna oraz odpowiedź na pytanie, dlaczego prawdziwa nawigacja nie liczy Dijkstry na żywo, tylko przelicza mapę wcześniej.

Czytaj dalej →

Kopce i kolejki priorytetowe: heapq, schedulery i token bucket

algorytmyPython

Piąta część serii o strukturach danych. Kopiec binarny zapisany w zwykłej tablicy, budowa w czasie liniowym i trzy operacje, które z niego wynikają. Po co utrzymywać częściowy porządek zamiast pełnego, jak wybrać dziesięć największych elementów bez sortowania miliona, czym jest heapq.merge przy danych większych niż pamięć i jak z kolejki priorytetowej robi się scheduler oraz ogranicznik ruchu.

Czytaj dalej →

Drzewa poszukiwań: BST, AVL i czerwono-czarne

algorytmyPython

Trzecia część serii o strukturach danych. Jak drzewo poszukiwań binarnych trzyma porządek bez przesuwania tablicy, dlaczego na danych posortowanych degeneruje się do listy i wykonuje dokładnie tyle samo porównań co sortowanie bąbelkowe, oraz jak temu zaradzić rotacjami. AVL kontra drzewa czerwono-czarne, animacja obu przypadków i odpowiedź na pytanie, po co komu drzewo, skoro jest szybszy słownik.

Czytaj dalej →

Wyszukiwanie liniowe i binarne: dwie pętle, w których łatwo się pomylić

algorytmyPython

Druga część serii o strukturach danych. Kiedy wyszukiwanie liniowe wystarcza, kiedy opłaca się posortować dane, jak napisać wyszukiwanie binarne bez pętli nieskończonej i skąd wziął się błąd przepełnienia, który siedział w bibliotece standardowej Javy przez dziewięć lat. Do tego moduł bisect, wyszukiwanie wykładnicze i rachunek, po ilu zapytaniach sortowanie zwraca się z nawiązką.

Czytaj dalej →

Tablice mieszające: co naprawdę siedzi w słowniku i tablicy asocjacyjnej

algorytmyPythonbezpieczeństwo

Pierwsza część serii o strukturach danych. Jak z funkcji skrótu robi się dostęp w czasie stałym, co się dzieje przy kolizjach, czym różni się łańcuchowanie od adresowania otwartego i dlaczego słownik czasem nagle zwalnia. Kontrakt hash i eq w Pythonie, klucz, który gubi dane, koszt amortyzowany przy rozrastaniu tablicy oraz trzy różne rzeczy nazywane tym samym słowem hash: skrót do wyszukiwania, kryptograficzny i do haseł.

Czytaj dalej →

Kiedy złożoność staje się podatnością: HashDoS, ReDoS i inne ataki na algorytmy

bezpieczeństwoalgorytmyPython

Tabelki złożoności czyta też atakujący. Jak kilka kilobajtów dobranego wejścia zajmuje rdzeń procesora na sekundy: kolizje w tablicach mieszających (HashDoS z 2011 roku), katastrofalny nawrót w wyrażeniach regularnych (27 minut awarii Cloudflare w 2019), pesymistyczny przypadek quicksorta, bomby dekompresyjne i encje XML. Z pomiarami w Pythonie, prawdziwymi liczbami i listą obron, które faktycznie działają.

Czytaj dalej →

Jak sortuje twój język: TimSort, Powersort, pdqsort i reszta

algorytmyPythonJavaScript

Ostatnia część cyklu o sortowaniu: co naprawdę dzieje się po wywołaniu sorted() w Pythonie, Arrays.sort w Javie, std::sort w C++, sort() w PHP i JavaScripcie oraz sort_unstable w Ruście. Powersort od CPythona 3.11, dual-pivot quicksort dla typów prostych, stabilność wymuszona specyfikacją, sortowanie zewnętrzne, quickselect zamiast sortowania i klasyczne pułapki: sortowanie liczb jak napisów oraz niespójny komparator.

Czytaj dalej →

Sortowanie bez porównań: zliczanie, pozycyjne i kubełkowe

algorytmyPythonmatematyka

Trzecia część cyklu o algorytmach sortowania. Skąd bierze się granica n log n dla wszystkich algorytmów porównawczych, dlaczego jest nieprzekraczalna i jak sortowanie przez zliczanie, pozycyjne i kubełkowe przechodzą pod nią suchą stopą, nie porównując ani razu dwóch elementów. Implementacje w Pythonie, animacje z licznikiem porównań ustawionym na zero oraz uczciwy rachunek kosztów: pamięć, zakres kluczy i rozkład danych.

Czytaj dalej →

Dziel i zwyciężaj: Merge, Quick, Heap, Tree, IntroSort i TimSort

algorytmyPython

Druga część cyklu o algorytmach sortowania: sortowanie przez scalanie, szybkie, przez kopcowanie i drzewiaste, a potem hybrydy, które naprawdę pracują w bibliotekach – IntroSort z C++ i TimSort z Pythona oraz Javy. Implementacje w Pythonie, animacje, wybór pivota, przypadek pesymistyczny quicksorta na żywo i pytanie, dlaczego szybkie bije scalanie mimo identycznej złożoności.

Czytaj dalej →

Algorytmy sortowania w akcji: od bąbelkowego do Shella

algorytmyPython

Wyścig dziewięciu algorytmów sortowania na żywo w przeglądarce, a potem spokojny rozbiór tych najprostszych: bąbelkowego, koktajlowego, grzebieniowego, gnoma, przez wybieranie, przez wstawianie i Shella. Implementacje w Pythonie, liczniki porównań i zapisów, stabilność, sortowanie w miejscu i adaptacyjność. Oraz to, o czym podręczniki milczą: kiedy O(n kwadrat) naprawdę wygrywa.

Czytaj dalej →

Dlaczego godzina ma 60 minut, a doba 24 godziny

matematykaPythonJavaScript

W kieszeni nosisz babiloński kalkulator sprzed czterech tysięcy lat. Skąd wziął się system sześćdziesiątkowy i liczenie na paliczkach, czemu 60 i 12 wygrywają z 10 liczbą dzielników, jak Egipcjanie podzielili noc na 12 godzin, skąd pochodzą słowa minuta i sekunda – i dlaczego rewolucyjna Francja przegrała z 10-godzinną dobą, choć jej dziesiętny czas przeżył w uniksowym timestampie.

Czytaj dalej →

Cyfry kontrolne – jak PESEL, NIP, IBAN i numer karty łapią literówki

matematykaJavaScriptPython

Ostatnia cyfra PESEL-u, NIP-u, numeru karty płatniczej i dwie cyfry w IBAN-ie nie są losowe – to sumy kontrolne oparte na arytmetyce modularnej. Jakie błędy człowiek robi najczęściej, dlaczego wagi i moduł pierwszy łapią przestawione cyfry, algorytm Luhna w 15 linijkach oraz implementacje walidacji PESEL, NIP i IBAN w Pythonie, PHP i JavaScript.

Czytaj dalej →

Od dni do sekund – uniksowy timestamp, problem roku 2038 i strefy czasowe

JavaScriptPythonLinux

Trzecia część cyklu o czasie: komputery nie liczą dat, tylko sekundy od 1970 roku. Skąd się bierze problem roku 2038 (i kogo naprawdę dotknie), czym są sekundy przestępne i dlaczego znikną do 2035, oraz czemu strefy czasowe to baza danych IANA, a nie matematyka – z dniami, które nie istnieją, i godzinami, które zdarzają się dwa razy.

Czytaj dalej →

Flask, FastAPI, Django – jak poznawałem trzy Pythony do weba

PythonFlaskFastAPI

Nie ranking z internetu, tylko moja droga: Flask, gdy chciałem najszybciej wystawić HTML; FastAPI, gdy potrzebowałem szybkiego API z walidacją i /docs; Django, gdy chciałem użytkowników, panel i ORM z pudełka. Trzy frameworki przez pryzmat roboty, do której po nie sięgałem – z kodem i szczerą tabelą decyzyjną.

Czytaj dalej →

Zamiana Liczb: Od Dziesiętnego do Binarnego

phpJavaScriptPython

Zamiana liczb dziesiętnych na binarne – z częścią całkowitą i (rzadko porządnie tłumaczoną) częścią ułamkową. Algorytm mnożenia przez 2, kiedy ułamek jest skończony, a kiedy nieskończony, wykrywanie okresu oraz implementacje w Pythonie, JavaScript, PHP i C++. Plus most do niedokładności liczb zmiennoprzecinkowych.

Czytaj dalej →

← Wszystkie wpisy