Archiwa kategorii: Ogólnie o programowaniu

Artykuły na temat programowania, które mogą być czytane przez nieinformatyków

Recenzja książki „Zawód: Programista” Macieja Aniserowicza

W tym wpisie będę zachęcać Was do przeczytania dzieła blogera, który ma zasięg o dwa rzędy wielkości większy od mojego. W pierwszej chwili pomyślałam, że nie ma to sensu, bo kto miał wiedzieć o jego książce ten wie z samego źródła.  Po namyśle uznałam jednak, że wśród mojej publiczności chyba więcej jest osób, które nie są programistami i tylko nieśmiało zaczynają interesować się tym tematem – a ta wyjątkowa pozycja jest przeznaczona także dla nich.

No to piszę.

Na moim blogu znajdziesz sporo tekstów opisujących zawód programisty i starających się odpowiedzieć na pytanie, kto może go wykonywać i czy warto (linki poniżej) – ale Maciej podszedł do tematu w sposób o wiele bardziej metodyczny.

Moje teksty na podobne tematy:

Maciej, czyli kto?

Maciej Aniserowicz jest autorem popularnego bloga https://devstyle.pl/, na którym pisze o technologiach związanych z .NET, ale także zamieszcza sporo ciekawych, ogólniejszych felietonów. Oprócz tego jest konsultantem, nagrywa podcast, występuje na konferencjach, prowadzi szkolenia. Jest organizatorem konkursu https://devstyle.pl/daj-sie-poznac/, który dał mi sporo inspiracji i motywacji podczas mojego pierwszego urlopu macierzyńskiego (dał mi także, w ramach nagrody za 3 miejsce, moją własną licencję na IntelliJ).

Ostatnio wydał książkę „Zawód: Programista” (https://zawodprogramista.pl/), której recenzję zamieszczam poniżej w postaci subiektywnej listy plusów i minusów tego dzieła.

Plus: świetnie ustrukturyzowana – spis treści daje dobre pojęcie, o czym jest ta książka

Mogę powiedzieć krótko, o czym jest ta książka: o tym, jak wygląda praca programisty, jakich potrzeba predyspozycji, jakie są możliwe poddziedziny, czy da się przekwalifikować, na jakie można liczyć zarobki… Ale zamiast wierzyć mi na słowo, możesz po prostu zerknąć na dostępny w Internecie spis treści i od razu będziesz wiedzieć, o czym i dla kogo jest ta książka.

Treść jest świetnie przemyślana i ustrukturyzowana. Jak maile pisane przez programistów ?

W każdym razie, nie kupujesz kota w worku.

Plus: naprawdę jest takie zapotrzebowanie na rynku

Być może przytaczałam już tę historię w którymś z moich wcześniejszych wpisów. Mam dobrego znajomego, który na żale znajomych „humanistów” na temat wysokości zarobków i traktowania pracowników w zawodach związanych ze sztuką, kulturą lub urzędami reagował irytacją i za każdym razem ucinał dyskusję twierdząc, że powinni przekwalifikować się na inny, potrzebny zawód (czyli, w skrócie, nasz zawód). Wydawał się bardzo pewny swego, aż któregoś dnia jeden z wspomnianych humanistów stanął wycieńczony na jego progu i poprosił o wskazówki, jak dokładnie się przekwalifikować. Nagle, gdy wygadany znajomy miał stać się odpowiedzialny za poprowadzenie osoby, która chce przeprowadzić taką zmianę w swoim życiu – nie był już tak pewny swego. Ostrożnie wykręcił się od udzielenia konkretnych porad.

Maciej, oczywiście, nie bierze odpowiedzialności za czyjąś reorganizację życia zawodowego, ale opisuje kroki i warunki pozwalające się na coś takiego odważyć. Wiem, że istnieje duża grupa osób, które na taki właśnie poradnik czekają.

Sama podjęłam kiedyś próbę nauczenia grupy lingwistów podstaw programowania (począwszy od pisania gramatyk formalnych dla znanych im języków naturalnych). Okazało się, że około jedna trzecia zespołu lingwistów i filologów doskonale sprawdziła się w tej roli. Część z nich pracuje dzisiaj jako programiści lub testerzy.

Plus: to jest po polsku.

W czasach self-publishingu niestety nie można tego brać za pewnik, ale ta książka rzeczywiście jest napisana po polsku. Przecinki są we właściwych miejscach (mam wątpliwości co do jednego, ale to podobno cytat), słowa są użyte zgodnie z ich znaczeniem (choć nie rozumiem kawałka o paraboli), imiesłowy działają jak trzeba. Dla mnie to istotne.

Plus: trzeźwe spojrzenie na finanse

W porównaniu do większości moich przyjaciół pracujących na etat, w IT zarabiam naprawdę dużo. W porównaniu do osób, które prowadzą własne, dobrze prosperujące firmy – niekoniecznie. To kompromis, na który w tej chwili chętnie się godzę. Nie siedzę po godzinach, a w nocy śpię. Jestem odpowiedzialna za wyznaczony dla mnie wycinek, a nie za cały dobrostan firmy. Mi pasuje.

Istnieje wiele mitów na temat nieprzyzwoicie wysokich zarobków w IT. Najwięcej szumu wywołał chyba ten artykuł: IT-arystokracja. Najbardziej zepsuta pensjami i przywilejami grupa zawodowa. W książce Maciej rzeczowo rozprawia się z zawartymi w nim (i podobnych publikacjach) tezami. Tłumaczy, jakiego wynagrodzenia można oczekiwać w jakich okolicznościach, przekonuje również, że kasa to nie wszystko. Podaje wskazówki, jak najlepiej zarządzać programistycznymi finansami – a zwłaszcza ich nadwyżką!

Mój ulubiony cytat: „Arystokracja IT”? Co to za arystokracja, która nie przeżyje miesiąca bez wypłaty?

Plus: miło obcować ze spełnionym człowiekiem

Książkę świetnie się czyta również dlatego, że napisał ją człowiek spełniony. Widać, że autor robi to, co lubi i jest w miejscu, w którym chciał być. Uwielbiam obcować z takimi ludźmi, nawet tylko przez kartki książki ?

Domyślam się, że znajdą się osoby, które niektóre fragmenty zaklasyfikują jako przechwałki. Nawet jeśli nie wszystkie historie z życia i wyliczanki są niezbędne – mnie takie podejście napawa optymizmem.

Plus: … na dodatek człowiekiem, który nie żyje tylko pracą

Jeden z najbardziej przerażających mnie aspektów naszej pracy to programiści-maniacy, w których życiu nie ma nic poza IT, którzy czytają tylko branżową prasę i specyfikacje frameworków. O dziwo, niektórzy z nich mają nawet żony (mężów?) i dzieci. Zdaję sobie sprawę z tego, że ja sama, z moimi dziesiątkami hobby i bandą ludzi, których uważam za niezbędnych w moim życiu, nigdy nie dorównam tym ludziom techniczną biegłością. Tym bardziej raduje się moje serce, kiedy Maciej pisze o znajdowaniu czasu dla rodziny, o nieprzekraczalnym warunku braku nadgodzin. Ogólnie o równowadze w życiu.

Plus: sporo rad uniwersalnych, np. związanych z produktywnością

Temat zachowania równowagi pomiędzy życiem prywatnym a zawodowym jest ważnym motywem tej książki. Jednocześnie od początku jest oczywiste, że jeśli chcemy coś osiągnąć, musimy wykonać dodatkową pracę i znaleźć na tę pracę czas. Poczytać coś po powrocie do domu, napisać trochę kodu albo tekstu na blogu, przygotować wystąpienie. Kiedy to wszystko robić? Jak to robić dobrze? Publikacja zawiera podrozdział „Jak zmotywować się do pracy po pracy?”, ale także poza nim przemycone jest trochę wskazówek na temat efektywnego zarządzania czasem (np. o metodzie pomodoro). To bardzo ważne.

Swoją drogą, mogę dorzucić kilka swoich wskazówek. Moje koleżanki często wyrażają podziw wobec tego, ile rzeczy mi udaje się zrobić po pracy. Oto jedna z moich najważniejszych zasad: bez żenady płacę innym za wykonywanie powtarzalnych czynności, które niczego mnie nie uczą. Raz w tygodniu przychodzi do mnie pani sprzątająca i wymiata miejsca, do których ja nigdy nie docieram (ani mąż, ani dziecko, które za to uwielbia ładować zmywarkę). Nie gotuję codziennie. Niektóre, w tym wykształcone i pracujące zawodowo, kobiety z jakiegoś powodu czują się zobligowane do regularnego wykonywania tych czynności, niekoniecznie ze względów finansowych. Później trudno im znaleźć czas na cokolwiek innego. A dzieci rysują w przedszkolu mamę z odkurzaczem.

Plus: odnośniki pozwalające dokładniej zgłębić temat

Książka ma bardzo strawną objętość – czytałam ją tylko przy karmieniu noworodka, skończyłam w trzy dni. Bardzo podoba mi się, że w wielu miejscach wskazuje źródła i autorów, z których publikacjami warto się zapoznać. Zawiera także linki do stron Macieja, gdzie znajdziemy listy blogów, inspiracji i inne obszerne zasoby, które niepotrzebnie nie zajmują miejscach na kartkach i które Autor może na bieżąco aktualizować. Zamierzam za kilkoma z takich linków podążyć.

Plus (i trochę minus): osobiste spojrzenie

Maciej pisze o swoim osobistym (przebogatym) doświadczeniu, starając się wyciągnąć z niego wnioski dla wszystkich. Przez większość czasu to się udaje. Na dodatek jest to dobre dla narracji – całą historię czyta się jak dobrą powieść ?. Mimo wszystko, oczywiście, nie każdemu uda się powtórzyć tę sztukę. Ludzie mają różne zdolności i różne granice. Sukces to ciężka praca, ale także odrobina szczęścia. To, że Maciejowi coś się udało, nie musi znaczyć, że uda się nam po odtworzeniu jego kroków. Z drugiej strony, coś, co jego zatrzymało, dla kogoś innego może okazać się jedynie drobnym potknięciem.

Minus: za mało dystansu do coachingu

Może jestem cyniczna i zblazowana, ale w dzisiejszych czasach – coachów sprzedających masom truizmy i cudze cytaty jako własne przemyślenia – jestem bardzo sceptycznie nastawiona do sformalizowanych form samorozwoju. Kiedy Maciej zupełnie bez ironii pisze o „wychodzeniu ze strefy komfortu”, włączają mi się wszystkie dzwonki alarmowe. Choć to oczywiste, że to akurat niezbędny krok, żeby do czegokolwiek dojść.

Minus: trochę sucharów, trochę powtórzeń

Książkę pisał informatyk. Nie wiem, czy trzeba dodawać więcej ? Parę tez i anegdotek powtarza się w kilku miejscach (choć w większości przypadków Autor sam to zauważa). Parę zdań mnie zażenowało. Najbardziej chyba to: „Wyobraź sobie, że młoda mama na macierzyńskim może zobaczyć światełko w tunelu, błyskające znad garów i mopa.” Wyobraź sobie, Macieju, że dla żadnej z moich rozlicznych koleżanek w rozlicznych zawodach urlop macierzyński nie sprowadził się do „garów i mopa”.

Minus: za mało o dyskryminacji w naszym zawodzie

Problem dyskryminacji w naszym zawodzie jest prawdziwy. Dostaje się kobietom, mniejszościom narodowym, osobom starszym. Sama miała szczęście pracować w firmach, które zapewniały przyzwoity poziom kultury w pracy – a i tak przynajmniej raz zdarzyło mi się płakać w toalecie po kolejnym komentarzu na temat umiejętności kobiet (chociaż pan „nie mówił o mnie”). Natomiast słyszę co nieco od koleżanek z innych firm. Mam nadzieję, że kiedyś dostanę pozwolenie, żeby ze szczegółami opisać tu historię człowieka, który naskarżył na koleżankę do działu HR za „psucie atmosfery w pracy”, kiedy protestowała przeciwko kolejnym rasistowskim żartom na open space.

Sama zaczynam zwracać uwagę na to, że zaczynam zawyżać średnią wieku w firmie. Irytują mnie zaproszenia do „młodych, dynamicznych zespołów” – nie tylko dlatego, że są nic nie znaczącą kalką. A przecież Maciej jest chyba mniej więcej w moim wieku?

Polecam ten ciekawy artykuł na temat ageismu i pracy w Google po pięćdziesiątce (nie, nie, my aż tak nie zawyżamy 😀 ): Surviving as an Old in the Tech World.

Podsumowanie

Zdecydowanie polecam książkę zarówno aktywnym programistom, jak i osobom rozważającym wybór tej ścieżki kariery, na różnych etapach życia. To bardzo trzeźwe i uczciwe spojrzenie na nasz zawód. Nawet jeśli nie wszystkie porady są uniwersalne i nawet jeśli kilka istotnych kwestii pominięto, jest tam sporo przydatnych informacji i wskazówek, a także materiału do refleksji nad przebiegiem własnej kariery.

Bonus personalny: moja walka o papierowy egzemplarz

Książkę można było zamówić z wyprzedzeniem, ale ja czekałam na moment, kiedy naprawdę będzie gotowa. Jak tylko zorientowałam się, że to już, weszłam na stronę https://zawodprogramista.pl/ w celu jej zamówienia. Ręka zadrżała mi nad formularzem adresowym. Chciałam i wersję elektroniczną, i papierową, ale data uniemożliwiła mi zamówienie książki do domu. Otóż akurat wybierałam się do innego miasta, żeby skorzystać z usług prywatnego szpitala położniczego (ciągle się zastanawiam, czy ten blog jest dobrym miejscem na szczere porównanie warunków i przestrzegania standardów w placówkach NFZ i prywatnych; naprawdę jest o czym pisać). Zarezerwowałam tam mieszkanie na okres dwóch tygodni (żeby być w odległości 15 minut, a nie 3 godzin od szpitala), ale nie wiedziałam dokładnie ile dni zostanę i nie znałam z góry dokładnego adresu z numerem mieszkania. W końcu zamówiłam książkę pierwszego dnia pobytu tam, a drugiego byłam już w szpitalu! Na szczęście właścicielka mieszkania okazała się na tyle miła, żeby odebrać przesyłkę i wysłać mi ją do Poznania. Jeszcze nie doszła, dlatego nie widać jej na półce.

Liliana ma dzisiaj 13 dni i jest uwielbiana przez wszystkich domowników na czele ze swoją starszą siostrą.

Literatura informatyczna: wspominki o tłumaczeniach i korektach

Dawno, dawno temu zajmowałam się tłumaczeniem książek (informatycznych). Początkowo dorabiałam w ten sposób do stypendium doktoranckiego, ale nie bez znaczenia była dla mnie przyjemność płynąca z pracy z językiem oraz możliwość poznania nowych technologii. Żeby coś dobrze przetłumaczyć, należy to najpierw dogłębnie zrozumieć. Drogi na skróty nie ma.

Stan circa 2010, przed nocą oczyszczenia na moich półkach z książkami IT

Dlaczego akurat teraz piszę o tym na blogu?

Po pierwsze, z racji zalania mózgu prolaktyną (jeszcze chwilka!) nie jestem w stanie generować nowych, ciekawych tematów i chciałam odgrzać tekst ze starego bloga. Ostatecznie napisałam artykuł zupełnie od nowa.

Po drugie, odezwał się do mnie mój ulubiony redaktor z propozycją przetłumaczenia nowego wydania książki, nad którą pracowałam dobrych parę lat temu. Nie zgodziłam się (patrz punkt 1), ale zaproponowałam wykonanie korekty merytorycznej tekstu przełożonego przez nowego tłumacza. To było dla mnie zupełnie nowe doświadczenie i chcę podzielić się przemyśleniami.

Po trzecie, znajoma rozważająca wejście w obszar tłumaczeń IT zadała mi kilka pytań o tę pracę, w związku z czym musiałam przypomnieć sobie, jak to było.

Po czwarte, wreszcie, to kolejna ścieżka rozwoju w szeroko rozumianym świecie IT, a przecież o tym jest ten blog.

Jak się dostaje taką pracę?

Wydawnictwa techniczne, inaczej niż czysto  literackie, miewają na stronach zaproszenie do współpracy dla tłumaczy. Szukają raczej znających język praktyków niż osób z papierami tłumacza czy filologa.

Rekrutacja polega najczęściej na przetłumaczeniu próbki (za darmo), a następnie już rozdziału książki (za pieniądze). Jeśli po tym doświadczeniu obie strony będą zadowolone, przyszły tłumacz otrzyma propozycję przekładu, kiedy pojawi się coś ze zgłoszonej przez niego dziedziny.

Cały proces może trochę potrwać, nawet kilka miesięcy.

Co jest łatwe, a co jest trudne w przekładach IT?

Kilka uwag poniżej.

1. Amerykańscy autorzy zawsze zwracają się czytelnika bezpośrednio

W pierwszych tłumaczonych przez siebie książkach stosowałam wymyślną ekwilibrystykę form bezosobowych i tradycyjnych zwrotów do “Czytelnika”, ale po jakimś czasie uznałam, że w literaturze IT i poradnikach przyjęła się już przecież forma bezpośrednia. Problem krążenia wokół bezpośrednich zwrotów wydawał się rozwiązany.

Niestety, w tej sytuacji ujawnił się nowy problem w postaci form czasowników w czasie przeszłym oraz w trybie przypuszczającym. W języku polskim ujawniają one rodzaj gramatyczny podmiotu. Kłopotliwe stały się wszystkie sformułowania typu “if you removed line 3″ (“gdybyś usunął/usunęła linię 3”). Jeśli posiłkuję się słowem “czytelnik”, słowo to wymusza rodzaj i wszystko jest w porządku. Zwracając się do odbiorcy bezpośrednio, mam problem. Jasne, można kombinować, ale gdy autor w co drugim zdaniu używa takich zwrotów, po chwili staje się to męczące dla obu stron (dla tłumacza i czytelnika, autora zostawmy w tym wypadku w spokoju).

W niektórych angielskojęzycznych książkach programista jest kobietą – autorzy stosują zaimek “she” (istnieje jeszcze bezpieczna forma “they”, jeśli z premedytacją odmawiamy podania płci). Po polsku to by nie przeszło. W naszym języku żeńskie formy są bardzo silnie nacechowane. Gdybym zaczęła zwracać się do czytającego książkę programisty lub studenta “jeśli miałaś kiedyś do czynienia z usługami sieciowymi”, to wprawiłabym w konsternację przedstawicieli obu płci. Techniczna książka ma się czytać płynnie i bezproblemowo.

Finalnie bez poczucia większej żenady stosuję rodzaj męski, zakładając, że piszę do domyślnego “czytelnika”.

2. Choćby nie wiem jak dziękowali korektorom, książki i tak często są napisane niechlujnie

Klasyczny przykład to zdanie “Możesz wybierać pomiędzy poniższymi trzema dostawcami”, po którym następuja lista złożona z czterech pozycji. Tego typu błędy dość łatwo wychwycić, choć człowiek zachodzi w głowę, czym dokładnie zajmował się wymieniony z nazwiska korektor.

Niestety, problemów często jest więcej:

  • zaimki (“to”) pasujące do trzech różnych wspomnianych wcześniej bytów lub nie pasujące do żadnego,
  • niedziałający kod,
  • twierdzenia, które na pewno nie są prawdziwe,
  • fragmenty kodu niemające nic wspólnego z akapitem, który ma je opisywać,
  • w połowie urwane zdania.

Jako tłumacz zawsze starałam się zrozumieć intencje autora i poprawiałam tego typu rzeczy, jednak ostatnio (o czym niżej) przekonałam się, że wcale nie jest to uniwersalne podejście.

3. Tłumaczenie książek napisanych po angielsku przez autorów, dla których angielski nie jest językiem ojczystym, to temat na co najmniej rozprawę doktorską

Programowanie jest dziedziną egalitarną. Nie trzeba być rdzennym Brytyjczykiem po Oxfordzie, żeby mieć wartościowy materiał na książkę informatyczną. Książki o popularnych frameworkach piszą więc Polacy i Bułgarzy, zarówno ci pracujący w swoich ojczystych krajach jak i ci na emigracji. Jednym i drugim wydaje się, że skoro w pracy skutecznie posługują się angielskim, ich znajomość języka wystarczy do napisania książki. No cóż, nie zawsze jest to prawda.

Najgorzej jest, oczywiście, w przypadku książek wydanych własnym sumptem, których autor oszczędzał na korekcie, ale na szczęście takie dzieła rzadko kiedy się tłumaczy. W każdym razie trudno podążyć logicznie za wywodem autora, który nie widzi różnicy pomiędzy rodzajnikiem określonym a nieokreślonym, bo w jego języku nie występują ani jedne, ani drugie.

4. Rdzenni Amerykanie potrafią przyłożyć popkulturą.

Największy koszmar i blokada tłumaczeniowa spotkały mnie przy mojej pierwszej książce, ponad dziesięć lat temu. Autor określił wówczas jakąś aplikację terminem “Borg-like”. Dzisiaj Internet podpowiada nieco więcej. Wtedy tego sformułowania po prostu nie można było znaleźć w Google.

Czego się dowiedziałam po dwóch dniach kminienia? Że Borg to rasa ze Star Treka (jestem geekiem, ale w Star Trek nigdy się nie wciągnęłam, za dużo materiału do nadrobienia), która przemocą asymiluje czy wręcz “wchłania” inne rasy. O to samo można oskarżyć niektóre aplikacje.

Jest nawet taki żarcik o SP2 do Windows XP:

“Windows XP SP2 is often called Windows XP Borg Edition, as it tries to assimilate all other software (or destroys it) as is the custom with the Borg. Also common with the borg, once you install ‘Borg’ edition, resistance is futile”

5. Listingi potrafią ciągnąć się przez cztery strony…

Tłumaczowi, jak wiadomo, płaci się od “strony tłumaczeniowej”, czyli de facto od liczby znaków w wynikowym tekście. Przy listingach jest wyjątkowo mało roboty, tym bardziej, że obecnie większość wydawnictw nie próbuje polonizować np. nazw zmiennych. Szybki zarobek.

6. … ale czasem trzeba z nich wygenerować spolonizowany zrzut ekranu.

Co robi się kłopotliwe, jeśli listing zawiera błędy i kod zwyczajnie nie chce działać. Wtedy nagle jedna strona może kosztować kilka godzin.

7. Informatyczna nowomowa.

Jakiś czas temu znajomy szykował się do napisania reklamacji do wydawnictwa odpowiedzialnego za polską wersję Millenium Larssona. Otóż na tylnej okładce podobno wydanej po polsku książki pojawiają się słowa “outsiderka” i “researcherka”.  Część rozmówców stanęła w obronie tłumacza, pisząc, że “zasysanie” słów z obcych języków jest procesem naturalnym. Moim zdaniem, tendencja do zasysania obcych słów jest usprawiedliwiona, o ile słowo o danym znaczeniu nie istnieje już w języku polskim. W przeciwnym razie to zwykłe pójście na łatwiznę, niedopuszczalne zwłaszcza w wykonaniu tłumacza, czyli osoby profesjonalnie zajmującej się językiem.

W informatyce angielskie słownictwo jest wszechobecne i obezwładniające. Zgadzam się, że wymyślanie na siłę narodowych odpowiedników jest kompletnie bez sensu. Zdarza mi się, choć nie jestem z tego dumna, używać (W MOWIE) słów takich jak “zakomitować”, “dump” albo “timeout”. Poddałam się też w końcu na słowie “framework”, z którym kiedyś próbowałam się szarpać. A jednak wiele wprowadzanych w ten sposób słów ma poprawne i zrozumiałe wersje polskie. Con za tym idzie: ie toleruję pluginów (wolę wtyczki), use case’ów (przypadki użycia), forków (rozwidlenia)… Załamuje mnie “diagram kolaboracji” (współpracy, u licha! okupacja za nami). Dla tych, którzy w tej chwili przyrzekają, że nigdy nie tkną moich tłumaczeń: zawsze podaję wersję oryginalną, która ma ułatwić odnalezienie się osobie, która wcześniej czytała oryginalną dokumentację.

8. Miło jest trzymać w ręku przetłumaczoną przez siebie książkę…

Tłumacz dostaje do ręki egzemplarz autorski! O ile książka jest wydawana na papierze, o co coraz trudniej.

9. … mniej miło, po jej otwarciu na losowej stronie, trafić na przeoczoną wcześniej literówkę.

Co rzeczywiście zdarzyło mi się w przypadku pierwszej książki, mimo że przeszła przez wszystkie tury korekty (techniczna, merytoryczna, językowa).

Tłumaczenia a sprawa kobieca

Wspomnę poniżej o dwóch aspektach.

1. Żeńskie końcówki

Wracając do wspomnianej powyżej “researcherki”, mam dość silną opinię na temat żeńskich końcówek w nazwach zawodów. Z całego serca ich nienawidzę! Nie rozumiem, dlaczego spory odłam feministek tak bardzo walczy o ich stosowanie. 

Dla mnie lekarz to lekarz, nie ma znaczenia jego płeć, tylko kompetencje i, na bliskim drugim miejscu, styl bycia i szacunek do pacjenta. Czym się różni “pisarka” od “pisarza” – pisarz tworzy literaturę, a pisarka powieści dla pensjonarek? Jakie znaczenie ma tutaj płeć?! Sprawę w moim odczuciu dodatkowo pogarsza to, że żeńskie końcówki często brzmią jak zdrobnienia, mniej poważne wersje pracy, którą wykonują mężczyźni. Nie chcę, nie potrzebuję.

2. Doskonałe żarciki

A skoro o żarcikach mowa, oto przykład, na który natknęłam się kiedyś w przekładanej przez siebie pozycji z branży:

Jak wiadomo, i jak wynika z powyższego, mężczyźni zajmują się czytaniem, kobiety zajmują się plotkami. Wszyscy o tym wiedzą.  I tu muszę oddać hołd mojemu redaktorowi. Zapytany, czy mogę sprowadzić te dwie osoby do jednej płci (wydawnictwo woli spolszczać imiona w przykładach, więc fragment i tak był do zmiany) odparł, że jeśli mi zależy, to mogę nawet je odwrócić 🙂 

Sumienność, czyli dlaczego już nie polecam tłumaczy

Dwa razy poleciłam swojemu redaktorowi kolegów-informatyków, o których wiedziałam, że znają się na rzeczy i bardzo dobrze posługują się angielskim. Dwa razy prawie się spaliłam ze wstydu, kiedy okazywało się, że panowie poprzekraczali wyznaczone terminy w taki sposób, że zgodnie z umową obcięto im część wynagrodzenia za przekład.

Nie wzięłam pod uwagę tego, że jedną z najistotniejszych cech tłumacza jest sumienność, pojęcie niezbyt dobrze znane wśród programistów. Programowanie to w dużej mierze szukanie dróg na skróty, sprytnych sposobów, żeby zrobić coś szybciej, łatwiej, mniejszym nakładem sił. Usunięcie 200 linii kodu i zastąpienie ich jedną, która robi to samo (chociaż czasami załącza 3 gigantyczne biblioteki) jest powodem do dumy. Tymczasem przy tłumaczeniach po prostu się tak nie da! Trzeba przetłumaczyć wszystko, każde zdanie (no, prawie), nawet jeśli autor przez trzy strony po prostu leje wodę, żeby nadmuchać objętość książki.

Inteligencja i rzutki umysł nie pozwolą nam usiąść do tłumaczenia po dwóch miesiącach prokrastynacji i załatwić sprawy w ciągu tygodnia. Z programowaniem czasami tak się udaje.

Czego dowiaduje się korektor

Jak już wspominałam, miałam ostatnio okazję sprawdzić się w roli korektora merytorycznego książki informatycznej. Było to dla mnie przeżycie wstrząsające, ponieważ zrozumiałam, jak różne podejście do przekładu mogą mieć różni tłumacze i jak odmiennie rozumieją swoją odpowiedzialność za tekst.

Opisywałam już powyżej swoje przygody z poszukiwaniem znaczenia terminu „Borg-like”. Utknąć nad stroną książki zdarzało mi się częściej: kiedy autor załączył niedziałający kod, a ja musiałam wygenerować screenshot, więc debugowałam i pisałam kawałki od nowa; kiedy napisał „to” i w ogóle nie było wiadomo, o co mu chodzi, więc musiałam wertować dokumentację na stronie twórcy biblioteki; kiedy podane przez niego przykłady w ogóle nie przystawały do opisywanego zagadnienia i pisałam je od nowa lub sprawdzałam, skąd je ściągnął i co dokładnie mu się pomyliło. Czułam się odpowiedzialna za jakoś tekstu, który ostatecznie podpiszę także moim nazwiskiem.

Ostatnio zasiadłam do korekty merytorycznej i zrozumiałam swoją wielką naiwność…

Co może zrobić tłumacz, kiedy oryginalne zdanie nie ma sensu? Przetłumaczyć je na polski w wersji, która również nie znaczyła zupełnie nic.

Co robi, kiedy nie działa listing i nie dało się łatwo wygenerować screenshotu? Dodaje komentarz „kod nie działa” i na tym kończy swoją pracę.

Połowa czasu spędzonego przeze mnie na „korekcie” była w rzeczywistości wprowadzaniem poprawek w dziurawym kodzie, żeby polska wersja książki, w przeciwieństwie do oryginalnej, pokazywała działające przykłady. Żebym wiedziała, że tak można, w czasach tłumaczeniowych zarobiłam tę samą kasę w o połowę krótszym czasie.

Okazało się też, że tłumacze techniczni potrafią mieć ego porównywalne do programistów na backendzie. Pokłóciłam się z tłumaczem o przekład słowa „immutable”, które zamienił na „niemutowalny” (patrz sekcja o nowomowie powyżej). Takiego słowa w języku polskim nie ma, natomiast moim zdaniem spokojnie działają tu „niemodyfikowalny” lub „niezmienny”. W większości tego typu dyskusji zaznaczałam swoje zalecenia i odpuszczałam, ale tutaj nie chciałam się pod czymś takim podpisać. Wtedy tłumacz poinformował mnie, że „tak się mówi w branży”… Co rozłożyło mnie na łopatki, bo parę stron dalej nie potrafił wygenerować screenshotu z kodu, w którym jedynym problemem był brak wywołania funkcji na koniec.

Chyba napiszę w końcu osobny tekst o ego programistów.

Czy tłumaczenia informatyczne są w ogóle potrzebne?

Z jednej strony, wydaje się, że coraz mniej. Po pierwsze, naprawdę nie sposób dziś być dobrym, oblatanym programistą bez znajomości angielskiego, a to oznacza, że coraz więcej informatyków jest w stanie czytać książki w oryginale (chociaż przeszkodą bywa cena!). Po drugie, wiadomo, rozwój sztucznej inteligencji i tłumaczenia maszynowego sprawia, że niektóre teksty można wrzucić do translatora i mniej więcej zrozumieć, o co chodziło autorowi.

Z drugiej strony, dzisiaj coraz więcej osób interesuje się informatyką i programowaniem. Te tematy stają się coraz bardziej powszechne i coraz silniej wchodzą w nasze życie. O chmurze, bitcoinach i Pythonie czytają nie tylko programiści, ale także starsze dzieci, księgowe i seniorzy. Dla nich obcy język, nawet angielski, jeszcze długo może być zaporą.

Co do automatycznie tłumaczonych tekstów… Translatory są dobre, jeśli chcemy zrozumieć komunikat systemowy lub odpowiedź na forum. Książki pełne są niuansów i wstecznych odwołań… A także błędów, które tłumacz i korektor mogą skorygować, w przeciwieństwie do automatycznego translatora 🙂 Wydaje mi się, że jeszcze przez sporo lat translatory (i pamięci tłumaczeniowe CAT) będą raczej pomocą dla tłumaczy niż konkurencją dla nich.

Choć mimo wszystko odradzałabym swojemu dziecku wybór kariery tłumacza w dzisiejszych czasach.

Quiz

W ramach pół-inteligentnej rozrywki, polecam sprawdzenie, jak w różnych krajach potocznie nazywa się znak @ („małpa”).

Przy czerwonym winie, o kobietach w informatyce, z kobietami w informatyce

Poznań tej jesieni to obszar objęty epidemią: od jelitówki, przez zwykłą grypę i przedszkolne żółte katary aż po powrót odry. Chorowanie nie sprzyja kreatywności, dlatego dzisiaj odgrzewam starszy tekst, z poprzedniego bloga. Pięć lat temu (!) postanowiłam przepytać kilka koleżanek o ich przygodę z programowaniem.

Czy dużo się od tego czasu zmieniło? Nie wprowadziłam prawie żadnych modyfikacji w treści tego wpisu. Nowe akapity oraz wtrącenia zaznaczam na ciemnozielono.

Zaczęłam rozmowę pytaniem o to, dlaczego dziewczyny wybrały informatykę jako kierunek do studiowania, a także o reakcje otoczenia na ten wybór. Oto, co odpowiedziały:

  • Eliza (programuje w Delphi, C# i JS – dzisiaj w PHP): Tak naprawdę to początkowo chciałam studiować psychologię, ale w trzeciej klasie okazało się, że nie daję sobie rady z biologią. Zawsze lubiłam matematykę, dlatego w końcu wybrałam informatykę. Rodzina nie zareagowała w żaden charakterystyczny sposób. Zawsze lubiłam też grać na komputerze – uwielbiałam Boulder Dash.
  • Ewa (obecnie używa Rails i JS  i Pythona, ale jako właścicielka małej firmy ma osobiste doświadczenia z ASP, C#, PHP i Javą): Komputery pociągały mnie od dziecka. Dużą przyjemność sprawiało mi siedzenie przy komputerze mamy, kopiowanie folderów, tworzenie prostych plików wsadowych… no i gra w Prince of Persia. Oboje rodzice pracują w dziedzinach technicznych (telekomunikacja i programowanie), dlatego cieszyli się z tych zainteresowań, chociaż każde próbowało namówić mnie do wyboru swojej dyscypliny. Jednak przed rozpoczęciem studiów w ogóle nie programowałam, jeśli nie liczyć AC Logo.
  • Magda (Java serwerowa, aplikacje na Androida, aplikacje internetowe w Javie): Mam w rodzinie tradycje matematyczne. Moi rodzice są nauczycielami matematyki, więc mój wybór nie wydawał się dziwny. Miałam zdolności w tym kierunku. Poza tym lubię rozwiązywać abstrakcyjne zagadki, a programowanie dla mnie to jak układanie z klocków!

Pytałam również o rozważane inne kierunki studiów. Eliza wspominała o psychologii. Ewa przez chwilę myślała o polonistyce, jednak ponieważ za naszych czasów można było złożyć papiery tylko w 3 różne miejsca, zarzuciła ten pomysł. Magda ukończyła dwa kierunki: matematykę i informatykę. Początkowo interesowała się matematyką stosowaną, jednak teraz jest zadowolona z tego, że wybrała programowanie.

Eliza mówi, że nie chciałaby, żeby jej dziecko było programistą – „bo to nudne”. Absolutnie się z nią nie zgadzamy, jednak trzeba przyznać, że jest to praca, o której trudno rozmawia się z ludźmi robiącymi coś innego.

W następnej kolejności zadałam pytanie, jaki był stosunek dziewczyn do chłopaków w ich szkole, na studiach i w pracy. Zapłaciłam karę za ten skrót myślowy – Ewa podała mi konkretne liczby, natomiast pierwszą odpowiedzią Elizy było „lubiłyśmy ich”

Liczby:

  • Eliza: 20-10 w liceum (rozszerzony angielski), 14-48 na uczelni, 4-22 w pracy.
  • Ewa: 11-20 w szkole (mat-fiz), 14-48, 3-3 w obecnej pracy (kierownikiem projektu jest kobieta, której zależy na zatrudnianiu kobiet, po części dlatego, że produkt jest związany z modą i faceci mają problemy z identyfikacją z nim; przez wiele dni wyśmiewali się ze słodkiego wielkanocnego zajączka, którego dziewczyny wstawiły na stronę).
  • Magda: 1/3 dziewczyn w liceum („ale to dziewczyny były lepsze”), nie pamięta dokładnych liczb z uczelni, ponieważ każde zajęcia odbywały się w innym składzie. Na pewno chłopaków było więcej. W pracy 3-10.

Kolejne pytanie: Czy Twoim zdaniem kobiety i mężczyzni na kierunku technicznym na studiach są traktowani tak samo? Jeśli nie, czy możesz podać przykłady nierówności (w obie strony)?

Spodziewałam się powodzi żalu,  jednak okazało się, że wcale nie jest tak źle. Oto, co wymieniły dziewczyny:

  • Magda: Panie w dziekanacie zawsze były milsze dla mężczyzn, zwłaszcza tych przystojniejszych Poza tym nie przypominam sobie, więc chyba grubszych spraw nie było.
  • Ewa: Jeden z prowadzących rozmawiał tylko z chłopakami, nawet jeśli mieli bardzo blade pojęcie o wspólnym projekcie, a przy tym ciągle mówił do nas „panowie”.
  • Część naszych kolegów z premedytacją zapisywała się na zajęcia prowadzone przez atrakcyjne dziewczyny, traktując je bardziej jako przyjemność estetyczną niż kompetentnego nauczyciela w istotnej dla nas dziedzinie.

Powtórzyłam to pytanie jeszcze raz, ale w kontekście pracy zawodowej:

  • Ewa opowiedziała nam o paru spotkaniach biznesowych, na których potencjalni klienci rozmawiali tylko z jej wspólnikiem, mimo że w wielku kwestiach to ona ma większą wiedzę. Twierdzi jednak, że mogło tam chodzić o kwestie autoprezentacji i smiałości w kontaktach.
  • Eliza wspomniała historię, w której rozwiązała koledze problem, z którym zmagał się od dłuższego czasu. Kolega pochwalił ją przy szefie. Szef spytał, jak Elizie udało się znaleźć rozwiązanie, a ona odpowiedziała, że wyszukała je w Google. „Aha, czyli miałaś szczęście” nie było raczej adekwatną reakcją.
  • Magda czasami w obecnej pracy spotyka się ze stwierdzeniem ze strony kolegów, że robi coś w inny sposób, bo jest kobietą. „Strasznie mnie to wkurza, bo co ma do rzeczy moja płeć.” We wcześniejszych miejscach pracy nie spotykała się z takimi komentarzami.

Chciałam również poznać opinię dziewczyn na temat liczby kobiet w informatyce. Czy jest naturalna? Czy kobiety nie chcą tego robić, nie potrafią, a może chodzi o coś jeszcze innego? Ostatecznie doszłyśmy do następującego wniosku: zmuszanie kobiet do pracy w tym zawodzie nie ma sensu, jednak zdecydowanie należy je zachęcać. Sam fakt, że programowaniem zajmuje się więcej mężczyzn niż kobiet nie musi być niczym złym ani nienaturalnym, ale aktualne proporcje nie odwzorowują realnego rozkładu umiejętności. Są warunkowane kulturowo: od małego słyszymy, że „chłopcy są lepsi w naukach ścisłych a dziewczynki w humanistycznych” a nawet że „chłopcy są zdolni, ale leniwi, a dziewczynki pracowite, ale przeciętne”.

Stereotypy działają w obie strony. Słyszymy że „tylko brzydkie dziewczyny idą na politechnikę”, „na informatykę laski idą po to, żeby łatwo znaleźć męża”, ale także „jeśli pójdziesz na techniczne studia, faceci będą cię szczypać w tyłek”.

Ewa opowiedziała nam o świeżej frustrującej sytuacji powiązanej z protestowani w sprawie ACTA. Została zaproszona na oficjalną imprezę, na której przedstawiono ją – i jej szwagra –  jednemu z polskich ministrów. Oboje zostali zaprezentowani jako informatycy, z naciskiem na to, że Ewa zajmuje się programowaniem. Minister spytał szwagra, co sądzi o ACTA a gdy ten odparł „nie wiem, nie czytałem” – kompletnie zarzucił temat, nie dając Ewie okazji do wyrażenia swojej rozbudowanej opinii.

Wracając do stosunku liczby kobiet do liczby mężczyzn. Zgodziłyśmy się, że parytety nie mają sensu, jednak więcej dobrych dziewczyn w informatyce to rzecz naprawdę pożądana. Popieramy wszelkie inicjatywy mające na celu zwiększenie udziału kobiet w tym zawodzie, pod warunkiem, że nie prowadzą one do wykluczenia facetów (spójrzmy jednak prawdzie w oczy, od tego jesteśmy jeszcze bardzo daleko).

Pod koniec rozmowy próbowałyśmy odpowiedzieć na pytanie, czy istnieją obszary informatyki, w których my (lub „większość kobiet”) sprawdzamy się lepiej niż mężczyźni (lub “większość mężczyzn”).

Wygląda na to, że większość kobiet ma jednak lepsze umiejętności komunikacyjne niż większość mężczyzn. Obecność paru kobiet w zespole ma bardzo dobry wpływ na atmosferę pracy. Często mamy więcej cierpliwości podczas objaśniania różnych spraw, także osobom spoza naszej dziedziny. Nie nosimy w sobie głębokiej nienawiści do pisania dokumentacji! Chociaż czasami praca ta nie jest odpowiednio doceniana. Być może łatwiej jest nam przyznać, że (jeszcze) czegoś nie wiemy. Obawiam się trochę, że ta cecha wcale nie wychodzi nam na korzyść: inaczej odbierane są osoby, które zaczynają zdania od „uważam, że”, a inaczej te, które mówią „jestem pewien”. Nie potrafimy wskazać żadnych poważniejszych różnic, jeśli chodzi o poziom, sposób czy styl kodowania.

Przy okazji wspomniałyśmy pewnego znanego nammężczyznę, który deklaruje, że nigdy nie zatrudni kobiet, ponieważ nie wie, jak z nimi rozmawiać. Twierdzi, że jeśli skarci pracownika-mężczyznę i powie mu, że powinien robić coś inaczej, ten powie „OK” i weźmie się do pracy. Kobieta, według, niego ”zamknie się na pół dnia w łazience i będzie płakać”. Pomijając już to, że żeby zgłaszać takie obserwacje, trzeba by jednak zatrudnić kobietę – po pierwsze, żadna z nas nie płacze z takiego powodu (dwa razy w życiu płakałam w łazience w pracy, oba razy po konkretnych seksistowskich uwagach kompletnie niezwiązanych z moją pracą). Po drugie, moje doświadczenie uczy, że co prawda wiele osób powie „OK”, co nie zmieni jednak faktu, że spróbują się za to odegrać, gdy nadarzy się okazja.

Zakończę ten radosny wpis cytatem z Magdy:

Wybrałam taki zawód, bo lubię. Chociaż czasami poziom frustracji sięga zenitu! Nie rozumiem natomiast dziewczyn, które w swojej pracy chcą udowodnić, że są lepsze od mężczyzn. Nie o to chyba w życiu chodzi żeby komuś coś udowadniać.

Sama po kilku latach przeczytałam ten tekst z zainteresowaniem. Czy coś zmieniło się w środowisku? Czy zmieniły się moje poglądy? Wypunktuję poniżej kilka luźnych uwag. 

  • Dzisiaj jeszcze bardziej niż wtedy jest dla mnie oczywiste, że za “zachęcanie” kobiet do IT (a jeszcze bardziej za ich niezniechęcanie) trzeba się zabrać bardzo wcześnie. Począwszy od sklepów z zabawkami i zawartości działów “dla chłopców” i “dla dziewczynek” oraz wyboru komplementów, jakimi obdarzamy małe dzieci. 
  • Dziś jeszcze mniej chętnie używam sformułowań “większość kobiet” i “większość mężczyzn”. 
  • Uważam,  że krótkoterminowo i w niektórych sytuacajch parytety mogą mieć sens. 
  • W sektorze IT potrzeba coraz więcej pracowników. Również z tego powodu, kobiet jest więcej niż jeszcze parę lat temu. Pewną nowością są osoby, które nie studiowały informatyki, ale udało im się przekwalifikować.
  • W backendowych zespołach, z którymi obecnie pracuję, nadal nie ma jednak ani jednej programistki (są za to dwie techniczne managerki: ludzi i produktu).
  • Głupie żarciki w pracy jak były, tak są. Wbrew obiegowej opinii, korporacje z reguły radzą sobie z tym tematem lepiej niż “przyjazne” niewielkie firmy. 
  • Wśród kobiet, które twierdzą, że jakakolwiek dyskryminacja w naszej branży jest wyssana z palca, wiele jest informatyczkami w drugim pokoleniu. Moim zdaniem potwierdza to tezę o znaczeniu warunkowania w domu, na najwcześniejszym etapie rozwoju. Jeśli dziewczynka wychodzi z domu rodzinnego przekonana, że może wszystko, jest znacznie mniej podatna na drobne przejawy seksizmu i dyskryminacji.

NLP w pigułce

Mam koleżankę, która jest doświadczoną programistką Javy oraz Scali. Kilkanaście razy w roku występuje na międzynarodowych konferencjach. Z opisu łatwo wydedukować, ze na co dzień nie potrzebuje mojej ekspertyzy technicznej ? Jednak kilka dni temu poprosiła mnie o pilne wsparcie. Napisała, że do tej pory traktowała NLP (przetwarzanie języka naturalnego, ang. natural language processing) jako „coś, z czego ludzie robią doktoraty”, a teraz musi sama poprawić kod z tej dziedziny.

Kod okazał się pluginem do Slacka, który pozwala programistom wydawać polecenia w języku naturalnym i w ten sposób zarządzać procesem budowania, testowania i wdrażania aplikacji. Chciała dopisać kilka poleceń, ale wystraszyły ją sformułowania takie jak „tokenizacja” czy „VP”, i inne, bezpośrednio związane z wykorzystywaną tam biblioteką OpenNLP. Poprosiła mnie o praktyczny kurs NLP w pigułce, opisujący kroki niezbędne do zrozumienia, o co użytkownikowi właściwie chodzi.

Oto on.

Pomijam kwestię rozpoznawania mowy, ponieważ niespecjalnie się na niej znam i nie ma ona znaczenia w przypadku pisania pluginów do slacka. Rozpoznawanie mowy to zagadnienie z dziedziny przetwarzania sygnałów, obecnie realizowane niemalże wyłącznie przy użyciu uczenia maszynowego. 

Na początku jest zdanie.

Tak przynajmniej załóżmy. W rzeczywistości zdań może być kilka – wtedy trzeba ja jakoś rozdzielić, co w zależności od języka może sprowadzić się do cięcia po kropkach, albo być super skomplikowanym zadaniem wymagającym wnikania w składnię.

Nietrywialny przykład z języka polskiego:

Poza tym nie wszystko jest zdaniem. Bezpieczniejszy jest termin wypowiedzenie (ang. utterance), który obejmuje również wszelkiego typu równoważniki i pojedyncze słowa.

Załóżmy, że nasze zdanie to „wrzuć wersję 3.1 config na produkcję”.

Zdanie trzeba podzielić na tokeny.

Token to, w przybliżeniu, słowo. W niektórych językach tokenizacja jest prosta. W polskim możemy chcieć rozdzielić np. „jasnozielony” na dwa tokeny: „jasno” i „zielony”. W angielskim zamienić „wanna” na „want to”. Po hiszpańsku „pokaż mi to” pisze się łącznie „muéstramelo”, co, żeby móc przeprowadzić jakąkolwiek analizę, musimy rozbić na trzy tokeny: „muestra” „me” „lo” (i po drodze zgubić akcent).

Normalizacja.

Czasami razem z tokenizacją przeprowadza się normalizację, czyli np. zamienia słowa „jeden”, „jedna” itp. na „1”.

Wszystko to po to, żeby uprościć sobie życie i zmniejszyć rozmiary modelu, w oparciu o który analizujemy tekst.

Dalej musimy rozpoznać byty nazwane (ang. named entities).

Byty nazwane to, w uproszczeniu, byty reprezentowane przez nazwy własne – w odróżnieniu od rzeczowników pospolitych. Ich rozpoznanie nie zawsze jest łatwe. Często zależy od kontekstu. Nierzadko w wyniku takiej analizy dostajemy kilka hipotez. Przykładowo, „house” to po angielsku „dom”, ale może to być również nazwa serialu lub nazwisko jego głównego bohatera.

Po tym kroku analizy powinniśmy wiedzieć, która część naszego wypowiedzenia to byt nazwany, i jakiego typu jest to byt (miejsce, osoba, tytuł, …).

W naszym przykładzie bytem nazwanym może być „config” (jako nazwa aplikacji) oraz „produkcja” (jako nazwa środowiska).

Ujednolicenie form wyrazów: lematyzacja lub stemming.

Etap ten ma różne znaczenie w zależności od języka. Chodzi tu o sprowadzenie różnych form tego samego słowa do wersji uznawanej za podstawową.

  • Stemming to obcięcie wszelkiego rodzaju przedrostków i przyrostków, mające na celu dotarcie do nieodmiennego „rdzenia” reprezentującego wyraz. Sam rdzeń niekoniecznie musi być poprawnym słowem. Algorytm stemmera nie musi być zależny od języka.
  • Lematyzacja to sprowadzenie słowa do jego podstawowej postaci. W przypadku czasownika będzie do bezokolicznik, w przypadku rzeczownika – mianownik liczby pojedynczej. Do wykonania tego zadania potrzebny jest słownik lub rozbudowany zestaw reguł fleksyjnych dla danego języka.

Oczywiście zadanie to jest trudniejsze dla silnie fleksyjnych języków, jak polski.

Rozpoznawanie części mowy.

W końcu powinniśmy się dowiedzieć, z jakimi częściami mowy mamy do czynienia, najlepiej również w jakich odmianach. Z reguły informację te zwraca lematyzator. Tegu typu analiza może być oparta o słownik, ale może również wykorzystywać końcówki fleksyjne (np. jeśli nieznane nam polskie słowo kończy się “zować”, można przyjąć hipotezę, że to czasownik).

Wreszcie dochodzimy do parsowania.

Parsowanie to analiza składniowa, jednak w praktyce już na tym etapie często wydobywa się także informacje semantyczną, czyli znaczenie wypowiedzenia.

Zasadniczo, do znaczenia można dobrać się na jeden z trzech sposobów:

Wyrażenia regularne.

To najprostsza, najbardziej naiwna metoda, jednak w przypadku pluginów do slacka, które mają pozwalać na wykonanie kilku prostych operacji, nierzadko okazuje się wystarczająca.

Możemy napisać:

lub coś odrobinę bardziej skomplikowanego i już dostaniemy wszystkie potrzebne nam informacje.

Gramatyki formalne

Oparte na teorii Chomskiego, gramatyki (tworzone ręcznie lub automatycznie) to zestawy reguł, które definiują, jak może wyglądać poprawne zdanie w danym języku (naturalnym, jak polski, albo sztucznym, jak C++).

Gramatyka może składać się np. z takich reguł:

Wówczas nasza grupa rzeczownikowa (NP) może mieć postać “a cat”, “the cat”, “a dog” i “the dog”.

Gramatykę można zapisać w postaci automatu skończonego.

Uczenie maszynowe

Efekt jest ostatecznie taki sam jak w przypadku gramatyk, tylko zamiast żmudnie definiowanych reguł wykorzystywane są wnioski wyciągnięte podczas trenowania systemu przy użyciu wybranej metody (np. CRF) na dużej ilości odpowiednio opisanego tekstu (na korpusie)

Reprezentacja danych semantycznych.

Ostatecznie powinniśmy otrzymać coś w rodzaju „ramy”, która często przypomina strukturę zdania. W naszym wypadku będzie to mniej więcej coś takiego:

Parsowanie płytkie i głębokie.

Głębokie parsowanie to pełne odtworzenie drzewa składniowego zdania. Parsowanie płytkie (czasami określane terminem chunking) ma na celu wydobycie istotnej informacji, bez potrzeby wyciągania wszystkich zależności składniowych pomiędzy słowami.

Analiza koreferencji.

Na początku napisałam, że punktem wyjścia jest dla nas zdanie (bądź wypowiedzenie), ale w języku naturalnym zdania mogą być ze sobą powiązane w taki sposób, że w celu zrozumienia zdania musimy cofnąć się o jedno lub więcej zdań wstecz.

W analizie koreferencji chodzi przede wszystkim o anaforę. Jeśli użytkownik wyda polecenie „wdróż to”, musimy zrozumieć, do jakiego wcześniej wspomnianego bytu się odnosi.

Przykład: OpenNLP

Istnieje trochę gotowych narzędzi i zasobów do uprawiania NLP: parsery, korpusy tekstów, treebanks (zdania rozbite na drzewa składniowe), biblioteki implementujące algorytmy uczenia maszynowego. Kod, przy którym pracowała Jessica, korzystał z javowej biblioteki OpenNLP, która oferuje trochę gotowych modeli językowych, a także umożliwia trenowanie własnych.

Co możemy od niej dostać?

Np. dla zdania “namiekko.pl is a the coolest site” otrzymamy:

Jak przełożyć to na nasze potrzeby? Musimy stworzyć jakieś mapowanie pomiędzy odnalezionymi grupami a naszą reprezentacją danych. Możemy napisać reguły takiego typu: jeśli czasownik w VP (verb phrase) to „deploy” lub „push”, to chcemy wykonać naszą akcję deploy. Argumentów dla tej akcji należy szukać w następujących elementach drzewa składniowego (…)

Zasoby

Wyrażenia regularne dla nieprogramistów

Wyrażenia regularne wspominałam już w poprzednim wpisie. Jest to narzędzie ukochane przez część programistów i znienawidzone przez innych. Dzisiaj chciałabym podzielić się następującą refleksją: wyrażenia regularne mogą ułatwić życie nie tylko programistom. Przy ich pomocy można uprościć wiele manualnych czynności, wykonywanych na przykład w pracy biurowej.

Czym są wyrażenia regularne?

Teoria raczej nie zachęci początkujących, ale do zastosowań praktycznych wystarczy potraktować je jako wzorce, które umożliwiają przeszukiwanie tekstu i dokonywanie w nim podmian.

Pełna składnia wyrażeń regularnych została opisana na przykład w tej (angielskojęzycznej) ściądze. Poniższa tabelka opisuje kilka najbardziej podstawowych symboli:

Symbol Znaczenie Przykład
. Dowolny znak. k.t pasuje do „kot” i „kat”
+ Powtórzenie poprzedzającego znaku jeden lub więcej razy. kot+ pasuje do „kot”, „kott”, „kott” itp.
* Powtórzenie poprzedzającego znaku zero lub więcej razy. kot* pasuje do „ko”, „kot”, „kott” itp.
{m,n} Powtórzenie poprzedzającego znaku od m do n razy. ko{2,4}t pasuje do „koot”, „kooot” i „kooot”.
^ Początek linii. ^k – literka k zapisana na początku linii
$ Koniec linii k$
[abc] Znaki ze zbioru, wyszczególnione k[ao]t pasuje do „kot” i „kat”.
[a-c] Znaki ze wskazanego przedziału [2-4] to cyfra „2”, „3” lub „4”.
\b Granica słowa .+a\b to dowolne słowo kończące się na literą „a”, np. „torba”.
\d Cyfra \d\d pasuje na przykład do „23”
\s Biały znak k\st pasuje do „k t”
\S Znak niebiały k\St pasuje do „kot”, „kit”, ale nie do „k t”

Zadanie

Wyobraźmy sobie teraz następujący scenariusz z życia biura. Szef firmy, pan Cebuliński, organizuje przedświąteczną galę. W ramach oszczędności poprosił siostrzenicę – studentkę pierwszego roku informatyki – o wydobycie z bazy danych informacji o klientach, którzy terminowo opłacali faktury. Na podstawie przesłanej przez nią listy menedżerka biura, pani Nokturniak, ma przygotować listę gości. Jej zadaniem jest znalezienie stu klientów, na których firma w tym roku zarobiła najwięcej. Dodatkowo, ponieważ prezes Cebuliński rozwodzi się ze swoją żoną Anną, na liście gości nie może znaleźć się ani jedna kobieta o tym imieniu.

Lista ma następującą postać:

1. Borowiak, Kazimierz; 10000 zł; terminowo; kborowiak@example.com
2. Borowiak, Ania B.; 10011 zł; nieterminowo; abborowiak@example.com
3. Nowak, Jan, 9321 zł; terminowo; a@example.com
4. Nowak, Janina, 9322 zł; nieterminowo; ab@example.com
...
9816. Zi łkowski, Andrzej; 100 zł; terminowo; aziolkowski@example.com

Zadania pani Nokturniak prezentują się następująco:

  1. Musi usunąć z listy wszystkie Anie, Anki i Anny.
  2. Zauważyła, że litera „ó” została zamieniona na spację. Musi więc przejrzeć listę prawie 10000 nazwisk i poprawić niektóre z nich.
  3. Musi znaleźć 100 „najdroższych” klientów spośród tych, którzy płacili terminowo, aby wysłać im zaproszenia.

Pani Nokturniak zaplanowała kolejną długą noc przy komputerze. Spróbujmy chociaż trochę ułatwić jej życie.

Potrzebny nam będzie edytor tekstu, który rozumie wyrażenia regularne (albo konsola Linuksa – pokażę w kolejnym wpisie, jak ją do tego wykorzystać). Może to być np. Notepad++. Załóżmy, że pani Nokturniak otworzyła już edytor i przekleiła do niego dane.

Usunięcie Ań

Co wspólnego mają ze sobą łańcuchy znaków „Ania”, „Anka” i „Anna”? Wyglądają prawie tak samo, różnią się jedynie trzecim znakiem. Zgodnie z zamieszczoną powyżej tabelą, kropka (.) to symbol uniwersalny. Do wszystkich trzech słów zostanie dopasowany dopasowany wzorzec:

An.a

Wyrażenie regularne w edytorze Notepad++ dopasowane do słowa w tekście
Wyrażenie regularne w edytorze Notepad++ dopasowane do słowa w tekście

Tu uwaga na drobną pułapkę. Ciąg znaków „Anna” może być częścią dłuższego słowa, np. nazwiska („Annakowski”). Dla pewności zaznaczmy, że interesują nas tylko te wystąpienia, które nie są częścią dłuższego słowa. Użyję do tego symbolu granicy słowa:

\bAn.a\b

Co dalej? Wyczyśćmy wszystkie linie zawierające imię Anna. Wzorzec musi mieć postać: „nieważne co – imię Anna – nieważne co”, czyli:

.*\bAn.a\b.*

albo jeszcze lepiej dodajmy do niego znak początku i końca linii (choć domyślnie wyrażenia regularne i tak działają jedynie w ramach jednej linii, czyli efekt będzie ten sam):

^.*\bAn.a\b.*$.

Każmy edytorowi zastąpić wszystkie takie linie linią pustą.

regex2
Zamiana linii zawierającej którąś z wersji imienia “Anna” na linię pustą.

W tej chwili nasz dokument nie zawiera już danych żadnych Ann.

W podobny sposób możemy od razu usunąć wiersze reprezentujące klientów nieterminowych, których także nie mamy uwzględniać w obliczeniach.

2. Zamiana (niektórych!) spacji na „ó”

Jeśli po prostu zamienię wszystkie spacje na „ó”, efekt nie będzie zadowalający:

Muszę odszukać tylko te spacje, które znajdują się pomiędzy dwiema małymi literami.

Mogę wykorzystać w tym celu przedziały:

[a-z] [a-z]

lub bezpieczniej

[a-zA-ZąśćżńżĄŚĆŻŃŹ] [a-zząśćżńż]

lub najbezpieczniej (z uwzględnieniem wszystkich, nie tylko polskich znaków w nazwiskach, ale nie w każdym edytorze to zadziała) pełną klasę małych liter:

\p{Lu} \p{Lu}

Ok, znaleźliśmy te spacje, tylko jak je teraz zamienić? Jeśli zamienię cały znaleziony łańcuch znaków, Zi łkowski nie zamieni się w Ziółkowskiego, tylko w Zókowskiego (litery dopasowane do [az] również zostaną zamienione). Na pomoc spieszą nam tzw. capturing groups, czyli grupy przechwytujące.

Wszystko, co napiszę w nawiasie, zostanie zapamiętane jako grupa oznaczona kolejnym numerem. Do grup mogę się następnie odnieść w wyrażeniu, którym chcę zastąpić odnaleziony wzorzec. Jak to zrobić? Mogę mój wzorzec zapisać tak:

([a-zA-Z]) ([a-z])

a wyrażenie zastępujące:

\1ó\2

Wówczas każde wystąpienie spacji pomiędzy dwiema literami (przy czym druga z nich musi być mała) zostanie zastąpione literą „ó” otoczoną oryginalnymi dwiema literami (z grupy pierwszej i drugiej).

regex3

3. Odnalezienie „najdroższych” klientów

Do tego zadania można podejść na dwa różne sposoby.

Łatwiej ale z pomocą z zewnątrz

W wersji pierwszej wystarczy sprowadzić dokument do formatu CSV (skrót od Comma-Separated Values, czyli wartości rozdzielane przecinkami, ale czym w rzeczywistości najczęściej są to średniki, a nie przecinki). Format ten jest rozumiany przez większość, jeśli nie wszystkie, programów kalkulacyjnych typu Excel. Następnie można posortować wiersze według kolumny zawierającej poniesione przez klienta koszty.

W obecnej chwili nasze wiersze mają następujący format:
1. Borowiak, Kazimierz; 10000 zł; terminowo; kborowiak@example.com
Wystarczy zamienić pierwszą kropkę na średnik albo usunąć liczbę i kropkę. Na dobrą sprawę moglibyśmy nawet zostawić numer porządkowy jak jest. Nie będzie miał sensu, ale nie przeszkodzi w naszych obliczeniach.

Dla porządku (sic) usuńmy jednak numer porządkowy. Chcemy dopasować się do liczby na początku linii, po której następuje kropka oraz spacja – i całość zastąpić pustym łańcuchem znaków. Czyli:

^\d+\. albo ^\d+. (kropka to symbol uniwersalny, w szczególności dopasuje się do symbolu kropki; jeśli chcemy na pewno złapać tylko kropkę, musimy poprzedzić ją we wzorcu tzw. symbolem ucieczki „\”, który odbiera znakowi jego specjalne znaczenie).

Dokument z liniami postaci:
Borowiak, Kazimierz; 10000 zł; terminowo; kborowiak@example.com

możemy już spokojnie otworzyć w excelu jako plik CSV i tam przeprowadzić sortowanie.

Wersja dla ambitniejszych

Alternatywnie możemy przestawić kwotę na początek linii i w oparciu o nią posortować linie w pliku. Z pomocą znowu przyjdą nam grupy. Plan jest następujący: podzielić każdą linię na 3 grupy: przed kwotą, kwota i za kwotą, następnie zmienić ich kolejność z 123 n 213. Na koniec posortować (w edytorze, jeśli daje taką możliwość, albo w wierszu poleceń dowolnego systemu operacyjnego za pomocą instrukcji sort).

Spróbujmy. Linię pasującą do wzorca

^(.+)(\d+ zł; )(.+)$

zamieńmy na

\2\1\3

W efekcie mamy linie:
10000 zł; 1. Borowiak, Kazimierz; terminowo; kborowiak@example.com
Takie linie możemy już posortować wg wartości liczbowych.

Sortowanie linii według wartości liczbiwych.
Sortowanie linii według wartości liczbiwych.

Możliwy kłopot z sortowaniem

Drobny kłopot: standardowe sortowanie leksykograficzne (czyli według alfabetu) ustawi nam liczby w nieodpowiedniej kolejności, np. 10 przed 9, np.:
1
10
11
2
22
9

Żeby takie sortowanie się udało, liczby muszą być tej samej długości – dopełnione na początku zerami (09 będzie przed 10).
01
02
09
10
11
22

Prawdę mówiąc na szybko nie potrafię podać jednej zamiany, która upora się z wszystkimi przypadkami! Ale można zastosować tę samą zamianę kilka razy, aż przestaniemy widzieć jakiekolwiek zmiany. Załóżmy, że chcemy, żeby wszystkie liczby ostatecznie zajmowały 10 cyfr.

Możemy wtedy zamieniać każdą liczbę na początku linii, która ma mniej niż 10 cyfr:

^(\d{1,9} )

na tę samą liczbę (grupa przechwytująca!) poprzedzoną zerem:

0\1

Kiedy zapis liczby osiągnie długość 10 znaków, wzorzec przestanie się dopasowywać.

Na koniec wreszcie poprawnie sortujemy – i już możemy rozsyłać zaproszenia.

Trwało do trochę krócej niż całą noc, prawda?

Przekwalifikowanie – mrzonka czy realna szansa?

Chociaż nie zawsze da się to rozpoznać po ubiorze bądź stylu życia* i niekoniecznie jest to sprawiedliwe, zarobki w miarę doświadczonych programistów czynią z nich jednych z najlepiej wynagradzanych ludzi w Polsce.

Nie wszyscy zajęli się informatyką z powodu absolutnej pasji. Kodowanie to bardzo przyjemna, satysfakcjonująca i stanowiąca wyzwanie praca – jednak wielu znanych mi programistów do poczucia osobistego spełnienia potrzebuje również samorealizacji w nieco bardziej humanistycznych dyscyplinach.** Być może dlatego nierzadko słyszę kolegów po fachu sarkających na bezrobotnych absolwentów kierunków miękkich. „Po co szedł na takie studia?”, „Wiadomo, że praca jest gdzie indziej”, „Niech się przekwalifikuje, przecież my też co chwilę od podstaw uczymy się czegoś nowego”.

Opinie te bywają powtarzane zdecydowanie i bez zastanowienia. A jednak nie tak dawno byłam świadkiem sytuacji, w której absolwent teatrologii (nie wymyślam tego!) zapytał zaprzyjaźnionego programistę, od czego zacząć przekwalifikowanie się… a programista zbladł. Co innego teoretyzować o zmianie w cudzym życiu, a co kogoś przekonać i przyjąć choć część odpowiedzialności za jego rozwój, a ostatecznie także sukces bądź porażkę.

W tym wpisie postaram się odpowiedzieć na pytanie, czy da się zostać programistą na późniejszym etapie życia i podzielę się wskazówkami na temat tego, jak zacząć.

Warunki konieczne

Skoro popyt jest tak duży, czy programistą może zostać każdy? Skrócona odpowiedź brzmi: absolutnie nie!!! Jednak z powodzeniem może się to udać całkiem sporej grupie osób, które wcześniej nie rozważały tej profesji.

Następujące cechy i umiejętności uważam za konieczne do rozpoczęcia nauki w tym kierunku:

1. Analityczne, uporządkowane myślenie

Programowanie to w dużej mierze praca kreatywna, ale ten rodzaj kreatywności ma niewiele wspólnego z twórczym chaosem. Musisz być w stanie myśleć algorytmicznie: wyraźnie definiować kroki prowadzące do uzyskania wyznaczonego celu. Musisz przykładać uwagę do szczegółów. Musisz przewidywać, co może pójść nie tak, jak niestandardowo może się zachować klient, jakie problemy mogą wystąpić. W dużej mierze sprowadza się to do tego, że programista powinien mieć stosunkowo wysoki iloraz „matematycznej” („tradycyjnej”) inteligencji.

2. Cierpliwość

Materiału do przyswojenia jest dużo. Tworzenie prawdziwych, złożonych aplikacji trwa i wymaga współpracy wielu osób. Co prawda istnieją trendy wytwarzania oprogramowania od strony interfejsu użytkownika, gdzie od razu widać włożony wysiłek, jednak musisz być gotowy na żmudną pracę, która długo nie przynosi widocznych efektów (oprócz przechodzących testów – bo oczywiście będziesz pisać testy).

3. Radość z pisania kodu

Większość znanych mi programistów bardzo wcześnie zaczęła zdradzać smykałkę do kodowania. Sama spędziłam długie godziny nad otrzymanym na komunię Commodore 64, programując quizy i przelatujące przez ekran rakiety ASCII Art (następnie mój rozwój zatrzymał się na lata na tym etapie). Jeśli jednak nie zostałeś odpowiednio zachęcony za młodu, postaraj się możliwie szybko znaleźć odpowiedź na pytanie: „czy sprawia mi to przyjemność?”. Po pierwszym kursie programowania lub po pierwszej przeczytanej książce – spróbuj rozwiązać prosty problem programistyczny (np. na sprawdzarce takiej jak ta: http://acm.timus.ru/). Jak było? Udało Ci się? Co czułeś, kiedy program działał coraz lepiej? Ogromną satysfakcję, a może ulgę, że wreszcie koniec? To bardzo ważne.

4. Znajomość angielskiego

W dzisiejszych czasach nie da się programować bez dobrej (biernej) znajomości (pisanego) angielskiego. Większość kursów (o których zaraz) jest po angielsku. Dokumentacja, którą będziesz czytać jest prawie zawsze po angielsku. Gotowe rozwiązania popularnych problemów są opisane po angielsku, np. na http://stackoverflow.com/. Być może uda Ci się dorwać podręcznik po polsku (warto), ale większość ratujących tyłek, aktualnych treści istnieje jedynie w języku angielskim.

Przydadzą się

Po pierwsze, na pewno przyda Ci się mentor. Życzliwa osoba już pracująca w zawodzie, o którym myślisz, skłonna poświęcić Ci trochę czasu i wskazać kierunki rozwoju. Znasz kogoś takiego? Doskonale. Nie znasz? Jeśli mieszkasz w większym mieście, przejdź się kilka razy na spotkania lokalnych User Groups***. W przeciwnym razie możesz spróbować uzyskać wsparcie w grupach i na forach w Internecie.

Po drugie – czy znasz języki obce? Jeśli tak, to tym lepiej dla Ciebie. Im więcej tym lepiej. Język programowania to też język, który ma swoją składnię i semantykę. Jeśli zdołałeś opanować język obcy (analitycznie, czyli potrafisz narysować drzewo składniowe zdania), w Twoim mózgu powinny już być wydeptane najważniejsze ścieżki umożliwiające korzystanie z języka programowania.

Jak się nauczyć?

O ile znasz angielski, a jak tłumaczyłam powyżej, właściwie musisz go znać, to masz do dyspozycji ogrom wiedzy przedstawionej w portalach MOOC (Massive Open Online Course, czyli masowe otwarte kursy online), takich jak Edx czy Coursera. W większości przypadków kursy składają się z wykładów, ćwiczeń praktycznych (w postaci testów) oraz zadań programistycznych, sprawdzanych albo automatycznie, albo przez innych uczestników kursu. To doskonały punkt startowy.

Oprócz tego są podręczniki, dokumentacje języków programowania, a także warsztaty**** (często darmowe) organizowane przez różne społeczności, np. Geek Girls Carrots.*****

Jaki język?

Uparcie utrzymuję, że najbardziej przyszłościowy (liczba ofert pracy, przeznaczenie) język, którego można się w miarę szybko nauczyć od podstaw, to Python. Ale możesz rozejrzeć się, czego potrzebują i uczą w Twojej okolicy.

Rozmowa o pracę

Są firmy, które nigdy nie zatrudnią początkującego programisty. Są szefowie gotowi pracować tylko z pasjonatami, od podstawówki piszącymi wirusy. W niektórych przypadkach takie wymagania mają sens, w innych niekoniecznie. Uwierz jednak, że istnieje masa firm gotowych podjąć ryzyko przyjęcia kogoś niezbyt doświadczonego i przeszkolenia go.

Nie będę tu powtarzać tradycyjnych porad na temat pisania CV i przygotowania do rozmowy rekrutacyjnej. Najważniejsze: nie ściemniaj! Jeśli jesteś w stanie psychicznie znieść porażkę, po nieudanej rekrutacji dopytaj, czego Ci zabrakło i spróbuj rozwinąć się trochę w tym kierunku.

Warto pamiętać, że informatycy w firmach wytwarzających oprogramowanie to nie tylko programiści. Do branży możesz wejść trochę „od tyłu”, na przykład jako tester. Mimo wszystko zachęcam do rozpoczęcia procesu zmian od przyswojenia jednego przynajmniej języka programowania.

Licz się z tym, że…

1. Będziesz się ciągle uczyć

Taki zawód. Jeśli chcesz coś w nim osiągnąć i mieć pewność zatrudnienia, będziesz co jakiś czas przerabiać nową książkę, nowy blog, nowe kursy. Nawet jeśli w pracy nie będziesz siedzieć po godzinach (rozsądni szefowie wiedzą, że liczba błędów wprowadzonych podczas nadgodzin często niweluje jakąkolwiek płynącą z nich wartość dodaną), ale czasem po pracy,  w prywatnym czasie, będziesz musiał przysiąść nad nową technologią.

2. Twoja głowa będzie stale w pracy

To również wynika ze specyfiki zawodu. Nierozwiązane problemy będą się za Tobą wlekły. Spędzisz wiele wieczorów, zastanawiając się, dlaczego to u licha nie działa. Dobra strona medalu: niejednokrotnie przekonasz się, że Twój mózg pracował, kiedy spałeś, a że niemożliwy do rozwiązania problem następnego dnia okaże się trywialny.

3. Koledzy z pracy nie raz zdziwią się, że czegoś nie wiesz

Nauczyłeś się pierwszego języka programowania. Na trzeciej z rzędu rozmowie rekrutacyjnej napisałeś test na 80%, pokazałeś, że jesteś odpowiedzialnym i zdeterminowanym człowiekiem – i dostałeś pracę. Pierwszego dnia przychodzisz do biura, dostajesz swoje pierwsze zadanie i nagle okazuje się, że kompletnie nie wiesz, jak zacząć. Znasz język, ale co oni mówią o LDAP, kontroli wersji, bazie danych…? W tym momencie wróć do punktu 1. Będziesz się ciągle uczyć. W obliczu nieznanych problemów spróbuj najpierw skorzystać z Google. Jeśli nie dajesz rady – poproś o pomoc. Zadbaj o to, żeby nigdy nie pytać dwa razy o to samo.

Studia informatyczne trwają pięć lat i nie polegają jedynie na nauce programowania. Ich absolwenci często sami nie zdają sobie sprawy, że niektóre zagadnienia nie wchodzą w zakres wiedzy ogólnej i mogą być komuś (bądź co bądź) w branży kompletnie nieznane. Przełknij dumę, uzupełnij luki, znajdź sobie miejsce w organizacji. Będzie dobrze.

4. Na początku możesz zarabiać mniej niż dotychczas

Nie tylko możesz zarabiać mniej niż dotychczas, ale na dodatek może to być mniej, niż zarabia o połowę od Ciebie młodszy dzieciak w sąsiednim kubiku. Nie przejmuj się, to tymczasowe. Nie ma lepszej metody nauki programowania niż w prawdziwej pracy – potraktuj to jako (opłacaną przecież!) inwestycję w siebie.

Uwaga: z awansami i podwyżkami w firmach informatycznych różnie bywa. Czasami jedyną metodą na zauważalną podwyżkę jest przejście do innej firmy.

Czy płeć ma znaczenie?

Serio, nie wiem.

Kobiecie, która chce się przekwalifikować, tak samo jak początkującej praktykantce, paradoksalnie może pomóc stereotyp „damy w opałach”. W zmaskulinizowanym biurze możesz pozwolić otoczyć się mentorską, dżentelmeńską i trochę protekcjonalną opieką, o ile całe Twoje jestestwo nie protestuje przeciwko takiemu stawaniu sprawy. Ostrzegam jednak – takie łatki trudno potem zgubić.

Czy znam ludzi, którym się udało?

Tak!!!

Słowa klucze: odwaga, wytrwałość, inteligencja, ciekawość.

A jeśli się nie uda?

Wysiłek włożony w przyswojenie tych kwestii i tak nie pójdzie na marne. Podstawy programowania będą coraz bardziej potrzebne do wykonywania innych zawodów. Wyraźnie to widać np. w dziedzinie biotechnologii.

Przypisy


* Nie piję tu przesadnie do stereotypu niedomytego informatyka. Uważam się za informatyka domytego, a jednak mam na koncie kuriozalne doświadczenie ze sklepu Zara, gdzie na podstawie nieformalnego i powyciąganego ubioru zostałam potraktowana jak złodziejka.

** Zdaniem wielu, stanie w takim rozkroku jest przepisem na porażkę. Polecam wystąpienie Larry’ego Smitha na TED, zatytułowane „Dlaczego nie zrobisz wielkiej kariery”. Jako świeżo upieczona matka karmiąca mam ostatnio dużo czasu na oglądanie takich wykładów, więc od czasu do czas będę się dzielić perełkami 🙂

*** Od razu ostrzegam, że poziom i kultura lokalnych społeczności programistycznych bywają różne. Niektóre są bardzo przyjazne dla początkujących, inne pielęgnują profesjonalny poziom i zadzierają nosa 😉

**** Odmienne od mojego zdanie na temat szkół programowania ma autor tego artykułu w portalu TechCrunch: Coding Academies Are Nonsense. Wrzucam jako ciekawostkę.

***** Powiem szczerze, że cykliczne spotkania Geek Girls Carrots nieco mnie rozczarowują, ponieważ są dużo bardziej startupowe niż programistyczne. Niezależnie od tego, organizacja tworzy i promuje sporo wartościowych kursów programowania dla początkujących.

Google w gąszczu danych: fotograficzny skandal i uczenie maszynowe dla laików

Dwa tygodnie temu media obiegła wieść o skandalicznej wpadce Google Photos. System automatycznego rozpoznawania twarzy i obiektów na zdjęciach zaklasyfikował dwie czarnoskóre osoby jako „goryle” i utworzył dla nich specjalny album o tym właśnie tytule.

Wśród tłumaczeń Google – a trzeba firmie przyznać, że zareagowała bardzo szybko – najbardziej spodobało mi się wyznanie, że twarze białych osób niejednokrotnie są rozpoznawane i podpisywane jako foki albo psy.

Moją uwagę przykuły komentarze czytelników, którzy domagali się „natychmiastowej zmiany algorytmu”. Pomyślałam, że to dobra okazja, żeby napisać kilka słów o uczeniu maszynowym i wyjaśnić, że za tę wpadkę nie odpowiada algorytm w klasycznym znaczeniu tego słowa.

Algorytm to skończony ciąg jasno zdefiniowanych czynności, koniecznych do wykonania pewnego rodzaju zadań. Ludzie stosują algorytmy w swoim codziennym życiu, mniej lub bardziej świadomie (każdy z nas wie mniej więcej, jakie kroki należy wykonać w celu wymiany  zepsutej żarówki). Jeżeli jednak chcemy skłonić do działania komputer, musimy powiedzieć mu wyraźnie i jednoznacznie, jak ma postąpić w określonej sytuacji.

Jedną z metod zapisu algorytmów są schematy blokowe. Poniższy diagram przedstawia schemat blokowy algorytmu sprzątania po swoim psie w miejscu publicznym.

algorytm-pies
Algorytm sprzątania po swoim psie w miejscu publicznym

Przykład pięknego „poważnego” algorytmu znajdziesz w moim poprzednim wpisie.

Algorytmy można badać i porównywać, dzięki czemu powstają ich coraz szybsze i sprawniejsze wersje. Istnieje jednak grupa problemów, które algorytmom nie poddają się najlepiej. Chodzi albo o zadania bardzo skomplikowane, w których rozpisywanie kroków zajęłoby całe lata, albo o takie, które ludzkie mózgi wykonują bardzo szybko, ale ich nosiciele sami nie są w stanie odpowiedzieć na pytanie, jak to się dzieje. Doskonałymi przykładami są tutaj rozpoznawanie twarzy i rozpoznawanie mowy. Sprawa nie jest trywialna. Wiadomo, że istnieją choroby, które odbierają ludziom wymienione przed chwilą umiejętności, nie zaburzając przy tym zdolności logicznego myślenia.

Problemy z opisanej kategorii można rozwiązywać przy użyciu uczenia maszynowego. Jest to dziedzina, która od lat dziewięćdziesiątych nabiera coraz większego znaczenia, w miarę jak wzrasta moc obliczeniowa komputerów i wraz z dostępnością coraz większej ilości danych w Internecie. Dominują dwa nurty: pierwszy oparty na sieciach neuronowych (mających naśladować budowę ludzkiego mózgu), drugi na statystyce i rachunku prawdopodobieństwa.  Poniżej przedstawię prosty (żeby nie użyć mocniejszego słowa) przykład statystycznego uczenia maszynowego.

Jak to działa? Rozważmy popularne zadanie wykrywania spamu. Jeżeli przeanalizujemy tysiąc maili, z których połowa została przez użytkownika oznaczona jako spam, a połowa to normalne, pożądane treści, będziemy w stanie wyciągnąć jakieś wnioski. Możemy, na przykład, utworzyć listę słów, które pojawiły się w wiadomościach i podliczyć, ile razy dane słowo pojawiło się w wiadomości oznaczonej jako spam, a ile razy w wartościowej wiadomości. W ten sposób dla każdego ze słów wyznaczymy prawdopodobieństwo „bycia spamem”. Kiedy pojawi się nowa wiadomość, możemy, w oparciu o listę słów, wyliczyć całkowite prawdopodobieństwo (ryzyko), że dana wiadomość to spam.

Poniżej przykładowy prosty model i związane z nim wyliczenia. Proszę pod żadnym pozorem nie uczyć się z tego statystyki!!!

Wiadomości otrzymane przez użytkownika, zaklasyfikowane przez niego jako wartościowe treści albo spam:

Treść wiadomości Klasyfikacja
Ciociu, jak będzie okazja, kup mi nad morzem wisiorek z bursztynem. Ok.
Okazja! Tylko dzisiaj kup viagrę za 30 zł! Okazja! Spam.

Analiza słów zawartych w wiadomościach:

Słowo Wystąpień „spam” Wystąpień „ok” Prawdopodobieństwo, że to spam
ciociu 0 1 0
kup 1 1 1/2
okazja 2 1 2/3
viagrę 1 0 1
wisiorek 0 1 0

Próba automatycznego oszacowania, czy nowe wiadomości należy wrzucić do folderu „spam”:

Treść nowej wiadomości Prawdopodobieństwo, że spam?
Ciociu, kup wisiorek. (0+1/2+0)/3 = 1/6 = 16.6%
Ciociu, kup viagrę. (0+1/2+1)/3 = 1/2 = 50%
Kup viagrę. (1/2+1)/2 = 3/4 = 75%

Można spotkać się z terminem „algorytm uczenia maszynowego”, ale należy pamiętać, że najczęściej mamy w tej kategorii do czynienia z matematycznymi metodami, które dadzą kompletnie odmienne wyniki w zależności od tego, na jakim zbiorze danych zostaną wytrenowane.

Jakie są efekty? Raczej dobre. Nie da się jednak dogodzić wszystkim, a już na pewno nie na podstawie jednego, wspólnego zbioru danych. Większość z nas chce, aby reklamy środków na powiększenie penisa automatycznie trafiały do katalogu „spam” lub do kosza, ale ktoś przecież takie środki kupuje i wówczas z pewnością chce się dowiedzieć, kiedy dotrze do niego upragniona przesyłka. Poza tym, zbiór danych użyty do trenowania może okazać się za mały, za duży, błędnie opisany lub niewystarczająco reprezentatywny.

Co dokładnie stało się w przypadku Google? Najprawdopodobniej dane wykorzystane do uczenia nie były wystarczająco reprezentatywne – występowali na nich głównie biali ludzie, więc system uwzględnił jasny kolor skóry jako istotny wyznacznik bycia człowiekiem. Warto dodać, że autor (i obiekt) fotografii, które rozpętały całe to zamieszanie, sam jest programistą i od razu zaznaczał, że wie co się stało. Pytał tylko retorycznie „skąd wzięliście te dane?”. Najbardziej wstydliwa możliwość, choć raczej mało prawdopodobna, jest taka, że podczas trenowania użyte zostały zdjęcia opatrzone rasistowskimi komentarzami, które system potraktował jako pewnik.

Problem nie jest łatwy do naprawienia. Być może firma do końca nie wie, skąd pochodziły dane. Być może trenowanie trwa wiele dni. Zgodnie z aktualnymi doniesieniami, etykieta „gorillas” została na wszelki wypadek kompletnie usunięta z systemu.

Wieża Babel. Skąd tyle języków programowania? (część 3 z 3)

Tekst jest oparty na mojej prezentacji z konferencji Kariera IT. Poprzednia część wpisu jest dostępna tutaj.

To ostatnia (po 1 i 2) część mojego krótkiego przewodnika po językach programowania. Zaczynam ją dwoma dość ekstrawaganckimi przykładami, by wreszcie przejść do podsumowań: który język do czego się nadaje i który może uczynić z Ciebie milionera! Na samym końcu znajdziesz quiz 🙂 – a także listę lektur, na wypadek, gdybyś chciał dalej zgłębiać wiedzę na ten temat.

Języki wyspecjalizowane – R

Do tej pory – w poprzednich dwóch wpisach – koncentrowałam się na językach ogólnego przeznaczenia. Dla równowagi chcę pokazać przynajmniej jeden język programowania z innej, bardziej specjalistycznej grupy.

R to język programowania i środowisko przeznaczone do obliczeń statystycznych i wizualizacji wyników. Oferuje zaawansowane wsparcie w dziedzinach takich jak analiza danych i uczenie maszynowe. R jest interpretowanym językiem proceduralnym. Ma pewne ograniczenia wydajnościowe (np. wszystkie dane przetwarzane przez program są w całości ładowane do pamięci podręcznej komputera). Kod R można łączyć z kodem napisanym w innych językach, takich jak C++.

Skoro zadania wykonywane w R można wykonać w C++, do tego kod w innym języku może działać szybciej, po co w ogóle dotykać R? W poprzednim wpisie z tej serii pojawił się punkt „Wydajność języka a wydajność programisty”. W R implementacja zadań związanych ze statystyką i analizą danych jest nieporównywalnie szybsza niż w językach ogólnego przeznaczenia. Programista nie musi pisać wielu linii, a wszystkie tradycyjnie używane w tej dziedzinie algorytmy (np. regresja liniowa) są od ręki dostępne w postaci funkcji.

Poniższy fragment kodu pochodzi z artykułu Producing Simple Graphs with R. Zobacz, jak łatwo można wyświetlić dane i ocenić, czy zachodzi między nimi korelacja.

Co dostaniemy po uruchomieniu programu (np. w środowisku R Studio)? RJeśli nie podoba Ci się myląca etykietac „samochody” przy osi y, na stronie z oryginalnym przykładem dowiesz się, jak go zmienić.

Nie tylko dla dzieci – programowanie graficzne

Istnieją języki programowania, które bardziej niż tekst w obcym języku przypominają… hieroglify. Programowanie polega nie na wpisywaniu poleceń, ale na przeciąganiu i upuszczaniu na planszy bloków symbolizujących poszczególne instrukcje.

Naturalnym odbiorcą tego typu przyjaznych środowisk są dzieci, co jakiś czas jednak powraca temat „rewolucji” w tworzeniu aplikacji przez (pół)profesjonalnych programistów – ostatnio za sprawą projektu Eve.

Przykład tego typu programu pojawił się w opublikowanym przeze mnie w międzyczasie (pomiędzy kolejnymi częściami serii o językach programowania) wpisie Kup swojemu dziecku sobie robota Lego Mindstorms. Znajdziesz tam kompletny opis „najtańszego programowalnego robota”, którego możesz zbudować z klocków Lego.

Poniżej „fragment kodu” dla takiego robota, którego w akcji możesz zobaczyć tutaj:

nxt-codeCo widać na rysunku? Nieskończoną pętlę, w której raz po raz odczytujemy kolor przesyłany przez czujnik światła (bądź koloru). W zależności od tego, czy robot znajduje się na linii (odczyt czarny) czy nie (odczyt biały) albo jedziemy prosto (obrót obu kół o tyle samo stopni), albo skręcamy w prawo.

Wydaje się to banalne, ale w taki sposób można tworzyć zaskakująco złożone programy, o czym przekonałam się kiedyś podczas zawodów programistycznych dla gimnazjalistów.

Który do czego?

Poniższa tabela zawiera wpisy dla tylko kilku spośród najpopularniejszych języków. Zdecydowanie nie wyczerpuje tematu – spójrz, ile pozycji ma lista języków programowania w Wikipedii.

Język Przeznaczenie (najsilniejsze strony) Paradygmat
C System
Operacje niskopoziomowe
Imperatywny
 C++ System Imperatywny
Obiektowy
Funkcyjny
 C# Szybkie tworzenie aplikacji okienkowych
Aplikacje klient-serwer
Aplikacje internetowe
Imperatywny
Obiektowy
Funkcyjny
 Erlang Aplikacje rozproszone
Telekomunikacja
Funkcyjny
 Haskell Aplikacje desktopowe i internetowe Funkcyjny
 Java Aplikacje serwerowe
Aplikacje mobilne (w tym Android)
Imperatywny
Obiektowy
Funkcyjny
JavaScript Aplikacje internetowe w przeglądarce, po stronie klienta Imperatywny
Obiektowy (prototypy!)
Funkcyjny
 Perl Skrypty
Przetwarzanie tekstu i dokumentów
Imperatywny
Obiektowy
Funkcyjny
 PHP  Aplikacje internetowe Imperatywny
Obiektowy
Proceduralny
 Prolog  Sztuczna inteligencja  Logiczny
 Python  Aplikacje internetowe
Skrypty
Imperatywny
Obiektowy
Funkcyjny
 R  Statystyka Imperatywny
Obiektowy
Funkcyjny
Proceduralny

Który da mi pracę?

Jeśli dopiero zaczynasz programować, jeśli myślisz o przekwalifikowaniu się, jeśli nudzi Cię Twoja obecna (może nawet informatyczna) praca, to pewnie zastanawiasz się, który z języków wybrać. O tym, który język najlepiej nadaje się jak pierwszy dla osoby, która nigdy wcześniej nie programowała, pisałam tutaj (tl;dr: Python).

Co z ofertami pracy? Gdybym miała odpowiedzieć bez namysłu, obserwując ruch na rynku pracy i wśród moich znajomych, powiedziałabym, że w Polsce dominują oferty dla programistów Javy (głównie serwerowej, czyli JEE) i, od niedawna, Pythona.

Na wszelki wypadek sprawdźmy też kilka poważnych źródeł.

A. Ranking RedMonk, oparty na popularności poszczególnych języków w repozytorium GitHub oraz na społecznościowej stronie z pomocą techniczną Stack Overflow (uwaga – prawdopodobnie zaniżona popularność języków używanych w firmach z zamkniętą bazą kodu).

Ranking RedMonk, oparty na danych z GitHub i Stack Overflow

1. JavaScript
2. Java
3. PHP
4. Python
5. C#
5. C++
5. Ruby
8. CSS
9. C
10. Objective-C
11. Perl
11. Shell
13. R
14. Scala
15. Haskell

B. Ranking zarobków programistów poszczególnych języków według Business Insider:

  1. Ruby on Rails
  2. Objective C
  3. Python
  4. JAVA
  5. C++
  6. JavaScript
  7. C
  8. R
  9. C#
  10. Visual Basic
  11. SQL
  12. PERL

C. Ranking na rok 2015 ze strony z konkursami programistycznymi CodeEval, oparty w dużej mierze na informacjach od pracodawców:

  1. Python
  2. Java
  3. C++
  4. C#
  5. Ruby
  6. JavaScript
  7. C
  8. PHP
  9. Go
  10. Perl

Bonus: Quiz!

Dla każdego z poniższych czterech fragmentów kodu spróbuj odpowiedzieć na następujące dwa pytania:

  • Jaki to język?
  • Co robi kod?

1. Na rozgrzewkę:

2. Dla spostrzegawczych:

 3. Na logikę:

4. Przypadek beznadziejny:

Poprawne odpowiedzi znajdziesz na dole strony.

PS.

Wróciłam ostatnio do grania na gitarze i doznałam nieoczekiwanego olśnienia informatycznego. C Sharp (zgodnie z zapisem C#) to po angielsku cis, czyli dźwięk o pół tonu wyższy od c 🙂

Polecane lektury

  1. Siedem języków w siedem tygodni. Praktyczny przewodnik nauki języków programowania (polskie wydanie Seven Languages in Seven Weeks: A Pragmatic Guide to Learning Programming Languages, polecam z całego serca!)
  2. Seven More Languages in Seven Weeks: Languages That Are Shaping the Future (kontynuacja poprzedniej pozycji, niestety na razie niedostępna w języku polskim)
  3. Programming Languages (kurs w portalu Coursera)
  4. Practical Foundations for Programming Languages (dla zaawansowanych)

Odpowiedzi do quizu

  1. Java, wypisze „dzień dobry”.
  2. C, wypisze liczbę Eulera (e), źródło: International Obfuscated C Code Contest.
  3. Prolog, rozwiązuje Sudoku, źródło: Programmable Life.
  4. Brainfuck, wypisze „Hello World”, źródło: Wikipedia.

Wieża Babel. Skąd tyle języków programowania? (część 2 z 3)

Tekst jest oparty na mojej prezentacji z konferencji Kariera IT. Pierwsza część wpisu jest dostępna tutaj.

Świat staje się coraz mniejszy. Wszyscy uczymy się angielskiego, a lokalne dialekty odchodzą w zapomnienie. Dlaczego wciąż upieramy się, by z komputerem rozmawiać na tyle różnych sposobów? Ile języków powinien znać programista? Od którego zacząć?

To druga część wpisu na temat współczesnych języków programowania i różnic pomiędzy nimi (pierwsza jest dostępna tutaj). W tej części mówię o różnicy pomiędzy językami kompilowanymi i interpretowanymi i tłumaczę, czym są maszyny wirtualne. Na końcu pokazuję, że języki programowania – tak samo jak języki, za pomocą których ludzie komunikują się między sobą – żyją i zmieniają się z czasem.

Kompilować czy interpretować?

Kolejny podział języków programowania opiera się na sposobie przetwarzania napisanego w nich kodu. Języki bywają dzielone na:

  • kompilowane, czyli przed uruchomieniem tłumaczone na kod maszynowy właściwy danej architekturze, zapisywany w osobnym pliku, np. C++, Pascal,
  • interpretowane, czyli uruchamiane bezpośrednio w oparciu o kod źródłowy, często wyposażone w interaktywne konsole, np. Perl, Ruby,
  • interpretowane przez maszynę wirtualną, tj. kompilowane do kodu bajtowego, jak Java, C#.

Warto wiedzieć:

Ten sam język, w zależności od środowiska, może być kompilowany lub uruchamiany.

Potrzeba kompilacji jest nie tyle cechą języka, co środowiska, z którego korzystamy, choć w praktyce konkretne języki są z reguły konsekwentnie przetwarzane w ten sam sposób.

Oba podejścia mają swoje zalety. Kod skompilowany do postaci maszynowej będzie działał optymalnie w architekturze, dla której jest przeznaczony. Kompilator bywa sprzymierzeńcem programisty – potrafi wytknąć błędy (czasami dość złożone), zanim jeszcze uruchomisz program. Z kolei w środowisku interpretowanym (w którym de facto kolejne instrukcje są kompilowane „w locie”) możesz pozwolić sobie na więcej improwizacji i beztroskich prób bez konieczności tworzenia kompletnego, zamkniętego programu.

Skompilowana wersja tego samego programu będzie wyglądała inaczej w systemie o innej architekturze. Program interpretowany wygląda tak samo niezależnie od tego, gdzie chcemy go uruchomić (o ile celowo nie odwołujemy się elementów istniejących jedynie w konkretnym systemie operacyjnym) – to środowisko (interpreter) musi być w stanie porozumieć się z procesorem.

Jeśli popełnisz poważny błąd w linii numer 100, kompilator w ogóle nie utworzy wykonywalnej wersji programu. Środowisko interpretowane prawdopodobnie bez szemrania wykona linie 1-99 i elegancko wyłoży się na linii 100. Zdecyduj sam, która opcja jest lepsza?

Kompromis pomiędzy wspomnianymi dwoma podejściami stanowią maszyny wirtualne.

Maszyny wirtualne

Poniższy rysunek przedstawia schemat działania maszyny wirtualnej (ang. Virtual Machine, VM).

VM
Zasada działania maszyny wirtualnej (na przykładzie JVM)

W przypadku języków z maszyną wirtualną (jak Java, C#) kod jest co prawda kompilowany, ale nie do postaci kodu maszynowego, tylko tzw. kodu bajtowego (ang. bytecode), przeznaczonego dla VM. Dzięki temu skompilowany kod zawsze wygląda tak samo i może być wdrażany w różnych systemach. Maszyna wirtualna właściwa danej architekturze (czyli np. działająca w systemie Windows) jest w stanie w locie tłumaczyć kod bajtowy do postaci kodu maszynowego – instrukcji dla procesora.

Warto wspomnieć, że niektóre maszyny wirtualne (np. JVM, czyli Maszyna Wirtualna Javy) są obecnie tak dojrzałe i wydajne, że twórcy nowych języków (jak w tym wypadku Scala, Clojure) decydują się na kompilowanie tych języków do kodu bajtowego, by skorzystać z optymalizacji wprowadzanych przez daną maszynę wirtualną.

Wydajność języka a wydajność programisty

Być może zwróciłeś uwagę na to, że kilka razy w tym wpisie pojawiły się słowa „wydajny” lub „optymalny”. Języki programowania można porównywać i w ten sposób. Ruby (czytaj: kod napisany w Ruby, uruchomiony w odpowiednim środowisku) działa wolniej niż Java, Java jest wolniejsza od C.

Skoro tak, to dlaczego więc wszyscy nie piszemy w C? Nie wolno zapomnieć o tym, że wydajności języka i wydajność programisty to dwie różne rzeczy.

Program powinien działać szybko, to jasne. Programy są jednak pisane i poprawiane przez ludzi. Ogromne znaczenie mają więc także:

  1. czas potrzebny do stworzenia działającego programu,
  2. czas potrzebny do naprawienia błędu przez autora kodu,
  3. czas potrzebny do naprawienia błędu przez innego programistę.

Jeśli chodzi o szybkość tworzenia programu od zera (1) – w ekstremalnej sytuacji prototyp tworzy się w jednym języku, a – jeśli pomysł chwyci – później w tle przepisuje się kod na inny, wydajniejszy język.

W kwestii naprawiania błędów (2), ale też szybkości kodowania, rozważ proszę następujące dwa fragmenty kodu.

C++

Java

Oba przykłady robią to samo: tworzą tablicę przechowującą 10 elementów typu całkowitego. W przypadku C++ musisz ręcznie zwolnić przydzieloną pamięć. Można uznać to za zaletę – masz pełną kontrolę nad pamięcią. Jeśli wiesz, że obiekt nie będzie już potrzebny, możesz się go natychmiast pozbyć. W Javie pamięć zwolni Odśmiecacz (ang. Garbage Collector) po wykryciu, że do zmiennej nie ma już odwołań. Tyle tylko, że zrobi to, kiedy będzie mu wygodnie… Może wcale.

Z ogromną dozą pewności pozwolę sobie napisać to:

Każdemu programiście języka C++ zdarzyło się co najmniej raz zapomnieć operatora delete.

Przykłady kodu są zabawkowe. Gdyby jednak taki kod znajdował się w pętli, gdyby tablica zawierała obiekty zamiast wartości int – mielibyśmy poważny problem.

Co do poprawiania błędów przez innych developerów (3): znana maksyma głosi, że kod jest czytany dużo częściej niż pisany. Warto zadbać o jego przejrzystość i strukturę. To, czy kod jest czytelny czy nie, nie zależy jedynie od wyboru języka, ale także od stosowania konwencji (nazw, formatu kodu) i abstrakcji (jak wzorce projektowe).

Języki programowania ewoluują!

Wiesz już (niekoniecznie ode mnie), że to, czy język się kompiluje czy interpretuje nie jest rdzenną cechą samego języka, ale środowiska, w którym ma działać Twój kod.

Wiesz, co jeszcze może ulegać zmianom? Sama składnia!

Język naturalny, czyli język, którym ludzie porozumiewają się między sobą, ewoluuje. Pojawiają się nowe słowa, stare zyskują nowe znaczenia. Uparcie powtarzane błędy w końcu wchodzą do kanonu (czy zastanawiałeś się kiedyś, dlaczego w wielu językach najczęściej używane czasowniki odmieniają się nieregularnie?)

Nie inaczej jest w przypadku języków programowania. W nowych wydaniach pojawiają się konstrukcje pozwalające w bardziej zwięzły sposób wyrazić te same treści. Dopuszczane są elementy innych paradygmatów (np. popularne ostatnio wyrażenia lambda, związane z programowaniem funkcyjnym).

Dla ilustracji, dwa fragmenty kodu w języku Java:

Obie wersje tworzą mapę (tablicę asocjacyjną), w której kluczami są łańcuchy znaków, a wartościami – listy zawierające łańcuchy znaków. Czyli, na przykład, na podstawie nazwiska mogę pobrać listę numerów telefonu przypisanych do danej osoby.

Druga, nowsza wersja jest wyraźnie krótsza. Dlaczego? Otóż dlatego, że programiści Javy od lat dostawali białej gorączki przez ostrzeżenia kompilatora na temat nieznanego typu podczas tworzenia kolekcji, mimo że typ można było jednoznacznie wywnioskować na podstawie deklaracji zmiennej. Ich skargi wreszcie dotarły gdzie trzeba, i oto efekt.

Dlaczego podałam numery wersji od 5 w górę? Ponieważ w wersji 4 nie można jeszcze było stosować uogólnień (ang. generics) – w efekcie nie mogłabym w ten sposób określić typu danych przechowywanych w kolekcji.

W następnej części

  • Języki wyspecjalizowane – R
  • Nie tylko dla dzieci – programowanie graficzne
  • Który do czego?
  • Który da mi pracę?
  • Quiz!
  • Polecane lektury

PS. Link dla odważnych

CINT, interpreter kodu C i C++.

Wieża Babel. Skąd tyle języków programowania? (część 1 z 3)

Tekst jest oparty na mojej prezentacji z konferencji Kariera IT

Świat staje się coraz mniejszy. Wszyscy uczymy się angielskiego, a lokalne dialekty odchodzą w zapomnienie. Dlaczego wciąż upieramy się, by z komputerem rozmawiać na tyle różnych sposobów? Ile języków powinien znać programista? Od którego zacząć?

Postaram się krótko opowiedzieć o współczesnych językach programowania i różnicach pomiędzy nimi. Dla porządku zacznę od (króciutkiego!) rysu historycznego. Dalej będzie z górki! 🙂

Pierwszy programista (nie róbmy z tego tajemnicy: chodził w spódnicy)

Jako pierwszego na świecie programistę często wymienia się Adę Lovelace. Ada była córką poety, Lorda Byrona. W latach 1842-1843 (!) przetłumaczyła z francuskiego rozprawę poświęconą „maszynie analitycznej” Charlesa Babbage’a. Tłumaczenie opatrzyła notatkami, w których znalazł się pierwszy na świecie opis algorytmu przeznaczonego do wykonania przez maszynę (algorytm wyznaczał kolejne liczby Bernoulliego). Działający egzemplarz takiej maszyny udało się zbudować dopiero w 1991 roku. Dokonało tego Muzeum Nauki w Londynie, przy użyciu materiałów dostępnych w czasach Babbage’a.

Ada Lovelace: portret

Wyrazami uznania dla pracy Ady Lovelace są między innymi język programowania Ada stworzony na początku lat osiemdziesiątych oraz nagroda Ada Award przyznawana „wybitnym dziewczętom i kobietom w sektorach cyfrowych”.

Odrobina kontekstu: kamienie milowe historii programowania

To nie jest wpis o historii programowania, dlatego wypunktuję tylko kilka przełomowych wydarzeń:

  • 1936: Alan Turing opisuje Maszynę Turinga, hipotetyczny „komputer” złożony z głowicy oraz nieskończonej taśmy, który może wykonywać algorytmy i stanowi teoretyczny model obliczeń.
  • 1943-1945: Powstaje ENIAC, powszechnie uważany za pierwszy komputer.
  • 1940-1960: Dominują języki niskopoziomowe. Na ich tle wWyróżnia się FORTRAN, język wyższego poziomu z własnym kompilatorem.
  • 1960-1970: Powstają stosowane do dzisiaj języki i paradygmaty: język C, Smalltalk (obiektowy), Prolog.
  • 1990-…: Internet staje się ogólnodostępny. Dominuje paradygmat obiektowy. Pojawia się sporo języków funkcyjnych i skryptowych.
  • 2010-…: Zwrot w stronę programowania funkcyjnego, metaprogramowanie i mechanizm refleksji, nacisk na wielowątkowość.

Z głową w chmurach: języki niskiego i wysokiego poziomu

Jeśli – chcąc nauczyć się nowego języka programowania – zaczniesz szukać informacji na jego temat w Internecie, prawie na pewno natkniesz się na informację o tym, że „X to język programowania wysokiego poziomu, który …”. Jeden za drugim, którego byś nie sprawdził, wszystkie są wysokopoziomowe. Co to znaczy?

Spójrz na fragmenty kodu w poniższej tabelce.

Kod maszynowy Asembler C

 

 

Każdy z przedstawionych fragmentów kodu (wzięłam je z Wikipedii; wystarczył mi jeden semestr z Asemblerem żeby wiedzieć, że nigdy więcej nie chcę go dotykać) robi to samo: wyznacza n-ty wyraz ciągu Fibonacciego.

Po lewej mamy kod maszynowy – kolejne liczby (zapisane szesnastkowo) to rozkazy procesora i ich argumenty. Kod taki jest nieprzenośny, tj. zależny od architektury. Przykładowy kod jest przeznaczony dla 32-bitowej maszyny x86. Programowanie w tym języku wymaga zapamiętania numerów poszczególnych instrukcji, lub korzystania z rozbudowanej ściągi (słownika). Jest to kod absolutnie niskopoziomowy.

Środkowa kolumna to Asembler (ang. Assembly language). To również język niskopoziomowy. Wygląda inaczej niż kod maszynowy, jednak w rzeczywistości stanowi odwzorowanie „jeden do jeden” instrukcji procesora, tyle że w sposób łatwiejszy do zrozumienia i zapamiętania przez człowieka. W przykładowym kodzie widać odwołania do rejestrów procesora x86 oraz do stosu.

Po prawej stronie język C. Kod różni się od przykładów po lewej stronie brakiem odwołań do architektury maszyny, na której działa. Wartości będą w końcu pobierane ze stosu, ale nigdzie nie oznaczamy, w jaki sposób ma się to odbyć. Funkcja ma zwrócić wartość, ale nigdzie w kodzie nie określamy mechanizmu jej przekazania. Wprowadzamy własne abstrakcje – zmienne lokalne wewnątrz instrukcji warunkowych oraz pętli – i nie przejmujemy się sposobem ich obsługi na docelowej maszynie.

Na podstawie powyższego możesz logicznie wywnioskować, że C jest językiem wysokiego poziomu. Jednak gdy podzielisz się tą opinią z zaprzyjaźnionymi programistami, większość z nich z niedowierzaniem pokręci głową. Dzisiaj C jest uznawany za, w najlepszym razie, język „średniego poziomu”. Wprowadza sporo użytecznych abstrakcji, ale jednocześnie (czego w naszym przykładzie akurat nie widać) pozwala na bezpośrednie odwołania do pamięci – nie do pomyślenia w większości języków wysokopoziomowych.

Możesz jeszcze natknąć się na określenie super high level language, czyli język bardzo wysokiego poziomu. Tym terminem określa się najczęściej języki dziedzinowe, zwiększające produktywność programisty poruszającego się na co dzień po specyficznym, zamkniętym obszarze. Z reguły są tą jednak tylko (?) nakładki na istniejące języki programowania wysokiego poziomu.

Rozkazuję ci… Języki imperatywne i deklaratywne

Kolejny ważny podział wśród języków programowania to rozróżnienie na paradygmat imperatywny i deklaratywny.

  • Program imperatywny zawiera ciąg instrukcji, zmieniających stan programu. Wydajemy komputerowi „rozkazy”: zwiększ wartość x o 5, zwróć wynik. Przykłady języków imperatywnych to Perl, Python, Java oraz wszystkie języki przedstawione w tabelce w poprzednim podrozdziale.
  • Program deklaratywny nie mówi komputerowi, jakie kroki ten ma wykonać. Zamiast tego, programista opisuje warunki, jakie musi spełniać rozwiązanie. Ważne i pożądane cechy języka deklaratywnego to bezstanowość i determinizm. Te same dane wejściowe zawsze prowadzą do uzyskania tego samego wyniku, nie wpływa na nie żaden wewnętrzny „stan”. Przykłady języków deklaratywnych to Haskell, Erlang i Prolog.

Świat imperatywny: klasy i prototypy

Jeśli chodzi o programowanie imperatywne, od dawna już (co najmniej od początku obecnego wieku) dominuje programowanie obiektowe, które wyparło mniej ustrukturyzowane programowanie proceduralne. W ścisłym ujęciu program obiektowy to program, którego wykonanie sprowadza się do przesyłania komunikatów pomiędzy obiektami. Nie wszyscy jednak wiedzą, że programować obiektowo można w dwóch „smakach”: przy użyciu klas lub paradygmatów.

Sytuację dobrze ilustruje ten oto obrazek (mojego autorstwa, wreszcie mogę się popisać!), inspirowany slajdem z prezentacji na temat zaskakujących elementów języka JavaScript:

Prototypy kontra klasy, ujęcie biologiczne i gratka dla fanów mojej kreski (są tacy!).
Prototypy kontra klasy, ujęcie biologiczne, Gratka dla fanów mojej kreski (są tacy!)

W podejściu klasycznym (nazwa jest tym bardziej odpowiednia, że to podejście dominuje – np. Java, C++) opisujemy świat za pomocą klas. W praktyce klasą może być „Okno Przeglądarki” albo „Ramka”, jednak w zastosowaniu edukacyjnym lepszym przykładem będzie nieśmiertelna klasa „Zwierzę”. Klasa Zwierzę ma pewne atrybuty: liczbę nóg lub umiejętność wydawania pewnego dźwięku. Klasa ta może mieć podklasę, na przykład Słoń. Słoń ma wszystkie atrybuty klasy Zwierzę, ale może definiować własne – na przykład trąba i jej długość 😉

W oparciu o klasy tworzymy obiekty, czyli konkretne instancje (egzemplarze) poszczególnych klas. I tak DumboMamaDumbo to dwa różne obiekty tej samej klasy Słoń. Klasy możemy podzielić na konkretne (które mogą mieć instancje) i abstrakcyjne (bardziej ogólne, pełniące tylko rolę szablonów).

Alternatywą jest podejście prototypowe, dostępne na przykład we wspomnianym już tutaj języku JavaScript. Jeśli programujemy z prototypami, całkowicie wyzbywamy się klas. Wszystko jest obiektem. Zwierzę to obiekt. Słoń to obiekt, dla którego obiekt Zwierzę jest prototypem. Dumbo to kolejny obiekt, wzorowany na Słoniu. Koneserzy tej wersji przekonują, że dopiero przy takim podejściu, gdzie wszystko jest obiektem, możemy mówić o programach prawdziwie obiektowych.

Jaka jest praktyczna różnica? Prototypy, jako obiekty, można modyfikować w czasie wykonania. Klasy są usztywnione – jeśli powiemy, że słoń ma cztery nogi, nie będziemy gotowi do obsłużenia egzemplarza z pięcioma. Ma to jednak swoją cenę. Większość języków prototypowych jest typowana dynamicznie. Oznacza to, że typ obiektu jest określany dopiero w czasie wykonania. Dla takich języków o wiele trudniej jest tworzyć dobre IDE (zintegrowane środowisko programistyczne). W przypadku statycznie definiowanych klas, edytor może nam sporo pomóc: np. podpowiedzieć, jakie funkcje da się wywołać na danym obiekcie.

Ograniczenia wprowadzane przez stosowanie klas stają się jednak coraz mniej uciążliwe z powodu rozbudowanych mechanizmów refleksji (zmiany istniejącego kodu w czasie wykonania) w nowoczesnych językach programowania.

Świat deklaratywny: języki funkcyjne i programowanie w logice

Języki funkcyjne przeżywają obecnie prawdziwy boom popularności. Główną przyczyną tego stanu (sic!) rzeczy jest ich bezstanowość i brak skutków ubocznych – cechy te ułatwiają programowanie współbieżne. Jest to istotne, ponieważ w roku 2014 dobiegamy do kresu prawa Moore’a, wieszczące (w uproszczeniu) wykładniczy wzrost szybkości układów scalonych. Zamiast coraz szybszych procesorów mamy teraz procesory z większą liczbą rdzeni i coś z tym fantem trzeba zrobić.

Program napisany w języku funkcyjnym sprowadza się do wartościowania (ewaluacji) funkcji matematycznych. Unikamy przy tym przechowywania i modyfikowania stanu. Do dyspozycji mamy języki czysto funkcyjne, jak Haskell (z dość dużym progiem wejścia, uwielbiane przez snobistycznych doświadczonych developerów), oraz nieco bardziej przystępne (acz kojarzące się z potworem Frankensteina) języki mieszane, jak Scala, które pozwalają na łamanie części zasad, przy jednoczesnej praktycznej dostępności pewnych silnych stron tego paradygmatu (jak wygodne wykonywanie funkcji na wszystkich elementach kolekcji).

Programowanie funkcyjne to duży temat, któremu zamierzam w przyszłości poświęcić osobny wpis.

Inny rodzaj programowania deklaratywnego to programowanie w logice, szczególnie przydatne przy problemach zahaczających o zagadnienia sztucznej inteligencji (rozumienie języka naturalnego, rozwiązywanie łamigłówek). W tym podejściu, zamiast szukać algorytmów,, musimy zdefiniować zależności i ograniczenia (ang. constraints) obowiązujące w danej dziedzinie. Interpreter języka logicznego, takiego jak Prolog, podejmie następnie próbę rozwiązania problemu „za nas” w oparciu np. o rachunek predykatów pierwszego rzędu.

Pierwsze doświadczenia z programowaniem w logice bywają bolesne. O ile w większości języków możemy napisać coś w stylu

X = 1; X = X + 1;

i spodziewać się odpowiedzi 2, o tyle Prolog w podobnych okolicznościach może zaskoczyć nas krótką i konstruktywną odpowiedzią NIE (X nigdy nie będzie równe X+1). Po co w ogóle pchać się w te cudaczne rejony?

Ano chociażby dlatego, że w Prolog pozwala na rozwiązanie bardzo skomplikowanych problemów (kostka Rubika, Sudoku) w zaskakująco niewielkiej liczbie linii kodu.

Poniżej kompletny kod rozwiązujący Sudoku o rozmiarach 9×9, napisany w Prologu. Program pochodzi z bloga Programmable Life, tam też znajdziesz kompletne objaśnienie.

W następnych częściach

PS. Zdjęcie w nagłówku

Zdjęcie przedstawia kartę perforowaną z zapisem kodu w języku Fortran. Kart perforowanych po raz pierwszy użyto w roku 1725 do sterowania pracą krosna.

W 1889 roku Herman Hollerith opatentował nowoczesną postać karty (oraz taśmy) dziurkowanej do zapisu danych. Zainspirował go system stosowany przez konduktorów amerykańskich kolei, którzy za pomocą dziurek kodowali na biletach wygląd pasażera („wysoki, niebieskie oczy”), który się danym biletem posługuje (żeby pasażerowie nie wymieniali się biletami).

Karty perforowane były szeroko stosowane do zapisu danych i programów aż do lat osiemdziesiątych XX wieku. Ich ostateczny upadek miał miejsce w roku 2000, gdy przez resztki papieru pozostałe w otworach kart nie wszystkie głosy zostały policzone poprawnie i w efekcie trzeba je było zliczyć ręcznie.