Wstęp do pythona: Różnice pomiędzy wersjami

Z RoboCity
(Nieco dłuższe programy)
(Jak w ogóle działa język programowania i co to jest?)
 
(Nie pokazano 21 pośrednich wersji utworzonych przez tego samego użytkownika)
Linia 1: Linia 1:
 
Kilka słów o języku programowania '''python'''. Skupimy się na używaniu tego języka pozostawiając szczegóły techniczne na boku.  
 
Kilka słów o języku programowania '''python'''. Skupimy się na używaniu tego języka pozostawiając szczegóły techniczne na boku.  
 
=== Jak w ogóle działa język programowania i co to jest? ===
 
=== Jak w ogóle działa język programowania i co to jest? ===
 +
 +
 
Komputery są przydatne o tyle, o ile potrafią wykonać to, czego od nich chcemy.  
 
Komputery są przydatne o tyle, o ile potrafią wykonać to, czego od nich chcemy.  
  
Jednym ze sposobów przekazywania innym, w miarę rozgarniętym bytom, czego od nich oczekujemy są instrukcje. Możemy na przykład poinstruować rodzeństwo, żeby nie dotykało tej kupki części i... Przynajmniej mieć nadzieję, że instrukcje zostaną wykonane. Jednak pomijając kłopoty komunikacyjne zastanówmy się chwilę co właściwie zrobiliśmy. Po pierwsze użyliśmy znanego pewnie nie więcej niż 100mln ludzi specyficznego języka (polskiego) z jego wszystkimi zasadami wymowy czy gramatyki, żeby przy pomocy dość skomplikowanej aparatury (nasze gardło i język -- powietrze -- uszy odbiorcy) przekazać myśl opisującą jakiego zachowania oczekujemy.  
+
Jednym ze sposobów przekazywania innym czego od nich oczekujemy są instrukcje. Możemy na przykład poprosić rodzeństwo, żeby nie dotykało tej kupki części i... Przynajmniej mieć nadzieję, że instrukcje zostaną wykonane.
  
Dokładnie na tym samym polega programowanie komputerów. W tej chwili jeszcze nie jest możliwe zagajenie rozmowy z komputerem w języku naturalnym, który jest zbyt zawiły i za bardzo wieloznaczny. Tym bardziej nie było to możliwe wcześniej. Z tego powodu informatycy opracowali pewne prostsze i bardziej precyzyjne języki.  Ponadto zrezygnowali z rozmów z komputerami i przyjęli zasadę, że treść programu trzeba dostarczyć na piśmie, co w przypadku komputerów oznacza plik tekstowy lub tekst wprowadzony z klawiatury.
 
  
Jeśli nauczymy się zapisywać swoje intencje, w którymś z języków, które nasz komputer rozumie, będziemy mogli wykorzystywać go do różnych, mniej lub bardziej przydatnych zajęć. Jednym programistom podoba się "przekonywanie" komputerów do wyświetlania wirtualnych światów, w których inni ludzie lubią przebywać. Innym udaje się tworzyć zestawy instrukcji, dzięki którym komputer potrafi samodzielnie kierować samochodem. Kody napisane przez niektórych sterują sondami w przestrzeni kosmicznej, które muszą samodzielnie zbierać dane (są zbyt daleko żeby człowiek mógł reagować na bieżąco!) i posyłać wyniki czekającym na Ziemi ludziom. Jak widać na filmie poniżej są też tacy, którzy tworzą zestawy instrukcji do tańca na śniegu, przysiadów z pudłami i szczerej cierpliwości wobec posiadaczy kijów hokejowych.  
+
Jednak pomijając kłopoty komunikacyjne zastanówmy się chwilę co właściwie zrobiliśmy. Po pierwsze użyliśmy znanego sobie i rodzeństwu języka (polskiego) z jego wszystkimi zasadami wymowy/gramatyki. Po drugie przy pomocy dość skomplikowanej aparatury (nasze aparat mowy --> powietrze --> uszy rodzeństwa) przekazaliśmy pewną myśl określającą jakiego zachowania oczekujemy. Kontaktując się z ludźmi wykonujemy te wszystkie czynności odruchowo nie zastanawiając się ile ciekawych procesów musi się udać, żeby to wszystko zadziałało.  
  
<youtube>rVlhMGQgDkY</youtube>
 
  
[[Plik:Blad_w_programie.jpg|thumb|right|Kiedy program steruje jakimś większym urządzeniem efekty błędów w kodzie bywają zaskakujące.]]
+
Na tym samym polega programowanie! Ponieważ jednak do niedawna komputery nie rozumiały języków naturalnych informatycy nie używają ich. Opracowali '''o wiele prostsze''' od naturalnych, a także '''bardziej precyzyjne''' ''języki (do) programowania''. Zrezygnowali także z rozmów z komputerami i przyjęli zasadę, że treść programu trzeba dostarczyć "na piśmie" jako plik tekstowy lub tekst wprowadzony z klawiatury. Jeśli chcemy więc spowodować, żeby komputer wykonał nasze polecenia, musimy nauczyć się zapisywać swoje zamiary w jakimś języku programowania. I o tym jest ta strona, a językiem, który zastosujemy będzie '''python'''. Nie wybraliśmy go ze względu na jakieś niezwykłe zalety, po prostu jest jednym na najbardziej popularnych obecnie. Dzięki informatyce teoretycznej wiadomo, że większość języków programowania powszechnie używanych ma formalnie te same możliwości, czyli mówiąc inaczej program, który da się zapisać w jednym z nich, można bez problemu zapisać w dowolnym innym. Wybór języka jest więc co najwyżej kwestią wygody lub innych praktycznych zalet. Umiejąc programować będziemy mogli robić różne ciekawe rzeczy: tworzyć wirtualne światy, pisać kody samodzielnie kierujące samochodami czy sondami w przestrzeni kosmicznej, które muszą samodzielnie reagować na zmieniającą się sytuację (są zbyt daleko żeby jakiś człowiek mógł reagować na bieżąco!), programować sztuczną inteligencję, albo mechanikę podobną do naturalnej jak widać na filmach poniżej. Tak czy inaczej programiści mogą wykrzesać z komputerów sporo i nauczenie się choćby jednego języka programowania może być początkiem ciekawej przygody -- dobrym przykładem może być Polak, którego drętwe zdjęcie z obozu informatycznego stało się kiedyś przebojem demotywatorów, a on obecnie programuje samodzielnie lądujące rakiety SpaceX i nie wykluczone, że niedługo jego kod pozwoli przeprowadzić lądowania na Marsie.
 +
 
 +
 
 +
<youtube>rVlhMGQgDkY</youtube><youtube>tf7IEVTDjng</youtube>
  
  
 
<span style="color:green">''Okazuje się więc, że pomimo prostoty języków programowania, potrafimy z ich pomocą wyrażać naprawdę skomplikowane instrukcje oraz zupełnie nieźle się przy tym bawić!'' </span>
 
<span style="color:green">''Okazuje się więc, że pomimo prostoty języków programowania, potrafimy z ich pomocą wyrażać naprawdę skomplikowane instrukcje oraz zupełnie nieźle się przy tym bawić!'' </span>
  
 +
<br clear=all>
 +
[[Plik:Blad_w_programie.jpg|thumb|right|Kiedy program steruje jakimś większym urządzeniem efekty błędów w kodzie bywają zaskakujące.]]
 +
 +
 +
Warto zwrócić uwagę na fakt, że maszyny ciągle jeszcze są bezmyślne i z chęcią zrealizują '''dowolne''' instrukcje o ile tylko zapiszemy je w zrozumiały dla nich sposób. '''Niestety ta zaleta komputerów jest jednocześnie ich najgorszą wadą.''' Kiedy instrukcje są bez sensu, maszyny wykonają działanie bez sensu bez żadnego sprzeciwu! Niestety z tego powodu programowanie przypomina opiekę nad bardzo szybkim, ale jednak ciągle "osiołkiem", który się sam nie domyśli, że coś robi źle.
  
Warto zwrócić uwagę na fakt, że w odróżnieniu od rodzeństwa, maszyny ciągle jeszcze są dość bezmyślne i z chęcią zrealizują '''dowolne''' instrukcje o ile tylko zapiszemy je w zrozumiały dla nich sposób. Niestety ta zaleta komputerów jest jednocześnie ich najgorszą wadą. Kiedy instrukcje są bez sensu, maszyny wykonają działanie bez sensu bez sprzeciwu. Niestety z tego powodu programowanie przypomina opiekę nad bardzo wydajnym, ale jednak ciągle "osiołkiem".
 
  
Praktyczna zasada: ''Jeżeli "komputer robi coś głupiego", to najwyższa pora przemyśleć instrukcje, które otrzymał; już dłużej nie da się zwlekać.''
+
Praktyczna zasada: ''Jeżeli myślisz, że to "komputer robi coś głupiego", to najwyższa pora przemyśleć instrukcje, które otrzymał; już dłużej nie da się zwlekać.''
  
 
<br clear=all>
 
<br clear=all>
  
 
=== Jak zacząć programować? ===
 
=== Jak zacząć programować? ===
 +
 
Wystarczy włączyć terminal i wpisać polecenie '''python'''.
 
Wystarczy włączyć terminal i wpisać polecenie '''python'''.
 +
  
 
  ktos@maszyna:~$ python
 
  ktos@maszyna:~$ python
Linia 31: Linia 40:
 
  Type "help", "copyright", "credits" or "license" for more information.
 
  Type "help", "copyright", "credits" or "license" for more information.
 
  >>>
 
  >>>
 +
  
 
W odpowiedzi zostaje uruchomiony program, który czeka na nasze instrukcje i będzie je wykonywał w miarę wpisywania. Stan oczekiwania na instrukcje sygnalizowany jest wyświetleniem '''>>>''' na początku linii. Na samym początku python wyświetla też kilka dodatkowych technicznych informacji na temat języka, oraz zachętę do skorzystania z kilku instrukcji w celu poznania dalszych szczegółów. Możemy te linijki zignorować.
 
W odpowiedzi zostaje uruchomiony program, który czeka na nasze instrukcje i będzie je wykonywał w miarę wpisywania. Stan oczekiwania na instrukcje sygnalizowany jest wyświetleniem '''>>>''' na początku linii. Na samym początku python wyświetla też kilka dodatkowych technicznych informacji na temat języka, oraz zachętę do skorzystania z kilku instrukcji w celu poznania dalszych szczegółów. Możemy te linijki zignorować.
  
<span style="color:green">Kiedy już skończymy wykonywanie różnych instrukcji '''pythona''' możemy wrócić do linii poleceń terminala używając kombinacji klawiszy '''Ctrl-D'''.</span> Możesz to sprawdzić od razu, ale nie zapomnij ponownie uruchomić '''pythona''' ponownie przed przejściem do następnych przykładów.
+
 
 +
<span style="color:green">Kiedy już skończymy wykonywanie różnych instrukcji '''pythona''' możemy zakończyć jego działanie i wrócić do linii poleceń terminala używając kombinacji klawiszy '''Ctrl-D'''.</span> Możesz to sprawdzić od razu, ale nie zapomnij ponownie uruchomić '''pythona''' przed przejściem do następnych przykładów.
  
 
=== Kilka prostych instrukcji i konstrukcji języka python na rozgrzewkę ===
 
=== Kilka prostych instrukcji i konstrukcji języka python na rozgrzewkę ===
Linia 40: Linia 51:
  
 
==== '''print''' (''ang. drukuj''), czyli wyświetlanie napisów ====
 
==== '''print''' (''ang. drukuj''), czyli wyświetlanie napisów ====
Spróbujmy wykonać jedną z prostszych instrukcji, która po prostu wypisuje podany tekst. Kiedyś, kiedy będziemy pisali dłuższe programy, taka instrukcja przyda nam się na przykład do wyświetlenia wyniku, albo komunikatu, że program skończył działanie pomyślnie i wykonał to czego chcieliśmy.
+
 
 +
 
 +
Spróbujmy wykonać jedną z prostszych instrukcji, która wypisuje jakiś tekst. Ona może być przydatna na przykład do wyświetlenia wyników, albo pokazania stopnia zaawansowania obliczeń jeśli program działa długo, lub ogólnie wszędzie tam, gdzie chcemy żeby program "zagadał" do użytkownika.
 +
 
 +
 
<source lang="python">
 
<source lang="python">
 
>>> print("Nie będę śpiewał kołysanek na lekcji")
 
>>> print("Nie będę śpiewał kołysanek na lekcji")
Linia 47: Linia 62:
 
</source>
 
</source>
  
Jak widać programowanie w '''pythonie''' jest zupełnie proste. Napisaliśmy nazwę funkcji ('''print''') po czym w nawiasie podaliśmy parametr (tutaj tekst, który należy wydrukować) i tyle. Po naciśnięciu ENTER zobaczymy nasz tekst.
 
  
Zwróćmy też uwagę, że tekst otoczony jest znakami cudzysłowu. Chodzi o to, że gdybyśmy go napisali bez cudzysłowu, na przykład <source lang="python" inline>print( print print )</source>, mogłoby być trudno w niektórych sytuacjach zrozumieć, które słowa należy traktować jak zwykły kawałek tekstu do wyświetlenia, a które należy interpretować jako instrukcje programu. Kiedy jednak napiszemy <source lang='python' inline>print( "print print" )</source> będzie oczywiste, że należy wyświetlić napis <code>print print</code>.
+
Jak widać programowanie w '''pythonie''' jest zupełnie proste. Napisaliśmy nazwę funkcji ('''print''') po czym w nawiasie podaliśmy parametr (tutaj tekst, który należy wydrukować) i tyle. Ponieważ interpreter pythona pracuje w trybie interaktywnym i wykonuje instrukcje zaraz po ich podaniu, po naciśnięciu ENTER zobaczymy efekt działania, czyli nasz tekst.
 +
 
 +
 
 +
Zwróć uwagę, że tekst otoczony jest znakami cudzysłowu. Gdybyśmy go napisali bez nich, na przykład zamiast <source lang="python" inline>print( "print")</source> byłoby <source lang="python" inline>print( print )</source>, mogłoby być trudno w niektórych sytuacjach zrozumieć, które słowa należy traktować jak zwykły kawałek tekstu do wyświetlenia, a które należy interpretować jako instrukcje programu. Kiedy jednak napiszemy <source lang='python' inline>print( "print" )</source> będzie oczywiste, że pierwsze ''print'' to instrukcja drukowania, a drugie ''print'' to tylko jakiś tekst, który ma być wypisany, i wobec tego '''python''' bez problemu wyświetli napis <code>print</code>.
 +
 
  
 
Jak widać powyżej tekst został wyświetlony w pierwszej pustej linii na ekranie, a zaraz pod nim ponownie znak oczekiwania na kolejną instrukcję. Wszystko razem wygląda trochę ciasno. Żeby temu zaradzić dodajmy zarówno przed tekstem jak i po nim znak przejścia do nowej linii. Przejście do nowej linii zostawi pustą linijkę dzięki czemu wyświetlony komunikat będzie się lepiej wyróżniał.  
 
Jak widać powyżej tekst został wyświetlony w pierwszej pustej linii na ekranie, a zaraz pod nim ponownie znak oczekiwania na kolejną instrukcję. Wszystko razem wygląda trochę ciasno. Żeby temu zaradzić dodajmy zarówno przed tekstem jak i po nim znak przejścia do nowej linii. Przejście do nowej linii zostawi pustą linijkę dzięki czemu wyświetlony komunikat będzie się lepiej wyróżniał.  
 +
  
 
<source lang="python">
 
<source lang="python">
Linia 60: Linia 79:
 
  >>>  
 
  >>>  
 
</source>
 
</source>
 +
  
 
A co jeśli chcielibyśmy wyświetlony tekst powtórzyć? '''Python''' pozwala użyć mnożenia w tym celu.  
 
A co jeśli chcielibyśmy wyświetlony tekst powtórzyć? '''Python''' pozwala użyć mnożenia w tym celu.  
 +
 
<source lang="python">
 
<source lang="python">
 
>>> print("\nNie będę śpiewał kołysanek na lekcji"*5)
 
>>> print("\nNie będę śpiewał kołysanek na lekcji"*5)
Linia 72: Linia 93:
 
>>>  
 
>>>  
 
</source>
 
</source>
 +
  
 
Wyświetlanie napisu wielokrotnie ma raczej mały sens ale, choć dla człowieka takie zadanie byłoby karą, komputer wykonuje kod bez problemu. Jeśli pomyłkowo pomnożymy napis milion razy, funkcja '''print''' cierpliwie wyświetli milion napisów...............
 
Wyświetlanie napisu wielokrotnie ma raczej mały sens ale, choć dla człowieka takie zadanie byłoby karą, komputer wykonuje kod bez problemu. Jeśli pomyłkowo pomnożymy napis milion razy, funkcja '''print''' cierpliwie wyświetli milion napisów...............
 +
  
 
<span style="color:green">Na wszelki wypadek dodajmy przy okazji, że zbyt długo pracujący program można przerwać kombinacją klawiszy '''Ctrl-C'''.</span>  
 
<span style="color:green">Na wszelki wypadek dodajmy przy okazji, że zbyt długo pracujący program można przerwać kombinacją klawiszy '''Ctrl-C'''.</span>  
 +
  
 
Czasem jednak powielenie tekstu może być przydatne. Na przykład przepis na wyświetlenie choinki mógłby wyglądać tak (zwróć uwagę, że jeśli w jednej linii podajemy wiele instrukcji -- tutaj '''print''' -- to rozdzielamy je średnikiem ''';'''):
 
Czasem jednak powielenie tekstu może być przydatne. Na przykład przepis na wyświetlenie choinki mógłby wyglądać tak (zwróć uwagę, że jeśli w jednej linii podajemy wiele instrukcji -- tutaj '''print''' -- to rozdzielamy je średnikiem ''';'''):
 +
 +
 
<source lang="python">
 
<source lang="python">
 
>>> print(" "*10 + "^"*1); print(" "*9 + "^"*3); print(" "*8 + "^"*5);print(" "*7 + "^"*7);print(" "*6 + "^"*9);
 
>>> print(" "*10 + "^"*1); print(" "*9 + "^"*3); print(" "*8 + "^"*5);print(" "*7 + "^"*7);print(" "*6 + "^"*9);
Linia 87: Linia 113:
 
>>>  
 
>>>  
 
</source>
 
</source>
 +
 +
 
Dzięki temu, że możemy łatwo powielić tekst poprzez mnożenie, stworzenie choinki składającej się z coraz krótszych kawałków spacji (10, 9, 8, 7, 6) oraz coraz dłuższych pięter choinki (znaki '''^''' powtórzone 1, 3, 5, 7 i 9 razy) było proste w zapisie. Jeśli nie wierzysz, spróbuj za pierwszym razem uzyskać ładną symetryczną choinkę licząc znaki poszczególnych pięter samemu i wstawiając odpowiednio długie ciągi znaków w kolejnych instrukcjach '''print'''.
 
Dzięki temu, że możemy łatwo powielić tekst poprzez mnożenie, stworzenie choinki składającej się z coraz krótszych kawałków spacji (10, 9, 8, 7, 6) oraz coraz dłuższych pięter choinki (znaki '''^''' powtórzone 1, 3, 5, 7 i 9 razy) było proste w zapisie. Jeśli nie wierzysz, spróbuj za pierwszym razem uzyskać ładną symetryczną choinkę licząc znaki poszczególnych pięter samemu i wstawiając odpowiednio długie ciągi znaków w kolejnych instrukcjach '''print'''.
  
Drukując napisy możemy jeszcze skorzystać z jednej bardzo przydatnej funkcji '''pythona'''. Bardzo często kiedy wyświetlamy jakiś komunikat na ekranie, chcielibyśmy w standardowym dłuższym tekście odpowiednio dopasować tylko jego krótki fragment. Na przykład gdybyśmy chcieli przywitać użytkownika, standardowy tekst mógłby brzmieć ''Witaj ?, miło Cię zobaczyć znowu!'' gdzie w miejsce znaku zapytania wstawiałoby się tylko imię użytkownika.  
+
 
 +
Drukując napisy możemy jeszcze skorzystać z jednej bardzo przydatnej funkcji '''pythona'''. Bardzo często kiedy wyświetlamy jakiś komunikat na ekranie, chcielibyśmy w standardowym dłuższym tekście odpowiednio dopasować tylko jego krótki fragment. Na przykład gdybyśmy chcieli przywitać użytkownika, standardowy tekst mógłby brzmieć ''Witaj ..., miło Cię zobaczyć znowu!'' gdzie w miejsce ... wstawiałoby się tylko imię użytkownika.  
 +
 
  
 
Do tego celu można się posłużyć następującą konstrukcją:
 
Do tego celu można się posłużyć następującą konstrukcją:
 +
  
 
<source lang="python">
 
<source lang="python">
Linia 100: Linia 131:
 
>>>  
 
>>>  
 
</source>
 
</source>
 +
  
 
Co zrobiliśmy? W tym miejscu tekstu, gdzie chcielibyśmy wstawić inny, umieściliśmy znacznik '''%s''' i dalej, już poza tekstem, po znaku '''%''' podaliśmy wartość, którą należy wstawić w zaznaczone miejsce. Posłużmy się jeszcze innym przykładem, w którym wstawiamy dwa różne teksty do innego.
 
Co zrobiliśmy? W tym miejscu tekstu, gdzie chcielibyśmy wstawić inny, umieściliśmy znacznik '''%s''' i dalej, już poza tekstem, po znaku '''%''' podaliśmy wartość, którą należy wstawić w zaznaczone miejsce. Posłużmy się jeszcze innym przykładem, w którym wstawiamy dwa różne teksty do innego.
 +
  
 
<source lang="python">
 
<source lang="python">
>>>print("\nNie będę śpiewał %s %s kołysanek na lekcji\n" % ("przerażająco", "dziwnych"))
+
>>>print("\nNie będę śpiewał %s kołysanek na lekcji %s\n" % ("dziwnych", "matematyki"))
  
Nie będę śpiewał przerażająco dziwnych kołysanek na lekcji
+
Nie będę śpiewał dziwnych kołysanek na lekcji matematyki
  
 
>>>  
 
>>>  
 
</source>
 
</source>
 +
  
 
A co jeśli chcielibyśmy wstawić nie tekst, ale liczbę? Wówczas musimy zastosować inny znacznik, czyli '''%d'''.
 
A co jeśli chcielibyśmy wstawić nie tekst, ale liczbę? Wówczas musimy zastosować inny znacznik, czyli '''%d'''.
 +
  
 
<source lang="python">
 
<source lang="python">
>>> print("\nNie będę śpiewał %s %s kołysanek na %d lekcji\n" % ("przerażająco", "dziwnych", 5))
+
>>> print("\nNie będę śpiewał %s kołysanek na %d lekcji %s\n" % ("dziwnych", 2, "matematyki"))
  
Nie będę śpiewał przerażająco dziwnych kołysanek na 5 lekcji
+
Nie będę śpiewał dziwnych kołysanek na 2 lekcji matematyki
  
 
>>>  
 
>>>  
 
</source>
 
</source>
  
W tej chwili powyższa konstrukcja może się wydawać nadmiarowa -- widać, że prościej byłoby zapisać całe zdanie od razu tak jak miało brzmieć. Ale jej duża przydatność wyjaśni się już w następnym punkcie.
+
 
 +
W tej chwili powyższa konstrukcja może się wydawać zbyteczna -- widać, że prościej byłoby zapisać całe zdanie od razu tak jak miało brzmieć. Ale jej przydatność wyjaśni się już w następnym punkcie.
  
 
==== '''zmienna''', czyli jak pamiętać to co program przetwarza ====
 
==== '''zmienna''', czyli jak pamiętać to co program przetwarza ====
Linia 175: Linia 211:
 
Całe zadanie sprowadza się do zapisania tekstu programu w pliku i potem przekazania go interpreterowi '''pythona''' do wykonania.  
 
Całe zadanie sprowadza się do zapisania tekstu programu w pliku i potem przekazania go interpreterowi '''pythona''' do wykonania.  
  
Dla przykładu weźmy ostatni przykład powyżej. Składa się z dwóch instrukcji: ustawienia wartości zmiennej <code>predkosc</code> i wyświetlenia jej wartości. Otwórzmy więc dowolny edytor tekstu (na przykład '''gedit''') i w nowym pliku wstawmy te dwie instrukcje:
+
Dla przykładu weźmy ostatni przykład powyżej. Składa się z dwóch instrukcji: ustawienia wartości zmiennej <code>predkosc</code> i wyświetlenia jej wartości w metrach na sekundę oraz kilometrach na godzinę. Otwórzmy więc dowolny edytor tekstu (na przykład '''gedit''') i w nowym pliku wstawmy te dwie instrukcje:
 +
 
  
 
<source lang="python">
 
<source lang="python">
Linia 183: Linia 220:
 
  print("\nAkualna prędkość wynosi %f [m/s] (= %f [km/h])\n" % (predkosc, predkosc * 3.6))
 
  print("\nAkualna prędkość wynosi %f [m/s] (= %f [km/h])\n" % (predkosc, predkosc * 3.6))
 
</source>
 
</source>
 +
  
 
Teraz zapiszmy plik z dowolną nazwą na dysku. Warto dać mu rozszerzenie '''.py''' (jak '''py'''thon), które jest standardowym oznaczeniem dla programów w '''pythonie'''. Jeśli tak zrobimy gedit powinien to zauważyć i zacząć kolorować składnię dzięki czemu kod będzie czytelniejszy.  
 
Teraz zapiszmy plik z dowolną nazwą na dysku. Warto dać mu rozszerzenie '''.py''' (jak '''py'''thon), które jest standardowym oznaczeniem dla programów w '''pythonie'''. Jeśli tak zrobimy gedit powinien to zauważyć i zacząć kolorować składnię dzięki czemu kod będzie czytelniejszy.  
  
Jeśli użyliśmy nazwy pliku <pre>pierwszy.py</pre> możemy wykonać program wywołując polecenie:
+
Jeśli użyliśmy nazwy pliku <code>pierwszy.py</code> możemy wykonać program wywołując polecenie:
<pre>
+
 
 +
 
 +
<source lang="text">
 
ktos@maszyna:~ $ python pierwszy.py
 
ktos@maszyna:~ $ python pierwszy.py
  
Linia 193: Linia 233:
  
 
ktos@maszyna:~ $
 
ktos@maszyna:~ $
</pre>
+
</source>
 +
 
 +
 
  
Jak widać program działa tak samo jak w powyżej. <span style="color:green">'''Natomiast teraz możemy umieścić w pliku nie jedną, ale wiele instrukcji i napisać dzięki temu dłuższy kod robiący ciekawsze rzeczy!'''</span>
+
Jak widać program działa tak samo jak w powyżej.  
  
Dodatkowa pierwsza linijka <code># coding: utf-8</code> jest potrzebna dlatego, że nasz tekst używa polskich znaków diakrytycznych (słowo ''pr'''ę'''dko'''ść''''' ma trzy), a bez ustawienia kodowania uwzględniającego polskie znaki '''python''' nie spodziewa się ich i zamiast wykonać program wyświetli jedynie rozpaczlliwy komunikat, że nie rozumie znaków spoza standardu ASCII (stary standard kodowania znaków jeszcze z poprzedniego wieku, nowsza 3 wersja pythona domyślnie używa bardziej uniwersalnego UTF-8):
 
  
 +
<span style="color:green">'''Natomiast teraz możemy umieścić w pliku nie jedną, ale wiele instrukcji i napisać dzięki temu dłuższy kod robiący ciekawsze rzeczy!'''</span>
 +
 +
 +
Dodatkowa pierwsza linijka <code># coding: utf-8</code> jest potrzebna dlatego, że nasz w tekście programu używamy polskich znaków diakrytycznych (słowo ''pr'''ę'''dko'''ść''''' ma trzy). Bez ustawienia kodowania obejmującego polskie znaki (czyli UTF-8) '''python''' nie spodziewa się innych liter niż angielskie i zamiast wykonać program wyświetli jedynie rozpaczliwy komunikat, że nie rozumie znaków spoza standardu ASCII (jest to stary standard kodowania znaków jeszcze z poprzedniego wieku):
 +
 +
 +
<source lang="text">
 +
File "/home/ktos/pierwszy.py", line 2
 +
SyntaxError: Non-ASCII character '\xc4' in file /home/ktos/pierwszy.py on line 2,
 +
                      but no encoding declared; see http://python.org/dev/peps/pep-0263/ for details
 +
</source>
 +
 +
 +
Warto zauważyć, że nowe wersje pythona, tj. 3+, domyślnie używają bardziej uniwersalnego UTF-8, więc jeśli używasz pythona 3 lub nowszego linijka <code># coding: utf-8</code> nie jest potrzebna do pracy z polskimi znakami.
  
File "/home/ktos/pierwszy.py", line 2
 
SyntaxError: Non-ASCII character '\xc4' in file /home/ktos/pierwszy.py on line 2, but no encoding declared; see http://python.org/dev/peps/pep-0263/ for details
 
  
 
Przy okazji zauważmy, że to co znajduje się w linijce po znaku # traktowane jest przez interpreter jako komentarz, a więc to co jest tam napisane nie będzie wykonywane jako program. Linie komentarza przydają się, żeby choćby samemu sobie napisać wskazówkę o co chodziło w kodzie, który jest w pobliżu. W bardzo długich programach można się szybko pogubić i rozsądnie napisany komentarz bardzo ułatwia życie. Na przykład:
 
Przy okazji zauważmy, że to co znajduje się w linijce po znaku # traktowane jest przez interpreter jako komentarz, a więc to co jest tam napisane nie będzie wykonywane jako program. Linie komentarza przydają się, żeby choćby samemu sobie napisać wskazówkę o co chodziło w kodzie, który jest w pobliżu. W bardzo długich programach można się szybko pogubić i rozsądnie napisany komentarz bardzo ułatwia życie. Na przykład:
 +
  
 
<source lang="python">
 
<source lang="python">
Linia 209: Linia 263:
 
   
 
   
 
  predkosc = 5.111
 
  predkosc = 5.111
  # Przelicznik 3.6 bierze się stąd, że 1 km/h = 1000 m / 3600 s = 1000/3600 m/s = 3.6 m/s
+
  # Przelicznik 3.6 bierze się stąd, że 1 [km/h] = (1000 [m] / 3600 [s] = 1000/3600 [m/s] ) = 1/3.6 [m/s],
 +
# skąd wynika odwrotna zależność że 1 [m/s] = 3.6 [km/h]
 
  print("\nAkualna prędkość wynosi %f [m/s] (= %f [km/h])\n" % (predkosc, predkosc * 3.6))
 
  print("\nAkualna prędkość wynosi %f [m/s] (= %f [km/h])\n" % (predkosc, predkosc * 3.6))
 
</source>
 
</source>
Linia 216: Linia 271:
 
Skoro potrafimy już używać programów składających się z wielu linijek zajmijmy się dłuższymi konstrukcjami języka.  
 
Skoro potrafimy już używać programów składających się z wielu linijek zajmijmy się dłuższymi konstrukcjami języka.  
 
==== '''instrukcja warunkowa''', czy co robić jeśli tak, a co jeśli nie ====
 
==== '''instrukcja warunkowa''', czy co robić jeśli tak, a co jeśli nie ====
Wracając do przykładu z rozmów między ludźmi dość często przekazując instrukcje używamy poleceń warunkowych nawet nie bardzo uświadamiając sobie ten fakt. Często uzależniamy działanie od jakiegoś wstępnego warunku mówiąc na przykład: ''Jeśli X zadzwoni o osiemnastej to będę musiał ..., a jak nie zadzwoni to możemy ...''.
 
  
Dokładnie tak samo możemy chcieć zaprogramować komputer. Na przykład jeśli na przeciwko robota stoi przeszkoda (sprawdzamy co podaje jakiś czujnik) to należy wykonać jej omijanie, a jeśli przeszkody nie ma, można kontynuować jazdę do przodu.
+
 
 +
Wracając do przykładu z rozmów między ludźmi dość często przekazując informacje używamy określeń warunkowych nawet nie bardzo uświadamiając sobie ten fakt. Czyli uzależniamy działanie od jakiegoś wstępnego warunku, który w tej chwili jeszcze nie jest rozstrzygnięty, ale na pewno trzeba go uwzględnić w działaniu. Mówimy na przykład:
 +
 
 +
 
 +
''Jeśli X przyjdzie o osiemnastej to będę musiał ..., a jak nie przyjdzie to możemy ...''.
 +
 
 +
 
 +
Dokładnie tak samo możemy chcieć zaprogramować komputer. Na przykład jeśli na przeciwko robota stoi przeszkoda (odczytujemy jakiś czujnik) to należy wykonać jej omijanie, a jeśli przeszkody nie ma, można kontynuować jazdę do przodu.
 +
 
  
 
Do sterowania programem w ten sposób służy właśnie instrukcja warunkowa, której schemat przedstawiony jest poniżej.
 
Do sterowania programem w ten sposób służy właśnie instrukcja warunkowa, której schemat przedstawiony jest poniżej.
 +
  
 
<source lang="python">
 
<source lang="python">
Linia 235: Linia 298:
 
...
 
...
 
</source>
 
</source>
 +
 +
 +
Zwróć uwagę, że w pythonie blok instrukcji, których wykonanie zależy od linijki powyżej jest przesunięty w prawo (wcięty). To nie jest tylko zabieg stylistyczny. W pythonie wcięcia mają znaczenie. Pierwsza nie wcięta linijka poniżej <code>else:</code> będzie wykonana niezależnie od tego czy warunek jest spełniony czy nie. Dokładnie tak to wygląda:
 +
 +
 +
<source lang="python">
 +
if warunek:
 +
    # 1 linijka która się wykona jeśli warunek jest prawdziwy
 +
    ...
 +
    # 2 linijka która się wykona jeśli warunek jest prawdziwy
 +
    ...
 +
else:
 +
    # 1 linijka która się wykona w przeciwnym przypadku
 +
    ... 
 +
    # 2 linijka która się wykona w przeciwnym przypadku
 +
    ...
 +
 +
# ta linijka wykona się jako następna po if/else i nie należy ani do bloku if, ani do bloku else
 +
...
 +
</source>
 +
 +
  
 
Zastosujmy instrukcję warunkową do modyfikacji wyświetlania komunikatu powyżej:
 
Zastosujmy instrukcję warunkową do modyfikacji wyświetlania komunikatu powyżej:
 +
  
 
<source lang="python">
 
<source lang="python">
Linia 251: Linia 337:
  
 
</source>
 
</source>
 +
  
 
Spróbuj zapisać ten program z różnymi wartościami prędkości i wykonać.  
 
Spróbuj zapisać ten program z różnymi wartościami prędkości i wykonać.  
 +
  
 
W przypadku wielolinijkowych konstrukcji '''pythona''' trzeba zwrócić uwagę na wcięcia linijek. Nie przypadkiem te instrukcje, które mają się wykonać dla spełnionego, i osobno dla niespełnionego, warunku są przesunięte o 4 spacje w prawo. Tylko dzięki temu przesunięciu interpreter '''pythona''' wie, które instrukcje wykonywać w zależności od spełnionego warunku. Popatrzmy na taki przykład:
 
W przypadku wielolinijkowych konstrukcji '''pythona''' trzeba zwrócić uwagę na wcięcia linijek. Nie przypadkiem te instrukcje, które mają się wykonać dla spełnionego, i osobno dla niespełnionego, warunku są przesunięte o 4 spacje w prawo. Tylko dzięki temu przesunięciu interpreter '''pythona''' wie, które instrukcje wykonywać w zależności od spełnionego warunku. Popatrzmy na taki przykład:
 +
  
 
<source lang="python">
 
<source lang="python">
Linia 269: Linia 358:
 
</source>
 
</source>
  
Jak zwykle warto uruchomić ten program ze zmienną <code>poziom_energii</code> mniejszą niż <code>1.0</code> żeby zobaczyć jego działanie w dwóch różnych przypadkach.
+
 
 +
Jak zwykle warto spróbować uruchomić program z modyfikacjami. Można ustawić zmienną <code>poziom_energii</code> liczbą mniejszą niż <code>1.0</code> żeby zobaczyć jego działanie w dwóch różnych przypadkach.
  
 
==== '''pętla''', czyli to co komputer potrafi robić bez znudzenia ====
 
==== '''pętla''', czyli to co komputer potrafi robić bez znudzenia ====
''ciąg dalszy nastąpi''
+
 
 +
 
 +
Bardzo często chcemy jakieś instrukcje powtórzyć określoną ilość razy. Na przykład chcielibyśmy po kolei zapalić diody podłączone do wyjść GPIO o numerach od 5 do 15. Moglibyśmy zapisać 10 następujących poleceń:
 +
 
 +
 
 +
<source lang="python">
 +
 
 +
# (...) dla jasności pominięte instrukcje wczytujące moduł obsługi wyjść GPIO oraz inicjujące płytkę
 +
 
 +
 
 +
gpio.output(5, 1)
 +
gpio.output(6, 1)
 +
gpio.output(7, 1)
 +
gpio.output(8, 1)
 +
gpio.output(9, 1)
 +
gpio.output(10, 1)
 +
gpio.output(11, 1)
 +
gpio.output(12, 1)
 +
gpio.output(13, 1)
 +
gpio.output(14, 1)
 +
gpio.output(15, 1)
 +
</source>
 +
 
 +
 
 +
Jednym słowem -- horror. Gdybyśmy chcieli zapalić na przykład 1024*768 diod w przeciętnym ekranie komputera przy takim sposobie kodowania musielibyśmy napisać blisko milion instrukcji!!!
 +
 
 +
 
 +
Na szczęście można to zrobić prościej. Wystarczy zastosować '''pętlę'''. Powyższy program zapisany z jej użyciem jest o wiele krótszy:
 +
 
 +
 
 +
<source lang="python">
 +
 
 +
# pominięte instrukcje wczytujące moduł obsługi wyjść gpio oraz inicjalizujące płytkę
 +
# ....
 +
 
 +
for numer in range(5, 16): 
 +
    gpio.output(numer, 1)
 +
</source>
 +
 
 +
 
 +
Co tu się dzieje dokładnie? Przede wszystkim funkcja '''range''' (''ang. zakres'') zwraca listę numerów z podanego przedziału z pominięciem ostatniego elementu. Sprawdźmy na przykład co zwróci użyte powyżej <code>range(5,16)</code>:
 +
 
 +
 
 +
<source lang="python">
 +
>>> range(5,16)
 +
[5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]
 +
>>>
 +
</source>
 +
 
 +
 
 +
Jak widać lista zaczyna się od 5, ale na końcu nie ma liczby 16.
 +
 
 +
 
 +
Po angielsku '''for''' oznacza '''dla''', '''in''' to po polsku '''w'''. Jeśli przepiszemy tekst programu po polsku, jego działanie stanie się praktycznie oczywiste
 +
 
 +
 
 +
'''dla''' numer '''w''' zakresie(5, 16): 
 +
    gpio.output(numer, 1)
 +
 
 +
 
 +
czyli wykonaj instrukcję <code>gpio.output(numer, 1)</code> podstawiając do zmiennej '''numer''' kolejne liczby z podanego zakresu. Proste prawda?
 +
 
 +
 
 +
Jeśli chciałoby się sprawdzić, że rzeczywiście zmienna '''numer''' zmienia się w podanym zakresie wystarczy ją wydrukować poznaną wcześniej instrukcją '''print'''.
 +
 
 +
 
 +
<source lang="python">
 +
>>> for numer in range(5,16): print(numer); 
 +
...
 +
5
 +
6
 +
7
 +
8
 +
9
 +
10
 +
11
 +
12
 +
13
 +
14
 +
15
 +
>>>
 +
</source>
 +
 
 +
 
 +
Załóżmy, że chcielibyśmy mrugnąć jedną diodą 20 razy. Nic prostszego! Wystarczy pętla o 20 krokach w środku której wykonamy jedno pełne mrugnięcie (a więc zapalenie, odczekanie chwilę, zgaszenie i znów odczekanie):
 +
 
 +
 
 +
<source lang="python">
 +
 
 +
# pominięte instrukcje wczytujące moduł obsługi wyjść gpio, moduł obsługi czasu time, oraz inicjalizujące płytkę
 +
# ...
 +
 
 +
for powtorka in range(1, 21):  # Pamiętaj, że range(1, 21) zwróci [1,2,...,20], bez 21.
 +
    gpio.output(numer, 1)
 +
    time.sleep(0.5)
 +
    gpio.output(numer, 0)
 +
    time.sleep(0.5)
 +
</source>
 +
 
 +
 
 +
Wielokrotnie taka konstrukcja się przyda. Na przykład, kiedy będziemy chcieli wykonać dokładnie 35 kroków silnika krokowego zamontownego po lewej stronie robota zapewne użyjemy pętli podobnej do takiej:
 +
 
 +
 
 +
<source lang="python">
 +
 
 +
# pominięte instrukcje wczytujące moduł obsługi silnika
 +
# ...
 +
 
 +
for powtorka in range(1, 36): 
 +
    krok(SILNIK_LEWY, DO_PRZODU)
 +
</source>
  
  
 
[[Category:Programowanie]]
 
[[Category:Programowanie]]

Aktualna wersja na dzień 22:06, 29 sty 2019

Kilka słów o języku programowania python. Skupimy się na używaniu tego języka pozostawiając szczegóły techniczne na boku.

Jak w ogóle działa język programowania i co to jest?

Komputery są przydatne o tyle, o ile potrafią wykonać to, czego od nich chcemy.

Jednym ze sposobów przekazywania innym czego od nich oczekujemy są instrukcje. Możemy na przykład poprosić rodzeństwo, żeby nie dotykało tej kupki części i... Przynajmniej mieć nadzieję, że instrukcje zostaną wykonane.


Jednak pomijając kłopoty komunikacyjne zastanówmy się chwilę co właściwie zrobiliśmy. Po pierwsze użyliśmy znanego sobie i rodzeństwu języka (polskiego) z jego wszystkimi zasadami wymowy/gramatyki. Po drugie przy pomocy dość skomplikowanej aparatury (nasze aparat mowy --> powietrze --> uszy rodzeństwa) przekazaliśmy pewną myśl określającą jakiego zachowania oczekujemy. Kontaktując się z ludźmi wykonujemy te wszystkie czynności odruchowo nie zastanawiając się ile ciekawych procesów musi się udać, żeby to wszystko zadziałało.


Na tym samym polega programowanie! Ponieważ jednak do niedawna komputery nie rozumiały języków naturalnych informatycy nie używają ich. Opracowali o wiele prostsze od naturalnych, a także bardziej precyzyjne języki (do) programowania. Zrezygnowali także z rozmów z komputerami i przyjęli zasadę, że treść programu trzeba dostarczyć "na piśmie" jako plik tekstowy lub tekst wprowadzony z klawiatury. Jeśli chcemy więc spowodować, żeby komputer wykonał nasze polecenia, musimy nauczyć się zapisywać swoje zamiary w jakimś języku programowania. I o tym jest ta strona, a językiem, który zastosujemy będzie python. Nie wybraliśmy go ze względu na jakieś niezwykłe zalety, po prostu jest jednym na najbardziej popularnych obecnie. Dzięki informatyce teoretycznej wiadomo, że większość języków programowania powszechnie używanych ma formalnie te same możliwości, czyli mówiąc inaczej program, który da się zapisać w jednym z nich, można bez problemu zapisać w dowolnym innym. Wybór języka jest więc co najwyżej kwestią wygody lub innych praktycznych zalet. Umiejąc programować będziemy mogli robić różne ciekawe rzeczy: tworzyć wirtualne światy, pisać kody samodzielnie kierujące samochodami czy sondami w przestrzeni kosmicznej, które muszą samodzielnie reagować na zmieniającą się sytuację (są zbyt daleko żeby jakiś człowiek mógł reagować na bieżąco!), programować sztuczną inteligencję, albo mechanikę podobną do naturalnej jak widać na filmach poniżej. Tak czy inaczej programiści mogą wykrzesać z komputerów sporo i nauczenie się choćby jednego języka programowania może być początkiem ciekawej przygody -- dobrym przykładem może być Polak, którego drętwe zdjęcie z obozu informatycznego stało się kiedyś przebojem demotywatorów, a on obecnie programuje samodzielnie lądujące rakiety SpaceX i nie wykluczone, że niedługo jego kod pozwoli przeprowadzić lądowania na Marsie.



Okazuje się więc, że pomimo prostoty języków programowania, potrafimy z ich pomocą wyrażać naprawdę skomplikowane instrukcje oraz zupełnie nieźle się przy tym bawić!


Kiedy program steruje jakimś większym urządzeniem efekty błędów w kodzie bywają zaskakujące.


Warto zwrócić uwagę na fakt, że maszyny ciągle jeszcze są bezmyślne i z chęcią zrealizują dowolne instrukcje o ile tylko zapiszemy je w zrozumiały dla nich sposób. Niestety ta zaleta komputerów jest jednocześnie ich najgorszą wadą. Kiedy instrukcje są bez sensu, maszyny wykonają działanie bez sensu bez żadnego sprzeciwu! Niestety z tego powodu programowanie przypomina opiekę nad bardzo szybkim, ale jednak ciągle "osiołkiem", który się sam nie domyśli, że coś robi źle.


Praktyczna zasada: Jeżeli myślisz, że to "komputer robi coś głupiego", to najwyższa pora przemyśleć instrukcje, które otrzymał; już dłużej nie da się zwlekać.


Jak zacząć programować?

Wystarczy włączyć terminal i wpisać polecenie python.


ktos@maszyna:~$ python
Python 2.7.11+ (default, Apr 17 2016, 14:00:29) 
[GCC 5.3.1 20160413] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>>


W odpowiedzi zostaje uruchomiony program, który czeka na nasze instrukcje i będzie je wykonywał w miarę wpisywania. Stan oczekiwania na instrukcje sygnalizowany jest wyświetleniem >>> na początku linii. Na samym początku python wyświetla też kilka dodatkowych technicznych informacji na temat języka, oraz zachętę do skorzystania z kilku instrukcji w celu poznania dalszych szczegółów. Możemy te linijki zignorować.


Kiedy już skończymy wykonywanie różnych instrukcji pythona możemy zakończyć jego działanie i wrócić do linii poleceń terminala używając kombinacji klawiszy Ctrl-D. Możesz to sprawdzić od razu, ale nie zapomnij ponownie uruchomić pythona przed przejściem do następnych przykładów.

Kilka prostych instrukcji i konstrukcji języka python na rozgrzewkę

Dla wygody poniżej posługujemy się kolorowaniem składni. W terminalu nie będzie ono widoczne, ale dzięki niemu poniższe przykłady czyta się łatwiej.

print (ang. drukuj), czyli wyświetlanie napisów

Spróbujmy wykonać jedną z prostszych instrukcji, która wypisuje jakiś tekst. Ona może być przydatna na przykład do wyświetlenia wyników, albo pokazania stopnia zaawansowania obliczeń jeśli program działa długo, lub ogólnie wszędzie tam, gdzie chcemy żeby program "zagadał" do użytkownika.


>>> print("Nie będę śpiewał kołysanek na lekcji")
Nie będę śpiewał kołysanek na lekcji
>>>


Jak widać programowanie w pythonie jest zupełnie proste. Napisaliśmy nazwę funkcji (print) po czym w nawiasie podaliśmy parametr (tutaj tekst, który należy wydrukować) i tyle. Ponieważ interpreter pythona pracuje w trybie interaktywnym i wykonuje instrukcje zaraz po ich podaniu, po naciśnięciu ENTER zobaczymy efekt działania, czyli nasz tekst.


Zwróć uwagę, że tekst otoczony jest znakami cudzysłowu. Gdybyśmy go napisali bez nich, na przykład zamiast print( "print") byłoby print( print ), mogłoby być trudno w niektórych sytuacjach zrozumieć, które słowa należy traktować jak zwykły kawałek tekstu do wyświetlenia, a które należy interpretować jako instrukcje programu. Kiedy jednak napiszemy print( "print" ) będzie oczywiste, że pierwsze print to instrukcja drukowania, a drugie print to tylko jakiś tekst, który ma być wypisany, i wobec tego python bez problemu wyświetli napis print.


Jak widać powyżej tekst został wyświetlony w pierwszej pustej linii na ekranie, a zaraz pod nim ponownie znak oczekiwania na kolejną instrukcję. Wszystko razem wygląda trochę ciasno. Żeby temu zaradzić dodajmy zarówno przed tekstem jak i po nim znak przejścia do nowej linii. Przejście do nowej linii zostawi pustą linijkę dzięki czemu wyświetlony komunikat będzie się lepiej wyróżniał.


 >>> print("\nNie będę śpiewał kołysanek na lekcji\n")
 
 Nie będę śpiewał kołysanek na lekcji
 
 >>>


A co jeśli chcielibyśmy wyświetlony tekst powtórzyć? Python pozwala użyć mnożenia w tym celu.

>>> print("\nNie będę śpiewał kołysanek na lekcji"*5)

Nie będę śpiewał kołysanek na lekcji
Nie będę śpiewał kołysanek na lekcji
Nie będę śpiewał kołysanek na lekcji
Nie będę śpiewał kołysanek na lekcji
Nie będę śpiewał kołysanek na lekcji
>>>


Wyświetlanie napisu wielokrotnie ma raczej mały sens ale, choć dla człowieka takie zadanie byłoby karą, komputer wykonuje kod bez problemu. Jeśli pomyłkowo pomnożymy napis milion razy, funkcja print cierpliwie wyświetli milion napisów...............


Na wszelki wypadek dodajmy przy okazji, że zbyt długo pracujący program można przerwać kombinacją klawiszy Ctrl-C.


Czasem jednak powielenie tekstu może być przydatne. Na przykład przepis na wyświetlenie choinki mógłby wyglądać tak (zwróć uwagę, że jeśli w jednej linii podajemy wiele instrukcji -- tutaj print -- to rozdzielamy je średnikiem ;):


>>> print(" "*10 + "^"*1); print(" "*9 + "^"*3); print(" "*8 + "^"*5);print(" "*7 + "^"*7);print(" "*6 + "^"*9);
          ^
         ^^^
        ^^^^^
       ^^^^^^^
      ^^^^^^^^^
>>>


Dzięki temu, że możemy łatwo powielić tekst poprzez mnożenie, stworzenie choinki składającej się z coraz krótszych kawałków spacji (10, 9, 8, 7, 6) oraz coraz dłuższych pięter choinki (znaki ^ powtórzone 1, 3, 5, 7 i 9 razy) było proste w zapisie. Jeśli nie wierzysz, spróbuj za pierwszym razem uzyskać ładną symetryczną choinkę licząc znaki poszczególnych pięter samemu i wstawiając odpowiednio długie ciągi znaków w kolejnych instrukcjach print.


Drukując napisy możemy jeszcze skorzystać z jednej bardzo przydatnej funkcji pythona. Bardzo często kiedy wyświetlamy jakiś komunikat na ekranie, chcielibyśmy w standardowym dłuższym tekście odpowiednio dopasować tylko jego krótki fragment. Na przykład gdybyśmy chcieli przywitać użytkownika, standardowy tekst mógłby brzmieć Witaj ..., miło Cię zobaczyć znowu! gdzie w miejsce ... wstawiałoby się tylko imię użytkownika.


Do tego celu można się posłużyć następującą konstrukcją:


>>>print("\nNie będę śpiewał %s kołysanek na lekcji\n" % "dziwnych")

Nie będę śpiewał dziwnych kołysanek na lekcji

>>>


Co zrobiliśmy? W tym miejscu tekstu, gdzie chcielibyśmy wstawić inny, umieściliśmy znacznik %s i dalej, już poza tekstem, po znaku % podaliśmy wartość, którą należy wstawić w zaznaczone miejsce. Posłużmy się jeszcze innym przykładem, w którym wstawiamy dwa różne teksty do innego.


>>>print("\nNie będę śpiewał %s kołysanek na lekcji %s\n" % ("dziwnych", "matematyki"))

Nie będę śpiewał dziwnych kołysanek na lekcji matematyki

>>>


A co jeśli chcielibyśmy wstawić nie tekst, ale liczbę? Wówczas musimy zastosować inny znacznik, czyli %d.


>>> print("\nNie będę śpiewał %s kołysanek na %d lekcji %s\n" % ("dziwnych", 2, "matematyki"))

Nie będę śpiewał dziwnych kołysanek na 2 lekcji matematyki

>>>


W tej chwili powyższa konstrukcja może się wydawać zbyteczna -- widać, że prościej byłoby zapisać całe zdanie od razu tak jak miało brzmieć. Ale jej przydatność wyjaśni się już w następnym punkcie.

zmienna, czyli jak pamiętać to co program przetwarza

Byłoby bardzo wygodnie, gdyby dało się napisać instrukcję powodującą zapisanie w pamięci komputera jakiegoś wyniku, który za chwilę wykorzystamy w dalszym ciągu programu. Taki podręczny "schowek" na dane to zmienna. W pythonie jej stworzenie jest zupełnie banalne, na przykład:

>>> jakas_liczba = 5
>>>

Wygląda tak, jakby nic się nie stało, ale wystarczy wpisać nazwę nowo zdefiniowanej zmiennej, a python wyświetli jej wartość, co oznacza, że ją zapamiętał!

>>> jakas_liczba
5
>>>

Co więcej, od teraz wszędzie, gdzie powołamy się na nazwę zmiennej otrzymamy jej aktualną wartość.

>>> jakas_liczba + 7
12
>>> jakas_liczba - 3
2
>>> print(":" + ")" * jakas_liczba)
:)))))
>>>

Ta prosta konstrukcja języka okazuje się bardzo użyteczna. Za chwilę poznamy różne inne zastosowania, ale już teraz możemy powiedzieć, że zmienna będzie się pojawiała co chwilę i bez niej wielu przydatnych rzeczy nie dałoby się wykonać.

Ponieważ wiemy już jak działa zmienna możemy wrócić do przykładu drukowania napisów, w którym wstawialiśmy do drukowanego tekstu inne treści. Załóżmy, że mierzymy co 1/10 sekundy prędkość naszego pojazdu i chcemy ją wyświetlić zarówno w metrach na sekundę jak i w kilometrach na godzinę. Jeśli wynik pomiaru zapiszemy sobie w zmiennej predkosc wówczas następująca instrukcja pozwoli nam drukować aktualnie zmierzoną wartość w sposób zrozumiały i wygodny dla człowieka (dla przykładu zmieniamy wartość prędkości dwa razy, żeby zasymulować różne pomiary):

>>> predkosc = 3.21
>>> print("\nAktualna prędkość wynosi %f [m/s] (= %f [km/h])\n" % (predkosc, predkosc * 3.6))

Aktualna prędkość wynosi 3.210000 [m/s] (= 11.556000 [km/h])

>>> predkosc = 5.111
>>> print("\nAktualna prędkość wynosi %f [m/s] (= %f [km/h])\n" % (predkosc, predkosc * 3.6))

Aktualna prędkość wynosi 5.111000 [m/s] (= 18.399600 [km/h])

>>>

Zwróć uwagę, że do wyświetlania liczb z przecinkiem używamy znacznika %f.

Nieco dłuższe programy

Powyżej widzieliśmy instrukcje, które mieszczą się w jednej linijce. Moglibyśmy kontynuować pisanie programów w ten sposób, ale za chwilę stałoby się to mało wygodne, a już na pewno mało czytelne. Musimy więc wyjaśnić jak pracować z dłuższymi programami. Na szczęście jest to całkiem proste.

Całe zadanie sprowadza się do zapisania tekstu programu w pliku i potem przekazania go interpreterowi pythona do wykonania.

Dla przykładu weźmy ostatni przykład powyżej. Składa się z dwóch instrukcji: ustawienia wartości zmiennej predkosc i wyświetlenia jej wartości w metrach na sekundę oraz kilometrach na godzinę. Otwórzmy więc dowolny edytor tekstu (na przykład gedit) i w nowym pliku wstawmy te dwie instrukcje:


 # coding: utf-8
 
 predkosc = 5.111
 print("\nAkualna prędkość wynosi %f [m/s] (= %f [km/h])\n" % (predkosc, predkosc * 3.6))


Teraz zapiszmy plik z dowolną nazwą na dysku. Warto dać mu rozszerzenie .py (jak python), które jest standardowym oznaczeniem dla programów w pythonie. Jeśli tak zrobimy gedit powinien to zauważyć i zacząć kolorować składnię dzięki czemu kod będzie czytelniejszy.

Jeśli użyliśmy nazwy pliku pierwszy.py możemy wykonać program wywołując polecenie:


ktos@maszyna:~ $ python pierwszy.py

Akualna prędkość wynosi 5.111000 [m/s] (= 18.399600 [km/h])

ktos@maszyna:~ $


Jak widać program działa tak samo jak w powyżej.


Natomiast teraz możemy umieścić w pliku nie jedną, ale wiele instrukcji i napisać dzięki temu dłuższy kod robiący ciekawsze rzeczy!


Dodatkowa pierwsza linijka # coding: utf-8 jest potrzebna dlatego, że nasz w tekście programu używamy polskich znaków diakrytycznych (słowo prędkość ma trzy). Bez ustawienia kodowania obejmującego polskie znaki (czyli UTF-8) python nie spodziewa się innych liter niż angielskie i zamiast wykonać program wyświetli jedynie rozpaczliwy komunikat, że nie rozumie znaków spoza standardu ASCII (jest to stary standard kodowania znaków jeszcze z poprzedniego wieku):


File "/home/ktos/pierwszy.py", line 2
SyntaxError: Non-ASCII character '\xc4' in file /home/ktos/pierwszy.py on line 2, 
                       but no encoding declared; see http://python.org/dev/peps/pep-0263/ for details


Warto zauważyć, że nowe wersje pythona, tj. 3+, domyślnie używają bardziej uniwersalnego UTF-8, więc jeśli używasz pythona 3 lub nowszego linijka # coding: utf-8 nie jest potrzebna do pracy z polskimi znakami.


Przy okazji zauważmy, że to co znajduje się w linijce po znaku # traktowane jest przez interpreter jako komentarz, a więc to co jest tam napisane nie będzie wykonywane jako program. Linie komentarza przydają się, żeby choćby samemu sobie napisać wskazówkę o co chodziło w kodzie, który jest w pobliżu. W bardzo długich programach można się szybko pogubić i rozsądnie napisany komentarz bardzo ułatwia życie. Na przykład:


 # coding: utf-8
 
 predkosc = 5.111
 # Przelicznik 3.6 bierze się stąd, że 1 [km/h] =  (1000 [m] / 3600 [s] = 1000/3600 [m/s] ) = 1/3.6 [m/s], 
 # skąd wynika odwrotna zależność że 1 [m/s] = 3.6 [km/h]
 print("\nAkualna prędkość wynosi %f [m/s] (= %f [km/h])\n" % (predkosc, predkosc * 3.6))

Kilka wielolinijkowych konstrukcji języka python

Skoro potrafimy już używać programów składających się z wielu linijek zajmijmy się dłuższymi konstrukcjami języka.

instrukcja warunkowa, czy co robić jeśli tak, a co jeśli nie

Wracając do przykładu z rozmów między ludźmi dość często przekazując informacje używamy określeń warunkowych nawet nie bardzo uświadamiając sobie ten fakt. Czyli uzależniamy działanie od jakiegoś wstępnego warunku, który w tej chwili jeszcze nie jest rozstrzygnięty, ale na pewno trzeba go uwzględnić w działaniu. Mówimy na przykład:


Jeśli X przyjdzie o osiemnastej to będę musiał ..., a jak nie przyjdzie to możemy ....


Dokładnie tak samo możemy chcieć zaprogramować komputer. Na przykład jeśli na przeciwko robota stoi przeszkoda (odczytujemy jakiś czujnik) to należy wykonać jej omijanie, a jeśli przeszkody nie ma, można kontynuować jazdę do przodu.


Do sterowania programem w ten sposób służy właśnie instrukcja warunkowa, której schemat przedstawiony jest poniżej.


if warunek:
    # instrukcje do wykonania 
    # jeśli warunek jest spełniony
    ...
else:
    # a tu instrukcje w przeciwnym przypadku
    # czyli jeśli warunek nie jest spełniony
    ...

# ciąg dalszy programu
...


Zwróć uwagę, że w pythonie blok instrukcji, których wykonanie zależy od linijki powyżej jest przesunięty w prawo (wcięty). To nie jest tylko zabieg stylistyczny. W pythonie wcięcia mają znaczenie. Pierwsza nie wcięta linijka poniżej else: będzie wykonana niezależnie od tego czy warunek jest spełniony czy nie. Dokładnie tak to wygląda:


if warunek:
    # 1 linijka która się wykona jeśli warunek jest prawdziwy
    ...
    # 2 linijka która się wykona jeśli warunek jest prawdziwy
    ...
else:
    # 1 linijka która się wykona w przeciwnym przypadku
    ...   
    # 2 linijka która się wykona w przeciwnym przypadku
    ...

# ta linijka wykona się jako następna po if/else i nie należy ani do bloku if, ani do bloku else
...


Zastosujmy instrukcję warunkową do modyfikacji wyświetlania komunikatu powyżej:


# coding: utf-8

predkosc = 5.111

if predkosc < 50:
    # wyświetlamy tak samo jeśli zmierzona prędkość wydaje się rozsądna
    print("\nAkualna prędkość wynosi %f [m/s] (= %f [km/h])\n" % (predkosc, predkosc * 3.6))    
else:
    # Robot przypadkiem wjechał na tory Pendolino?
    print("\nCzujnik zwariował!!! Ten robot nie może jechać z prędkością %f [m/s] (= %f [km/h])\n" % (predkosc, predkosc * 3.6))


Spróbuj zapisać ten program z różnymi wartościami prędkości i wykonać.


W przypadku wielolinijkowych konstrukcji pythona trzeba zwrócić uwagę na wcięcia linijek. Nie przypadkiem te instrukcje, które mają się wykonać dla spełnionego, i osobno dla niespełnionego, warunku są przesunięte o 4 spacje w prawo. Tylko dzięki temu przesunięciu interpreter pythona wie, które instrukcje wykonywać w zależności od spełnionego warunku. Popatrzmy na taki przykład:


# coding: utf-8

poziom_energii = 2.0

if poziom_energii < 1.0:  # Z powodu wcięcia tekstu programu dwie następne instrukcje wykonają się zależnie od warunku.
    print("UWAGA: Energia się kończy!") 
    print("Najbliższa stołówka za rogiem!") 

print("Aktualnie masz %f kcal energii." % poziom_energii) # Ta instrukcja nie zależy od warunku i wykona się zawsze.


Jak zwykle warto spróbować uruchomić program z modyfikacjami. Można ustawić zmienną poziom_energii liczbą mniejszą niż 1.0 żeby zobaczyć jego działanie w dwóch różnych przypadkach.

pętla, czyli to co komputer potrafi robić bez znudzenia

Bardzo często chcemy jakieś instrukcje powtórzyć określoną ilość razy. Na przykład chcielibyśmy po kolei zapalić diody podłączone do wyjść GPIO o numerach od 5 do 15. Moglibyśmy zapisać 10 następujących poleceń:


# (...) dla jasności pominięte instrukcje wczytujące moduł obsługi wyjść GPIO oraz inicjujące płytkę 


gpio.output(5, 1)
gpio.output(6, 1)
gpio.output(7, 1)
gpio.output(8, 1)
gpio.output(9, 1)
gpio.output(10, 1)
gpio.output(11, 1)
gpio.output(12, 1)
gpio.output(13, 1)
gpio.output(14, 1)
gpio.output(15, 1)


Jednym słowem -- horror. Gdybyśmy chcieli zapalić na przykład 1024*768 diod w przeciętnym ekranie komputera przy takim sposobie kodowania musielibyśmy napisać blisko milion instrukcji!!!


Na szczęście można to zrobić prościej. Wystarczy zastosować pętlę. Powyższy program zapisany z jej użyciem jest o wiele krótszy:


# pominięte instrukcje wczytujące moduł obsługi wyjść gpio oraz inicjalizujące płytkę 
# ....

for numer in range(5, 16):  
    gpio.output(numer, 1)


Co tu się dzieje dokładnie? Przede wszystkim funkcja range (ang. zakres) zwraca listę numerów z podanego przedziału z pominięciem ostatniego elementu. Sprawdźmy na przykład co zwróci użyte powyżej range(5,16):


>>> range(5,16)
[5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]
>>>


Jak widać lista zaczyna się od 5, ale na końcu nie ma liczby 16.


Po angielsku for oznacza dla, in to po polsku w. Jeśli przepiszemy tekst programu po polsku, jego działanie stanie się praktycznie oczywiste


dla numer w zakresie(5, 16):  
    gpio.output(numer, 1)


czyli wykonaj instrukcję gpio.output(numer, 1) podstawiając do zmiennej numer kolejne liczby z podanego zakresu. Proste prawda?


Jeśli chciałoby się sprawdzić, że rzeczywiście zmienna numer zmienia się w podanym zakresie wystarczy ją wydrukować poznaną wcześniej instrukcją print.


>>> for numer in range(5,16): print(numer);   
... 
5
6
7
8
9
10
11
12
13
14
15
>>>


Załóżmy, że chcielibyśmy mrugnąć jedną diodą 20 razy. Nic prostszego! Wystarczy pętla o 20 krokach w środku której wykonamy jedno pełne mrugnięcie (a więc zapalenie, odczekanie chwilę, zgaszenie i znów odczekanie):


# pominięte instrukcje wczytujące moduł obsługi wyjść gpio, moduł obsługi czasu time, oraz inicjalizujące płytkę 
# ...

for powtorka in range(1, 21):  # Pamiętaj, że range(1, 21) zwróci [1,2,...,20], bez 21. 
    gpio.output(numer, 1)
    time.sleep(0.5)
    gpio.output(numer, 0)
    time.sleep(0.5)


Wielokrotnie taka konstrukcja się przyda. Na przykład, kiedy będziemy chcieli wykonać dokładnie 35 kroków silnika krokowego zamontownego po lewej stronie robota zapewne użyjemy pętli podobnej do takiej:


# pominięte instrukcje wczytujące moduł obsługi silnika
# ...

for powtorka in range(1, 36):  
    krok(SILNIK_LEWY, DO_PRZODU)