(prawie) Codzienny wtręt programisty (31-40)
(prawie) Codzienny wtręt programistyczny to seria krótkich wpisów na moich social mediach, gdzie dzieliłem się krótkimi radami i przemyśleniami na temat programowania. W tym artykule znajdziesz spisane treści wpisów o numerach od 31 do 40.
Wstęp
Treści, które tutaj zobaczysz, oryginalnie były publikowane na moich social mediach. Są nieco inne niż tematyka tego bloga: porady dla osób zaczynających pracę w IT oraz rzeczy związane typowo z front-endem i JavaScriptem. Blog z założenia miał być zawsze bardziej ogólny, skupiający się na uniwersalnej wiedzy z zakresu informatyki niezależnie od technologii, wykształcenia i zawodu.
Jeśli chciałbyś/chciałabyś być na bieżąco z podobnymi treściami, zapraszam do obserwowania moich social mediów:
#31 4 sposoby na zaokrąglanie liczb
Wiesz, że klasycznie w językach programowania mamy 4 sposoby na zaokrąglanie liczb zmiennoprzecinkowych do całkowitych? Zobacz kolejne obrazki i dowiedz się, czym każda z tych opcji się różni.
A Ty których najczęściej używasz i dlaczego?
Round — zaokrąglenie do najbliższej wartości
Math.round(2.1); // 2
Math.round(3.7); // 4
Math.round(5.5); // 6
Math.round(-2.1); // -2
Math.round(-3.7); // -4
Math.round(-5.5); // -5
Warto zwrócić uwagę, jak w Twoim języku programowania traktowany jest przypadek piątki po przecinku!
Floor — podłoga; zaokrąglenie w dół
Math.floor(2.1); // 2
Math.floor(3.7); // 3
Math.floor(5.5); // 5
Math.floor(-2.1); // -3
Math.floor(-3.7); // -4
Math.floor(-5.5); // -6
Uwaga: nie jest to obcięcie części dziesiętnej! Zobacz przykłady dla liczb ujemnych.
Ceil — sufit; zaokrąglenie w górę
Math.ceil(2.1); // 3
Math.ceil(3.7); // 4
Math.ceil(5.5); // 6
Math.ceil(-2.1); // -2
Math.ceil(-3.7); // -3
Math.ceil(-5.5); // -5
Truncate — obcięcie części dziesiętnej
Math.trunc(2.1); // 2
Math.trunc(3.7); // 3
Math.trunc(5.5); // 5
Math.trunc(-2.1); // -2
Math.trunc(-3.7); // -3
Math.trunc(-5.5); // -5
#32 Czy umiemy się uczyć?
Mówi się, że praca w IT to ciągły rozwój, potrzeba stałej nauki. Warto jednak zadać sobie pytanie, czy umiemy się uczyć?
Moim zdaniem można zauważyć trzy główne problemy, przez które czy to studiując, czy robiąc kursy, niewiele z tego wynosimy. Sam zresztą miałem okazje przez nie przejść.
Wkuwamy teorię zamiast zrozumieć
- ➡️ Typowo szkolne 3Z: „zakuć, zdać, zapomnieć”.
- ➡️ Faza „zapomnieć” zwykle zachodzi bardzo szybko.
Uczymy się gotowych rozwiązań bez teorii
- ➡️ Szczególnie zauważalne przy tutorialach z Internetu.
- ➡️ Interesuje nas tylko rozwiązanie problemu, a nie jego sedno.
- ➡️ Zapamiętane rozwiązania rzadko można przełożyć na ogólny przypadek.
Uczęszczamy w szkoleniach dla „papierka”
- ➡️ Nie uczestniczymy aktywnie w szkoleniu.
- ➡️ Mimo że kojarzy się z uczelniami wyższymi, to często odnosi się to też do szkoleń branżowych kończących się certyfikatem.
#33 Reszta z dzielenia jest dziwna
O ile dla liczb dodatnich reszta z dzielenia jest niemal zawsze taka sama, to problemy zaczynają się, gdy pojawiają się liczby ujemne. Różne języki implementują inne sposoby jej obliczania, stąd wyniki się różnią i do tego są nie do końca zgodne z matematyczną definicją tego działania.
Zobacz dalej, jakie wyniki operacja ta daje w różnych językach.
Jeśli chcesz wiedzieć, skąd to się bierze, a także jak uzyskać tę matematyczną wersję, zapraszam do lektury: https://swistak.codes/post/dziwny-przypadek-reszty-z-dzielenia/
Dart
void main() {
print('8 mod 5 = ${8 % 5}');
print('-8 mod 5 = ${-8 % 5}');
print('8 mod -5 = ${8 % -5}');
print('-8 mod -5 = ${-8 % -5}');
}
// 8 mod 5 = 3
// -8 mod 5 = 2
// 8 mod -5 = 3
// -8 mod -5 = 2
Python
print(f'8 mod 5 = {8 % 5}')
print(f'-8 mod 5 = {-8 % 5}')
print(f'8 mod -5 = {8 % -5}')
print(f'-8 mod -5 = {-8 % -5}')
# 8 mod 5 = 3
# -8 mod 5 = 2
# 8 mod -5 = -2
# -8 mod -5 = -3
JavaScript
console.log(`8 mod 5 = ${8 % 5}`);
console.log(`-8 mod 5 = ${-8 % 5}`);
console.log(`8 mod -5 = ${8 % -5}`);
console.log(`-8 mod -5 = ${-8 % -5}`);
// 8 mod 5 = 3
// -8 mod 5 = -3
// 8 mod -5 = 3
// -8 mod -5 = -3
#34 Mniej oczywiste korzyści unit testów
W kontekście testów jednostkowych zawsze się mówi, że możemy dzięki nim sprawdzić kod, czy poprawnie się wykonuje. To prawda, ale nie jest to jedyna korzyść, jaką one dają.
Żywa dokumentacja
- ➡️ Dobrze napisane testy spełniają funkcję podobną do dokumentacji.
- ➡️ Patrząc na test, jesteś w stanie lepiej wywnioskować, co autor miał na myśli.
Wymuszają pisanie ładnych funkcji
- ➡️ Nie da się łatwo napisać testów dla funkcji wykonujących wiele rzeczy (łamanie SRP).
- ➡️ Tak samo nie da się łatwo testować funkcji z efektami ubocznymi.
Wymuszają dobre konwencje architektoniczne
- ➡️ Jeśli nie stosuje się odwrócenia zależności, doprowadzenie mocków do działania może zająć więcej miejsca niż testy.
- ➡️ Zmuszają do rozdzielania kodu na mniejsze jednostki, które łatwiej się testuje (np. na front-endzie wydzielenie logiki komponentów na zewnątrz).
#35 Pamiętaj o tym, tworząc nowy projekt JS-owy
Jeśli zakładasz nowy projekt JS-owy, pamiętaj o konfiguracji trzech narzędzi, które sprawią, że kod będzie spójny, czytelny, a także ułatwią Ci sprawdzanie pull requestów.
ESLint
- ➡️ Statyczna analiza kodu.
- ➡️ Umożliwia uwspólnienie stylu kodowania bez ręcznego spisywania zasad.
Prettier
- ➡️ Automatyczne formatowanie kodu.
- ➡️ Zapewnia czytelny i spójny kod pod kątem formatowania.
EditorConfig
- ➡️ Narzuca edytorowi reguły formatowania.
- ➡️ Przydatny tam, gdzie Prettier i ESLint nie potrafią działać, np. na plikach konfiguracyjnych.
Jak z nimi pracować?
- ➡️ Sprawdzanie jako kroki pipeline CI.
- ➡️ Git Hook na pre-commit (np. korzystając z Husky).
- ➡️ Wtyczki do edytorów, aby podświetlały błędy i je automatycznie naprawiały.
#36 Złożoność cyklomatyczna a unit testy
Złożoność cyklomatyczna to jedna z podstawowych metryk wskazujących poziom skomplikowania pisanego przez nas kodu. Co ciekawe, ma ona wpływ na pisanie unit testów. Czytaj dalej, aby dowiedzieć się, w czym rzecz!
Złożoność cyklomatyczna
- ➡️ Liczba mówi, ile różnych ścieżek przejścia kodu jest w danej funkcji.
- ➡️ Im wyższa, tym bardziej skomplikowany jest nasz kod.
- ➡️ Powinniśmy pisać kod tak, aby wartość była jak najniższa
Jak liczyć?
- ➡️ Każde zwrócenie wartości daje złożoność 1.
- ➡️ Każda instrukcja przepływu sterowania (warunki, pętle) zwiększa złożoność o 1.
- ➡️ Możesz stosować wtyczki do edytorów, np. CodeMetrics do VSCode.
Przykład
Co to ma do unit testów?
- ➡️ Zakłada się, że aby funkcję przetestować poprawnie, powinna ona mieć tyle testów, co jej złożoność cyklomatyczna.
- ➡️ Jeśli masz tyle testów, ile wynosi złożoność cyklometryczna, to powinieneś/powinnaś mieć 100% branch coverage.
#37 3 lata świstak.codes
Nietypowo dzisiejszy wtręt jest bardziej o mnie, bo właśnie wybija trzecia rocznica założenia mojego bloga świstak.codes. Na slajdach poniżej kilka faktów z 3 lat istnienia. A jeśli jeszcze nie miałeś(-aś) okazji go poczytać, to zapraszam na https://swistak.codes !
Początki
Blog początkowo był oparty na Wordpressie i wyglądał tak:
Dziś
Dziś jest przeze mnie napisany od zera w Next.js. Przepisanie zajęło mi 3 miesiące i opisałem je w tym artykule:
Jeszcze wcześniej...
Rok przed założeniem świstak.codes publikowałem na Medium:
https://tomasz-swistak.medium.com/
Social media
Początkowo wystartowałem tylko z blogiem. Dziś świstak.codes to też profil na Facebooku i Instagramie.
Kto wie, może niedługo będzie coś więcej?
statystyki na moment oryginalnej publikacji wpisu, czyli 28.04.2023 A teraz trochę statystyk
- ➡️ Na blogu znajdziecie 71 artykułów, kolejny już 10 maja!
- ➡️ Przez ostatni rok bloga odwiedziło ponad 41 tysięcy unikalnych odwiedzających (licząc tylko tych, którzy nie blokują analityki).
- ➡️ W Google zaś linki do bloga były klikane ponad 45 tysięcy razy.
Najczęściej odwiedzany artykuł
Ciekawostka
Nie dziwię się, że jest odwiedzany, bo sam bym nic nie wyciągnął z tego fragmentu 😀
Najrzadziej odwiedzany artykuł 😢
https://swistak.codes/post/jak-komputer-rysuje-okregi/
Dajcie mu trochę miłości i go odwiedźcie!
Jeszcze na koniec...
Zapraszam do regularnych odwiedzin!
Nowe artykuły wrzucam co 2 tygodnie.
#38 Programowanie z AI
Wielu pokazuje, jak wspomagać się w pracy programistycznej ChatGPT. Ja jednak chciałem Ci przedstawić inne narzędzie: www.phind.com.
Zobacz kolejne obrazki, gdzie opisuję, co to za narzędzie, i pokazuję przykłady, jak działa.
Co to jest phind.com?
- ➡️ Wyszukiwarka dla programistów operująca językiem naturalnym.
- ➡️ Oparta na GPT-4.
- ➡️ Pisze rozbudowane odpowiedzi z odnośnikami do źrodeł (StackOverflow, blogi programistyczne, dokumentacje).
- ➡️ Łączy wiedzę z różnych źródeł, dając unikalne wyjaśnienia.
A co możemy w nim zrobić? Zobacz dalej przykłady ⏭️
Implementacje algorytmów wraz z wyjaśnieniami
Dokumentacja funkcji
Przykłady użycia bibliotek
Ciekawe pomysły
Nawet potrafi pisać muzykę
(tak naprawdę to nie umie 😀)
I nie ogranicza się tylko do tematów technicznych
#39 Usuwanie domyślnych stylów
Pracując na frontendzie, prawie zawsze trafiamy na problem, gdzie napisaliśmy bardzo ładnego CSS-a, ale nie działa on tak, jakbyśmy tego chcieli, bo przeglądarka narzuca własne style.
Jeśli chcesz poznać dwa sposoby na usunięcie domyślnych stylów, czytaj dalej.
Gotowe stylesheety resetujące wszystko
- ➡️ Reset CSS (https://meyerweb.com/eric/tools/css/reset/)
- ➡️ Normalize.css (https://necolas.github.io/normalize.css/)
- ➡️ modern-css-reset (https://www.npmjs.com/package/modern-css-reset)
Usunięcie stylów pojedynczego elementu:
element {
all: unset;
}
Przykład
#40 Powtarzanie kodu w testach jest OK
Często się mówi, że powinniśmy nie powtarzać kodu, unikać robienia kopiuj-wklej. Zamiast tego powinniśmy uwspólniać jak najwięcej kodu. Zgoda, ale nie zawsze powinniśmy.
Przeczytaj dalej, dlaczego w przypadku testów warto czasem powielić kod.
Ta sama akcja, ale testujemy coś innego
- ➡️ Testując, nieraz mamy sytuację, że wywołanie funkcji jest takie samo, tylko przyjmuje inne dane. Nawet asercja może wyglądać tak samo.
- ➡️ Jednak inne dane mogą oznaczać zupełnie inny przypadek, który powinniśmy inaczej opisać.
- ➡️ Pamiętaj: testy mają funkcję dokumentacji. Najpierw opisz wszystkie przypadki, a potem napisz do nich kod. Nawet duplikujący się, to nie jest nic złego!
Przykład
- ➡️ Mamy funkcję konwertującą kolor do wspólnego formatu:
normalizeColor(color: string): string
. - ➡️ Niezależnie od tego, w którym formacie kolor zostanie podany na wejściu, wyjście powinno zawsze zwrócić ten sam format (załóżmy, że hex zapisany dużymi literami).
- ➡️ Zakładamy, że jeśli nie potrafi przekonwertować formatu (nieobsługiwany lub błędne wejście), zwracamy to samo, co było na wejściu.
Moglibyśmy wszystko zamknąć w jednym teście
it.each`
color | expected
${'#b4cd12'} | ${'#B4CD12'}
${'#b4c'} | ${'#B4C'}
${'rgb(255,0,0)'} | ${'#F00'}
${'hsl(68 73% 60%)'} | ${'#D0E34F'}
${'aquamarine'} | ${'aquamarine'}
`('should normalize colors', ({ color, expected }) => {
expect(normalizeColorValue(color)).toEqual(expected);
});
Ale lepiej będzie podać konkretne przypadki:
it.each`
color | expected
${'#b4cd12'} | ${'#B4CD12'}
${'#b4c'} | ${'#B4C'}
`('should uppercase hex colors', ({ color, expected }) => {
expect(normalizeColorValue(color)).toEqual(expected);
});
it.each`
color | expected
${'rgb(255,0,0)'} | ${'#F00'}
`('should convert rgb to uppercased hex', ({ color, expected }) => {
expect(normalizeColorValue(color)).toEqual(expected);
});
it.each`
color | expected
${'hsl(68 73% 60%)'} | ${'#D0E34F'}
`('should convert hsl to uppercased hex', ({ color, expected }) => {
expect(normalizeColorValue(color)).toEqual(expected);
});
it.each`
color | expected
${'aquamarine'} | ${'aquamarine'}
`('should return the same if not supported', ({ color, expected }) => {
expect(normalizeColorValue(color)).toEqual(expected);
});
Dlaczego tak?
- ➡️ Dokumentujemy funkcję: pokazujemy wprost, co ona obsługuje.
- ➡️ Dodatkowo wyszczególniamy konkretnie, co robi.
- ➡️ Wyraźnie wskazujemy nieobsługiwane przypadki.
- ➡️ W przypadku regresji łatwiej jest wskazać, który przypadek przestał działać.
Koniecznie polub świstak.codes na Facebooku, obserwuj na Instagramie, LinkedIn lub zasubskrybuj mój kanał RSS!
Możesz też wesprzeć moją działalność klikajac link poniżej: