Jeszcze jeden blog o programowaniu

Radosne twórczości leniwego programisty

Archive for the ‘Rozwiązania’ Category

Jak odzyskać trochę czasu dzięki porządkom w telefonie

leave a comment »

Nie tak dawno temu zdarzyło mi się wysłuchać krótkiego podcastu od Developer Tea w którym to autor – Jonathan Cutrell – przedstawia bardzo prostą metodę na odzyskanie drobnych porcji czasu poprzez wprowadzenie niewielkich zmian w telefonie (i w sumie w każdym używanym intensywnie urządzeniu).

Trzeba mieć świadomość jednak, że nie sprawi to nagle, że przybędzie nam 5 godzin do całej doby do wykorzystania na inne aktywności, ale jak to ma miejsce w przypadku wielu takich małych optymalizacji – ich połączenie może być już całkiem zauważalne – nie tylko z punktu widzenia oszczędności czasu ale i naszego samopoczucia.

Wbrew pozorom nie chodzi o tak banalne i oczywiste rady jak: odinstaluj gry, odinstaluj aplikacje społecznościowe oraz wyłącz wszelkie powiadomienia.

Ta prosta zmiana zamyka się w reorganizacji ikon aplikacji, z których korzystamy najczęściej.

Zazwyczaj po odblokowaniu telefonu na ekranie główny miałem: zdjęcie syna w centrum ekranu, widget zegara w górnej części ekranu i dookoła katalogi tematyczne: Finanse, Nauka, Google, …
Ogólnie, gdy potrzebowałem coś zrobić, to najczęściej wymagało to najpierw przypomnienia sobie lokalizacji katalogu na ekranie, otwarcie go – ponownie, zlokalizowanie konkretnej aplikacji i dopiero jej uruchomienie. O ile w katalogu „Finanse” było tylko kilka aplikacji (aplikacja banku, PayPal, moBILET, Monefy) to inne katalogi wymagały nierzadko przewijania.
Ogólnie pole do popisu było spore.

I tak: wszystkie katalogi zostały delikatnie mówiąc zaorane. Pozostały jedynie 2 katalogi w dolnej części ekranu i 2 przyciski – okrojone tylko do aplikacji używanych przeze mnie codziennie. Jak czegoś potrzebowałem raz w tygodniu po prostu wylatywało.

W tej chwili wygląda to i używa się tego dużo lepiej.
Od lewej jest to przycisk Połączenia. Wcześniej trzymałem tutaj katalog z Połączeniem, Wiadomościami i Kontaktami – ale zauważyłem, że tych ostatnich nie używam wystarczająco często.
Następnie jest przycisk wyświetlania wszystkich zainstalowanych aplikacji.
Później katalog z aplikacjami Aparat i Galeria – podejrzewam, że też mógłby wylecieć, ale jeszcze nie zdecydowałem.
Na szarym końcu – najbliżej kciuka – katalog z najczęściej używanymi aplikacjami – oczywiście jeszcze odpowiednio posortowany: Chrome, Podcast Addict, Todoist, aplikacja banku, eReader Prestigio, Business Calendar i kilka innych – w tym komunikatory.

Katalogi i aplikacje są przypięte na dole, więc widoczne są na każdym ekranie – nie tylko startowym. Drugi ekran to tylko 2 widgety: aktualna lista z Todoist i Brain Focus (do techniki pomodoro) i wspomniana wcześniej przypięta u dołu ekranu lista.

Spotkałem się też z opinią, że przeglądarka to także aplikacja rozpraszająca – źródło, więc można także rozważyć jej usunięcie z szybkiego dostępu.

Przy okazji różnych poszukiwań znalazłem przyjemny dla oka (po instalacji odpowiednich motywów i niewielkiej konfiguracji) i szybki CM Launcher.

Cały odcinek podcastu do odsłuchania (7 minut): One Super Simple Tactic to Regain Your Time

Written by Filip Górczyński

2018.05.28 at 13:26:48

PyCharm – jedna konfiguracja na wielu instancjach

leave a comment »

Ponownie chciałbym pochwalić PyCharma – w sumie to wszystkie IDE od JetBrains.

Otóż narzędzie to pozwala nam na współdzielenie naszej ulubionej konfiguracji środowiska pomiędzy różnymi instancjami – jeśli używamy tego IDE w pracy i w domu to warto z tego skorzystać.
Oczywiście ma to też ten plus, że w przypadku kradzieży/zniszczenia możemy w całkiem prosty sposób odzyskać poprzednią konfigurację.

A sprawa jest całkiem prosta:

  1. Zakładamy nowe repozytorium, np. w serwisie GitHub (tak, może być też GitLab albo jakiekolwiek inne – ja lubię GitHub)
  2. W PyCharm wybieramy kolejno File > Settings Repository i ustawiamy konkretny Upstream URL na adres repozytorium
  3. Nadpisujemy zdalne (Overwrite Remote)
  4. To samo robimy na pozostałych instancjach nadpisując ustawienia lokalne (Overwrite Local)

Gdy już mamy zsynchronizowane, każda zmiana powinna być automatycznie pobierana z i wysyłana do repozytorium – jednak opcja Merge też w niektórych sytuacjach może się przydać 🙂

Written by Filip Górczyński

2018.04.20 at 15:44:06

Wąż w stringach

leave a comment »

Jednym z pierwszych typów danych o których uczymy się w ramach najróżniejszych kursów programowania jest typ łańcuchowy – często określany jako string. Nie bez powodu jest to jeden z najczęściej używanych w programowaniu typów. A dlaczego? Ponieważ jako ludzie głównie działamy na tekście: czytamy książki, piszemy listy, ostrzegamy o wysokim napięciu, opisujemy substancje chemiczne, gryzmolimy tagi na rozkładach jazdy (kto wracał komunikacją nocną i nie mógł odczytać rozkładu przez głupie tagi wie, że tego typu teksty są najmniej lubiane) – w dużym skrócie – tekstu używamy wszędzie.

Oczywiście ma to swoje konsekwencje -w programowaniu wykorzystujemy tekst aby wyświetlić cokolwiek na ekranie, do logowania aktualnego stanu aplikacji, gdy prosimy użytkownika o podanie informacji, przesyłamy informacje przez sieć.

Łańcuch znaków jest po prostu kolekcją… znaków. Mogą to być zarówno znaki drukowalne, jak np. litery alfabetu, cyfry czy znaki interpunkcyjne lub niedrukowalne – znaki o specjalnym znaczeniu – spacje, tabulacje, „dzwonek systemowy”.
Stringi mogą mieć długość od zera do… prawie rozmiaru pamięci zainstalowanej w komputerze. Oczywiście, mają tutaj jeszcze ogromne znaczenie inne czynniki – np. wersja Pythona czy architektura komputera, jednak dla codziennych zastosowań nie powinniśmy się tym aż tak bardzo przejmować. Gdybyśmy jednak chcieli zrobić kopię zapasową Internetu możemy w pewnym momencie zderzyć się z błędem MemoryError.

Długość (między innymi) łańcuchów określa się wbudowaną w Pythona funkcją len jednak należy mieć na uwadze, że ilość znaków, którą widzimy to nie zawsze rzeczywista długość łańcucha trzymana w pamięci. Posiłkując się StackOverflow:

Dla Pythona 2 wyniki są jeszcze bardziej zaskakujące (w odpowiedzi na StackOverflow został właśnie użyty Python 2).

Stringi w Pythonie możemy zapisywać w kodzie na kilka różnych sposobów:

Jednak wyświetlanie na ekranie prostych łańcuchów znaków może w pewnym momencie stać się dość nudne – na szczęście wynaleziono interpolację.

Interpolacja to wg Słownika Języka Polskiego: „wstawienie wyrazów, zwrotów, zdań do pierwotnego tekstu; też: takie wstawione wyrazy, zwroty, zdania”.
W naszej sytuacji chodzi o podstawienie wartości ze zmiennych w konkretne miejsca w łańcuchu znaków.
Przykładowo jeśli posiadamy szablon z informacją o uczniu i jego ocenie: "Cześć {imię i nazwisko ucznia}. Uzyskałeś {ilość punktów} punktów z egzaminu." to każde nasze wystąpienie {coś tam} będziemy mogli podmienić konkretnymi wartościami.
Do uzyskania konkretnego łańcucha znaków – z już podmienionymi wartościami możemy podejść (ponownie) na kilka sposobów – lepszych lub gorszych.
I tak na przykład, jednym z nich – niezbyt fajnym ani wygodnym – będzie po prostu łączenie łańcuchów znaków:

Nie da się chyba tego lubić. Przy okazji warto zwrócić uwagę, że pamiętać musimy o rzutowaniu na odpowiedni typ funkcją str albo zderzymy się z błędem TypeError.

Inny ciekawy (dla masochistów) sposób, to zapisanie wszystkiego jako lista i jej połączenie pustym łańcuchem:

Kod tak wspaniały, że aż oczy bolą… No dobra, są sytuacje, gdzie podobne podejście będzie akceptowalne, całkiem zwięzłe i czytelne… ale to nie jest ten przypadek.

Zmierzamy powoli w kierunku lepszego jutra – rozwiązanie dość popularne jeszcze do niedawna:

Plusem tego sposobu interpolowania łańcucha jest to, że korzysta on z wielu dostępnych specyfikatorów formatowania – co pozwala nam z kolei przyoszczędzić na jawnym konwertowaniu wartości zmiennych na łańcuchowy typ danych – musimy jednak zadbać o odpowiedni specyfikator w stringu.

Pierwszy z zalecanych (moim zdaniem) sposobów interpolowania to wykorzystanie metody format obiektu string:

Sposób ten jest tak fajny, że aż dorobił się własnej strony internetowej z najróżniejszymi przykładami.

Drugim zalecanym (znów, moim zdaniem) sposobem jest użycie tzw f-stringów – dostępnych niestety dopiero od Pythona 3.6:

Jeszcze innym sposobem interpolowania o którym warto wspomnieć jest użycie klasy Template z modułu string:

jednak nie spotykałem się z nim zbyt często – warto jednak wiedzieć, że coś takiego jest.

Więcej o samej interpolacji w Pythonie poczytać możemy w oficjalnych dokumentach PEP-0215PEP-0498, PEP-0501 oraz PEP-0502.

Dodatkowo, sam łańcuch znaków jako obiekt ma całkiem sporo metod pozwalających operować na danym łańcuchu, przytaczając kilka takich metod:

UWAGA: Wywołanie takiej metody na stringu nie powoduje jej zmiany w pamięci.

I tym oto sposobem przechodzimy do faktu, że łańcuchy znaków są niezmiennym typem danych (tzw. immutable). Cool. I co to znaczy?
W dużym skrócie chodzi o to, że jeśli zmienimy łańcuch znaków to zmieni się jego lokalizacja w pamięci – zostanie utworzony nowy, zmodyfikowany obiekt. Najlepiej zaobserwujemy to na przykładzie:

Dla wygody skorzystałem z wbudowanych funkcji hex i id.

Na koniec warto wspomnieć o dostarczanym ze standardową biblioteką Pythona modułem string, który głównie może okazać się przydatny jeśli będziemy potrzebowali kolekcji znaków: małych lub dużych liter, cyfr (także ósemkowych lub szesnastkowych) czy białych znaków, itp.

Dodatkowe źródła:
[1] A string of unexpected lengths
[2] Moduł string

Written by Filip Górczyński

2018.04.20 at 13:26:43

GitHub – szablony dla Issue i Pull Request

leave a comment »

Ciekawą funkcją GitHuba – szczególnie przydatną w przypadku wieloosobowych zespołów są szablony dla nowo tworzonych Pull Requestów lub Issue.

Jeśli zależy nam na fajnej kulturze pracy z kodem możemy sobie takie szablony zaaplikować w swoich repozytoriach i na szczęście nie jest to skomplikowane i kończy się w momencie utworzenia plików o odpowiednich nazwach: issue_template.md oraz pull_request_template.md, na przykład w katalogu .github, który także tworzymy w naszym projekcie.

Jak widać po rozszerzeniu, pliki te to po prostu najzwyklejsze dokumenty Markdown, więc w ich treść można wrzucić wszystko, co Markdown jest w stanie obsłużyć: nagłówki, pogrubienie tekstu, kursywę, dowolne typy list, kawałki kodu czy co najfajniejsze – pola do zaznaczenia.

Prosty Issue Template:

oraz Pull Request Template:

W przypadku automatyzacji Pull Requestów można nasz szablon rozdzielić na kilka różnych plików i przekazując odpowiednie parametry w adresie – sterować wybieranym szablonem. Szczegóły można znaleźć na w dokumentacji GitHub.

Więcej przykładów oraz informacji znaleźć można w następujących repozytoriach: github-issue-templatesawesome-github-templates.

 

Written by Filip Górczyński

2018.03.12 at 17:04:18

Narzędzia do statycznej analizy kodu źródłowego w PyCharm

leave a comment »

Kilkukrotnie wspominałem już o IDE PyCharm i jego możliwościach. Oprócz kolorowania składni i obsługi kilku innych głupotek pozwala na przykład definiować narzędzia, które później możemy uruchamiać w trakcie pisania kodu.

Jako programiści Pythona możemy do tych narzędzi zaliczyć te dbające o jakość pisanego przez nas kodu. Oprócz standardowego PEP8 – który jest tylko czubkiem góry lodowej – osobiście chciałbym polecić także: flake8, pylint oraz radon.

flake8 jako linter sprawdza kod pod kątem zgodności ze standardami – dodatkowo rozszerza wspomniany przed chwilą PEP8 o kilka innych wartościowych usprawnień, np. takie związane z komentarzami, nazewnictwem zmiennych, itp.

Podobnie ma się sytuacja z pylint-em, jednak jego zaletą jest ocena naszego kodu z użyciem skali – każda zmiana może wpływać pozytywnie lub negatywnie zgodnie z następującym wzorem. Satysfakcją jest uzyskać ocenę 10.00/10.00 :). Oprócz oceny liczbowej otrzymujemy także zestawienie i najróżniejsze statystyki.

radon natomiast w całkiem przyjemny sposób prezentuje nam informacje na temat złożoności fragmentów naszego kodu – może nam się wtedy zapalić czerwona lampka, że pewne elementy powstałego kodu mogą potencjalnie stanowić wąskie gardło w aplikacji i są dobrym miejscem zaczepienia jeśli chodzi o refaktoryzację.

Zainstalujmy więc sobie narzędzia w czystym środowisku wirtualnym:

flake8 zostanie zainstalowany jako zależność podczas instalacji radon-a.

Klikamy „+” aby dodać nowe narzędzie. W otwartym okienku uzupełniamy jak poniżej:

Oczywiście dobrym pomysłem jest także grupowanie naszych narzędzi, np. ze względu na technologię oraz konfiguracja skrótów klawiaturowych:

Poniżej kilka zrzutów po uruchomieniu:

  • flake8:

  • pylint

  • radon

Więcej doczytać można w następujących źródłach:

  1. About style guide of python and linter tool. pep8, pyflakes, flake8, haking, Pylint.
  2. What is Flake8 and why we should use it?

Written by Filip Górczyński

2018.03.07 at 18:06:39

Sortowanie po wirtualnej kolumnie w Django

leave a comment »

Nie tak dawno temu w ramach jednego z zadań w Django było uporządkowanie wyników wg innego klucza niż najprostsze ORDER BY. Chodziło o nadanie pewnego rodzaju wag dla wierszy, które możliwie najlepiej wpasowały się w poniższe kryteria:

  • pierwszeństwo miały wiersze, które zawierały dokładne dopasowanie szukanej frazy
  • następnie wiersze, które od szukanej frazy się zaczynały
  • kolejno wiersze, które na podaną frazę się kończyły
  • kończąc wierszami, które podaną frazę zawierały w dowolnym miejscu
  • opcjonalnie pozostałe wiersze, jeśli query nie było jedynym kryterium filtrowania.

Przydatny okazał się poniższy kawałek kodu tworzący nieistniejącą w modelu CaseWhen columnę exact w postaci nowych warunków w obiekcie QuerySet  – po której następnie sortował:

Dodatkowe porządkowanie wg kolumny name służy do alfabetycznego uporządkowania wierszy, którym została nadana ta sama waga.

Jeśli nie zostanie przekazana fraza do szukania (parametr q) używana jest fraza beer. Żeby mieć pogląd jakie rzeczywiście wyniki są zwracane – w migracji aplikacji casewhen dodaję kilka wierszy do bazy.

Rozwiązanie zostało wdrożone w ramach integracji z Django REST Framework, ale chodzi tylko o zasadę działania, więc kod można wykorzystać także bez DRF.

Oczywiście całość do przejrzenia bezpośrednio na GitHub.

Written by Filip Górczyński

2018.03.07 at 17:14:26

Wykonanie kodu przy starcie aplikacji w Django

leave a comment »

Wielokrotnie zdarzyło mi się (i pewnie nie tylko mi) musieć uzupełnić jakimiś wartościami bazę danych w trakcie zmian w projekcie. Chodziło konkretnie o dane, które powinny się pojawić po wdrożeniu zmian i nie powinny dawać możliwości ich zmiany bądź usunięcia ze względu na potencjalny wpływ na działanie całej aplikacji.

Pierwszy pomysł tego rozwiązania to użycie migracji, jak w poniższym przykładzie:

Po wykonaniu migracji w bazie pojawią nam się wymagane wpisy. Jednak istotnym minusem tego rozwiązania jest to, że nadal można usunąć je bezpośrednio w bazie czy nawet w panelu administracyjnym Django i nie zostaną one odtworzone.

Kolejne podejście do problemu to przeniesienie kodu odpowiedzialnego za dodawanie wpisów do bazy do pliku apps.py, który uruchamiany jest przy starcie aplikacji – czyli praktycznie zawsze po restarcie serwera. Wrzucenie kodu do metody ready pozwoli nam obejść w całkiem elegancki sposób wspomniany wcześniej problem:

Na co zwrócić musimy uwagę, w pliku __init__.py naszej aplikacji musimy jawnie wskazać ścieżkę do pliku konfiguracyjnego aplikacji, jako że plik ten jest opcjonalny:

Warto także zerknąć na kilka innych kawałków kodu, m. in. uniemożliwienie edytowania kluczowych informacji w panelu administracyjnym Django czy usuwanie tych danych. Zauważyć też można 2 drobne usprawnienia: 1) wizualna reprezentacja zapisanego koloru w panelu administracyjnym dzięki użyciu funkcji format_html oraz 2) zmiana tytułu kolumny w panelu administracyjnym poprzez właściwość short_description.

Kawałek kodu związany z synchronizacją modeli z bazą danych został zaczerpnięty ze StackOverflow, a błąd dotyczący braku synchronizacji ujawnił się dopiero przy uruchomieniu testów.

Cały kod do pobrania i przejrzenia znaleźć można na GitHub.

Written by Filip Górczyński

2018.03.05 at 09:11:29

%d blogerów lubi to: