Sekretny Mikołaj w Pythonie – Warsztat Migawki

utworzone przez | 05/12/2019 | Warsztat

sekretny mikołaj w pythonie

Oto pierwszy warsztat 🔧 migawki. Celem warsztatu jest poprawienie prostego skryptu i pokazanie jak rozwiązujemy codzienne problemy oraz na co zwracamy uwagę przy ocenie jakości kodu. “Pierwsza wersja wszystkiego to śmieci”, my, też przejdziemy przez parę iteracji, ale mam nadzieje, że efekt końcowy zaskoczy Cię tak samo jak mnie😱

Jest to eksperyment na łamach migawki, więc bardzo liczę na waszą opinie. Daj znać w komentarzach czy wpis się wam podobał. Jeśli stwierdzicie, że nie, to skupimy się na tradycyjnych artykułach😃 Natomiast przy pozytywnym odbiorze – w kolejce czeka kolejny algorytm do warsztatu migawki.

Sekretny Mikołaj

Sekretny Mikołaj to zabawa, gdzie grupa osób umawia się na zrobienie sobie wzajemnie małych niespodzianek. Do kapelusza wkładamy imiona wszystkich uczestników zapisane na karteczkach. Następnie każdy losuje karteczkę. Jeśli wylosował swoje imię, to losuje jeszcze raz. Jeśli wylosował kogoś innego, to szykujemy mały prezent dla tej osoby. Ważne, aby nie zdradzać wylosowanych imion!

Oryginalny kod

Oryginalny kod, który wziąłem na warsztat, znalazłem na jednej z grup Pythonowych. Autor, tego kodu, nazwijmy go Mikołaj, zaczyna swoją przygodę z Pythonem i przygotował taki prosty skrypt: 

Skrypt jest całkiem prosty, jednak zawiera pewien drobny błąd:

O ile raz na jakiś czas się trafi takie dopasowanie, o tyle gdy nie znajduje to wyrzuca błąd.

Rzeczy do poprawy

Mamy tutaj kilka problemów, które będziemy rozwiązywać:

  1. Skrypt ma działać zawsze
  2. Nazewnictwo zmiennych (osoby i osoby2 nie mówią nic o przeznaczeniu tych zmiennych, tylko o zawartości)
  3. Nadpisywanie zmiennych (w pętli for używamy tych samych przy zwracaniu pojedynczych elementów)
  4. Powinniśmy podzielić kod w funkcje
  5. Brakuje if __name__ == “__main__”

Pierwsza iteracja

Widząc te proste problemy, rzuciłem się w wir implementacji. Przecież taki kod to chleb powszedni dla takiego wymiatacza jak ja! Na początek postanowiłem rozwiązać pierwsze trzy problemy, były one najważniejsze.

Brak wyjątków

Przede wszystkim skrypt ma działać, to najważniejszy cel. Problem postanowiłem rozwiązać implementując kilka prostych kroków:

  • iterowanie po wszystkich uczestnikach zabawy 
  • usunięcie aktualnie losującej osoby z puli losowanych
  • losowanie osoby, której podarujemy prezent

Nazewnictwo

Drugi problem, czyli nazewnictwo, jest bardzo często ignorowany w świecie IT. Jednak oceńcie sami. Lepiej nazwać zmienne osoby i osoby2, czy może givers (dający) i recipients (odbiorcy)? Przy takich nazwach wiemy, że listy zawierają osoby, które mają nam coś dać i osoby, które mają coś otrzymać. Dodaliśmy kontekst!

Nadpisywanie zmiennych

Trzeci problem, czyli nadpisywanie zmiennych. Tego zwyczajnie nie powinniśmy robić. Chociaż nasz skrypt będzie działać, to wprowadza to zamieszanie i może powodować powstawanie w przyszłości nowych nieoczekiwanych błędów.

Rozwiązanie

Mając na uwadze powyższe problemy, przygotowałem na szybko ich rozwiązanie. Co mnie bardzo cieszy, udało się pozbyć if-ów z kodu. Ifologia zawsze zmniejsza czytelność i jest przyczyną powstawania kodu legacy. Taki prosty nawyk, stosowany systematycznie nawet w najprostszych skryptach gwarantuje sukces w dużych projektach.

Uruchomiłem skrypt kilka razy. Wszystko działało, więc rozwiązanie zostało opublikowane na grupie. Pełen sukces! 🎉

Houston, mamy problem

Życie okazało się jednak być okrutne. W kodzie był błąd!

Jeśli pod koniec działania skryptu w tabeli recipients zostanie tylko osoba, która jeszcze nie losowała karteczki, powstaje ten błąd.

Fala pomysłów

Oczywiście internet zaszumiał falą pomysłów na ominięcie błędu: “Dodajmy ify”, “Dodajmy try/except”, “Ponów wykonanie funkcji, aż się uda”. Ja im wszystkim mówię stanowcze NIE! Dlaczego? Pomysły wprawdzie sprawiają, że skrypt zaczyna działać, jednak nie rozwiązują problemu. Zostaje on tylko ukryty, a to może się na nas zemścić. Praktyka pokazała mi, że to zawsze się dzieje. Prędzej czy później, ale własnoręcznie popełniony zły kod i tak nas dopadnie!

Nastał piątek

O błędzie dowiedziałem się w piątek. Wiedziałem, że musi być lepsze rozwiązanie, że możemy uniknąć ifologi i rozwiązać ten problem sprytem! Nie miałem jednak jak tego zrobić przez trzy długie, trzy bardzo długie dni. Cały weekend nie miałem dostępu do komputera 😭

Druga iteracja

Nastał koniec weekendu, wreszcie można wrócić do algorytmu. Tym razem podchodzę do niego jak na seniora przystało.

Wymyślanie koła na nowo

Przeszukując internet trafiłem na ten same problemy. Większość materiałów proponowała liczne iteracje, skomplikowaną ifologię. Kilka artykułów skupiało się nawet na rozwiązaniach opartych o grafy. To wszystko wydawało się zbyt skomplikowane lub nieestetyczne. Jednak w jednym z artykułów o grafach trafiłem na złotego grala!

Rozwiązanie bez if-ów i pętli

Algorytm polega na trzech bardzo prostych operacjach:

  1. wymieszaj listę osób
  2. stwórz kopię osób i przesuń ją o jeden
  3. przypisz do siebie osoby o odpowiednich indeksach z obu list

Oto ostateczna wersja?

Rzeczy do poprawy – sprawdzenie

Jeśli sprawdzimy naszą początkową listę z zaobserwowanymi problemami zobaczysz, że wszystkie zostały już rozwiązane. Program przede wszystkim działa. Dla 1 miliona uruchomień otrzymałem 0 błędów! Nazwy są przejrzyste, kod został podzielony na funkcje i dodałem brakujący warunek if __name__ == “__main__”.

Jednak co najważniejsze, uniknęliśmy zbędnych pętli, if-ów, sprawdzania warunków brzegowych, ponawiania algorytmu w przypadku problemów. Uzyskaliśmy, czysty i przejrzysty kod. 

Dodatkowy zysk

Implementacja zawiera jeszcze jedną ciekawą zaletę. Funkcja reprezentująca główną logikę, czyli match_persons, nie definiuje sposobu prezentacji wyniku. Jest on prezentowany dopiero w funkcji secret_santa. Pozwoli nam to w prosty sposób przetestować działanie tej funkcji.

Niech prowadzą mnie testy

Czy można było zrobić wszystko lepiej i szybciej? Oczywiście, że tak. Gdybym do tego problemu podszedł stosując TDD prawdopodobnie uniknąłbym publikowania rozwiązania, które zawierało błąd. Jeśli chcecie uniknąć takich sytuacji to zapraszam was do serii Piotrka o TDD.

Podsumowanie

Celem tego warsztatu było pokazanie kilku rzeczy, które warto zapamiętać na przyszłość:

  • nawet proste problemy można rozwiązać w ciekawy sposób
  • nie każdy błąd należy poprawiać dodatkowym if-em
  • w internecie jest ogrom złych rozwiązań

Spodobała ci się taka forma postów? Chcesz więcej? Jeśli tak, to my również😃 Nie dowiemy się jednak o tym, bez feedbacku z twojej strony. Jak możesz pomóc? Zostaw komentarz lub łapkę pod tym artykułem. Dzięki.

O autorze

O autorze

Grzegorz Kocjan

8 lat z Pythonem to wspaniała przygoda, nieważne czy musiałem naprawić błąd na wczoraj, czy zaprojektować zaawansowany i wydajny system, Python nigdy mnie nie zawiódł! 🐍

Czysta architektura okiem ekipy migawka.it

Jakie problemy napotkaliśmy na początku? W czym nam pomogła? Kiedy na pewno z niej nie skorzystamy?

Nie przeszkadzaj mi! Jak nie dać się wyrwać z flow

Ile razy ostatnio zostałeś brutalnie oderwany od swojej pracy? Zaszywasz się w biurze i nagle pojawiają się oni – nieoczekiwani goście i ich pytania, które nie niosą ze sobą grozy awarii albo powagi hotfixa. Ale są to pytania, które teraz, dokładnie w tym momencie muszą paść i oderwać cię od bieżącej pracy. Jak sobie z nimi poradzić?

Precyzyjne twoje wiadomości być muszą

Dostajesz wiadomość e-mail i zastanawiasz się, czy to na pewno do ciebie i co właściwie masz zrobić. Wysyłasz pilną informację na komunikatorze i czekasz tydzień na odpowiedź. Dlaczego? Przecież wszystko było jasne. Najwyraźniej jednak nie było. Chwila moment i dowiesz się wszystkiego.

Testowanie wielu pól

Ponoć kiedy kod jest już napisany nie da się stwierdzić, czy był pisany w modelu TDD. Jest jednak kilka śladów zbrodni, które pozostają. Na przykład testy sprawdzające zbyt wiele rzeczy na raz i zakładające, że czytelnik posiada wiedzę tajemną.

Te bezsensowne interakcje przerywające pracę

Ile razy byłeś poirytowanie faktem, że musisz w pięciu mailach wyjaśniać o co chodzi? Ile razy miałeś wrażenie, że banalne tematy ciągną się w nieskończoność, a ty czułeś się jak niezastąpiona jednostka centralna, bez której nic w zespole się nie zadzieje? Oczywiście wszystko kosztem twojej efektywności i nieustannego przerywania własnej pracy. Posłuchaj pewnej historii i naucz się prostej techniki, która wyeliminuje zbędne interakcje.

Praca zdalna – komunikacja na czacie

Jak przenieść codzienne rozmowy z biura do świata online? Co z bezcennymi dyskusjami w kuchni? Najczęściej wrzucamy całą firmę na jakiś komunikator i liczymy, że zadzieje się magia. Nic bardziej mylnego i dziś opowiem ci jak sobie z tym poradzić.

Prześlij komentarz

Twój adres email nie zostanie opublikowany. Pola, których wypełnienie jest wymagane, są oznaczone symbolem *

Pozostań w kontakcie