"Klient nie płaci za czysty kod"

0

Jeśli aplikacja jest typu "napisz i zapomnij"

Prawie nigdy nie jest. Owszem, jakieś doraźne skrypty albo prototypy mogą takie być, ale jeśli to jest normalna produkcyjna apka, to prawie nigdy nie ma "napisz i zapomnij", bo prawie zawsze ktoś to potem będzie musiał utrzymywać. Owszem, może to być już inna firma, ale to jest z deka nieprofesjonalne podejście "piszemy brzydko, bo i tak kto inny potem to będzie utrzymywać". Niestety widzę takie podejście nagminnie. I potem firma X przejmuje g**no kod zrobiony w firmie Y. Albo jeden freelancer przejmuje brzydki kod zrobiony przez brzydkiego innego freelancera, który też traktował to jako "napisz i zapomnij" (bo napisał i zapomniał).

Takie podejście to trochę jak brudzenie deski klozetowej w publicznej toalecie.

Czasem nawet pojedynczy pracownikach w firmie piszą brzydki kod, a potem odchodzą z firmy albo przechodzą do innego projektu - spotkałem się nawet z tym, że osobnik, który pisał najgorszy kod w projekcie (sprawdziłem git blame najgorszy kod, jaki zobaczyłem) przeszedł potem do innego projektu w tej firmie i jeszcze awansował na jakiegoś seniora, team leadera czy kogoś takiego.

edit: lol, napisałem "brzydkiego freelancera"

1
somekind napisał(a):
Troll anty OOP napisał(a):

Widzę tu w wątku ludzie bardzo nisko szacują różnicę w czasie wykonania byle jak, od czasu wykonania, by być w pełni usatysfakcjonowanym w jakości. Bo równie dobrze ta różnica może nie być 2-krotna, a 20-krotna. I tylko w nielicznych częściach programu może być warto tę 20-krotność czasu zrobienia byle jak poświęcić.

Czemu nie 200 albo 2000?

Wartość 20 oszacowałem na podstawie osobistego doświadczenia. Dopóki nie zacząłem pracować sam, uważałem że gdyby nie głupota kierownictwa, to wszędzie miałbym piękny kod. Gdy sam decyduję o tym, jak zrobić... no jednak często wolę mieć zrobione jakkolwiek, bo nikt mi nie płaci od godziny pracy. A później to utrzymuję, w razie potrzeby przepisując różne części od nowa (oczywiście intensywnie korzystając ze słynnej metody kopiuj-wklej). Zależnie od człowieka i zagadnień, które przyszło mu rozwiązać, ta różnica może być inna. Ja u siebie oszacowałem koszt robienia dobrze jako 20-krotność robienia byle jak.

To jest problem cieniasów, którzy nie znają wzorców, idiomów i często podstawowych konstrukcji języka, i nie potrafią wystarczająco szybko projektować.

To jest typowa metoda do namawiania człowieka, by robił coś wbrew swojemu interesowi: próba wzbudzenia w nim wstydu, na przykład przez nazwanie go cieniasem, nieukiem, itp. Metoda ze świetnymi skutkami praktykowana także w innych sferach życia.

Zamiłowanie do Fashion Driven Development i nieumiejętność odnalezienia się w dobrze napisanym kodzie sprzed paru lat, bo nie jest "wystarczająco nowoczesny" (czyli jak sądzę niezgody z tym, co pokazują aktualnie tutoriale) to też domena cieniasów.

To czy nazwiemy te osoby cieniasami, czy grubasami, czy jeszcze jakoś inaczej, nie ma większego znaczenia. Istotny fakt jest taki, że jest ich dużo. Może nam się ten fakt podobać lub nie, ale firmy muszą go uwzględniać w decyzjach dotyczących swojej strategii.

0

Na podstawie opinii kolegi, wspólnika średniej wielkości firmy konsultingowej świadczącej usługi w obszarach IT wynika, że całkowity czas poświęcony na czytelny kod, komentarze + ewentualnie minimalna ale wystarczająca dla osoby technicznej dokumentacja (bądź zwykły opis funkcjonalności) wynosi średnio 40% czasu. Projekty jakimi się zajmują to głównie zagadnienia związane z wdrażaniem rozwiązań opartych na SQL Server + narzędzia powiązane (SSIS, SSAS, SSRS) + aplikacje C#. Możliwe, że w innych obszarach będzie to wyglądać inaczej.

4

Jak patrzę na różne kody, to często mam wrażenie, że to nie o to chodzi, że ktoś "umie pisać ładny kod, ale się śpieszył", tylko że ludzie po prostu nie umieją pisać, wyciągać odpowiednich abstrakcji (więc piszą wszędzie "na pałę") nie znają tych wszystkich "dobrych praktyk" (jak SRP), a często nawet nie znają języka, w którym piszą (i odkrywają koło na nowo, pisząc z palca coś, co mają już w języku).

Myślę, że w takim wypadku im dłużej taki delikwent siedzi w projekcie, tym gorzej. Tacy ludzie powinni jak najszybciej kodzić, bo im więcej kodzą, tym gorzej wygląda projekt. Task naklepany przez "cieniasa" w 2 godziny nie będzie jeszcze tak zły, jak task naklepany przez niego w 20 czy 200 godzin (to w ogóle byłaby tragedia).

0

całkowity czas poświęcony na czytelny kod, komentarze + minimalna ale wystarczająca dla osoby technicznej dokumentacja (bądź zwykły opis funkcjonalności) wynosi średnio 40% czasu.

I teraz pytania, na które chyba nie ma jednoznacznej odpowiedzi:

Czy te 40% więcej się zwróci?
Czy klient zapłaci o 40% więcej za napisanie "ładne" programu, który będzie działa dokładnie tak samo, jak zakodowany bylejak (bo zakładam, że mimo napisania niezgodnie z zasadami, program-prowizorka będzie także działać)?
Czy planujesz tyle poważnych zmian, żeby zainwestowany w porządne napisanie czas się zwrócił przy okazji dalszego rozwoju aplikacji?

1

Nie zapominajmy że słaby kod = większa rotacja pracowników.
I akurat to dość dobrze przekłada się na $£¥

3

Problemem, nie jest czas ani słabe wynagrodzenie. Problemem jest to, że się nie umie. Jak mnie uber senior mówi, że restowy serwis "aplikacyjny\user case" ma mieć metody "OrderUpdate, OrderCreate, OrderDelete" a Serwisy, zamiast komunikować się ewenami czy infrastrukturą mają się przeplatać nawzajem, bo w przeciwny wypadku jest to over enginiering (To takie mainstremowe określenie jak się nie umie nic oprócz encji na twarz to się nazywa to over enginiering) no to sorry, coś jest nie tak po prostu z pracownikami...

1

w przeciwny wypadku jest to over enginiering (To takie mainstremowe określenie jak się nie umie nic oprócz encji na twarz to się nazywa to over enginiering)

No, też zauważyłem, że ludzie czasem nazywają overengineeringiem, "przekombinowaniem" czy innymi tego typu zwrotami coś, co jest proste, ale czego po prostu nie rozumieją, bo nie są dość doświadczeni, albo wyedukowani w programowaniu.

Z drugiej strony często naprawdę coś jest przeinżynierowane.

a Serwisy, zamiast komunikować się ewenami czy infrastrukturą mają się przeplatać nawzajem

Czasem naprawdę to może być dobre podejście. Wszystko zależy. Projekty oparte o eventy (albo z jakąś "sprytną infrastrukturą") też potrafią być tak niepotrzebnie pokomplikowane, że należałoby się zastanowić, czy nie lepiej byłoby z tego zrezygnować (przynajmniej w miejscach, gdzie nie jest to potrzebne). Skrajne podążanie za dogmatami, że coś "musi być jakieś" nie jest dobre.

4
Troll anty OOP napisał(a):

Wartość 20 oszacowałem na podstawie osobistego doświadczenia. Dopóki nie zacząłem pracować sam, uważałem że gdyby nie głupota kierownictwa, to wszędzie miałbym piękny kod. Gdy sam decyduję o tym, jak zrobić... no jednak często wolę mieć zrobione jakkolwiek, bo nikt mi nie płaci od godziny pracy. A później to utrzymuję, w razie potrzeby przepisując różne części od nowa (oczywiście intensywnie korzystając ze słynnej metody kopiuj-wklej). Zależnie od człowieka i zagadnień, które przyszło mu rozwiązać, ta różnica może być inna. Ja u siebie oszacowałem koszt robienia dobrze jako 20-krotność robienia byle jak.

Pracowałem w dużych i małych zespołach, robiłem też projekty jako freelancer i na podstawie osobistego doświadczenia szacuję, że różnica jest na korzyść pisania dobrego kodu.

Tylko dobry kod nie oznacza overengineeringu i robienia 15 warstw, możliwości podmiany każdej klasy przy pomocy mechanizmu pluginów oraz autorskiego frameworka do generowania GUI na podstawie konfiguracji trzymanej w XML w bazie. W takim przypadku faktycznie wyszłoby 20 razy więcej czasu. Ale to nie byłby dobry kod.

To jest typowa metoda do namawiania człowieka, by robił coś wbrew swojemu interesowi: próba wzbudzenia w nim wstydu, na przykład przez nazwanie go cieniasem, nieukiem, itp. Metoda ze świetnymi skutkami praktykowana także w innych sferach życia.

Mnie absolutnie nie chodzi o to, żeby kogokolwiek do czegokolwiek namawiać. Stwierdzam tylko fakty - jeśli ktoś nie umie czegoś robić, bo jest słaby w tej dziedzinie, to robienie porządnie idzie mu wolno.

Istotny fakt jest taki, że jest ich dużo. Może nam się ten fakt podobać lub nie, ale firmy muszą go uwzględniać w decyzjach dotyczących swojej strategii.

No to już od firmy zależy.

4

3

Ja właśnie pracuję przy projekcie, przy którym przez lata było praktykowane tłuczenie wszystkiego byle szybciej, byle do przodu.
Efektem jest wielka klasa na ~10k linijek, która przebija się przez całą, aż jedną, warstwę abstrakcji. Do tego brak jakichkolwiek testów automatycznych, związanie na amen operacji na danych z ich wyciąganiem, brak jakichkolwiek obiektów(w tym zwykłych struktur danych w formie DTO, bo po co, skoro jest array czy własna implementacja Dictionary?), już nie mówiąc o obiektach takich, jakimi powinny być - posiadających swoje zachowanie.
SOLID, SRP, YAGNI czy jakiekolwiek sensowne podejście do tego, co się robi nie istnieje, a przy tym są kwiatki typu "własna implementacja kodowania i dekodowania HTML", którą trzeba poprawiać...

I projekt się toczy od lat. Z tego co wiem niespecjalnie na siebie zarabia, nie ma wzięcia... A doprowadzenie do stanu, w którym można by go rozwijać wymagałoby przepisania praktycznie od nowa, na co zgody nie ma i nie będzie.

Jedynie się zastanawiam dlaczego ktoś wybrał język obiektowy, żeby później tłuc w nim procedurami po słownikach i DataSetach.

Co więcej, ile razy rozmawiam z ludźmi, tyle razy okazuje się, że choćby minimalne dbanie o jakość tego co się pisze powoduje efekty odwrotne - pracownik po roku czuje się w projekcie lepiej niż "kompletnie, kurna, bez pojęcia", produkt zarabia i daje się rozwijać.

Oczywistym jest, że chore, purystyczne podejście jest niezdrowe... Ale twierdzenie, że, przy większym projekcie, robienie "byle jak" się opłaca i nie warto do tego przykładać wagi to jest jakiś absurd, który nawet przy robieniu stron-wizytówek niekoniecznie się sprawdza.

Co więcej, jakim cudem, ludziom mającym pojęcie o tym co robią, napisanie testów i przemyślenie jak sensownie zaprojektować rozwiązanie, a później pójście za tym, zajmuje mniej czasu niż trzaśnięcie "na pałę", skoro drugi sposób podobno jest szybszy?

10

Większość klientów nie płaci za czysty kod.

Za to ktoś płaci za brudny. Przy pewnej dozie szczęścia jest to klient (ale przeważnie na krótką metę), ale najczęściej to firma gdzie ten syf się tworzy.

Firma, która stawia na syf płaci:

  • za błędy, jakie wyłażą na produkcji - ale to pikuś,
  • za to, że odchodzą bardziej ogarnięci ludzie,
  • za to, że dobrze się zadomowiają syfiarze,
  • za to, że jak się kogoś lepszego szuka to trzeba dużo więcej dać kasy :-)
  • za to, że ludzie nie pracują efektywnie, bo są zdemotywowani,
  • za to, że nie ma testów automatycznych i każdy ficzer trzeba odpalić gdzieś na serwerze co trwa wielokrotnie dłużej,

Firma traci pieniądze na tym, że ludzie boją się ruszać kod - więc nie oferuje się ich klientowi, lub daje zaporowe ceny,

I pewnie jeszcze wiele innych elementów się znajdzie.

0

Jedynie się zastanawiam dlaczego ktoś wybrał język obiektowy, żeby później tłuc w nim procedurami po słownikach i DataSetach.

Bez przesady. Każdy się kiedyś uczył, a najlepiej się uczyć na produkcji, i jeszcze mając płacone za naszą wesołą twórczość i pierwsze kroki w programowaniu. Może ktoś, kto to pisał, po prostu nie umiał jeszcze pisać obiektowo.

A tak na serio to uważam, że powinno się osiągnąć jakiś minimalny poziom, zanim człowiek się zatrudni w jakiejś firmie jako programista. I pracodawcy w ogóle takich osób nie powinni zatrudniać.

Efektem jest wielka klasa na ~10k linijek,

Serio? Myślałem, że 10-tysięczniki to tylko metafora używana na konferencjach przez Sobótkę (bodajże).

2


małą próbka, polecam inne materiały od tego gościa, albo jego książkę "Clean Code".

0

Efektem jest wielka klasa na ~10k linijek,

Serio? Myślałem, że 10-tysięczniki to tylko metafora używana na konferencjach przez Sobótkę (bodajże).

SQLite, chyba najbardziej rozpowszechniona baza danych na swiecie:

  • btee.c - 10199 linii
  • pager.c - 7703 linie
  • os_unix.c - 7866 linii
  • vdbe.c - 7580 linii (prawie caly kod to jest pojedyncza funkcja)

Z tego co pamietam w zrodlach Pythona funkcja se switchem odpowiadajaca switchowi z vdbe.c jest rownie ambitna. Tyle ze podzielili ja na 2 funkcje. I dodali komentarz ktory brzmial jakos tak: "mimo ze na to nie wyglada, to musi byc podzielone. kiedys nie bylo i to powodowalo blad ktorego nikt nie zauwazyl przez 2 lata".

Jak widac rozmiar nie ma wiekszego znaczenia. Po prostu trzeba potrafic uzywac (to bardziej sie tyczylo SQLite niz Pythona, ktorego jak wszyscy wiedza nie da sie poprawnie uzywac).

0

No ale to C, może tak się pisze w C po prostu (często jak patrzę w kod źródłowy projektów pisanych w C/C++ to widzę tam kilometrowe pliki, więc wnioskuję, że taka kultura kodu i może to im nie przeszkadza. I że może programiści innych języków dzielą kod na pliki, a programiści C/C++ dzielą je tylko na funkcje?)

1
Trzeźwy Kaczor napisał(a):

SQLite, chyba najbardziej rozpowszechniona baza danych na swiecie:

  • btee.c - 10199 linii
  • pager.c - 7703 linie
  • os_unix.c - 7866 linii
  • vdbe.c - 7580 linii (prawie caly kod to jest pojedyncza funkcja)

Po pierwsze, to połowa, jeżeli nie 2/3 tego kodu to komentarze. Po drugie, być może chodzi o jakieś optymalizacje i oszczędzanie każdego skoku procesora, które w przypadku bazy danych mają sens. Po trzecie, to nie jest zbyt ekspresywny język, jedna linijka kodu C#/Java opowiada kilkudziesięciu w C.
Jeśli ktoś mówi o klasie na 8k linijek w C#/Javie, trzeba by pokazać plik na 160-400k linijek w C, żeby móc mówić o podobnie słabym poziomie.

0
LukeJL napisał(a):

No ale to C, może tak się pisze w C po prostu (często jak patrzę w kod źródłowy projektów pisanych w C/C++ to widzę tam kilometrowe pliki, więc wnioskuję, że taka kultura kodu i może to im nie przeszkadza. I że może programiści innych języków dzielą kod na pliki, a programiści C/C++ dzielą je tylko na funkcje?)

Nie. Mylisz długość pliku z organizacja kodu.

0
somekind napisał(a):
Trzeźwy Kaczor napisał(a):

SQLite, chyba najbardziej rozpowszechniona baza danych na swiecie:

  • btee.c - 10199 linii
  • pager.c - 7703 linie
  • os_unix.c - 7866 linii
  • vdbe.c - 7580 linii (prawie caly kod to jest pojedyncza funkcja)

Po pierwsze, to połowa, jeżeli nie 2/3 tego kodu to komentarze. Po drugie, być może chodzi o jakieś optymalizacje i oszczędzanie każdego skoku procesora, które w przypadku bazy danych mają sens. Po trzecie, to nie jest zbyt ekspresywny język, jedna linijka kodu C#/Java opowiada kilkudziesięciu w C.
Jeśli ktoś mówi o klasie na 8k linijek w C#/Javie, trzeba by pokazać plik na 160-400k linijek w C, żeby móc mówić o podobnie słabym poziomie.

Słaby poziom w C widać już po kilkunastu liniach.

0

Jest w tym coś z kultury, bo przeważnie ci dogmatycznie wierzący w rozmaite modne współcześnie dobre teoryjki, uciekli do języków mających renomę bardziej nowoczesnych, a C pozostaje azylem dla niewierzących. Z drugiej strony praktycznie wszystkie dobre teoryjki (nazywane "dobre praktyki"), tworzone są z myślą o typowych projektach robionych w tych "nowoczesnych" językach, a w nich problemów w rodzaju implementacja SQLite zazwyczaj się nie rozwiązuje, tylko używa rozwiązań wykonanych w C. - Troll anty OOP wczoraj, 23:53

W C jeśli się coś modyfikuje nie będąc zaangażowanym pierwotnie w projekt to są to głównie nie mające ujrzeć światła dziennego poza serwerownią modyfikacje kerneli, czy demonów usług. Jak ktoś trafia na pisanie tego od podstaw, to najczęściej ma wystarczająco wysokie IQ i zdolności modelowania żeby stworzyć sobie wystarczający do realizacji zadania szkielet ideowy nawet jeśli widzi pierwszy raz na oczy dany rodzaj zagadnienia. Odmiennie też analizuje się kod w tym pisany, bo tu wystarczy prześledzenie kolejnych wywołań z poziomu przykładowo CScope by się zorientować w kodzie i nie zastanawiać co na jakim poziomie przeciążą co i co przysłania i temu podobnych kwestii znanych z tych "ułatwiających programowanie paradygmatów obiektowych".

Dobry kod w C to dobra literatura. Kod uznawany za dobry w obiektówce to zaś coś na kształt holiwoodzkiej produkcji tasmowej filmów akcji - sztampa goni sztampę.

1
Programista C napisał(a):

Słaby poziom w C widać już po kilkunastu liniach.

A w C# po pół linijki. Ale nie o to chodzi - rozmowa tyczy się przerośniętych plików. W korpoprojektach pisanych w korpoęzykach nie ma powodu, żeby cała zawartość pliku nie mieściła się na ekranie, ale zakładam, że w przypadku projektów takich jak SZBD w C taka zasada nie ma sensu.

Pędzący Młot napisał(a):

Kod uznawany za dobry w obiektówce to zaś coś na kształt holiwoodzkiej produkcji tasmowej filmów akcji - sztampa goni sztampę.

Bynajmniej. Dobry kod w języku obiektowym może być czytany przez osoby nietechniczne ze zrozumieniem.

1

Popatrzcie na duże projekty pisane w python, pliki mają po kilka tysięcy lini kodu i tak się po prostu pisze. Nikt nie buduje rozbujanej abstrakcji na 200 plików i podfolderów tylko skaczesz sobie w jednym pliku. Myślę, że jeżeli ciągle piszesz w jednym języku w stylu enterprise to nie mogłeś spojrzeć na programowanie z innej perspektywy. W językach typu c# skupiasz się bardziej na myśleniu jak coś dobrze zakodować, zamiast jak ten problem najskuteczniej rozwiązać. Przynajmniej tak zauważyłem, mogę się mylić.

Edit: Miałem na myśli, że nie ma jednej definicji jak powinno się pisać, to zależy co robimy, w jakim języku piszemy. Nie porównuje języku tylko zwracam uwagę, że nie można na to patrzeć tylko z punktu widzenia programisty statycznego, obiektowego języka.

Polecam przejrzeć źródła gitlaba pisanego w rubym, zauważyłem tam kilku polskich programistów, można popatrzeć jak to u nich wygląda.

0

Uczyłem się / programowałem ponad miesiąc w Pythonie. Wszystkie te dni były cierpieniem.
A co oni mają zrobić ? Pisać wszędzie Method(self): self.__składowa. To problem język, a nie stylu programowania.

0
Visual Code napisał(a):

W językach typu c# skupiasz się bardziej na myśleniu jak coś dobrze zakodować, zamiast jak ten problem najskuteczniej rozwiązać.

A jak można skutecznie rozwiązać problem jeśli nie zakoduje się tego dobrze? Co jest miarą skuteczności wg Ciebie?

0

W językach typu c# skupiasz się bardziej na myśleniu jak coś dobrze zakodować, zamiast jak ten problem najskuteczniej rozwiązać.

To nie jest kwestia C#, w C# też można pisać kaszanę, która tylko "najskuteczniej rozwiązuje problem".

0
somekind napisał(a):
Programista C napisał(a):

Słaby poziom w C widać już po kilkunastu liniach.

A w C# po pół linijki. Ale nie o to chodzi - rozmowa tyczy się przerośniętych plików. W korpoprojektach pisanych w korpoęzykach nie ma powodu, żeby cała zawartość pliku nie mieściła się na ekranie, ale zakładam, że w przypadku projektów takich jak SZBD w C taka zasada nie ma sensu.

Zależy od stopnia abstrakcji. Sterownika wielokanałowych urzędzeń midi raczej jednak nie zmieści się na jednym ekranie.

Pędzący Młot napisał(a):

Kod uznawany za dobry w obiektówce to zaś coś na kształt holiwoodzkiej produkcji tasmowej filmów akcji - sztampa goni sztampę.

Bynajmniej. Dobry kod w języku obiektowym może być czytany przez osoby nietechniczne ze zrozumieniem.

Wątpię. Do tego ja piszę o sztampowości, ty o czytelności dla "nietechnicznych".

0
Biały Ogrodnik napisał(a):

Zależy od stopnia abstrakcji. Sterownika wielokanałowych urzędzeń midi raczej jednak nie zmieści się na jednym ekranie.

Napisałem: "W korpoprojektach pisanych w korpoęzykach".

Wątpię.

W co wątpisz? Że czytelny kod biznesowy jest osiągalny? Na podstawie własnych doświadczeń?

Do tego ja piszę o sztampowości, ty o czytelności dla "nietechnicznych".

Bo zbiór imperatywnych instrukcji najeżony wskaźnikami i innymi szczegółami implementacji, to nie jest dobra literatura. Tę można osiągnąć tylko mogąc tworzyć odpowiednie abstrakcje i mądrze z tej możliwości korzystając.

0
somekind napisał(a):
Biały Ogrodnik napisał(a):

Zależy od stopnia abstrakcji. Sterownika wielokanałowych urzędzeń midi raczej jednak nie zmieści się na jednym ekranie.

Napisałem: "W korpoprojektach pisanych w korpoęzykach".

A ja o C, do którego się odnosiłeś. Czytaj powoli i ze zrozumieniem.

Wątpię.

W co wątpisz? Że czytelny kod biznesowy jest osiągalny? Na podstawie własnych doświadczeń?

Wątpię w twoją zdolność czytania ze zrozumieniem.

Do tego ja piszę o sztampowości, ty o czytelności dla "nietechnicznych".

Bo zbiór imperatywnych instrukcji najeżony wskaźnikami i innymi szczegółami implementacji, to nie jest dobra literatura. Tę można osiągnąć tylko mogąc tworzyć odpowiednie abstrakcje i mądrze z tej możliwości korzystając.

Dalej brak związku z brakiem sztampowości. Może zajrzyj do słownika co ten termin oznacza.

0

Nie wiem, co właściwie próbowałeś osiągnąć wrzucając przykład SQLite do dyskusji o korporacyjnych koszmarkach, ale to już teraz nieważne. Widzę, że zaczęło się ad personam, więc argumenty merytoryczne zostały wyczerpane.

0

Generalnie chyba rozmawiacie o różnych rzeczach. Jest kod który ma działać szybko i jest kod który ma być czytelny. I to nie zawsze ten sam kod

1 użytkowników online, w tym zalogowanych: 0, gości: 1