1 Wprowadzenie
Żyjemy obecnie w epoce trzeciej rewolucji przemysłowej1, zwanej inaczej rewolucją cyfrową. Jest ona powiązana z przejściem z technologii mechanicznych i analogowych na technologie elektroniczne i cyfrowe. W tej epoce nastąpiło stworzenie i rozpowszechnieniem się komputerów, co w efekcie spowodowało szerokie zmiany społeczno-ekonomiczne. Wiele z tych zmian jest pozytywnych, ale istnieją również zmiany negatywne, bądź też takie które trudno jednoznacznie ocenić. Przykładowo, wyraźną korzyścią społeczną jest znacznie ułatwiony dostęp do informacji. Jednocześnie taki dostęp powoduje sytuację określaną jako przeciążenie informacją (ang. information overload), w której występuje zbyt wielka ilość informacji aby podjąć właściwą decyzję lub zrozumieć sens danego tematu.
Rozwój technologiczny spowodował też transformację produkcji przemysłowej i zmiany gospodarcze. Firmy zajmujące się technologiami informacyjnymi, tj. Microsoft, Apple, czy Google, są obecnie jednymi z najbardziej dochodowych przedsiębiorstw, a twórca platformy Amazon, Jeff Bezos, jest najbogatszym człowiekiem świata2. Wiele z tych technologii nie byłoby możliwych bez programowania. Programowanie, w znacznym uproszczeniu, to proces tworzenia serii instrukcji, które informują komputer jak wykonać pewne zadanie. Ta seria instrukcji jest zazwyczaj zapisywana na komputerze w postaci tekstu w wybranym języku programowania. Co w takim razie powoduje, że programowanie ma tak istotny wpływ na wiele elementów codziennego życia?
Programowanie cechuje kilka unikatowych możliwości. Po pierwsze, programowanie i jego efekty można w prosty sposób powielać niemal w nieskończoność. Wcześniej stworzenie pewnego towaru opierało się o ograniczone zasoby, takie jak surowce naturalne. Nie możliwe było wykucie zbroi raz, a następnie natychmiastowe powielenie jej wiele razy i sprzedanie jej wielu kopii. We współczesnym świecie, jedna aplikacja może być sprzedana (lub rozpowszechniona) wiele razy, a często większy nacisk kładzie się na rozbudowę i ulepszanie istniejących popularnych aplikacji niż tworzenie nowych3. Ułatwia to też budowę nowych rozwiązań na podstawie już istniejących4. Współcześnie programowanie umożliwia wykonywanie trylionów (1018) operacji arytmetycznych na sekundę5. Pozwala to na znaczne zwiększenie wydajności dostępnych rozwiązań (np. księgowość), otwiera możliwość praktycznego wykorzystania istniejących idei (np. modele klimatu), lub też tworzenia nowych pomysłów (np. internet). Inną cechą programowania jest też jego prosta możliwość automatyzacji powtarzanych czynności oraz ułatwiona powtarzalność (ang. reproducibility). Posiadając kod źródłowy danego oprogramowania lub skrypt wykonujący analizę danych, możliwe jest odtworzenie tego wyniku przez inną osobę na drugim końcu świata, lub też przez siebie samego po paru miesiącach. Ostatnią cechą programowania jest jego uniwersalność. Jest ono wykorzystywane w transporcie, przemyśle, nauce, rozrywce i wielu innych strefach życia. W efekcie zrozumienie i znajomość języków programowania jest cenną umiejętnością we współczesnym świecie.
1.1 Mity programistyczne
Programowanie komputerowe ma obecnie już długą historię - pierwszy język programowania Plankalkül powstał w latach 1943-19456. Fortran, stworzony w roku 1957, jest nadal używany współcześnie do wielu celów, między innymi wymagających dużej wydajności obliczeń hydrologicznych, prognozowania pogody czy modelowania klimatu. Programowanie ewoluowało i nadal ewoluuje wraz z rozwojem dostępności i możliwości komputerów, ale także wraz ze zmieniającymi się potrzebami. Pojawiły się nowe paradygmaty programowania oraz wiele nowych języków. W tym samym czasie narosło również wiele mitów dotyczących programowania7.
Jednym z mitów jest to, że programowanie polega tylko na siedzeniu przed ekranem komputera i wpisywaniu do niego kolejnych linii kodu. Jest to oczywiście istotna część pracy programistycznej, ale prawdopodobnie nie jest ona nawet dominująca w przeciętym dniu programisty. Wcześniej konieczne jest zastanowienie się jaki problem rozwiązujemy oraz zaprojektowanie możliwego rozwiązania tego problemu. Stworzony kod może okazać się być nieprzystępny dla użytkownika, słabo zoptymalizowany, lub nawet błędny. Dlatego też innym ważnym elementem jest testowanie kodu w celu wyłapania potencjalnych problemów. Innym aspektem programowania jest tworzenie dokumentacji. Żaden program nie może zachęcić do siebie użytkowników, jeżeli nie będą oni w stanie zrozumieć jak on działa. Dokumentacja jest też cenna dla twórców programu, szczególnie kiedy konieczne jest użycie czy modyfikacja programu kilka miesięcy po jego ostatnim użyciu. Programy komputerowe są też zazwyczaj w dużej sieci powiązań z już istniejącymi bibliotekami czy oprogramowaniem. Zmiana w tych bibliotekach czy oprogramowaniu może skutkować nie zawsze oczekiwanymi zmianami w stworzonym programie. Częścią programowania jest również utrzymywanie istniejącego kodu źródłowego oraz jego ulepszanie. Programiści do swojej pracy wykorzystują też odpowiednie wspierające ich narzędzia, takie jak edytory kodu źródłowego, debugery, zintegrowane środowiska programistyczne czy systemy kontroli wersji.
Mitem również jest przekonanie, że programowanie to męskie zajęcie. Bierze się ono z obecnej na rynku pracy struktury, w której około 75% programistów to mężczyźni a tylko 25% to kobiety. Ta struktura jednak nie jest odzwierciedleniem jakichś wrodzonych umiejętności. Za pierwszego programistę często uważa się Adę Lovelace, angielskiego matematyka i poetkę8. To ona w 1843 opublikowała pierwszy program komputerowy. Jej algorytm do obliczenia liczb Bernoulliego nie został jednak przetestowany, ponieważ urządzenie do tych obliczeń (zwane maszyną analityczną9) nie zostało skonstruowane. Ponad wiek później, gdy istniały już techniczne możliwości tworzenia komputerów, programowanie było uważane za kobiecy zawód10 (Rycina 1.1). Z uwagi na szereg czynników społecznych i historycznych11, w latach 1970 nastąpiło odwrócenie proporcji w tym zawodzie. Obecnie podejmowanych jest szereg inicjatyw, które mają na celu zachęcić kobiety do programowania. Wśród nich można wymienić działania organizacji R-Ladies, PyLadies, girls.js, czy Women in Machine Learning & Data Science. Mit programisty mężczyzny jest też powiązany z wymienionym kilka akapitów niżej mitem samotnego programisty.
Kolejny jest mit wielkiego produktu. Oznacza on, że po nauczeniu się podstaw danego języka programowanie, jest się od razu w stanie stworzyć bardzo złożony program, np. nowy system operacyjny, skomplikowaną aplikację na telefon, czy grę komputerową. W rzeczywistości takie produkty zazwyczaj opierają się o tysiące godzin pracy wielu programistów. Dodatkowo, nie są one tworzone od podstaw, ale używając szeregu dostępnych narzędzi, bibliotek i innych rozwiązań. Celem pisania kodu, więc nie powinno być stworzenie od zera bardzo złożonej aplikacji, lecz odpowiednie użycie istniejących rozwiązań. Jednocześnie pisanie złożonego oprogramowania wymaga uzyskania niezbędnego doświadczenia. Mit wielkiego produktu wiąże się również z wymienionym w kolejnym akapicie mitem samotnego programisty.
W popkulturze osoba, która potrafi programować spędza czas samotnie, gwałtownie wpisując kolejne linie kodu do komputera w ciemnym pokoju. W rzeczywistości jednak większość profesjonalnych programistów pracuje w zespołach, których członkowie pracują nad różnymi aspektami tego samego problemu. Pisanie programów często wymaga współpracy różnych osób, dlatego też umiejętność pracy w grupie jest coraz istotniejsza. Warto dodać, że współpraca nad pisaniem programów nie musi odbywać się w jednym pokoju czy budynku. Ze względu na charakter takiej pracy i możliwości technologiczne, wiele formalnych i nieformalnych grup pracuje zdalnie nad projektami. Wiele przykładów takich zachowań można znaleźć przyglądając się otwartemu oprogramowaniu (ang. open-source software) na platformie GitHub (np. https://github.com/trending/r).
W poprzednim akapicie celowo użyłem stwierdzenia “osoba, która potrafi programować” zamiast “programista”. Jest to kolejny powszechny mit, że każda osoba która potrafi stworzyć program musi od razu zostać pełnoetatowym programistą. Pisanie programów jest narzędziem, które ma wspomóc twórcę w pewnym celu. Jednym z celów może być zostanie profesjonalnym deweloperem stron internetowych, aplikacji mobilnych, gier komputerowych, itd. Nie jest to jednak jedyny cel - programowanie może być, na przykład przydatnym narzędziem w analizie danych12. Umiejętności programistyczne są wykorzystywane przez ekonomistów, biologów, geografów i osób z wielu innych dziedzin. Dodatkowo, podstawowe aspekty programowania są bardzo cenne w zawodach, w których ważna jest częsta współpraca z programistami.
Kolejny mitem jest mit programisty geniusza. W tym micie programują tylko osoby, która ma nadludzką pamięć oraz wyróżniającą wiedzę matematyczną. Oczywiście, takie cechy przydają się w programowaniu, ale nie są do niego wymagane. W programowaniu częściej od dobrej pamięci przydaje się umiejętność szybkiego znalezienia rozwiązania czy odpowiedzi na problem w internecie. Programista nie musi znać na pamięć setek różnych poleceń i funkcji, ważne że umie je zidentyfikować. Natomiast zamiast głębokiej wiedzy matematycznej do większości zadań programistycznych wystarczy podstawowa znajomość algebry. Z tym mitem wiąże się też inna kwestia - założenia że ten programista geniusz posiadł całą wiedzę programistyczną. Podobnie jak nauka języka obcego, nauka języka programowania wymaga dużo pracy i czasu. Dodatkowo, języki programowania czy techniki programowania zmieniają się znacznie częściej niż języki naturalne, dlatego też częścią programowania jest ciągłe uczenie się.
Ostatni mit natomiast mówi o tym, że dla każdego problemu programistycznego istnieje tylko jedno najlepsze rozwiązanie. Jeden problem można zazwyczaj rozwiązać na dziesiątki różnych sposobów. Wynika to z tego, że wiele aspektów programowania opiera się o personalne preferencje, np. wybór danego języka programowania, używanych bibliotek, czy stylu pisania kodu. W efekcie zazwyczaj nie możliwe jest jednoznaczne określenie, które rozwiązanie jest lepsze, szczególnie jeżeli wiele rozwiązań ma podobną wydajność. Istnieje jednak kilka reguł, z którymi zgadza się większość programistów. Pierwsza z nich mówi, że wolny działający kod jest lepszy niż szybki niedziałający kod13. Kolejna opiera się o zasadę DRY (nie powtarzaj się, ang. Don’t Repeat Yourself), zalecającą unikanie różnego rodzaju powtórzeń wykonywanych przy programowaniu, np. używania tych samych fragmentów kodu w wielu miejscach. Ostatnia reguła mówi, żeby pisać programy w sposób modularny, czyli taki w którym każda funkcja spełnia tylko jedno i nie więcej zadanie, a złożone funkcje składają się z szeregu prostych funkcji.
1.2 Języki programowania
Głównym sposobem przekazywania instrukcji do komputera jest użycie języków programowania. Pozwalają one na precyzyjny zapis zadań, które następnie mają zostać wykonane przez komputer. Języki programowania składają się ze zbioru reguł syntaktycznych (składni) oraz semantyki. Składnia (forma) mówi o tym jakie symbole są dostępne w danym języku oraz jak te symbole mogą być łączone w większe struktury. Semantyka (treść) natomiast definiuje znaczenie poszczególnych symboli.
W przeciwieństwie do języków naturalnych, języki programowania wymagają wysokiej precyzji. Mówiąc w języku naturalnym możemy popełnić jakiś błąd (np. gramatyczny czy składniowy) i nadal być łatwo zrozumianym przez otoczenie. Języki programowania nie akceptują takich błędów i nie są w stanie wykonać danego polecenia. Obecnie istnieją tysiące14 języków programowania i każdego roku powstają nowe. Nie ma wśród nich jednego najlepszego, uniwersalnego języka programowania i w najbliższej przyszłości ten stan się nie zmieni. Jest to związane z bardzo szerokim zastosowaniem programowania w wielu dziedzinach czy problemach, które mają od siebie zupełnie różne wymagania. Przykładowe wymagania mogą dotyczyć np. szybkości wykonywanych obliczeń, łatwości pisania kodu, stabilności języka programowania, czy celu obliczeń. Do tego dochodzą również rożne kwestie historyczne i społeczne, jak na przykład preferowanie danego języka programowania przez osoby w danej branży. Obecnie wśród najpopularniejszych języków programowania można wymienić takie języki jak Java, C, Python, C++, Visual Basic .NET, JavaScript, C#, PHP, SQL, Objective-C, język asemblera, Perl, czy R. Języki programowania można podzielić na wiele różnych grup w zależności od przyjętych kryteriów. Poniżej wyjaśnionych jest kilka możliwych podziałów języków programowania.
Jednym z nich jest sposób wykonywania kodu - to czy kod w danym języku jest kompilowany czy też interpretowany. Kompilacja kodu (np. C czy Java) polega na jego tłumaczeniu do postaci języka maszynowego. W efekcie zapewnia to wysoką wydajność programu, ale za to kod jest ściśle powiązany z daną platformą sprzętową. Programowanie w językach kompilowanych jest zazwyczaj bardziej złożone i trudniejsze w nich jest odnajdywanie błędów (tzw. debugging). Interpretowane języki programowania (np. R czy Python), często również nazywane językami skryptowymi, charakteryzuje to, że w momencie uruchomienia kod jest zamieniany na postać zrozumiałą dla komputera i od razu wykonywany. W efekcie można szybko zobaczyć efekt zmian. Wadą tego typu języków jest ich zmniejszona wydajność w porównany do języków kompilowanych.
Innym powszechnym podziałem języków programowania jest ich rozróżnianie na podstawie poziomu. Tutaj można wyróżnić języki od niskiego poziomu do wysokiego poziomu. Na najniższym poziomie jest język maszynowy, czyli taki w którym zapis programu wyrażony jest w postaci liczb binarnych. Powyżej umieszczony jest język asemblera, w którym program jest zapisany poprzez serię instrukcji. Na najwyższym poziomie stawia się języki, które są wspomagane przez kompilator albo interpreter.
Języki programowania można też rozróżnić ze względu na paradygmat programowania. Definiuje on w jaki sposób w danym języku wykonywany jest przepływ sterowania czy też jak kod jest organizowany. Dwa podstawowe paradygmaty programowania to programowanie imperatywne i deklaratywne. Programowanie imperatywne (np. Fortran, C) opisuje proces wykonywania kodu jako sekwencję instrukcji zmieniających stan programu. Obejmuje ono inne paradygmaty, jak na przykład programowanie proceduralne czy obiektowe. Programowanie deklaratywne skupia się natomiast na warunkach jakie musi spełniać końcowe rozwiązanie, a nie na sekwencji kroków do jego stworzenia. W skład tej grupy wchodzi, między innymi, programowanie funkcyjne czy matematyczne. Niektóre języki mogą być zaklasyfikowane do kilku paradygmatów. Przykładowo R wspiera zarówno paradygmat funkcyjny, ale zawiera też możliwości programowania obiektowego.
1.3 R
W tej książce wprowadzenie do programowania opiera się o język R (Rycina 1.2).
Wynika to z szeregu zalet tego języka:
- R jest bezpłatnym, otwartym oprogramowaniem, który można uruchomić na różnych systemach operacyjnych (Windows, Mac OS i Linux), zarówno na komputerach osobistych jak i na dużych klastrach obliczeniowych. W efekcie nie ma on finansowej bariery rozpoczęcia pracy, a kod napisany na jednym komputerze można również przenieść i uruchomić na innym sprzęcie.
- R jest językiem interpretowalnym, czyli wykonanie w nim komend nie wymaga kompilacji. Ten aspekt ułatwia szybsze zrozumienie działania tego języka.
- R posiada wiele wbudowanych narzędzi analizy i wizualizacji danych. Pozwala to na relatywnie szybkie osiąganie wymiernych efektów z korzystania z tego języka.
- R posiada tysiące dodatkowych rozszerzeń (zwanych pakietami) pozwalających na, między innymi, przetwarzanie różnorodnych danych, ich wizualizację, czy zaawansowane modelowanie. Oficjalnym portalem zawierającym dodatkowe pakiety R jest CRAN.
- R ma przyjazną społeczność użytkowników tego języka, zarówno online jak i spotykających się na żywo na tzw. meetupach.
- W celu ułatwienia pracy z R powstało również zintegrowane środowisko programistyczne RStudio, które wspomaga pisanie i analizę kodu w R.
- R został zaprojektowany jako narzędzie ułatwiające komunikację między różnymi językami programowania, głównie C oraz Fortran15. Obecnie R pozwala na łatwe łączenie kodu pochodzącego również z takich języków jak C++, Python, JavaScript, itd.
- R jest używany przez wiele małych firm, jak i wielkich korporacji, wliczając w to BBC, Facebook, Google, Microsoft, Mozilla, Netflix, T-Mobile, czy Uber16.
Oczywiście, uniwersalny i idealny język nie istnieje:
- R jest językiem interpretowalnym, czyli wykonanie w nim komend nie wymaga kompilacji. W efekcie R nie jest najszybszym językiem programowania.
- Podobnie jak wiele innych języków, również R zawiera wiele niekonsekwencji, wynikających z wieloletniej ewolucji tego języka. W efekcie istnieje wiele specjalnych przypadków czy wyjątków, które warto znać (Burns 2012).
Ta książka skupia się na prezentacji głównym konceptów programistycznych używając języka R. W sekcji 2.5 można znaleźć listę różnorodnych materiałów, książek, blogów, kursów, czy serwisów ułatwiających i wspomagających naukę R. Istnieje także wiele wprowadzających materiałów do nauki innych języków. Przykładowo, osoby zainteresowane nauką Pythona mogą skorzystać z istniejących książek (Gries, Campbell, and Montojo (2017) oraz Guzdial and Ericson (2016)), czy też kursów Software Carpentry oraz Python Course. W pracy programistycznej przydaje się również często znajomość linii komend. Tutaj również można użyć materiałów z kursu Software Carpentry lub książki The Unix Workbench (Kross 2017).
1.4 Zadania
- Pomyśl do czego jesteś w stanie wykorzystać programowanie w swoim życiu zawodowym lub prywatnym?
- Zastanów się nad mitami związanymi z programowaniem. Czy jesteś w stanie wskazać jakieś mity nie wymienione powyżej?
- Wybierz trzy języki programowania z listy wymienionej w tym rozdziale i poszukaj informacji o nich. Do czego są one stosowane? Jakie mają wady i zalety?
Bibliografia
Burns, Patrick. 2012. The R Inferno. Lulu.com.
Gries, Paul, Jennifer Campbell, and Jason Montojo. 2017. Practical Programming: An Introduction to Computer Science Using Python 3.6. Pragmatic Bookshelf.
Guzdial, Mark, and Barbara Ericson. 2016. Introduction to Computing and Programming in Python. Pearson.
Kross, Sean. 2017. The Unix Workbench.
Niektórzy wydzielają już nawet obecny czas jako czwartą rewolucję przemysłową - https://en.wikipedia.org/wiki/Industry_4.0.↩︎
https://en.wikipedia.org/wiki/The_World%27s_Billionaires#2018↩︎
Efektem tego jest też coraz większa popularność modeli subskrypcyjnych - https://en.wikipedia.org/wiki/Subscription_business_model.↩︎
https://en.wikipedia.org/wiki/Standing_on_the_shoulders_of_giants↩︎
Przecięty człowiek jest w stanie wykonać około pół operacji na sekundę - https://en.wikipedia.org/wiki/Computer_performance_by_orders_of_magnitude.↩︎
Zobacz porównanie oczekiwań i rzeczywistej pracy programisty na https://www.youtube.com/watch?v=HluANRwPyNo.↩︎
https://www.history.com/news/coding-used-to-be-a-womans-job-so-it-was-paid-less-and-undervalued↩︎
Wiąże się to z popularnym na Zachodzie terminem data science, który łączy programowanie, analizę danych i wiedzę dziedzinową.↩︎
Parafrazując Donalda Kuntha “We should forget about small efficiencies, say about 97% of the time: premature optimization is the root of all evil. Yet we should not pass up our opportunities in that critical 3%.”↩︎