Pytanie:
Jak radzić sobie ze starszym współpracownikiem, który napisał własny język programowania?
ThrowAway
2018-04-18 19:24:26 UTC
view on stackexchange narkive permalink

Jestem w zespole ze starszym programistą, który pracuje w firmie przez długi czas (może 15 lat) i pracuje wyłącznie nad architekturą backendu naszego 25-letniego produktu. Niedawno w ramach modernizacji nasz zespół otrzymał zadanie zaktualizowania produktu, aby aplikacje internetowe mogły komunikować się z produktem za pomocą JSON. Aby rozwiązać ten problem, ten programista napisał niestandardową warstwę tłumaczenia, która przekształciła wiadomości od klientów internetowych za pośrednictwem protokołu HTTP (JSON) na wiadomości, które produkt może wypowiadać, i odwrotnie.

Na początku ta warstwa była dość prosta - po prostu tłumaczył komunikaty między klientami sieciowymi a produktem. Jednak z biegiem czasu ta warstwa stawała się coraz bardziej złożona; ta warstwa może teraz przekształcać wiadomości, przeprowadzać sprawdzanie poprawności wiadomości, wykonywać zapytania do bazy danych, wysyłać żądania sieciowe do systemów innych firm, pętlę danych, wykonywać złożone warunki i nie tylko. Rozrosło się do tego stopnia, że ​​myślę, że słuszne jest nazywanie go pełnoprawnym językiem programowania.

Jesteśmy punktem, w którym cała nowa logika biznesowa jest zapisana w tej warstwie tłumaczenia . Uważam, że jest to zły pomysł ™ z kilku powodów:

  • Jest bardzo mało dokumentacji na temat pisania kodu w tej warstwie tłumaczenia
  • W wyniku # 1, każdy dołączający do zespołu ma teraz bardzo stromą krzywą uczenia się.
  • Opracowanie nowej logiki biznesowej prawie zawsze wymaga pomocy ze strony tego programisty.
    • W rzeczywistości każdy sprint, który mu dajemy „wsparcie API” zadania na naszej tablicy scrum, które są poświęcone pomaganiu innym członkom zespołu w rozwiązywaniu problemów podczas tworzenia w warstwie tłumaczeniowej.
  • Doświadczenie programistyczne jest słabe, ponieważ wszystkie nasze narzędzia programistyczne muszą być napisane przez tego programistę

Być może najbardziej irytujące jest to, że mamy również serwer Node przed tą warstwą tłumaczenia. Jednak pisanie logiki biznesowej w tej warstwie jest odradzane przez tego programistę (i naszego architekta, który jest trochę oderwany od naszego zespołu) przede wszystkim ze względu na spójność - nie podoba mu się pomysł posiadania logiki biznesowej w dwóch miejscach.

Jak mogę przekonać tego programistę (i resztę mojego zespołu, którzy są dość bierni w tego typu sprawach), że to zły pomysł? Jak mam walczyć z nieuniknionym argumentem, że pisanie logiki biznesowej w Node byłoby niezgodne z wzorcami, które już ustaliliśmy?

A może jestem arogancki, zakładając, że podejście tego programisty jest źle? Ma za sobą więcej lat doświadczenia w programowaniu i dużo wiedzy instytucjonalnej.

Niektóre informacje: mam około 5 lat doświadczenia, z czego 2 pracowałem firma. Jeśli mam wybór, skłaniam się bardziej w kierunku rozwoju front-end. Wspomniana powyżej warstwa tłumaczeniowa była rozwijana przez około 2 lata, ale nie została jeszcze wdrożona do produkcji. Zobacz komentarze, aby uzyskać dodatkowe szczegóły techniczne dotyczące tej warstwy tłumaczenia.

Wygląda na inteligentną osobę, nie bardzo pewną swojej dokumentacji i umiejętności wsparcia.On ugruntował swoje znaczenie i rolę we wszystkim, musisz dobrze płynąć pod prąd ...
Jestem zdezorientowany co do jego opisu jako języka programowania.To brzmi bardziej jak ramy.
@GlenPierce istnieje niewielka różnica między małym językiem programowania a dużym frameworkiem.
To jest klasyczna platforma Inner: https://en.wikipedia.org/wiki/Inner-platform_effect.Jeśli architekt nie może / nie chce tego zatrzymać, sprawa jest rozstrzygnięta.Żyj z tym lub idź dalej.Walka z tym jest bezcelowa.
@WesleyLong, czyli przypuszczenie, że „architekt” miałby prawo skłonić starszego programistę do porzucenia własnego języka zbudowanego.W przeciwnym razie to zależy od każdego wyższego szczebla ze strony kierownictwa, zakładając, że możesz podać im właściwe argumenty.Na przykład tłumaczenie liczb, co oznacza „bardzo stromą krzywą uczenia się” z powodu tego utworu i tego, czego oczekujesz bez niego, może pomóc.
W jakim języku jest faktycznie wbudowany ten „język wewnętrzny” / struktura?Czy są jakieś opcje, aby przejść krok po kroku od korzystania z samodzielnie utworzonych bibliotek współpracownika do czegoś bardziej standardowego w branży?
Nie jest językiem programowania, chyba że ma kompilator lub interpreter.Wygląda na to, że program ma większy zakres niż powinien.
Termin, który chciałbym tutaj zastosować, brzmiałby „język specyficzny dla domeny” i jest to całkiem dobrze zrozumiały sposób podejścia do złożonych domen (co może brzmieć tak): https://en.wikipedia.org/wiki / język_pecyficzny dla domeny Mają również dość dobrze zrozumiałe wady (o których mówi link do Wikipedii). Często systemy są bardziej złożone, niż mogłoby się wydawać na pierwszy rzut oka, i jest całkiem możliwe, że DSL jest świetnym narzędziem do zarządzania nimi.Co może nie przeważać nad problemami, ale wahałbym się, czy przyjąć twierdzenie, że to z konieczności coś złego.
@autophage wygląda na to, że wyrósł organicznie z czegoś prostego, mediatora, w DSL - i to, imho, zawsze jest czerwoną flagą, że prawdopodobnie nie został zaprojektowany do rozwiązywania problemów z DSL itp. Fakt, że to jest już 2 latastary bez produkcji to kolejna czerwona flaga.Jeśli zdobędę doświadczenie w pisaniu czegoś, co mógłbym następnie umieścić w swoim CV jako „projektowanie i budowanie DSL”, to dobrze, ale jeśli mam tylko doświadczenie w „pisaniu rzeczy w niestandardowym języku pracodawców”, to właśnie bym to prowadziłz dala od szybkiego.
Może to być również * język specyficzny dla domeny *, który, jeśli zostanie wdrożony umiejętnie (co jest bardzo trudne), może * znacznie * ułatwić życie klientom.
„ponieważ wszystkie nasze narzędzia programistyczne muszą być napisane przez tego programistę” - dlaczego tak jest?ponieważ ludzie nie rozumieją tego wystarczająco, aby wnieść swój wkład, lub nie wolno im w tym uczestniczyć?
Możesz nazwać to makrami, na pewno nie językiem programowania.Wyolbrzymiasz swój problem.
Aby dodać więcej szczegółów dotyczących warstwy tłumaczeniowej: warstwa jest napisana w [RAML] (https://raml.org/).Warstwa implementuje serię „wtyczek”, do których można uzyskać dostęp za pośrednictwem [adnotacji RAML] (https://github.com/spotify/ramlfications/wiki/RAML-v1.0:-Annotations).W pliku RAML każdy punkt końcowy może zdefiniować liczbę „kroków”, które definiują zachowanie punktu końcowego (tj. Walidację obiektu, wykonanie zapytania do bazy danych, przekształcenie wyniku itp.).Deweloper napisał niestandardowy parser, który wykorzystuje te pliki RAML do wykonania.TL; DR: cała logika biznesowa jest implementowana wyłącznie w plikach RAML.
Lepszy link do adnotacji RAML: https://raml.org/blogs/announcing-raml-10-ga#annotations
Pięć odpowiedzi:
OnoSendai
2018-04-18 21:02:57 UTC
view on stackexchange narkive permalink

Podajmy trochę kontekstu Twojemu pytaniu.

Twoja firma ma:

  • 25-letni produkt
  • Starszy programista back-end ze znaczną wiedzą instytucjonalną.
  • Założenie: kilku średnich / młodszych programistów
  • Chęć zmodernizowania środowiska
  • Warstwa tłumaczenia

Niewyczerpująca lista wymagań dotyczących warstwy tłumaczeniowej:

  • Transformacja wiadomości
  • Walidacja wiadomości
  • Łączność z bazą danych
  • Integracja z siecią z systemami innych firm
  • Przetwarzanie danych
  • Złożone wykonywanie warunkowe

Tak więc tę warstwę tłumaczenia można nazwać integracyjnym oprogramowaniem pośrednim . Obsługuje logikę biznesową niezwiązaną z podstawowym 25-letnim produktem, z (spodziewam się) różnymi przepływami i paradygmatami.

Jest kilka aspektów, które nazwałbym Bad Ideas ™, ale istnieje integracyjne oprogramowanie pośredniczące nie jest jednym z nich. Najgorszy, IMHO, jest brak dokumentacji : może mieć to swoje źródło w tym, że masz tylko jednego programistę z wystarczającym doświadczeniem, aby zwizualizować cały proces. Powinien udokumentować proces, więc jeśli zostanie potrącony przez autobus, rozwój nie zatrzyma się z piskiem. Zmniejszy to również zapotrzebowanie zespołu devteam na zadania wsparcia API.

O serwerze Node - jestem zmuszony, przynajmniej na początku, zgodzić się z twoim architektem. Dzielenie logiki biznesowej na różne platformy / języki bez silnego powodu architektonicznego można nazwać złym pomysłem ™. Dwie bazy kodów do utrzymania, dwa zestawy wymagań dla nowych stanowisk pracy. Zasady KISS mogły zostać tutaj zastosowane w celu obniżenia kosztów.

Nie mówię, że nie należy podejmować takiej decyzji, ale należy wziąć pod uwagę wszystkie koszty (ponowne szkolenie, mapowanie procesów, walidację przepływu itp.), a Twój architekt prawdopodobnie jest ich świadomy. Język używany do kodowania starszego produktu może zostać wycofany, na przykład wymuszając pełną migrację na inną platformę, a pełną implementację NodeJS można wybrać jako Plan A.

Mimo to myślę, że chęć Poprawa obecnej sytuacji jest godna podziwu i cenna, a zamiast toczyć żmudną bitwę, zasugerowałbym inny plan.

Fakt, że starszy programista kieruje wysiłkiem w zakresie oprogramowania pośredniego, sugeruje, że nie jest on przeciwny do zmiany i zdolnym profesjonalistą. Podziel się z nim swoim punktem widzenia i wysłuchaj jego opinii. Może to docenić, przedstawić własny punkt widzenia (który pomoże zrozumieć uzasadnienie obecnego stanu) i rozważyć chęć unowocześnienia rozwiązania z uwzględnieniem całej wiedzy instytucjonalnej - i dojść do wniosku, że pomysł nie jest bez zasług. Firma polega na jego możliwościach, a jego sugestia dotycząca modernizacji może mieć duże znaczenie.

+1.Wydaje się, że najlepszym rozwiązaniem tego problemu jest udokumentowanie tego, co istnieje.
+1 za dokumentację.Niezależnie od rozwiązania, którego użyjesz, aby spełnić swoje wymagania, nadal będziesz mieć pewien rodzaj interfejsu API lub framework, których mogą się nauczyć programiści.
Ponieważ brak dokumentacji jest tutaj dużym winowajcą, a OP ma rozsądne doświadczenie, być może mogą zwrócić się do starszego programisty i poprosić o napisanie dokumentacji oprogramowania pośredniego z starszym programistą jako mentorem.Nawet dokumentacja napisana tylko dla części, których używasz, ma swoje zalety.
@LoganPickup Zgadzam się.Dokumentacja nie musi być napisana przez oryginalnego programistę.Heck, większość programistów, których znam (łącznie ze mną) i tak nie jest zbyt dobra w pisaniu tego.Zawsze pomaga ktoś inny - przynajmniej może zaoferować wgląd w to, co jest ważne do udokumentowania.
+1 Kolejny głos na dokumentację.Aby dodać do tego, dokumentowanie procesów takich jak ten zmusza programistę do nauczenia się, jak komunikować proces komuś, kto nie jest na jego poziomie.Zwykle ujawnia to wiele na temat łatwości utrzymania, która jest nieodłącznie związana z implementacją, jak intuicyjne są procesy i implementacje itp. Dla mnie, jeśli przedstawiasz części, a ludzie przyjmują błędne założenia co do tego, jak to działa, prawdopodobnie projekt jest wadliwy.Byłoby to świetne do przeglądu architektury i sposobów jej ulepszenia.
Wygląda na to, że framework jest monolityczny i obsługuje wiele różnych rzeczy, które mogą być obsługiwane przez oddzielne moduły.Myślę, że oddzielenie logiki biznesowej od walidacji wiadomości byłoby opłacalnym zadaniem.Zaskoczyła mnie też liczba wezwań do dokumentacji.Najlepszy kod sam się dokumentuje.A jeśli naprawdę poważnie myślisz o ucieczce od tej potworności lub jej refaktoryzacji, udokumentowanie całej sprawy tylko spowolni.(Ale pozostawienie komentarzy przez mylące fragmenty może być pomocne).
AnoE
2018-04-19 00:19:04 UTC
view on stackexchange narkive permalink

Pełne ujawnienie: w przeszłości byłem starszym facetem, na którego narzekasz. Byłem, nie z wyboru, ale z konieczności, głównym architektem i programistą frameworka uderzająco podobnego do tego, co opisujesz.

Powiem ci, że zdawałem sobie sprawę ze wszystkich problemów technicznych i organizacyjnych przez cały czas . To był proces narastający; nigdy nie było takiego punktu w czasie, w którym można by podjąć jedną decyzję, aby to powstrzymać. Prawie każdy krok wydawał się wówczas dobrym pomysłem.

Istnieje sposób myślenia i pewne inne aspekty (np. Presja czasu, postrzegana presja, kultura zespołowa itp.), co prowadzi do takich rozwiązań. Nie mówi ci nic o inteligencji, charakterze ani żadnych ukrytych planach twojego programisty.

Skończyłem bałagan tymi środkami, które zajęły dosłownie lata:

  • Wybierz zupełnie nowy język programowania i framework sieciowy oraz ekosystem modułów, który zastąpi stare języki i nasz własny framework, który mieliśmy do tej pory.
  • Oceniaj i ucz się wszystkiego w wolnym czasie.
  • Wdrażaj mały, w pełni opłacony projekt klienta jako dowód koncepcji z tą technologią, upewniając się, że używasz tylko podejść, które są naprawdę standardowe, ogólnie akceptowane sposoby w tym ekosystemie, aby upewnić się, że nowe osoby (posiadające wcześniejszą znajomość języka, ale nie naszej domeny) mają dobry start.
  • Znajdź sposoby na uruchomienie nowego rozwiązania poza starym, bez ponownego wpadnięcia w pułapkę oprogramowania pośredniego (tj. luźno połączone przez mikrousługi lub pośrednio przez przeglądarkę klienta.
  • Powoli i pracochłonnie przekonaj bardzo konserwatywny zespół, że GoodIdea [tm] nie tworzy nowych projektów / funkcji w starym frameworku, ale zanurza się w nowym. To było bardzo wyczerpujące emocjonalnie.
  • Zmiana orientacji mojej roli w firmie, ostatecznie opuszczenie tego zespołu i zbudowanie nowego pod innym kątem, aby odciąć wszystkie więzi z (techniczną) przeszłością (część problemu polegała na tym, że potrafiłem rozwiązywać problemy w tym starym zespole i musiałem ich zmusić, aby stanęli na własnych nogach, odchodząc).

To była fajna jazda iz perspektywy czasu bardzo udana. Zespół jest teraz na dobrej drodze do wyjścia z tamtej epoki. Ale podejście też było dość nietrywialne. Może daje ci to kilka pomysłów i ośmielam się twierdzić, że albo będziesz potrzebować pełnego wsparcia swojego dewelopera Seniour, albo usuniesz go z tego stanowiska (w jakikolwiek możliwy sposób). Usiądź i porozmawiaj z nim długo, jeśli masz jakąkolwiek pozycję, aby to zrobić, rozmowa typu „gdzie chcemy być za 5 lat” ...

Jedna uwaga, co nie może być wystarczająco podkreślone: ​​istniejący system może być świetny (właściwie prawdopodobnie był, skoro mógł przetrwać tak długo), ale będą problemy organizacyjne związane z podejściem. Istnieje ogromny problem z dokumentacją, ogólną dystrybucją know-how, współczynnikiem ciężarówki i bardzo długą fazą uczenia się nowych kolegów. Ponadto wielu, zwłaszcza młodszych programistów, nie jest zainteresowanych inwestowaniem dużej ilości wiedzy w bardzo specyficzny kontekst aplikacji, co wcale nie pomoże im w dalszych projektach. Powody takie jak ten (w moim przypadku) doprowadziły do ​​opisanej zmiany, a mówienie o nich otwarcie usuwa osobiste żądło z problemu.

Dalsza lektura: Zgodnie z komentarzami nie wydaje się jeden, który wymyślił ten proces. :-) Zobacz wzorzec StranglerApplication, aby uzyskać więcej przemyśleń na ten temat.

Dokładnie.W takich sytuacjach istnieje duża inercja instytucjonalna, a zmiana kierunku wymaga czasu i wysiłku.+1.
Zakłada się, że istniejący system jest rzeczywiście zły i należy go wymienić.Opierając się na informacjach zawartych w pytaniu, nie zakładałbym od razu, że tak jest.Jeśli tak jest, to jest to dobre rozwiązanie.
Proces, który opisałeś, bardzo przypomina wzorzec [„StranglerApplication”] (https://www.martinfowler.com/bliki/StranglerApplication.html).
Świetne znalezisko, @tavnab!`Alternatywną drogą jest stopniowe tworzenie nowego systemu wokół krawędzi starego, pozwalając mu rosnąć powoli przez kilka lat, aż stary system zostanie uduszony.Brzmi to ciężko, ale coraz częściej myślę, że jest to jedna z tych rzeczy, których nie próbowano wystarczająco.`=> idealnie.
@rooby, wręcz przeciwnie.Istniejący system może być świetny (w rzeczywistości prawdopodobnie * był * mógł przetrwać tak długo), ale mogą wystąpić problemy organizacyjne związane z podejściem.Istnieje ogromny problem z dokumentacją, ogólną dystrybucją know-how, współczynnikiem ciężarówki i bardzo długą fazą uczenia się nowych kolegów.Ponadto wielu, zwłaszcza młodszych programistów, nie jest zainteresowanych inwestowaniem dużej ilości wiedzy w bardzo specyficzny kontekst aplikacji, co wcale nie pomoże im w dalszych projektach.Takie powody (w moim przypadku) doprowadziły do opisanej zmiany.
Zacząłeś swoją odpowiedź jako „Byłem starszym facetem”.Jaka jest różnica między „I been the Senior guy” a „I am the senior guy” ????
@IamtheMostStupidPerson AnoE nie jest dosłownie Senior Dev opisanym w OP, ale kilka lat temu był w bardzo podobnej sytuacji.Jego odpowiedź opisuje, jak to zmienił, więc nie jest już na takiej pozycji.
„Nie mówi ci nic o inteligencji, charakterze ani żadnych ukrytych planach twojego dewelopera”.Dzięki za to, to naprawdę pomogło „zdemonizować” tego dewelopera w mojej głowie.Łatwo jest pozwolić swoim emocjom przeszkodzić i przyjąć najgorsze z jego intencji / umiejętności.
Strader
2018-04-18 19:42:24 UTC
view on stackexchange narkive permalink

Wygląda na to, że ten programista opanował rynek. Niezłe narzędzie negocjacyjne do negocjacji wynagrodzenia na koniec roku.

IMHO, logika biznesowa nie należy do tłumacza, możesz zasugerować podział tego tłumacza na warstwy , oddzielając logikę biznesową od prostych metod tłumaczenia.

Przygotuj się na to, że deweloper będzie temu przeciwny;)

Ponadto kierownictwo może po jego stronie, określając dodatkowy wysiłek / koszt by to potrwało.

To może być długa walka i możesz być tym, który ostatecznie dokona separacji;)

BigMadAndy
2018-04-18 19:55:51 UTC
view on stackexchange narkive permalink

Jak mogę przekonać tego programistę (i resztę mojego zespołu, którzy są dość bierni w tego typu sprawach), że to zły pomysł?

To nie jest Twoim zadaniem jest „przekonać” programistę.

Zasadniczo główne pytanie dotyczy Twojej pozycji:

  • jeśli jesteś tylko kolegą na tym samym lub niższym poziomie możesz zgłosić ryzyko kierownictwu. Skoncentruj się przy tym na problemach, które mogą wyniknąć z obecnego systemu. To wtedy to ich decyzja, a nie twój problem;
  • jeśli jesteś szefem , uzgodnij z innymi menedżerami potrzebę zmiany systemu programowania, a następnie przekaż tę decyzję programistom . Decyzja powinna być uzasadniona i poprawnie zakomunikowana (zarządzanie zmianą w Google) oraz zorganizowana zmiana, ale wtedy powinieneś oczekiwać, że Twoi podwładni dostosują się do niej. Możesz zaoferować starszemu programistowi wpisowe, aby został z firmą, np. podwyżka pensji, więcej dni wolnych i troska o jego ego.

Pracując dla firmy ważne jest, aby rozwinąć umiejętność oderwania się od siebie i braku troski. pozytywny sens! Jeśli próbujesz zmienić coś, czego nikt inny nie chce zmienić, zostaniesz znienawidzony przez współpracowników i kierownictwo.

Skoncentruj się więc na tym, czym jest Twoje zadanie. Oznacz i informuj - ale pozwól podejmować je ludziom, którzy faktycznie są odpowiedzialni za podejmowanie decyzji. Nie ma znaczenia, czy masz rację - znam wiele osób, łącznie ze mną, którzy zostali zwolnieni, mimo że mieli rację - lub dlatego, że miała rację.

Akapit „jeśli jesteś szefem” to naprawdę zła rada.Menedżer, który podejmuje decyzje techniczne i wymaga od zespołu ich akceptacji, jest menedżerem niekompetentnym, dla którego nie warto pracować - nawet jeśli decyzje są rozsądne z technicznego punktu widzenia.
Tutaj jest kilka dobrych rad.Oderwanie się było dla mnie trudne, ale @Toss jest bardzo poprawny.Menedżerowie i współpracownicy odrywają się od pracownika, który wciąż forsuje ich program.+1 sir.
Paul Statezny
2018-04-18 22:19:20 UTC
view on stackexchange narkive permalink

Edycja: nie rezygnuj z pracy; Miałem błędne przekonanie

Wow, kiedy pierwotnie czytałem ten post, rozwiązanie techniczne brzmiało jak warstwa tłumaczeniowa, która niepotrzebnie wykonywała niepowiązane zadania. Brzmiało to bardzo sprzecznie z zasadą „pojedynczej odpowiedzialności” / filozofią UNIX, niezbyt spójne lub dobrze skonstruowane.

Myślę, że kluczowym szczegółem, którego przegapiłem, było to, że jest to archaiczny system zaplecza obsługujący podstawową logikę biznesową i myślę, że to sugeruje, że biznes utknął na tym z jakiegoś zrozumiałego powodu. Dzięki komentarzom i głosom negatywnym za skłonienie mnie do uznania tego.

Ponieważ firma jest stara, prawdopodobnie nie chce jej dotykać. Lub możliwe, że firma logika zaimplementowana w warstwie translacji jest całkowicie niezwiązana z celem tego podstawowego zaplecza.

Inne komentarze są słuszne; dokumentacja jest w porządku

Decyzja o napisaniu warstwy tłumaczeniowej wydaje się rozsądna teraz, gdy czuję, że mam w głowie dokładniejszy obraz rzeczywistości.

To, co opisujesz, nie działa Brzmi to tak bardzo jak nowy język programowania, być może nowy framework, napisany specjalnie dla tego przypadku użycia. Brzmi jak dość standardowa inżynieria w tym, co teraz rozumiem jako scenariusz.

Musisz zapoznać się z kodem, a Ty i Twoi koledzy potrzebujecie szkolenia i dokumentacji, aby zrozumieć system. Efektywne byłoby pisanie dokumentacji na temat rzeczy, gdy się ich uczysz.

To wydaje się przesadną reakcją na sytuację, która jest w zasadzie całkiem normalna w dużych organizacjach - najczęściej sprowadza się do tego, że „nikt nie chce pisać dokumentacji” z tego, co widzę.
„Warstwa tłumaczenia” niekoniecznie jest zła.Nie mamy na ten temat żadnych danych, jedynie opinię PO.Jest całkiem możliwe, że jest to dobry, solidny kawałek inżynierii (który wymaga lepszej dokumentacji), a dużo młodszy OP pokazuje tylko trochę "ale nie tego nauczyli nas w szkole".
Z poważaniem: dziękuję za głosy w dół i komentarze.Źle zrozumiałem pełny obraz.Zmodyfikowałem odpowiedź w kolorze.


To pytanie i odpowiedź zostało automatycznie przetłumaczone z języka angielskiego.Oryginalna treść jest dostępna na stackexchange, za co dziękujemy za licencję cc by-sa 3.0, w ramach której jest rozpowszechniana.
Loading...