Dobry kod oraz jego powstawanie

D1
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 99
0

Witam

Zamieszczam post ponieważ nie jestem pewien czy we właściwy sposób myślę o tworzeniu naprawdę dobrego kodu. Mamy fazę początkową w której kod tworzymy np od 0 , a w kolejnej fazie rozwiązujemy problemy kompilatora z bugami lub niewłaściwy działaniem mimo iż program startuje.
Później kiedy mamy dobrą podstawę możemy kod refaktoryzować i liczyć że skrócimy go o 50%. Następnie optymalizujemy go oszczędzając kolejne sekundy przetwarzania go przez procesor, a zwieńczeniem wszystkiego będzie testowania.
Chyba, że kolejność pomyliłem.
Zdaje sobie sprawę, że praca nad kodem to nie tylko produkcja nowych linijek i poczucie satysfakcji, że byłem dziś naprawdę wydajny ;)

Charles_Ray
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 1907
2

Najpierw masa, potem rzeźba (szczególnie w dobie Claude Code).

B1
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 487
4

To zależy, jak program jest większy to bym nie dążył do tego żeby go móc wystartować, a potem dopiero refactoryzować, tylko bym zrobił jakieś TDD i po kawałku pisał już dobry kod.

KL
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 604
2

We właściwy i tak było zawsze. Lepiej zrobić rozwiązanie wystarczająco dobre, ale działające niż poświęcać 2 czy 3 razy więcej czasu w imię upiększania kodu, który później dla innych może się i tak nie okazać taki piękny jak myślałeś 😉

Poza tym, wymagania często się zmieniają i później nagle się okazuje że trzeba przeorać ten kod.

elwis
  • Rejestracja: dni
  • Ostatnio: dni
1

Kilka zastrzeżeń. Przede wszystkim, to co opisałeś to jedna iteracja skupiona na jednej małej cesze. Bo, jeśli zakładasz, że napiszesz więcej w jednym takim cyklu to twój trud rośnie wykładniczo. Po drugie, optymalizacja pod kontem wydajności tylko w razie wyraźnej potrzeby, pomiaru czasu i ustalonych parametrów docelowych. Po trzecie, jeśli projekt jest nastawiony na prototypowanie, to refactor też może się nie opłacać, jeśli niedługo i tak będzie trzeba przepisać na czysto.

Riddle
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 10227
2
delform_17 napisał(a):

Witam

Zamieszczam post ponieważ nie jestem pewien czy we właściwy sposób myślę o tworzeniu naprawdę dobrego kodu. Mamy fazę początkową w której kod tworzymy np od 0 , a w kolejnej fazie rozwiązujemy problemy kompilatora z bugami lub niewłaściwy działaniem mimo iż program startuje.
Później kiedy mamy dobrą podstawę możemy kod refaktoryzować i liczyć że skrócimy go o 50%. Następnie optymalizujemy go oszczędzając kolejne sekundy przetwarzania go przez procesor, a zwieńczeniem wszystkiego będzie testowania.
Chyba, że kolejność pomyliłem.
Zdaje sobie sprawę, że praca nad kodem to nie tylko produkcja nowych linijek i poczucie satysfakcji, że byłem dziś naprawdę wydajny ;)

Powiedziałeś o samych mechanistycznych krokach, a całkowicie pominąłeś wszystkie rzeczy które są "niewidziane", a mimo to mają duży wpływ na jakość oprogramowania.

To co jednoznacznie wpływa na jakość aplikacji, to jest to w jaki sposób programista myśli o aplikacji. Czy pisze ją na dowal się, czy faktycznie przechodzi jakiś proces myślowy nt tego co pisze. Czy dostaje feedback w odpowiednio krótkim czasie, oraz czy reaguje na to w odpowiedni sposób. To czy stara się w odpowiedni sposób zaprojektować cały system. To czy nie podejmuje niepotrzebnych decyzji na starcie, czyli wtedy kiedy wie o aplikacji najmniej. Czy pracuje w małych krokach.

Jeśli pracujesz w małych krokach, zbierasz feedback bardzo szybko (sekundy), i wkładasz głowę i mózg w projektowanie systemu, to zyskasz lepszej jakości system, niż jak tego nie robisz.

SL
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 1017
3

Dobry kod to kod, który spełnia swoją funkcję:

  • robi to co ma robić
  • jest napisany szybko
  • jest prosty/trudny do zrozumienia
  • jest wydajny
  • spełnia normy np. bezpieczeństwa
  • ma testy
  • jest rozszerzalny w generalnym kontekście (np. nie zawiera wrednych copy-past)
  • jest rozszerzalny w przewidywanym przez nas kontekście (np. przewidywana abstrakcja, która ułatwi dalszy rozwój)

Mógłbym wypisać jeszcze wiele innych cech. Tak czy owak wniosek jest taki, że nie da się spełnić tego wszystkiego. Przykładowo:

  • wydajny kod wymaga nakładu czasowego i obniża wynik innych cech np. bezpieczeństwo albo rozszerzalność
  • kod z testami testującymi zachowanie, gdzie jest duża szansa, że kod pójdzie do całkowitej zmiany (bo np. eksperymentujemy albo piszemy jednorazowy kod) to często strata czasu
  • zrobienie czegoś dobrze to zazwyczaj narzut czasowy. Możliwe, że w konkretnej sytuacji lepiej skupić się na czymś innym
  • abstrakcja pod konkretny przewidywany rozwój kodu może utrudniać rzeczywisty rozwój, jeśli dokonamy złego wyboru
  • kod bez testów ciężko modyfikować np. żeby bardziej go zoptymalizować albo rozszerzyć logikę lub ją naprawić

Nie ma innej opcji niż posiadanie głębokiej wiedzy teoretycznej i praktycznej, myślenie nad alternatywami i dobre zdefiniowane co cenimy sobie bardziej i na czym zamierzamy się skupić bardziej a na czym mniej.

Na pewno dobrą radą jest takie pisanie kodu, żeby każda kolejna iteracja dawała nam nową wiedzę na temat przyszłego rozwoju. Zamiast przesadnie optymalizować kod warto wybrać wariant najbardziej pasujący do przewidywanych wymagań i pisać logikę w czysty sposób, która jest często większym problemem.

Miang
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 1787
2
delform_17 napisał(a):

Witam

Zamieszczam post ponieważ nie jestem pewien czy we właściwy sposób myślę o tworzeniu naprawdę dobrego kodu. Mamy fazę początkową w której kod tworzymy np od 0 , a w kolejnej fazie rozwiązujemy problemy kompilatora z bugami lub niewłaściwy działaniem mimo iż program startuje.
Później kiedy mamy dobrą podstawę możemy kod refaktoryzować i liczyć że skrócimy go o 50%. Następnie optymalizujemy go oszczędzając kolejne sekundy przetwarzania go przez procesor, a zwieńczeniem wszystkiego będzie testowania.

Myślisz o tworzeniu kodu a nie programu? Taka sztuka dla sztuki?
Piszemy od początku dobrze opierając się na swoim doświadczeniu z pisania innych programów
Jak mamy dobrą podstawę to nie robimy obfuskacji którą określasz mianem refaktoryzacji.
Kod ma być łatwy do czytania, łatwy do rozszerzania przez innych programistów.
Nie służy do pokazywania co się ostatnio nauczyłeś
Oszczędzanie sekund to już w ogóle kompletna głupota, zwłaszcza że na innym procesorze/systemie możesz tymi zmianami dołożyć do czasu wykonania

Chyba, że kolejność pomyliłem.
Zdaje sobie sprawę, że praca nad kodem to nie tylko produkcja nowych linijek i poczucie satysfakcji, że byłem dziś naprawdę wydajny ;)

może poszukaj poczucia satysfakcji w tym ze piszesz poprawnie a nie szybko
24 Polecam wszystkim książkę Ho...

somekind
  • Rejestracja: dni
  • Ostatnio: dni
  • Lokalizacja: Wrocław
3
delform_17 napisał(a):

Witam

Zamieszczam post ponieważ nie jestem pewien czy we właściwy sposób myślę o tworzeniu naprawdę dobrego kodu. Mamy fazę początkową w której kod tworzymy np od 0 , a w kolejnej fazie rozwiązujemy problemy kompilatora z bugami lub niewłaściwy działaniem mimo iż program startuje.
Później kiedy mamy dobrą podstawę możemy kod refaktoryzować i liczyć że skrócimy go o 50%. Następnie optymalizujemy go oszczędzając kolejne sekundy przetwarzania go przez procesor, a zwieńczeniem wszystkiego będzie testowania.
Chyba, że kolejność pomyliłem.
Zdaje sobie sprawę, że praca nad kodem to nie tylko produkcja nowych linijek i poczucie satysfakcji, że byłem dziś naprawdę wydajny ;)

Dlaczego refaktoryzować dopiero co napisany kod?
Coś w trakcie musiało pójść nie tak, skoro już wymaga refaktoryzacji.

SL
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 1017
1

Coś w trakcie musiało pójść nie tak, skoro już wymaga refaktoryzacji.

@somekind w każdej pracy kreatywnej jest rozjad pomiędzy zrobię X, bo to będzie najlepsze a coś mi się w ostatecznym wyniku nie podoba, zmieńmy to

Odnosząc to do innej dziedziny. Taki Mozart był znany z tego, że potrafił pisać swoje utwory bez najmniejszej poprawki z głowy, gdzie po szkicach Beethovena widać jego agonię w procesie twórczym przy ogromnej ilości różnych szkiców i eksperymentów. Jedna i druga metoda jest dobra, bo jedyne co się liczy to wynik końcowy

elwis
  • Rejestracja: dni
  • Ostatnio: dni
2
somekind napisał(a):

Dlaczego refaktoryzować dopiero co napisany kod?
Coś w trakcie musiało pójść nie tak, skoro już wymaga refaktoryzacji.

O ile Twoje zadanie wymaga odrobiny kreatywności (co innego jeśli robisz kolejnego CRUDa będąc seniorem), napisanie od razu dobrego kodu jest mało prawdopodobne (chyba, że jesteś geniuszem). Zwykle uczymy się problemu w trakcie prób rozwiązywania go. Byłoby bez sensu pisać 100% ładny kod gdy tylko rozpatrujemy nową możliwość. A kiedy wreszcie zadziała dobrze, zwykle kod wymaga choćby kosmetycznych poprawek.

KR
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 2518
2

Nie szalałbym też z TDD w trakcie częstych zmian produktu bo dojście do sensownego rozwiązania zajmie Ci mega dużo czasu. Zrób najpierw MVP (minimum value product) i testuj tylko end to end i fragmenty które na 100% zostawisz a muszą działać poprawnie lub są łatwe do skaszanienia - dopiero mając MVP TDD ma dużo więcej sensu. Ale też nie deklaruj managerowi że skończyłeś mając prototyp - poczekaj aż skończysz testy bo zostaniesz bez testów i zaczniesz nad nową rzeczą pracować :D

Riddle
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 10227
1
krwq napisał(a):

Nie szalałbym też z TDD w trakcie częstych zmian produktu bo dojście do sensownego rozwiązania zajmie Ci mega dużo czasu. Zrób najpierw MVP (minimum value product) i testuj tylko end to end i fragmenty które na 100% zostawisz a muszą działać poprawnie lub są łatwe do skaszanienia - dopiero mając MVP TDD ma dużo więcej sensu. Ale też nie deklaruj managerowi że skończyłeś mając prototyp - poczekaj aż skończysz testy bo zostaniesz bez testów i zaczniesz nad nową rzeczą pracować :D

A jak bez TDD wprowadzasz częste zmiany, to nie zepsujesz przypadkiem czegoś? I naprawianie tego zajmie i tak więcej czasu, niż napisanie testów wcześniej? Właśnie prędzej bym skipnął TDD jak nie ma zmian. Wtedy możesz napisać i zostawić.

elwis
  • Rejestracja: dni
  • Ostatnio: dni
1

Zdecydowanie testy warto mieć. Jakiś bardzo duży odsetek pokrycia nie jest konieczny, ale tam gdzie jest logika, która może umknąć podczas pracy z programem warto mieć. Za często się zdarza, że jakaś zmiana wysypuje działanie kodu w niespodziewanym miejscu. Wprawdzie to jak kod nabierze złożoności, ale lepiej zacząć od początku, bo potem dorabianie testów do dużej ilości kodu to nic przyjemnego. Zwłaszcza jeśli nie jest się na świeżo z logiką działania. Umarłbym ze stresu w pracy bez testów. A taka odpalam sobie testy kilka razy dziennie i zmiany też weryfikuję testami i potem śpię spokojnie. :)

CZ
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 2536
1

Kod jest dobry kiedy klient go kupi, produkt można dowolnie skalować i świeżo zatrudniony stażysta/hindus jest w stanie go zrozumieć i naprawić buga.

Inne gówna nie mają znaczenia. Szkoda tracić czasu na takie spowalniacze jak TDD czy scrum. Możesz sobie nazywać zmienne "twoja stara", albo rysować szlaczki. Nikogo to nie obchodzi, jedynie polskich/ukraińskich/rosyjskich programistów co walą sobie do tego czy jakiś tam if jest zagnieżdżony czy nie.

Radziłbym się nie przejmować tylko dodawać nowości, żeby utrzymać się na rynku.

KamilAdam
  • Rejestracja: dni
  • Ostatnio: dni
  • Lokalizacja: Silesia/Marki
  • Postów: 5545
0
Czitels napisał(a):

Kod jest dobry kiedy (...) świeżo zatrudniony stażysta/hindus jest w stanie go zrozumieć i naprawić buga.

(...) Możesz sobie nazywać zmienne "twoja stara",

Ale naprawdę łatwo naprawia ci się bugi w cudzym kodzie gdzie zmienne to "twoja stara"? ja pamiętam jak poprzednim projekcie mnie spowolniło że czasem w kodzie był client a czasem subclient. bo client w ui zakładany przez admina to był client w kodzie. a client ui zakładany przez normalnego klienta to był w kodzie subclient. trochę musiałem nad tym podumać. podobnie jak szukałem różnic między customerem, clientem/subclientem, userem, personą i account. wszystkie te nazwy były użyte w kodzie a ja dniami poznawałem różnice między nimi. było trudno to ogarnąć (jak ogarnąłem to mnie do innego projektu przerzucono). ale jakbym w kodzie miał klasy TwojaStara1 TwojaStara2 TwojaStaraN to bym za chiny ludowe już tego nie rozkodował.

Ale zgadzam się że w dzisiejszych czasach częstego wymieniania developerów to dobry kod to taki co można siąść do niego i się go rozumie. tylko właśnie dobre nazwy zmiennych, nie zagnieżdżone ify i testy (zwłaszcza e2e) w tym pomagają

CZ
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 2536
2
KamilAdam napisał(a):
Czitels napisał(a):

Kod jest dobry kiedy (...) świeżo zatrudniony stażysta/hindus jest w stanie go zrozumieć i naprawić buga.

(...) Możesz sobie nazywać zmienne "twoja stara",

Ale naprawdę łatwo naprawia ci się bugi w cudzym kodzie gdzie zmienne to "twoja stara"? ja pamiętam jak poprzednim projekcie mnie spowolniło że czasem w kodzie był client a czasem subclient. bo client w ui zakładany przez admina to był client w kodzie. a client ui zakładany przez normalnego klienta to był w kodzie subclient. trochę musiałem nad tym podumać. podobnie jak szukałem różnic między customerem, clientem/subclientem, userem, personą i account. wszystkie te nazwy były użyte w kodzie a ja dniami poznawałem różnice między nimi. było trudno to ogarnąć (jak ogarnąłem to mnie do innego projektu przerzucono). ale jakbym w kodzie miał klasy TwojaStara1 TwojaStara2 TwojaStaraN to bym za chiny ludowe już tego nie rozkodował.

Ale zgadzam się że w dzisiejszych czasach częstego wymieniania developerów to dobry kod to taki co można siąść do niego i się go rozumie. tylko właśnie dobre nazwy zmiennych, nie zagnieżdżone ify i testy (zwłaszcza e2e) w tym pomagają

Chodziło mi o to, że wszystkie te dobre praktyki, wzorce projektowe itd zaczniesz wdrażać samoistnie jak zaczniesz myśleć o powyższych zasadach. Nie musisz przeczytać "Czysty kod", bo i tak będziesz tak programował. Jedyną rzeczą, którą myślę, ze należy się nauczyć to kompozycja, bo jak niektórzy myślą o skalowalności to dziedziczą w c++ a taki kod jest nie do utrzymania w przyszłości, wiem bo niestety było mi dane w czymś takim pracować. Jakby ktoś umiał wrzucic "Twoja Stara" to dla mnie git. ctrl + shit + f, debugger, szukasz wystąpień i już.

Na TDD, albo retro to nie wiem kto ma czas, chyba tylko bogate firmy. W jednej właśnie tak było, dopisujesz coś w kilka dni i reszta to testy, kłótnie na CR i cover kodu, którego nie pisaliśmy, bo Jankesom się nie chciało. Tam był jeszcze problem, że to było na embedded. Mógłbym się zgodzić na TDD, ale tylko kiedy projekt jest tak pisany od zera a nie, że zza oceanu pisali na szybko, żeby sprzedać a potem po wielu latach dali polaczkom do utrzymania i nagle sobie przypomnieli o "dobrych" praktykach xD.

KR
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 2518
2
Riddle napisał(a):
krwq napisał(a):

Nie szalałbym też z TDD w trakcie częstych zmian produktu bo dojście do sensownego rozwiązania zajmie Ci mega dużo czasu. Zrób najpierw MVP (minimum value product) i testuj tylko end to end i fragmenty które na 100% zostawisz a muszą działać poprawnie lub są łatwe do skaszanienia - dopiero mając MVP TDD ma dużo więcej sensu. Ale też nie deklaruj managerowi że skończyłeś mając prototyp - poczekaj aż skończysz testy bo zostaniesz bez testów i zaczniesz nad nową rzeczą pracować :D

A jak bez TDD wprowadzasz częste zmiany, to nie zepsujesz przypadkiem czegoś? I naprawianie tego zajmie i tak więcej czasu, niż napisanie testów wcześniej? Właśnie prędzej bym skipnął TDD jak nie ma zmian. Wtedy możesz napisać i zostawić.

Absolutnie nie mówie żeby w ogóle nie pisać testów. Oczywiście przetestuj porządnie logikę biznesową, ale nie przesadzaj w miejscach gdzie oczekujesz dalszych zmian a ewentualne błędy są łatwe do złapania i naprawiania. Zdarzyło mi się być w projekcie gdzie pisanie testów służyło bardziej faszerowaniu czyjegoś ego niż rozwijaniu produktu i było przesadnie dużo testowane w zbyt wczesnej fazie np. sprawdzanie czy error message nie zmienił treści, bo potem jakakolwiek zmiana będzie powodowała nie tylko poprawianie setki bezużytecznych testów, ale jeszcze osoby które nad tymi testami pracowały będą miały poczucie żebyś dodał kolejne bezużyteczne testy.

W późniejszych fazach rozwoju projektu albo przed większymi zmianami więcej dokładniejszych testów jest lepsze i często sam dopisuje przed zmianami, ale we wczesnej częściej mnie to ugryzło niż pomogło - testy E2E za to zawsze są przydatne. Rrzeczy, które są tzw. error-prone - takie zawsze lepiej testować wcześnie bo zawsze gryzą.

Riddle
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 10227
1
krwq napisał(a):
Riddle napisał(a):
krwq napisał(a):

Nie szalałbym też z TDD w trakcie częstych zmian produktu bo dojście do sensownego rozwiązania zajmie Ci mega dużo czasu. Zrób najpierw MVP (minimum value product) i testuj tylko end to end i fragmenty które na 100% zostawisz a muszą działać poprawnie lub są łatwe do skaszanienia - dopiero mając MVP TDD ma dużo więcej sensu. Ale też nie deklaruj managerowi że skończyłeś mając prototyp - poczekaj aż skończysz testy bo zostaniesz bez testów i zaczniesz nad nową rzeczą pracować :D

A jak bez TDD wprowadzasz częste zmiany, to nie zepsujesz przypadkiem czegoś? I naprawianie tego zajmie i tak więcej czasu, niż napisanie testów wcześniej? Właśnie prędzej bym skipnął TDD jak nie ma zmian. Wtedy możesz napisać i zostawić.

Absolutnie nie mówie żeby w ogóle nie pisać testów. Oczywiście przetestuj porządnie logikę biznesową, ale nie przesadzaj w miejscach gdzie oczekujesz dalszych zmian a ewentualne błędy są łatwe do złapania i naprawiania. Zdarzyło mi się być w projekcie gdzie pisanie testów służyło bardziej faszerowaniu czyjegoś ego niż rozwijaniu produktu i było przesadnie dużo testowane w zbyt wczesnej fazie np. sprawdzanie czy error message nie zmienił treści, bo potem jakakolwiek zmiana będzie powodowała nie tylko poprawianie setki bezużytecznych testów, ale jeszcze osoby które nad tymi testami pracowały będą miały poczucie żebyś dodał kolejne bezużyteczne testy.

W późniejszych fazach rozwoju projektu albo przed większymi zmianami więcej dokładniejszych testów jest lepsze i często sam dopisuje przed zmianami, ale we wczesnej częściej mnie to ugryzło niż pomogło - testy E2E za to zawsze są przydatne. Rrzeczy, które są tzw. error-prone - takie zawsze lepiej testować wcześnie bo zawsze gryzą.

Mówisz o przypadku kiedy napisane testy były ciasno przywiązane do implementacji, i przeszkadzało to w dalszej zmianie. To jest częsty problem, ale na szczęście są proste sposoby jak się przed tym chronić. Można wtedy spokojnie pokryć całość aplikacji testami.

KR
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 2518
1

są proste sposoby jak się przed tym chronić

@Riddle jakie np.?

Riddle
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 10227
0
krwq napisał(a):

są proste sposoby jak się przed tym chronić

@Riddle jakie np.?

W zasadzie każde które zwiększają loose-coupling. Pokaż mi przykład takiego testu to Ci podpowiem. Ale w skrócie to: odpowiedni design, abstrakcja, enkapsulacja, SRP, proste, krótkie funkcje, ostrożnie z 3rd party, małe moduły; Noi dodatkowo dwa najlepsze: po pierwsze testy najpierw, a po drugie wyzbycie się złych praktyk.

Riddle
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 10227
0
Riddle napisał(a):
krwq napisał(a):

są proste sposoby jak się przed tym chronić

@Riddle jakie np.?

W zasadzie każde które zwiększają loose-coupling. Pokaż mi przykład takiego testu to Ci podpowiem. Ale w skrócie to: odpowiedni design, abstrakcja, enkapsulacja, SRP, proste, krótkie funkcje, ostrożnie z 3rd party, małe moduły; Noi dodatkowo dwa najlepsze: po pierwsze testy najpierw, a po drugie wyzbycie się złych praktyk.

Dla przykładu, mam małą aplikacje którą rozwijam 2 tygodnie, mam tam pelne pokrycie testami jednostkowymi oraz akceptacyjnymi, oba suite'y wytworzone z TDD. Wczoraj zrobiłem gruntowny refactor, zamieniłem całkowicie architekture i zamieniłem miejscami która aplikacja jest serwerem a która klientem, wraz ze zmianą protokołu. Zauważ że nie musiałem zmienić żadnego testu, ani jednostkowego ani akceptacyjnego, dodalem tylko kilka nowych:

screenshot-20251119153431.png

D1
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 99
0

Dzięki Panowie za tak obszerną odpowiedź mimo wywiązania się z tego niewielkiej dyskusji. Analizując wasze wypowiedzi wiem, że nieco mam do nadrobienia oraz kończąc to konkluzją. Dobry kod to w pewien sposób artystyczny proces wymagający nieco czasu wliczająć w to błędy, poprawki. Zdaje sobie sprawę, że dla Was to prawie oczywistość, ale akurat jestem nieco na innym etapie ;)

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.