<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="pl">
	<id>http://brain.fuw.edu.pl/edu/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=RobertJB</id>
	<title>Brain-wiki - Wkład użytkownika [pl]</title>
	<link rel="self" type="application/atom+xml" href="http://brain.fuw.edu.pl/edu/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=RobertJB"/>
	<link rel="alternate" type="text/html" href="http://brain.fuw.edu.pl/edu/index.php/Specjalna:Wk%C5%82ad/RobertJB"/>
	<updated>2026-04-13T07:41:36Z</updated>
	<subtitle>Wkład użytkownika</subtitle>
	<generator>MediaWiki 1.34.1</generator>
	<entry>
		<id>http://brain.fuw.edu.pl/edu/index.php?title=PPy3/Wej%C5%9BcieWyj%C5%9Bcie&amp;diff=11511</id>
		<title>PPy3/WejścieWyjście</title>
		<link rel="alternate" type="text/html" href="http://brain.fuw.edu.pl/edu/index.php?title=PPy3/Wej%C5%9BcieWyj%C5%9Bcie&amp;diff=11511"/>
		<updated>2025-11-28T09:16:24Z</updated>

		<summary type="html">&lt;p&gt;RobertJB: /* Czytanie dowolnych danych z pliku */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=Obsługa wejścia i wyjścia=&lt;br /&gt;
&lt;br /&gt;
Większość sensownych programów służy do przetworzenia jakichś informacji uzyskanych z zewnątrz programu: w najprostszym przypadku,&lt;br /&gt;
z pliku na dysku, lub z danych wprowadzonych przez użytkownika za pomocą klawiatury. W przypadku programów wywoływanych z linii poleceń, istnieje też poręczny i łatwy do wykorzystania mechanizm by wskazać programowi, co ma robić - za pomocą tzw. opcji i/lub wartości parametrów wpisanych na linii poleceń, po nazwie wywoływanego programu. Często też chcemy, by wyniki działania programu, np. przetworzone dane lub wyniki obliczeń, znalazły się w pliku na dysku - choć czasami możemy woleć, aby również (lub zamiast tego) zostały one wyświetlone na ekranie. Omówimy teraz krótko, jak to osiągnąć.&lt;br /&gt;
&lt;br /&gt;
==Pliki tekstowe vs. binarne==&lt;br /&gt;
&lt;br /&gt;
Zawartość każdego pliku na dysku to tak naprawdę ''strumień bajtów'' - bajt, czyli grupa ośmiu bitów, może być traktowany jako reprezentacja (w zapisie dwójkowym), jakiejś liczby całkowitej dodatniej z zakresu 0-255. Często jednak zawartość ta ma być traktowana jako reprezentacja tekstu, czyli ciągu znaków stosowanych w zapisie jakiegoś języka - może to być język naturalny (polski, angielski, chiński, ...) lub np. język programowania (Python, Java, C++, ...), język tworzenia stron WWW (HTML), itd. W tym celu stworzono tzw. ''kodowania'', czyli standardy reprezentowania znaków stosowanych w systemach zapisu języków naturalnych za pomocą bajtów lub grup bajtów (języki programowania itp. zasadniczo posługują się tymi samymi zestawami znaków, co języki naturalne - a zwłaszcza angielski).&lt;br /&gt;
&lt;br /&gt;
Nie wchodząc za bardzo w szczegóły, obecnie stosowane reprezentacje cyfrowe tekstu oparte są na standardzie ''Unicode'', który m. in. definiuje tzw. uniwersalny zestaw znaków (UCS) - tablicę, zawierającą wszystkie znaki (alfanumeryczne, przestankowe, ideogramy - właściwe dla języków dalekowschodnich, i szeregu innych kategorii) stosowane w systemach pisma wszystkich żywych języków świata (i wielu języków martwych). Wewnętrzna reprezentacja danych napisowych w Pythonie oparta jest na standardzie Unicode - zatem pythonowy napis może zawierać znaki z wszelkiego rodzaju systemów pisma, w dowolnej kombinacji. Zapis tych danych w pliku dyskowym - i odwrotne, zinterpretowanie strumienia bajtów odczytanego z pliku dyskowego jako reprezentacji pewnego napisu - wymaga przyjęcia jakiegoś konkretnego kodowania. Unicode nie stanowi sam w sobie kodowania - określa on repertuar znaków oraz pozycję każdego z nich w tablicy UCS, nie zaś bajt lub grupę bajtów go reprezentującą. &lt;br /&gt;
&lt;br /&gt;
W Pythonie problem ten rozwiązany jest w sposób następujący: domyślnie, zawartość wczytywana z plików interpretowana jest jako dane tekstowe (chyba, że zażyczymy sobie inaczej), zgodnie z pewnym domyślnym kodowaniem, właściwym dla systemu operacyjnego (chyba, że wskażemy że ma być stosowane inne) - w przypadku Linuxa będzie to prawie zawsze kodowanie o nazwie UTF-8, które się dobrze nadaje do zastosowania dla języków zachodnich, posługujących się systemem pisma opartym na alfabecie łacińskim. Inaczej może być w środowiskach języków posługujących się np. cyrylicą, czy języków azjatyckich (pismo arabskie lub ideograficzne - chińskie, japońskie, koreańskie, itd.). W środowiskach Windows może być inaczej...&lt;br /&gt;
&lt;br /&gt;
Z powyższego widać, że rozróżnienie - plik tekstowy czy binarny - jest dość umowne, i dotyczy raczej interpretacji zawartości pliku (plik zapisany zgodnie z nieznanym nam i/lub nieoczekiwanym kodowaniem jest nie do odróżnienia od pliku binarnego). Co więcej, pliki zapisywane przez programy takie, jak MS Word, lub pliki PDF, nawet zawierające wyłącznie tekst, nie są w tym rozumieniu plikami tekstowymi, tylko binarnymi. W przykładach będziemy mieli do czynienia prawie wyłącznie z plikami tekstowymi - warto jednak wiedzieć, że w Pythonie jest osobny typ danych - ciągi bajtów (''bytes''), o własnościach nieco podobnych do napisów, ale o elementach będących bajtami, a nie znakami pisma.&lt;br /&gt;
&lt;br /&gt;
==Czytanie tekstu z pliku==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
&lt;br /&gt;
f = open('nazwa_pliku.txt')&lt;br /&gt;
for linia in f:&lt;br /&gt;
    przetworz(linia)&lt;br /&gt;
f.close()&lt;br /&gt;
&lt;br /&gt;
# albo może lepiej:&lt;br /&gt;
&lt;br /&gt;
with open('nazwa_pliku.txt') as f:&lt;br /&gt;
    for linia in f:&lt;br /&gt;
        przetworz(linia)&lt;br /&gt;
&lt;br /&gt;
# jeszcze inaczej&lt;br /&gt;
&lt;br /&gt;
tresc = open('nazwa_pliku.txt').read() # wczytujemy od razu całą treść pliku&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*Otwarty do odczytu plik tekstowy dopuszcza iterację, w której kolejnymi elementami są linie tekstu - wraz z kończącym je kodem przejścia do nowej linii; w ostatniej linijce pliku kodu tego może brakować (lub nie);&lt;br /&gt;
*Wartość zmiennej &amp;lt;tt&amp;gt;linia&amp;lt;/tt&amp;gt; to w każdym obiegu pętli, treść kolejnej linii tekstu jako napis; zawartość (bajtowa) pliku jest interpretowana jako napis zgodnie z domyślnym kodowaniem systemowym (można to zmienić poprzez dodatkowy parametr wywołania &amp;lt;tt&amp;gt;open&amp;lt;/tt&amp;gt;);&lt;br /&gt;
*Jeżeli zawartość pliku ''nie'' jest zgodna z założeniem, że można go interpretować jako tekst w przyjętym kodowaniu, to w trakcie przetwarzania może wystąpić błąd (wyjątek);&lt;br /&gt;
*Po zakończeniu przetwarzania plik należy zamknąć, wywołując metodę &amp;lt;tt&amp;gt;close&amp;lt;/tt&amp;gt;; ewentualnie można to pominąć, jeśli wiemy '''na pewno''' że wraz z końcem przetwarzania pliku kończy się cały program - wraz z zakończeniem działania programu otwarte pliki zostaną zamknięte;&lt;br /&gt;
*Druga postać wprowadza nową instrukcję złożoną - blok &amp;lt;tt&amp;gt;with&amp;lt;/tt&amp;gt;; to, jak on dokładnie działa, zależy od typu obiektu do jakiego odwołujemy się po słowie &amp;lt;tt&amp;gt;with&amp;lt;/tt&amp;gt; - jeżeli jest nim otwarty plik, to zostanie on automatycznie zamknięty wraz z końcem bloku;&lt;br /&gt;
*Odwoływanie się do pliku, który już został zamknięty, będzie nieskuteczne; żadne operacje się nie powiodą.&lt;br /&gt;
*Ostatnia wersja jest odrobinę ryzykowna - jeśli plik jest ''bardzo'' duży, to na jego treść może nie wystarczyć pamięci RAM, i program się wywróci. W dzisiejszych czasach oznacza to jednak, że rozmiar pliku sięga wielu gigabajtów.&lt;br /&gt;
&lt;br /&gt;
==Czytanie dowolnych danych z pliku==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
&lt;br /&gt;
f = open('nazwa_pliku', mode='rb')&lt;br /&gt;
dane = f.read(1024*1024) # wczytujemy 1 MB danych (lub mniej, jeśli tylu już nie ma)&lt;br /&gt;
(...)&lt;br /&gt;
f.seek(0) # &amp;quot;przewinąć&amp;quot; do początku pliku (lub innej pozycji, względem początku)&lt;br /&gt;
(...)&lt;br /&gt;
pos = f.tell() # uzyskać aktualną pozycję&lt;br /&gt;
(...)&lt;br /&gt;
f.close()&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*To, co odczytamy - czyli &amp;lt;tt&amp;gt;dane&amp;lt;/tt&amp;gt;, to będzie łańcuch bajtów;&lt;br /&gt;
*Można odpowiednio wykorzystać blok &amp;lt;tt&amp;gt;with&amp;lt;/tt&amp;gt;, aby uniknąć ręcznego zamykania pliku;&lt;br /&gt;
*Wywołanie &amp;lt;tt&amp;gt;read()&amp;lt;/tt&amp;gt; bez argumentu oznacza: wczytaj wszystko;&lt;br /&gt;
*Jeśli wywołanie &amp;lt;tt&amp;gt;read&amp;lt;/tt&amp;gt; z dodatnim argumentem zwróci łańcuch o długości zero - to dotarliśmy do końca pliku.&lt;br /&gt;
&lt;br /&gt;
==Zapis danych do pliku==&lt;br /&gt;
&lt;br /&gt;
Aby był możliwy zapis danych do pliku dyskowego, należy go otworzyć w trybie do zapisu:&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
&lt;br /&gt;
f = open('nazwa_pliku.txt', 'w')&lt;br /&gt;
(...)&lt;br /&gt;
f.write(dane)&lt;br /&gt;
(...)&lt;br /&gt;
f.close()&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''UWAGA:''' otwarcie pliku w trybie do zapisu (&amp;lt;tt&amp;gt;'w'&amp;lt;/tt&amp;gt;) spowoduje usunięcie poprzedniej zawartości pliku - o ile dotyczy pliku już istniejącego. Jeżeli nazwa odnosi się do pliku jeszcze nieistniejącego, to zostanie on utworzony. Jeżeli chcemy zachować poprzednie dane, dopisując nowe do końca pliku, należy plik otworzyć w trybie &amp;lt;tt&amp;gt;'a'&amp;lt;/tt&amp;gt; (''append'').&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&amp;lt;small&amp;gt;&lt;br /&gt;
Domyślnie plik jest otwierany w trybie zapisu tekstu, zgodnie z domyślnym kodowaniem. A więc &amp;lt;tt&amp;gt;dane&amp;lt;/tt&amp;gt; powinny być napisem. Jeżeli chcemy zapisywać surowe bajty, należy użyć trybu &amp;lt;tt&amp;gt;'wb'&amp;lt;/tt&amp;gt;. Jeżeli chcemy użyć kodowania innego niż domyślne, możemy w funkcji &amp;lt;tt&amp;gt;open&amp;lt;/tt&amp;gt; użyć parametru ''encoding'', w postaci:&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
&lt;br /&gt;
f = open('nazwa_pliku.txt', 'w', encoding='cp1250')&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
w tym przykładzie użyto nazwy kodowania stosowanego do języka polskiego w Windows.&lt;br /&gt;
&amp;lt;/small&amp;gt;&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Standardowe strumienie i przekierowania==&lt;br /&gt;
&lt;br /&gt;
===Wprowadzenie===&lt;br /&gt;
&lt;br /&gt;
System operacyjny z rodziny unixów (np. Linux lub MacOS) udostępnia każdemu procesowi (uruchomionemu programowi) trzy tzw. standardowe strumienie, mogące być źródłem danych (tzw. standardowy strumień wejściowy, ''stdin'') lub kanałem przekazywania wyników, komunikatów itp. (standardowy strumień wyjściowy, ''stdout'' i standardowy strumień błędów, ''stderr'').&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&amp;lt;small&amp;gt;&lt;br /&gt;
W systemach z rodziny Windows jest podobnie, w odniesieniu do programów uruchamianych z linii poleceń, czyli okna programu ''cmd.exe''.&lt;br /&gt;
&amp;lt;/small&amp;gt;&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Co to konkretnie znaczy? Domyślnie, zawartością ''stdin'' są dane wprowadzane z klawiatury, natomiast dane wypisywane na ''stdout'' i ''stderr'' pojawiają się na ekranie - w oknie terminalowym, z którego uruchomiono dany program. Przyjęto umowę, że na ''stdout'' wypisuje się dane, stanowiące wynik zgodnej z przewidywaniami pracy programu (oczywiście o ile nie przewidziano zapisu tych wyników bezpośrednio do pliku na dysku), natomiast na ''stderr'' - jedynie komunikaty dotyczące sytuacji nieprzewidzianych, a więc błędów przetwarzania, lub ostrzeżenia - pojawiające się w sytuacjach, gdy wprawdzie kontynuacja pracy programu jest możliwa, ale okoliczności wskazują, że jej wyniki mogą być pod jakimś względem wątpliwe.&lt;br /&gt;
&lt;br /&gt;
Powyższe ma sens, ponieważ domyślne powiązania - ''stdin'' z klawiaturą, a ''stdout'' i ''stderr'' z ekranem można zmienić - poprzez mechanizmy tzw. przekierowania. W szczególności, strumienie wyjścia i błędu można rozdzielić, np. przekierowując treść ''stdout'' do pliku, a pozostawiając ''stderr'' jako związany z ekranem.&lt;br /&gt;
&lt;br /&gt;
W środowisku Python standardowe strumienie dostępne są jako elementy modułu &amp;lt;tt&amp;gt;sys&amp;lt;/tt&amp;gt;: &amp;lt;tt&amp;gt;sys.stdin&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;sys.stdout&amp;lt;/tt&amp;gt; i &amp;lt;tt&amp;gt;sys.stderr&amp;lt;/tt&amp;gt;. Mają one właściwości plików tekstowych, choć bez możliwości przewijania (&amp;lt;tt&amp;gt;seek&amp;lt;/tt&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
'''Funkcja &amp;lt;tt&amp;gt;print&amp;lt;/tt&amp;gt; w Pythonie domyślnie wypisuje dane do strumienia ''stdout''; można to zmienić, używając parametru wywołania ''file'', którego wartością powinien być plik otwarty do zapisu w trybie tekstowym.'''&lt;br /&gt;
&lt;br /&gt;
===Sposoby przekierowania===&lt;br /&gt;
&lt;br /&gt;
Przekierowanie strumieni dokonuje się na poziomie systemu operacyjnego, całkowicie poza środowiskiem Pythona - program nie ma możliwości wykrycia, czy strumienie standardowe na jakich operuje zostały przekierowane. Przekierowania określa się na linii poleceń w momencie uruchomienia programu.&lt;br /&gt;
&lt;br /&gt;
Przekierowanie ''stdin'' z pliku:&lt;br /&gt;
&amp;lt;source lang=bash&amp;gt;&lt;br /&gt;
$ program.py &amp;lt; plik_wejsciowy.txt&lt;br /&gt;
$ &amp;lt; plik_wejsciowy.txt program.py&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Oba powyższe polecenia są równoważne i skutkują tym, że dane czytane przez program z &amp;lt;tt&amp;gt;sys.stdin&amp;lt;/tt&amp;gt; będą tak na prawdę pochodzić z pliku o podanej nazwie (a treść wprowadzana z klawiatury będzie w programie niedostępna).&lt;br /&gt;
&lt;br /&gt;
Przekierowanie ''stdout'' do pliku:&lt;br /&gt;
&amp;lt;source lang=bash&amp;gt;&lt;br /&gt;
$ program.py &amp;gt; plik_wyjscia.txt&lt;br /&gt;
$ &amp;gt; plik_wyjscia.txt program.py&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dane pisane do &amp;lt;tt&amp;gt;sys.stdout&amp;lt;/tt&amp;gt; nie pojawią się w oknie terminala, tylko znajdą się w pliku. Dane pisane do &amp;lt;tt&amp;gt;sys.stderr&amp;lt;/tt&amp;gt; dalej będą trafiać na ekran.&lt;br /&gt;
&lt;br /&gt;
Przekierowania równoczesne:&lt;br /&gt;
&amp;lt;source lang=bash&amp;gt;&lt;br /&gt;
$ program.py &amp;lt; plik_wejsciowy.txt &amp;gt; plik_wyjscia.txt&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Oba poprzednio opisane przekierowania można również wykonać równocześnie. Elementy polecenia również mogą wystąpić w innym porządku.&lt;br /&gt;
&lt;br /&gt;
Przekierowanie ''stderr'':&lt;br /&gt;
&amp;lt;source lang=bash&amp;gt;&lt;br /&gt;
$ program.py 2&amp;gt; plik_bledow.txt&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Komunikaty o błędach i ostrzeżenia znajdą się w pliku o podanej nazwie, zamiast na ekranie. Analogicznie do &amp;lt;tt&amp;gt;2&amp;gt;&amp;lt;/tt&amp;gt;, strumieniom ''stdout'' i ''stdin'' przypisane są numerki 1 i 0 - można więc pisać odpowiednio &amp;lt;tt&amp;gt;1&amp;gt;&amp;lt;/tt&amp;gt; i &amp;lt;tt&amp;gt;0&amp;amp;lt;&amp;lt;/tt&amp;gt;, ale tu te wartości numerów strumieni przekierowanych (naprawdę - ''deskryptorów plików'') są domyślne i niemal zawsze się je pomija.&lt;br /&gt;
&lt;br /&gt;
===Potoki===&lt;br /&gt;
&lt;br /&gt;
Oprócz przekierowania do i z plików, istnieje jeszcze analogiczny mechanizm, gdzie np. strumień ''stdout'' jednego procesu łączy się z strumieniem ''stdin'' innego procesu - skutkiem czego dane wyjściowe pierwszego są wprowadzane do drugiego jako dane wejściowe, tworząc to co się nazywa ''potokiem''. Najprostszy przykład:&lt;br /&gt;
&amp;lt;source lang=bash&amp;gt;&lt;br /&gt;
$ program1.py | program2.py&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
tu ''operatorem potoku'' w systemowej linii poleceń jest znak kreski pionowej (&amp;lt;tt&amp;gt;|&amp;lt;/tt&amp;gt;), a &amp;lt;tt&amp;gt;program1.py&amp;lt;/tt&amp;gt; przekazuje wyniki swojej pracy do dalszego przetwarzania kolejnemu, &amp;lt;tt&amp;gt;program2.py&amp;lt;/tt&amp;gt;. Taki potok może mieć więcej niż dwa etapy i może łączyć się z zastosowaniem przekierowań do plików, np.&lt;br /&gt;
&amp;lt;source lang=bash&amp;gt;&lt;br /&gt;
$ &amp;lt; plik_wejsciowy.txt program1.py 2&amp;gt;bledy.txt | program2.py &amp;gt; plik_wynikow.txt&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Pożytecznym narzędziem do stosowania w potokach jest polecenie (program) o nazwie &amp;lt;tt&amp;gt;tee&amp;lt;/tt&amp;gt;:&lt;br /&gt;
&amp;lt;source lang=bash&amp;gt;&lt;br /&gt;
$ program.py &amp;lt; dane.txt | tee wynik.txt&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
w tym przypadku program wczyta zawartość pliku &amp;lt;tt&amp;gt;dane.txt&amp;lt;/tt&amp;gt;, a wynik wypisany do &amp;lt;tt&amp;gt;sys.stdout&amp;lt;/tt&amp;gt; zarówno pojawi się na ekranie (w oknie terminala, jak i zostanie zapisany w pliku &amp;lt;tt&amp;gt;wynik.txt&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==Odczyt linii poleceń==&lt;br /&gt;
&lt;br /&gt;
Zawartość linii poleceń dostępna jest w obiekcie &amp;lt;tt&amp;gt;sys.argv&amp;lt;/tt&amp;gt; - czyli moduł (standardowy) &amp;lt;tt&amp;gt;sys&amp;lt;/tt&amp;gt;, element &amp;lt;tt&amp;gt;argv&amp;lt;/tt&amp;gt;. Jest to lista argumentów - ,,słów&amp;quot; jakie wywołujący program umieścił w linii poleceń. Inaczej mówiąc, treść linii poleceń ulega wstępnemu rozbiorowi - na słowa, według reguł zależnych od systemu operacyjnego. Najczęściej poszczególne słowa oddzielają spacje (jedna lub więcej), jeśli chcemy, by ciąg zawierający spacje był potraktowany jako pojedyncze słowo (np. nazwa pliku zawierająca spacje), należy ciąg ten np. umieścić w cudzysłowach (które zostaną usunięte z treści argumentu). Treść linii poleceń na ogół ulega jeszcze innym formom obróbki przez system operacyjny (np. rozwijanie rozmaitych skrótów), ale dzieje się to poza kontrolą Pythona.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
&lt;br /&gt;
from sys import argv&lt;br /&gt;
for arg in argv:&lt;br /&gt;
    print(arg)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Korzystając z powyższego kodu możemy dowiedzieć się, jak wygląda lista argumentów już ''po'' jej obróbce przez system operacyjny.&lt;br /&gt;
&lt;br /&gt;
Na początku listy &amp;lt;tt&amp;gt;argv&amp;lt;/tt&amp;gt; czyli w pozycji &amp;lt;tt&amp;gt;argv[0]&amp;lt;/tt&amp;gt; znajduje się nazwa uruchomionego programu (tj. nazwa pliku z kodem uruchomionego jako program główny).&lt;br /&gt;
&lt;br /&gt;
===Przykłady===&lt;br /&gt;
&lt;br /&gt;
=1.=&lt;br /&gt;
Jeśli przewidujemy, że jedynymi argumentami wywołania naszego programu będą nazwy plików, na każdym z których należy wykonać jakąś czynność, to można to zrealizować tak:&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
&lt;br /&gt;
#! /usr/bin/python3&lt;br /&gt;
&lt;br /&gt;
from sys import argv&lt;br /&gt;
&lt;br /&gt;
def przetwarzaj(plik):&lt;br /&gt;
    # tu określamy na czym polega &amp;quot;przetworzenie&amp;quot; pliku&lt;br /&gt;
&lt;br /&gt;
for plik in argv[1:]:&lt;br /&gt;
    przetwarzaj(plik)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*Wzięcie wycinku z &amp;lt;tt&amp;gt;argv&amp;lt;/tt&amp;gt; służy pominięciu pliku zawierającego kod programu;&lt;br /&gt;
*Elementami &amp;lt;tt&amp;gt;argv&amp;lt;/tt&amp;gt; są ''nazwy'' plików - napisy.&lt;br /&gt;
&lt;br /&gt;
=2.=&lt;br /&gt;
Nieraz jest pożądane, aby program przetwarzający strumień danych mógł działać na dwa sposoby: albo wywołany z argumentami będącymi nazwami plików z danymi wejściowymi wczytuje kolejno zawartość tych plików; albo wywołany bez takich argumentów, czyta dane wejściowe ze standardowego strumienia wejściowego, w którym one znajdują się zazwyczaj w wyniku poprzedniego kroku przetwarzania potokowego. Nota bene w ten sposób działa wiele tradycyjnych narzędzi systemowych w Linuxie. &lt;br /&gt;
&lt;br /&gt;
W standardowej bibliotece Pythona jest moduł &amp;lt;tt&amp;gt;fileinput&amp;lt;/tt&amp;gt;, który ułatwia realizację takiego podejścia. W najprostszym przypadku:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
#! /usr/bin/python3&lt;br /&gt;
&lt;br /&gt;
import fileinput&lt;br /&gt;
&lt;br /&gt;
def przetwarzaj(linia):&lt;br /&gt;
    # tu określamy na czym polega przetworzenie linii treści&lt;br /&gt;
&lt;br /&gt;
for linia in fileinput.input():&lt;br /&gt;
    przetwarzaj(linia)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
W pętli w powyższym przykładzie wystąpią kolejno wszystkie linie w treści plików wymienionych na linii poleceń (z pominięciem pliku samego programu), lub jeśli linia poleceń jest pusta &amp;amp;mdash; linie w treści &amp;lt;tt&amp;gt;sys.stdin&amp;lt;/tt&amp;gt;. Ewentualnie można wywołać funkcję &amp;lt;tt&amp;gt;fileinput.input(pliki)&amp;lt;/tt&amp;gt;, tj. zamiast bez argumentów to z argumentem będącym sekwencją nazw plików zawierających dane wejściowe. Może to być np. lista argumentów programu, ale po usunięciu z niej pozycji będących opcjami, a nie nazwami plików. Oczywiście w dokumentacji znajdziemy jeszcze dalsze możliwości.&lt;br /&gt;
&lt;br /&gt;
=Ćwiczenia=&lt;br /&gt;
&lt;br /&gt;
1. Napisać program, który wczyta dany plik linia po linii i znajdzie wśród nich podzbiór linii o maksymalnej długości (w znakach) oraz wartość tej maksymalnej długości. Niech wynikiem działania programu będzie wypisanie liczby oznaczającej maksymalną długość linii występujących w badanym pliku, a następnie - treść tych linii, w kolejności w jakiej pojawiały się w pliku. Wypróbować ten program na pliku ''/usr/share/dict/words''. W końcowej wersji program powinien operować na pliku, którego nazwę podamy jako argument na linii poleceń.&lt;br /&gt;
&lt;br /&gt;
''Wskazówka:'' długość linii nie powinna uwzględniać kodu przejścia do nowej linii, zapisywanego symbolicznie jako &amp;lt;tt&amp;gt;'\n'&amp;lt;/tt&amp;gt; kończącego (prawie) każdą linię. &lt;br /&gt;
&lt;br /&gt;
2. Napisać program, który wczyta dany plik linia po linii i znajdzie wśród nich podzbiór linii o danej długości w znakach. Niech wynikiem działania programu będzie wypisanie linii o żądanej długości występujących w treści pliku w takiej kolejności, w jakiej pojawiały się w pliku. Długość szukanych linii podajemy jako pierwszy, a nazwę badanego pliku jako drugi argument na linii poleceń.&lt;br /&gt;
&lt;br /&gt;
3. Napisać program, który wyznaczy rozkład długości linii w treści danego pliku - nazwę pliku podajemy na linii poleceń. Wynikiem działania programu jest wypisanie ciągu linijek postaci &amp;lt;tt&amp;gt;''długość'' : ''ile''&amp;lt;/tt&amp;gt;, gdzie liczba ''ile'' opisuje, ile linii o danej długości wystąpiło w treści pliku. Pozycje, w których ''ile'' wynosiłoby 0 nie pojawiają się.&lt;br /&gt;
&lt;br /&gt;
4. Napisać program, który wyznacza częstości występowania w treści pliku określonych znaków. Zestaw znaków, których wystąpienia zamierzamy zliczać podajemy jako pierwszy argument na linii poleceń, nazwę badanego pliku jako drugi. Wynikiem działania programu jest wypisanie ciągu linijek postaci &amp;lt;tt&amp;gt;''znak'' : ''częstość''&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
5. Napisać program, który znajduje w pliku ''/usr/share/dict/words'' wszystkie słowa, składające się z tych samych liter co słowo, podane jako argument na linii poleceń - choć niekoniecznie występujących tę samą liczbę razy. Inaczej mówiąc, każda z liter występujących w podanym słowie występuje również w słowach szukanych, a nie występują w nich żadne inne znaki. Program wypisuje na ekran znalezione słowa, po jednym na linijkę.&lt;br /&gt;
 &lt;br /&gt;
6. Niech program znajduje wszystkie słowa, jakie można utworzyć korzystając z danego zestawu liter (podanego jako pierwszy argument na linii poleceń); tzn. tak jak w ''Scrabble'' dysponujemy takimi literami i w takiej liczbie, jakie składają się na to słowo (lub ,,słowo&amp;quot;). Źródłem słów jakie można utworzyć jest plik podany jako drugi argument (domyślnie - ''/usr/share/dict/words'').&amp;lt;br&amp;gt;&lt;br /&gt;
''Wskazówka:'' może się tu przydać operacja &amp;lt;tt&amp;gt;L.remove(x)&amp;lt;/tt&amp;gt;, gdzie &amp;lt;tt&amp;gt;L&amp;lt;/tt&amp;gt; jest listą; usuwa ona z listy pierwsze z kolei znalezione w niej wystąpienie elementu &amp;lt;tt&amp;gt;x&amp;lt;/tt&amp;gt;. &amp;lt;br&amp;gt;&lt;br /&gt;
''Uwaga:'' operacja ta zwróci błąd, jeśli element &amp;lt;tt&amp;gt;x&amp;lt;/tt&amp;gt; ''nie'' występuje w &amp;lt;tt&amp;gt;L&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
[[PPy3/Moduły|poprzednie]] | [[&amp;quot;Programowanie z Pythonem3&amp;quot;|strona główna]] | [[PPy3/NumPy|dalej]]&lt;br /&gt;
&lt;br /&gt;
[[Użytkownik:RobertJB|RobertJB]] ([[Dyskusja użytkownika:RobertJB|dyskusja]]) 13:26, 4 sie 2016 (CEST)&lt;/div&gt;</summary>
		<author><name>RobertJB</name></author>
		
	</entry>
	<entry>
		<id>http://brain.fuw.edu.pl/edu/index.php?title=PPy3/Wprowadzenie&amp;diff=11427</id>
		<title>PPy3/Wprowadzenie</title>
		<link rel="alternate" type="text/html" href="http://brain.fuw.edu.pl/edu/index.php?title=PPy3/Wprowadzenie&amp;diff=11427"/>
		<updated>2025-10-02T10:53:49Z</updated>

		<summary type="html">&lt;p&gt;RobertJB: /* Ogólnie o pracy z komputerem */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Wprowadzenie==&lt;br /&gt;
&lt;br /&gt;
Aby komputer wykonał za nas jakąś pracę, musimy mu przekazać dość precyzyjne instrukcje, mówiące co ma zrobić. Taki zestaw instrukcji nazywa się ''programem'', a proces tworzenia programów - to ''programowanie''. Stworzenie programu wymaga wykonania dwóch zasadniczych zadań:&lt;br /&gt;
&lt;br /&gt;
#wymyślenia algorytmu&lt;br /&gt;
#zapisania tegoż algorytmu w sposób możliwy do zinterpretowania przez komputer - a więc w jakimś języku programowania.&lt;br /&gt;
&lt;br /&gt;
Podczas opracowywania algorytmu musimy zastanowić się, jak dojdziemy do poszukiwanego rozwiązania. W jaki sposób z posiadanych danych wejściowych uzyskać możemy oczekiwany wynik? Jakie operacje po drodze muszę wykonać? Ile razy? Co po drodze muszę wiedzieć, a co dodatkowo sprawdzić? Jeśli wiemy już, jakie niezbędne etapy obliczeń musimy wykonać możemy przejść do fazy drugiej, czyli pisania właściwego programu.&lt;br /&gt;
&lt;br /&gt;
Programy piszemy używając specjalnych języków stworzonych do komunikacji z komputerami. Zawierają one pewien zestaw słów — poleceń, które komputer może wykonać. Wybór konkretnego języka może zależeć od rozwiązywanego problemu, ale w wielu wypadkach jest sprawą drugorzędną. Ponieważ, tak jak w przypadku języków obcych, aby porozumieć się z cudzoziemcem musimy nauczyć się obcego języka, tak i tu musimy nauczyć się wybranego języka (języków) programowania.&lt;br /&gt;
&lt;br /&gt;
Dlaczego uczymy się programować akurat w języku Python?&lt;br /&gt;
&lt;br /&gt;
*Jest jednym z najłatwiejszych do opanowania języków programowania, i najbardziej czytelnych dla człowieka.&lt;br /&gt;
*Jest narzędziem dojrzałym, rozwijanym od wielu lat i dobrze sprawdzonym.&lt;br /&gt;
*Zawiera jako standardowe wyposażenie wiele gotowych rozwiązań, które można wykorzystać jako elementy własnych programów.&lt;br /&gt;
*Jest coraz szerzej wykorzystywany do zadań naukowych.&lt;br /&gt;
*Jest dostępny bezpłatnie i bez uciążliwych ograniczeń licencyjnych na wiele różnych platform - systemów operacyjnych.&lt;br /&gt;
&lt;br /&gt;
Na początku nauczymy się podstaw języka, aby móc zacząć pisać i uruchamiać pierwsze, na razie proste programy. Następnie przećwiczymy rozwiązywanie rozmaitych zagadnień, wymyślając do tego odpowiednie algorytmy i zapisując je w postaci programów w Pythonie. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&lt;br /&gt;
Pracując z komputerem tak jak sekretarz czy księgowy, nie potrzeba w zasadzie nic wiedzieć o programowaniu i wewnętrznym działaniu komputera. Tak jak kurs nauki jazdy nie uczy, jak projektować konstrukcje samochodów, ani nawet jak je naprawiać. Założeniem studiów na fizyce jest jednak przygotowanie absolwenta, który będzie umiał sobie radzić z nowymi zadaniami i rozwiązywać problemy, a nie jedynie wykonywać pewne procedury. Elementarna umiejętność programowania jest jednym z narzędzi do tego celu.&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Instalacja===&lt;br /&gt;
&lt;br /&gt;
W systemach z rodziny '''Linux''' Python należy do wyposażenie standardowego. Niewykluczone, że dla celów drugiej części kursu będzie potrzeba doinstalowania opcjonalnych składników środowiska Python, m. in. narzędzi do obliczeń numerycznych i wizualizacji danych (tj. wykresów, itp.). Oczywiście na pracowniach dydaktycznych zostało to już za nas wykonane. &lt;br /&gt;
&lt;br /&gt;
Dla systemów z rodziny '''Windows''' możemy np. skorzystać z [https://docs.microsoft.com/en-us/windows/python/beginners dystrybucji] dostępnej ze &amp;quot;sklepu&amp;quot; Microsoft, lub z [https://www.python.org/downloads/windows/ pakietów] dostępnych z oficjalnych stron projektu Python. Dla bardziej zaawansowanych użytkowników, którzy jednak nie chcą opuszczać środowiska Windows, ciekawym rozwiązaniem może być [https://docs.microsoft.com/en-us/windows/wsl/install WSL] &amp;amp;mdash; emulacja środowiska Linux wewnątrz Windows.&lt;br /&gt;
&lt;br /&gt;
W systemie '''MacOS''' Python dostępny jest domyślnie, preinstalowana wersja może być jednak niepełna i/lub przestarzała. Pakiety instalacyjne Pythona dostępne są np. [https://www.python.org/downloads/macos/ tu].&lt;br /&gt;
&lt;br /&gt;
Często najlepszym sposobem stworzenia sobie środowiska pracy do programowania w Pythonie jest skorzystanie z narzędzia [https://docs.astral.sh/uv/ uv] &amp;amp;mdash; zwłaszcza gdy zachodzi potrzeba użycia najnowszej wersji Pythona (albo innej, ściśle określonej), i/lub wielu składników opcjonalnych (modułów, bibliotek), pomiędzy którymi musi zostać zachowana zgodność wersji. UV jest dostępne dla wszystkich wymienionych systemów, a jego instalacja nie wymaga uprzedniej instalacji Pythona.&lt;br /&gt;
&lt;br /&gt;
===Ogólnie o pracy z komputerem===&lt;br /&gt;
&lt;br /&gt;
Tu jest właściwy moment, aby zapoznać się (o ile jest to komuś obce) z kilkoma podstawowymi faktami dotyczącymi&lt;br /&gt;
,,zaawansowanej&amp;quot; pracy z komputerem, a nie dotyczącymi samego Pythona &amp;amp;mdash; w tym:&lt;br /&gt;
&lt;br /&gt;
*logiczna organizacja danych na dysku; foldery (katalogi), podfoldery&lt;br /&gt;
*prawa dostępu do plików i folderów&lt;br /&gt;
*pliki tekstowe i jak je edytować&lt;br /&gt;
*co to jest terminal i powłoka systemowa (''shell'')&lt;br /&gt;
*co to jest katalog bieżący; podstawowe operacje na plikach w linii poleceń (''ls'', ''pwd'', ''cd'', ''cp'', ''mv'', ''rm'', ...)&lt;br /&gt;
*jak uruchomić program w linii poleceń; ścieżka wyszukiwania&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
[[&amp;quot;Programowanie_z_Pythonem3&amp;quot;|Strona główna]] | [[PPy3/PierwszeKroki|dalej]]&lt;br /&gt;
&lt;br /&gt;
--[[Użytkownik:RobertJB|RobertJB]] ([[Dyskusja użytkownika:RobertJB|dyskusja]]) 12:50, 2 paźdz 2025 (CEST)&lt;/div&gt;</summary>
		<author><name>RobertJB</name></author>
		
	</entry>
	<entry>
		<id>http://brain.fuw.edu.pl/edu/index.php?title=PPy3/Wprowadzenie&amp;diff=11426</id>
		<title>PPy3/Wprowadzenie</title>
		<link rel="alternate" type="text/html" href="http://brain.fuw.edu.pl/edu/index.php?title=PPy3/Wprowadzenie&amp;diff=11426"/>
		<updated>2025-10-02T10:52:48Z</updated>

		<summary type="html">&lt;p&gt;RobertJB: /* Instalacja */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Wprowadzenie==&lt;br /&gt;
&lt;br /&gt;
Aby komputer wykonał za nas jakąś pracę, musimy mu przekazać dość precyzyjne instrukcje, mówiące co ma zrobić. Taki zestaw instrukcji nazywa się ''programem'', a proces tworzenia programów - to ''programowanie''. Stworzenie programu wymaga wykonania dwóch zasadniczych zadań:&lt;br /&gt;
&lt;br /&gt;
#wymyślenia algorytmu&lt;br /&gt;
#zapisania tegoż algorytmu w sposób możliwy do zinterpretowania przez komputer - a więc w jakimś języku programowania.&lt;br /&gt;
&lt;br /&gt;
Podczas opracowywania algorytmu musimy zastanowić się, jak dojdziemy do poszukiwanego rozwiązania. W jaki sposób z posiadanych danych wejściowych uzyskać możemy oczekiwany wynik? Jakie operacje po drodze muszę wykonać? Ile razy? Co po drodze muszę wiedzieć, a co dodatkowo sprawdzić? Jeśli wiemy już, jakie niezbędne etapy obliczeń musimy wykonać możemy przejść do fazy drugiej, czyli pisania właściwego programu.&lt;br /&gt;
&lt;br /&gt;
Programy piszemy używając specjalnych języków stworzonych do komunikacji z komputerami. Zawierają one pewien zestaw słów — poleceń, które komputer może wykonać. Wybór konkretnego języka może zależeć od rozwiązywanego problemu, ale w wielu wypadkach jest sprawą drugorzędną. Ponieważ, tak jak w przypadku języków obcych, aby porozumieć się z cudzoziemcem musimy nauczyć się obcego języka, tak i tu musimy nauczyć się wybranego języka (języków) programowania.&lt;br /&gt;
&lt;br /&gt;
Dlaczego uczymy się programować akurat w języku Python?&lt;br /&gt;
&lt;br /&gt;
*Jest jednym z najłatwiejszych do opanowania języków programowania, i najbardziej czytelnych dla człowieka.&lt;br /&gt;
*Jest narzędziem dojrzałym, rozwijanym od wielu lat i dobrze sprawdzonym.&lt;br /&gt;
*Zawiera jako standardowe wyposażenie wiele gotowych rozwiązań, które można wykorzystać jako elementy własnych programów.&lt;br /&gt;
*Jest coraz szerzej wykorzystywany do zadań naukowych.&lt;br /&gt;
*Jest dostępny bezpłatnie i bez uciążliwych ograniczeń licencyjnych na wiele różnych platform - systemów operacyjnych.&lt;br /&gt;
&lt;br /&gt;
Na początku nauczymy się podstaw języka, aby móc zacząć pisać i uruchamiać pierwsze, na razie proste programy. Następnie przećwiczymy rozwiązywanie rozmaitych zagadnień, wymyślając do tego odpowiednie algorytmy i zapisując je w postaci programów w Pythonie. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&lt;br /&gt;
Pracując z komputerem tak jak sekretarz czy księgowy, nie potrzeba w zasadzie nic wiedzieć o programowaniu i wewnętrznym działaniu komputera. Tak jak kurs nauki jazdy nie uczy, jak projektować konstrukcje samochodów, ani nawet jak je naprawiać. Założeniem studiów na fizyce jest jednak przygotowanie absolwenta, który będzie umiał sobie radzić z nowymi zadaniami i rozwiązywać problemy, a nie jedynie wykonywać pewne procedury. Elementarna umiejętność programowania jest jednym z narzędzi do tego celu.&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Instalacja===&lt;br /&gt;
&lt;br /&gt;
W systemach z rodziny '''Linux''' Python należy do wyposażenie standardowego. Niewykluczone, że dla celów drugiej części kursu będzie potrzeba doinstalowania opcjonalnych składników środowiska Python, m. in. narzędzi do obliczeń numerycznych i wizualizacji danych (tj. wykresów, itp.). Oczywiście na pracowniach dydaktycznych zostało to już za nas wykonane. &lt;br /&gt;
&lt;br /&gt;
Dla systemów z rodziny '''Windows''' możemy np. skorzystać z [https://docs.microsoft.com/en-us/windows/python/beginners dystrybucji] dostępnej ze &amp;quot;sklepu&amp;quot; Microsoft, lub z [https://www.python.org/downloads/windows/ pakietów] dostępnych z oficjalnych stron projektu Python. Dla bardziej zaawansowanych użytkowników, którzy jednak nie chcą opuszczać środowiska Windows, ciekawym rozwiązaniem może być [https://docs.microsoft.com/en-us/windows/wsl/install WSL] &amp;amp;mdash; emulacja środowiska Linux wewnątrz Windows.&lt;br /&gt;
&lt;br /&gt;
W systemie '''MacOS''' Python dostępny jest domyślnie, preinstalowana wersja może być jednak niepełna i/lub przestarzała. Pakiety instalacyjne Pythona dostępne są np. [https://www.python.org/downloads/macos/ tu].&lt;br /&gt;
&lt;br /&gt;
Często najlepszym sposobem stworzenia sobie środowiska pracy do programowania w Pythonie jest skorzystanie z narzędzia [https://docs.astral.sh/uv/ uv] &amp;amp;mdash; zwłaszcza gdy zachodzi potrzeba użycia najnowszej wersji Pythona (albo innej, ściśle określonej), i/lub wielu składników opcjonalnych (modułów, bibliotek), pomiędzy którymi musi zostać zachowana zgodność wersji. UV jest dostępne dla wszystkich wymienionych systemów, a jego instalacja nie wymaga uprzedniej instalacji Pythona.&lt;br /&gt;
&lt;br /&gt;
===Ogólnie o pracy z komputerem===&lt;br /&gt;
&lt;br /&gt;
Tu jest właściwy moment, aby zapoznać się (o ile jest to komuś obce) z kilkoma podstawowymi faktami dotyczącymi&lt;br /&gt;
,,zaawansowanej&amp;quot; pracy z komputerem, a nie dotyczącymi samego Pythona &amp;amp;mdash; w tym:&lt;br /&gt;
&lt;br /&gt;
*logiczna organizacja danych na dysku; foldery (katalogi), podfoldery&lt;br /&gt;
*prawa dostępu do plików i folderów&lt;br /&gt;
*pliki tekstowe i jak je edytować&lt;br /&gt;
*co to jest terminal i powłoka systemowa (''shell'')&lt;br /&gt;
*co to jest katalog bieżący; podstawowe operacje na plikach w linii poleceń (''ls'', ''pwd'', ''cd'', ''cp'', ''mv'', ''rm'', ...)&lt;br /&gt;
*jak uruchomić program w linii poleceń; ścieżka wyszukiwania&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
[[&amp;quot;Programowanie_z_Pythonem3&amp;quot;|Strona główna]] | [[PPy3/PierwszeKroki|dalej]]&lt;br /&gt;
&lt;br /&gt;
--[[Użytkownik:RobertJB|RobertJB]] ([[Dyskusja użytkownika:RobertJB|dyskusja]]) 13:16, 29 wrz 2017 (CEST)&lt;/div&gt;</summary>
		<author><name>RobertJB</name></author>
		
	</entry>
	<entry>
		<id>http://brain.fuw.edu.pl/edu/index.php?title=%22Programowanie_z_Pythonem3%22&amp;diff=11425</id>
		<title>&quot;Programowanie z Pythonem3&quot;</title>
		<link rel="alternate" type="text/html" href="http://brain.fuw.edu.pl/edu/index.php?title=%22Programowanie_z_Pythonem3%22&amp;diff=11425"/>
		<updated>2025-10-02T10:40:26Z</updated>

		<summary type="html">&lt;p&gt;RobertJB: /* Semestr zimowy 2023/2024 */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Grafika:Python-logo.png]]&lt;br /&gt;
&lt;br /&gt;
[[Category:Informatyka]]&lt;br /&gt;
== Semestr zimowy 2025/2026 ==&lt;br /&gt;
&lt;br /&gt;
'''''W trakcie opracowania'''''&lt;br /&gt;
&lt;br /&gt;
===Uwagi ogólne===&lt;br /&gt;
&lt;br /&gt;
Zasady zaliczenia ćwiczeń w roku 2025/2026:&lt;br /&gt;
&lt;br /&gt;
* maksymalnie można zdobyć 40 punktów&lt;br /&gt;
* w semestrze będą dwa kolokwia, w połowie i pod koniec; na każdym można zdobyć po 15 punktów&lt;br /&gt;
* w sesji będzie kolokwium dodatkowe, dla chętnych; wynik z niego (maks. 15 punktów) zastępuje gorszy z wyników kolokwiów z semestru, o ile jest on od niego lepszy&lt;br /&gt;
* maksymalnie 10 punktów uzyskuje się na podstawie zadań domowych i kartkówek na ćwiczeniach&lt;br /&gt;
* zaliczenie ćwiczeń na pozytywną ocenę wymaga co najmniej 50% punktów (20 p.)&lt;br /&gt;
* ocena rośnie o pół stopnia z osiągnięciem progu każdych kolejnych 10%, tj. 4 punktów&lt;br /&gt;
* prowadzący może przyznać dodatkowo do 3 punktów &amp;quot;premiowych&amp;quot; na podstawie aktywności na ćwiczeniach&lt;br /&gt;
&lt;br /&gt;
Obecność na ćwiczeniach jest obowiązkowa. Dopuszczalne są '''dwie''' nieobecności nieusprawiedliwione w semestrze. '''Za każdą kolejną nieobecność nieusprawiedliwioną powyżej dwóch odejmujemy od wyniku 5 punktów.'''&lt;br /&gt;
&lt;br /&gt;
Ocena końcowa z przedmiotu składa się z oceny z ćwiczeń, oraz z oceny z egzaminu testowego kończącego wykład, w proporcji 3:2 - z tym, że '''obie te oceny cząstkowe muszą być pozytywne''' aby ocena z całości była pozytywna.&lt;br /&gt;
&lt;br /&gt;
===Spis treści===&lt;br /&gt;
&lt;br /&gt;
#[[PPy3/Wprowadzenie|Wprowadzenie]]&lt;br /&gt;
#[[PPy3/PierwszeKroki|Pierwsze kroki]]&lt;br /&gt;
#[[PPy3/StałeIZmienne|Stałe i zmienne]]&lt;br /&gt;
#[[PPy3/InstrukcjaWarunkowa|Instrukcja warunkowa]]&lt;br /&gt;
#[[PPy3/SekwencjeIIteracja|Sekwencje i iteracja]]&lt;br /&gt;
#[[PPy3/Funkcje|Funkcje]]&lt;br /&gt;
#[[PPy3/Kolekcje|Kolekcje]]&lt;br /&gt;
#[[PPy3/Moduły|Moduły i biblioteki]]&lt;br /&gt;
#[[PPy3/WejścieWyjście|Obsługa wejścia i wyjścia]]&lt;br /&gt;
#[[PPy3/NumPy|NumPy]] - rachunki numeryczne na tablicach liczb&lt;br /&gt;
#[[PPy3/Matplotlib|Matplotlib]] - wizualizacja danych&lt;br /&gt;
#[[PPy3/TematyDodatkowe|Tematy dodatkowe]] - uzupełnienie&lt;br /&gt;
#[[PPy3/DobrePraktyki|Zasady dobrej praktyki]]&lt;br /&gt;
&lt;br /&gt;
===O skrypcie===&lt;br /&gt;
&lt;br /&gt;
Opracowane na nowo przez [[Użytkownik:RobertJB|RobertJB]], częściowo z wykorzystaniem [[&amp;quot;Programowanie z Pythonem&amp;quot;|poprzedniej wersji]].&lt;/div&gt;</summary>
		<author><name>RobertJB</name></author>
		
	</entry>
	<entry>
		<id>http://brain.fuw.edu.pl/edu/index.php?title=PPy3/PierwszeKroki&amp;diff=10905</id>
		<title>PPy3/PierwszeKroki</title>
		<link rel="alternate" type="text/html" href="http://brain.fuw.edu.pl/edu/index.php?title=PPy3/PierwszeKroki&amp;diff=10905"/>
		<updated>2024-10-03T11:44:57Z</updated>

		<summary type="html">&lt;p&gt;RobertJB: /* Używanie linii poleceń interpretera */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
= Pierwsze kroki =&lt;br /&gt;
&lt;br /&gt;
==Podstawowe cegiełki==&lt;br /&gt;
&lt;br /&gt;
*Program w Pythonie to tekst, stanowiący ciąg instrukcji; są one wykonywane przez ''interpreter'' (zasadniczo) kolejno jedna po drugiej.&lt;br /&gt;
*''Prosta'' instrukcja to (zasadniczo) jedna linijka, kończy się wraz z przejściem do kolejnej linii.&lt;br /&gt;
*Instrukcja złożona, to linijka otwierająca '''zawsze zakończona dwukropkiem''', a po niej - '''blok wcięty''', tj. ciąg instrukcji (prostych i/lub złożonych) pisanych z dodatkowym ''wcięciem'' w stosunku do linijki otwierającej; mogą to być dodatkowe (np. dwie lub cztery) spacje, lub kod tabulacji, na początku każdej linijki. Koniec instrukcji złożonej następuje wraz z powrotem do poprzedniego ''poziomu wcięcia''.&lt;br /&gt;
*W tekście programu można umieszczać komentarze; komentarz zaczyna się od znaku &amp;lt;tt&amp;gt;#&amp;lt;/tt&amp;gt;, a kończy się wraz z końcem bieżącej linii. Komentarze nie są częścią programu, tzn. są ignorowane przy jego wykonaniu.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&lt;br /&gt;
*Wyjątki od podanych reguł, istnienie których sygnalizuje słowo ''zasadniczo'', będą przedstawione później.&lt;br /&gt;
*Należy się raz zdecydować, jak dokładnie będziemy tworzyć poziomy wcięcia, i konsekwentnie się tego trzymać. Najlepiej po dwie lub cztery spacje (wg. upodobań), i ustawić w opcjach edytora kodu, żeby wciśnięcie klawisza ''Tab'' skutkowało odpowiednią liczbą spacji. Mieszanie w tekście kodu spacji i tabulacji zawsze prowadzi do kłopotów.&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Przykłady instrukcji prostych:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
x = 1 + 2&lt;br /&gt;
y = 2 * x&lt;br /&gt;
x = x + 1&lt;br /&gt;
print(x, y)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Przykłady instrukcji złożonych:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
if x &amp;gt; 0:&lt;br /&gt;
    print(x)&lt;br /&gt;
&lt;br /&gt;
def dodaj1(x):&lt;br /&gt;
    return x + 1&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ważnym elementem są komentarze:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
# a teraz, powiększę x o 1&lt;br /&gt;
x = x + 1&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*Instrukcje budowane są z wyrażeń, a wyrażenia - z nazw, stałych i operatorów.&lt;br /&gt;
*'''Nazwa''' może składać się z liter, cyfr i znaku podkreślenia (_). Nie może zaczynać się od cyfry. Litery małe i wielkie są rozróżniane.&lt;br /&gt;
*Przykładem stałych są liczby - całkowite i ułamki dziesiętne. Zamiast przecinkiem, część ułamkową oddziela się kropką.&lt;br /&gt;
*Inny rodzaj stałych to napisy. Można je budować na kilka sposobów:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
'to jest napis'&lt;br /&gt;
&amp;quot;to jest drugi napis&amp;quot;&lt;br /&gt;
'''a to jest...&lt;br /&gt;
jeszcze jeden napis'''&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*Ostatni przypadek to wyjątek od zasady że koniec linii kończy instrukcję. Napis podany w pierwszych dwóch postaciach nie może zawierać przejścia do nowej linii.&lt;br /&gt;
*Nazwy są po to, aby oznaczać nimi wartości. Wartościami mogą być np. liczby i napisy:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
pi = 3.14159&lt;br /&gt;
komunikat = 'Uwaga!!!'&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''UWAGA:''' znak równości to nie porównanie, a ''operator przypisania''. Powoduje on, że nazwa po jego lewej stronie będzie odtąd oznaczać wartość zapisaną po prawej. W szczególności, po lewej stronie znaku równości nie może występować np. stała liczba.&lt;br /&gt;
&lt;br /&gt;
*Więcej o stałych i nazwach na następnej stronie, na razie tyle nam wystarczy.&lt;br /&gt;
*Inne operatory, to w szczególności arytmetyka:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
+ - * /  // % **&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'*' to mnożenie, '//' to dzielenie całkowitoliczbowe, '%' to reszta z dzielenia (na ogół stosowana do liczb całkowitych, ale niekoniecznie), '**' to potęgowanie.&lt;br /&gt;
&lt;br /&gt;
*Napisy też można &amp;quot;dodawać&amp;quot;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
imie = 'Jacek'&lt;br /&gt;
powitanie = 'witaj ' + imie&lt;br /&gt;
print(powitanie)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;small&amp;gt;Czemu właściwie operację ,,sklejania&amp;quot; napisów oznaczono plusem? W matematyce zazwyczaj plus stosuje się na oznaczenie operacji przemiennych, tzn. takich, których wynik nie zależy od kolejności składników &amp;amp;mdash; a sklejanie napisów ewidentnie taką operacją nie jest. Ale cóż, tak się przyjęło.&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Używanie linii poleceń interpretera==&lt;br /&gt;
&lt;br /&gt;
''Interpreter'' to aplikacja, która potrafi czytać tekst kodu w języku Python i wykonać zapisane w nim polecenia. Może on być używany jako samodzielne polecenie, wywoływane w oknie terminala, lub zintegrowany z środowiskiem programistycznym w rodzaju ''Spyder'' lub ''Visual Studio Code''. &lt;br /&gt;
&lt;br /&gt;
Zanim zaczniemy pisać &amp;quot;poważne&amp;quot; programy, nauczymy się korzystać z ''trybu interaktywnego'' interpretera, który pozwala na wpisywanie po jednym poleceniu i natychmiastowe uzyskanie wyniku jego wykonania. Można go używać do podręcznych rachunków - zamiast kalkulatora -- i do eksperymentowania z kodem w Pythonie. Do pracy interaktywnej warto używać &amp;quot;wzbogaconej&amp;quot; wersji interpretera, wywoływanej poleceniem&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=bash&amp;gt;&lt;br /&gt;
$ ipython3&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
w najprostszych zastosowaniach niewiele się on różni od &amp;quot;zwykłego&amp;quot; interpretera, wywoływanego przez &amp;lt;tt&amp;gt;python3&amp;lt;/tt&amp;gt;, ale posiada pewne dodatkowe możliwości, które niedługo się nam przydadzą.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&lt;br /&gt;
'''UWAGA:''' polecenie &amp;lt;tt&amp;gt;ipython&amp;lt;/tt&amp;gt; (bez 3) wywoła domyślną wersję Pythona &amp;amp;mdash; aktualnie wersję 3. &lt;br /&gt;
Podobnie, &amp;lt;tt&amp;gt;python&amp;lt;/tt&amp;gt; wywoła domyślną wersję (3) &amp;quot;zwykłego&amp;quot; interpretera.  Natomiast - &amp;lt;tt&amp;gt;python2&amp;lt;/tt&amp;gt; wywołuje starszą wersję &amp;quot;zwykłego&amp;quot; interpretera, z której nie należy już aktualnie korzystać. Jeszcze parę&lt;br /&gt;
lat temu wersja 2 była domyślną, więc działało to odwrotnie.&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Wykonywanie rachunków===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
$ ipython3&lt;br /&gt;
Python 3.5.1+ (default, Mar 30 2016, 22:46:26) &lt;br /&gt;
Type &amp;quot;copyright&amp;quot;, &amp;quot;credits&amp;quot; or &amp;quot;license&amp;quot; for more information.&lt;br /&gt;
&lt;br /&gt;
IPython 2.4.1 -- An enhanced Interactive Python.&lt;br /&gt;
?         -&amp;gt; Introduction and overview of IPython's features.&lt;br /&gt;
%quickref -&amp;gt; Quick reference.&lt;br /&gt;
help      -&amp;gt; Python's own help system.&lt;br /&gt;
object?   -&amp;gt; Details about 'object', use 'object??' for extra details.&lt;br /&gt;
&lt;br /&gt;
In [1]: 7 * (3 + 5)&lt;br /&gt;
Out[1]: 56&lt;br /&gt;
&lt;br /&gt;
In [2]: 2.81 / (1.25 - .33)&lt;br /&gt;
Out[2]: 3.054347826086957&lt;br /&gt;
&lt;br /&gt;
In [3]: 2**128&lt;br /&gt;
Out[3]: 340282366920938463463374607431768211456&lt;br /&gt;
&lt;br /&gt;
In [4]: 1/9&lt;br /&gt;
Out[4]: 0.1111111111111111&lt;br /&gt;
&lt;br /&gt;
In [5]: 11//9, 11%9&lt;br /&gt;
Out[5]: (1, 2)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Zapis wyrażeń arytmetycznych raczej nie zaskakuje. Drobne uwagi:&lt;br /&gt;
&lt;br /&gt;
*spacje w zapisie wyrażenia, pomiędzy liczbami a operatorami (lub ich brak), nie mają znaczenia&lt;br /&gt;
*reguły pierwszeństwa operatorów (najpierw potęgowanie, potem mnożenie i dzielenie, potem odejmowanie i dodawanie,...) są w zasadzie takie, jak należy się spodziewać; kolejność operacji możemy narzucić nawiasami - ale tylko okrągłymi, które można wielokrotnie zagnieżdżać&lt;br /&gt;
*pisząc ułamek dziesiętny (liczbę z kropką), można pominąć część całkowitą lub ułamkową, o ile ma ona być zero (nie można jednak pominąć obu);&lt;br /&gt;
*liczby całkowite mogą być dowolnie duże (w ramach fizycznych ograniczeń komputera)&lt;br /&gt;
*operacje na ułamkach należy zawsze traktować jako przybliżone - w operacjach na liczbach ułamkowych komputer może ogarnąć tylko skończoną liczbę cyfr&lt;br /&gt;
*zwykłe dzielenie da zawsze wynik ułamkowy; istnieje jednak operator &amp;lt;tt&amp;gt;//&amp;lt;/tt&amp;gt; dzielenia całkowitego, który odrzuca resztę&lt;br /&gt;
*gdy chcemy zakończyć &amp;quot;rozmowę&amp;quot; z interpreterem, piszemy &amp;lt;tt&amp;gt;exit()&amp;lt;/tt&amp;gt;; jeżeli pracujemy w Linuxie, zadziała również dwukrotne &amp;lt;tt&amp;gt;Ctrl-D&amp;lt;/tt&amp;gt; (tzn. trzymając naciśnięty klawisz &amp;lt;tt&amp;gt;Ctrl&amp;lt;/tt&amp;gt; stukamy dwukrotnie w klawisz &amp;lt;tt&amp;gt;D&amp;lt;/tt&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
==Jak uzyskać pomoc==&lt;br /&gt;
&lt;br /&gt;
W programie IPython mamy w każdej chwili dostęp do pomocy na temat poleceń, funkcji itd. Pythona:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
In [8]: print?&lt;br /&gt;
Type:        builtin_function_or_method&lt;br /&gt;
String form: &amp;lt;built-in function print&amp;gt;&lt;br /&gt;
Namespace:   Python builtin&lt;br /&gt;
Docstring:&lt;br /&gt;
print(value, ..., sep=' ', end='\n', file=sys.stdout, flush=False)&lt;br /&gt;
&lt;br /&gt;
Prints the values to a stream, or to sys.stdout by default.&lt;br /&gt;
Optional keyword arguments:&lt;br /&gt;
file:  a file-like object (stream); defaults to the current sys.stdout.&lt;br /&gt;
sep:   string inserted between values, default a space.&lt;br /&gt;
end:   string appended after the last value, default a newline.&lt;br /&gt;
flush: whether to forcibly flush the stream.&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
W tym przykładzie uzyskaliśmy szczegółowy opis zastosowania funkcji wbudowanej &amp;lt;tt&amp;gt;print&amp;lt;/tt&amp;gt;. Wprawdzie po angielsku, ale mam nadzieję, że nie jest to przeszkoda nie do przeskoczenia. Już niedługo będziemy dokładnie rozumieli to, co jest tu napisane.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&lt;br /&gt;
Jeżeli tekst pomocy jest dłuższy, to będzie wyświetlany w trybie pozwalającym m. in. na jego przewijanie z użyciem klawiszy strzałek czy &amp;lt;tt&amp;gt;PgUp&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;PgDn&amp;lt;/tt&amp;gt;. Aby wyjść z tego trybu i powrócić do interpretera, wystarczy nacisnąć &amp;lt;tt&amp;gt;q&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Najprostszy program==&lt;br /&gt;
&lt;br /&gt;
Za pomocą ulubionego edytora tekstowego stwórzmy plik o nazwie &amp;lt;tt&amp;gt;hello.py&amp;lt;/tt&amp;gt; i następującej treści:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
#! /usr/bin/python3&lt;br /&gt;
&lt;br /&gt;
print('Witaj świecie!')&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Zgodnie z tradycją, będzie to program wykonujący jedno banalne zadanie: wypisanie komunikatu o ustalonej treści. Zgodnie z zasadą, że programowanie w Pythonie ma być maksymalnie proste - jedynym niezbędnym elementem tego programu jest linijka wywołująca funkcję &amp;lt;tt&amp;gt;print&amp;lt;/tt&amp;gt;. W tym przykładzie, uzupełniłem treść programu o pierwszą linijkę, zaczynającą się od znaku kratki (&amp;lt;tt&amp;gt;#&amp;lt;/tt&amp;gt;) - istotne jest, aby była to dokładnie pierwsza linijka w pliku, i by zaczynała się od pierwszej pozycji w wierszu. Czyli, aby &amp;lt;tt&amp;gt;#!&amp;lt;/tt&amp;gt; były dokładnie dwoma pierwszymi znakami w treści pliku. Z punktu widzenia Pythona, linijka ta jest komentarzem, i przy uruchamianiu pliku jest ignorowana. Pozwala ona jednak, by plik ten był automatycznie rozpoznawany przez system operacyjny (Linux) jako zawierający program w języku Python. Jaki z tego pożytek, dowiemy się za chwilę.&lt;br /&gt;
&lt;br /&gt;
Aby ten program uruchomić, jest parę sposobów. Najprościej:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=bash&amp;gt;&lt;br /&gt;
$ python3 hello.py&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
powyższe polecenie wpisujemy w terminalu, w trybie powłoki systemowej (''nie w programie IPython!''). Tutaj musieliśmy jawnie wywołać interpreter Pythona i wskazać mu plik &amp;lt;tt&amp;gt;hello.py&amp;lt;/tt&amp;gt; jako zawierający kod do uruchomienia.&lt;br /&gt;
&lt;br /&gt;
Zamiast tego, możemy nadać plikowi &amp;lt;tt&amp;gt;hello.py&amp;lt;/tt&amp;gt; atrybut pliku wykonywalnego, czyli programu, i uruchomić go bezpośrednio:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=bash&amp;gt;&lt;br /&gt;
$ chmod +x hello.py&lt;br /&gt;
$ ./hello.py&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*Polecenie z pierwszej linijki wystarczy wykonać raz dla danego pliku&lt;br /&gt;
*Zamiast z linii poleceń, można w okienku ''Właściwości'' pliku znaleźć odpowiednie pole do kliknięcia&lt;br /&gt;
*Postać drugiej linijki tłumaczy się tym, że nasz program &amp;lt;tt&amp;gt;hello.py&amp;lt;/tt&amp;gt; nie jest zainstalowany w systemie i nie zostanie odnaleziony przez przeszukanie standardowych lokalizacji programów na dysku. Należy wyraźnie wskazać, że chodzi o plik znajdujący się w bieżącym folderze - i to tu robimy.&lt;br /&gt;
*Plik z kodem w Pythonie nie musi mieć nazwy kończącej się na &amp;lt;tt&amp;gt;.py&amp;lt;/tt&amp;gt; - jest to jednak wygodne, bo np. edytory tekstu traktują to jako sugestię co do zawartości pliku, i mogą dostosować do tego swoje działanie (np. &amp;lt;tt&amp;gt;gedit&amp;lt;/tt&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
==Ćwiczenia==&lt;br /&gt;
&lt;br /&gt;
===Rachunki w linii poleceń===&lt;br /&gt;
&lt;br /&gt;
#Ile wynosi reszta z dzielenia 2&amp;lt;sup&amp;gt;999&amp;lt;/sup&amp;gt; przez 7?&lt;br /&gt;
#Która z tych liczb mniej się różni od pierwiastka kwadratowego z 2: 721/510 czy 722/510?&lt;br /&gt;
#Oblicz pierwiastek kwadratowy z 2, a następnie - podnieś go do kwadratu; ile wynosi względny błąd wyniku?&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
''CDN''&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
[[PPy3/Wprowadzenie|poprzednia]] | [[&amp;quot;Programowanie z Pythonem3&amp;quot;|Strona główna]] | [[PPy3/StałeIZmienne|dalej]]&lt;br /&gt;
&lt;br /&gt;
--[[Użytkownik:RobertJB|RobertJB]] ([[Dyskusja użytkownika:RobertJB|dyskusja]]) 13:53, 15 cze 2016 (CEST)&lt;/div&gt;</summary>
		<author><name>RobertJB</name></author>
		
	</entry>
	<entry>
		<id>http://brain.fuw.edu.pl/edu/index.php?title=%22Programowanie_z_Pythonem3%22&amp;diff=9478</id>
		<title>&quot;Programowanie z Pythonem3&quot;</title>
		<link rel="alternate" type="text/html" href="http://brain.fuw.edu.pl/edu/index.php?title=%22Programowanie_z_Pythonem3%22&amp;diff=9478"/>
		<updated>2023-09-29T10:48:56Z</updated>

		<summary type="html">&lt;p&gt;RobertJB: /* Semestr zimowy 2022/2023 */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Grafika:Python-logo.png]]&lt;br /&gt;
&lt;br /&gt;
[[Category:Informatyka]]&lt;br /&gt;
== Semestr zimowy 2023/2024 ==&lt;br /&gt;
&lt;br /&gt;
'''''W trakcie opracowania'''''&lt;br /&gt;
&lt;br /&gt;
===Uwagi ogólne===&lt;br /&gt;
&lt;br /&gt;
Zasady zaliczenia ćwiczeń w roku 2023/2024:&lt;br /&gt;
&lt;br /&gt;
* maksymalnie można zdobyć 40 punktów&lt;br /&gt;
* w semestrze będą dwa kolokwia, w połowie i pod koniec; na każdym można zdobyć po 15 punktów&lt;br /&gt;
* w sesji będzie kolokwium dodatkowe, dla chętnych; wynik z niego (maks. 15 punktów) zastępuje gorszy z wyników kolokwiów z semestru, o ile jest on od niego lepszy&lt;br /&gt;
* maksymalnie 10 punktów uzyskuje się na podstawie zadań domowych i kartkówek na ćwiczeniach&lt;br /&gt;
* zaliczenie ćwiczeń na pozytywną ocenę wymaga co najmniej 50% punktów (20 p.)&lt;br /&gt;
* ocena rośnie o pół stopnia z osiągnięciem progu każdych kolejnych 10%, tj. 4 punktów&lt;br /&gt;
* prowadzący może przyznać dodatkowo do 3 punktów &amp;quot;premiowych&amp;quot; na podstawie aktywności na ćwiczeniach&lt;br /&gt;
&lt;br /&gt;
Obecność na ćwiczeniach jest obowiązkowa. Dopuszczalne są '''dwie''' nieobecności nieusprawiedliwione w semestrze. '''Za każdą kolejną nieobecność nieusprawiedliwioną powyżej dwóch odejmujemy od wyniku 5 punktów.'''&lt;br /&gt;
&lt;br /&gt;
Ocena końcowa z przedmiotu składa się z oceny z ćwiczeń, oraz z oceny z egzaminu testowego kończącego wykład, w proporcji 3:2 - z tym, że '''obie te oceny cząstkowe muszą być pozytywne''' aby ocena z całości była pozytywna.&lt;br /&gt;
&lt;br /&gt;
===Spis treści===&lt;br /&gt;
&lt;br /&gt;
#[[PPy3/Wprowadzenie|Wprowadzenie]]&lt;br /&gt;
#[[PPy3/PierwszeKroki|Pierwsze kroki]]&lt;br /&gt;
#[[PPy3/StałeIZmienne|Stałe i zmienne]]&lt;br /&gt;
#[[PPy3/InstrukcjaWarunkowa|Instrukcja warunkowa]]&lt;br /&gt;
#[[PPy3/SekwencjeIIteracja|Sekwencje i iteracja]]&lt;br /&gt;
#[[PPy3/Funkcje|Funkcje]]&lt;br /&gt;
#[[PPy3/Kolekcje|Kolekcje]]&lt;br /&gt;
#[[PPy3/Moduły|Moduły i biblioteki]]&lt;br /&gt;
#[[PPy3/WejścieWyjście|Obsługa wejścia i wyjścia]]&lt;br /&gt;
#[[PPy3/NumPy|NumPy]] - rachunki numeryczne na tablicach liczb&lt;br /&gt;
#[[PPy3/Matplotlib|Matplotlib]] - wizualizacja danych&lt;br /&gt;
#[[PPy3/TematyDodatkowe|Tematy dodatkowe]] - uzupełnienie&lt;br /&gt;
#[[PPy3/DobrePraktyki|Zasady dobrej praktyki]]&lt;br /&gt;
&lt;br /&gt;
===O skrypcie===&lt;br /&gt;
&lt;br /&gt;
Opracowane na nowo przez [[Użytkownik:RobertJB|RobertJB]], częściowo z wykorzystaniem [[&amp;quot;Programowanie z Pythonem&amp;quot;|poprzedniej wersji]].&lt;/div&gt;</summary>
		<author><name>RobertJB</name></author>
		
	</entry>
	<entry>
		<id>http://brain.fuw.edu.pl/edu/index.php?title=PPy3/TematyDodatkowe&amp;diff=9476</id>
		<title>PPy3/TematyDodatkowe</title>
		<link rel="alternate" type="text/html" href="http://brain.fuw.edu.pl/edu/index.php?title=PPy3/TematyDodatkowe&amp;diff=9476"/>
		<updated>2023-07-13T11:32:38Z</updated>

		<summary type="html">&lt;p&gt;RobertJB: /* Trochę więcej o klasach i obiektach */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Tematy dodatkowe =&lt;br /&gt;
&lt;br /&gt;
== Błędy i wyjątki ==&lt;br /&gt;
&lt;br /&gt;
Każdy programista popełnia błędy &amp;amp;mdash; jest to nieunikniona część tej działalności. &lt;br /&gt;
&lt;br /&gt;
*Są błędy, które można nazwać banalnymi: literówka w nazwie lub słowie kluczowym, zapomniany dwukropek, niedomknięte nawiasy, itp. &lt;br /&gt;
*Są bardziej podstępne błędy logiczne: gdy algorytm, którego zapisem ma być tworzony kod, po prostu nie robi dokładnie tego, co nam się wydaje. &lt;br /&gt;
*I w końcu są sytuacje wyjątkowe: gdy w toku pracy programu zachodzą nieoczekiwane okoliczności &amp;amp;mdash; użytkownik podał błędną nazwę pliku z danymi, zawartość tego pliku nie jest zgodna z oczekiwaniami programu, połączenie sieciowe ulega przerwaniu w trakcie pobierania lub przesyłania danych, itp. &lt;br /&gt;
&lt;br /&gt;
Wszystkie te sytuacje nazywa się wyjątkami, i tym samym słowem określa się mechanizm, jakiego wiele współczesnych języków programowania (w tym Python) dostarcza programiście, aby mu pomóc określić działania jakie program miałby podjąć w sytuacjach wyjątkowych. Wyjątkowość takich sytuacji generalnie polega na tym, że w przypadku ich wystąpienia program po prostu nie może kontynuować przewidzianego toku działania:&lt;br /&gt;
&lt;br /&gt;
*błąd w składni programu oznacza, że kod nie daje się zinterpretować w sposób jednoznaczny; najlepsze co można zrobić, to w momencie wykrycia błędu przerwać działanie i spróbować dostarczyć programiście (w formie komunikatu) informację ułatwiającą określenie i naprawienie błędu;&lt;br /&gt;
*błędne działanie algorytmu można np. spróbować wykrywać za pomocą tzw. asercji (polecenie ''assert'') badających, czy pewne warunki, jakie powinny być spełnione przez dane przetwarzane w programie są istotnie spełnione;&lt;br /&gt;
*wyjątki powstałe na skutek okoliczności zachodzących w trakcie działania programu, uniemożliwiających jego normalną kontynuację, można spróbować przewidzieć i przygotować program do odpowiedniego zareagowania, czyli ''obsługi wyjątku''. Na przykład, można spróbować ponowić jeszcze raz (lub kilka razy) próbę łączności sieciowej, i poddać się dopiero po określonej liczbie niepowodzeń; natomiast w sytuacji błędu wynikającego z podania przez użytkownika programu niewłaściwych argumentów uruchomienia, warto postarać się o przekazanie użytkownikowi komunikatu informującego go w sposób dla niego zrozumiały, o właściwym sposobie uruchamiania programu.&lt;br /&gt;
&lt;br /&gt;
=== Błędy składniowe i podobne ===&lt;br /&gt;
&lt;br /&gt;
Jak wspomniano powyżej, w przypadku napotkania błędu składniowego w kodzie programu interpreter natychmiast przerwie wykonywanie programu i wypisze komunikat. Komunikaty te '''warto czytać uważnie''' &amp;amp;mdash; w większości przypadków znajduje się w nich cała informacja konieczna dla naprawienia błędu. Przykład: usiłujemy uruchomić program &amp;lt;tt&amp;gt;błąd.py&amp;lt;/tt&amp;gt;, którego treść to&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
x = (2 + 3) 4&lt;br /&gt;
print x&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wynik pierwszej próby to:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=bash&amp;gt;&lt;br /&gt;
$ python3 błąd.py &lt;br /&gt;
  File &amp;quot;błąd.py&amp;quot;, line 1&lt;br /&gt;
    x = (2 + 3) 4&lt;br /&gt;
                ^&lt;br /&gt;
SyntaxError: invalid syntax&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Z komunikatu całkiem jasno wynika, że napotkany został błąd składni (''SyntaxError''), że wykryto ten błąd w linijce 1, a nawet dokładnie &amp;amp;mdash; że miejscem, w którym interpreter stwierdził, że ma do czynienia z nieprawidłowy kodem, było wystąpienie cyfry 4 po zamykającym nawiasie. Po prostu zapomnieliśmy, że &amp;amp;mdash; inaczej niż w powszechnie stosowanej notacji matematycznej &amp;amp;mdash; w Pythonie aby uzyskać mnożenie, konieczne jest napisanie jawnie znaku operatora (gwiazdki).&lt;br /&gt;
&lt;br /&gt;
Po naprawieniu tej pomyłki próbujemy jeszcze raz, i wynik to:&lt;br /&gt;
&amp;lt;source lang=bash&amp;gt;&lt;br /&gt;
$ python3 błąd.py &lt;br /&gt;
  File &amp;quot;błąd.py&amp;quot;, line 2&lt;br /&gt;
    print x&lt;br /&gt;
          ^&lt;br /&gt;
SyntaxError: Missing parentheses in call to 'print'. Did you mean print(x)?&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Tutaj już jaśniej być nie może; interpreter nie tylko wskazał nam dokładne miejsce wystąpienia błędu, ale nawet dokładnie opisał, jak go naprawić.&lt;br /&gt;
&lt;br /&gt;
Oczywiście nie zawsze interpreter będzie w stanie wskazać nam błąd aż tak precyzyjnie. Jako przykład weźmy następujący plik:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
x, y, z = 3, 4, 5&lt;br /&gt;
print(max(x, y, z)&lt;br /&gt;
print(X * y * z)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
i wynik jego uruchomienia:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=bash&amp;gt;&lt;br /&gt;
$ python3 błąd.py &lt;br /&gt;
  File &amp;quot;błąd.py&amp;quot;, line 3&lt;br /&gt;
    print(X * y * z)&lt;br /&gt;
        ^&lt;br /&gt;
SyntaxError: invalid syntax&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dlaczego został wytknięty błąd składniowy w linijce 3? Przecież to w linijce 2 zapomnieliśmy zamknąć jeden z nawiasów.&lt;br /&gt;
&lt;br /&gt;
Otóż jeżeli z końcem linii Python stwierdza, że nie wszystkie dotąd otwarte nawiasy zostały zamknięte, to traktuje to jako oznaczające, że kolejną linijkę należy potraktować jako ciąg dalszy bieżącej. I w tym przypadku dopiero napotykając w kolejnej linijce nazwę &amp;lt;tt&amp;gt;print&amp;lt;/tt&amp;gt; &amp;amp;mdash; a nie np. przecinek, albo nawias zamykający &amp;amp;mdash; stwierdza, że coś musi być nie tak. Miejsce wykrycia błędu niestety nie zawsze się będzie pokrywało z miejscem jego faktycznego wystąpienia.&lt;br /&gt;
&lt;br /&gt;
Po poprawce, czyli zamknięciu nawiasu na linii 2, próbujemy jeszcze raz &amp;amp;mdash; z wynikiem&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=bash&amp;gt;&lt;br /&gt;
python3 błąd.py &lt;br /&gt;
5&lt;br /&gt;
Traceback (most recent call last):&lt;br /&gt;
  File &amp;quot;błąd.py&amp;quot;, line 3, in &amp;lt;module&amp;gt;&lt;br /&gt;
    print(X * y * z)&lt;br /&gt;
NameError: name 'X' is not defined&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
I tym razem chyba jest wszystko jasne: pojawiła się nazwa &amp;lt;tt&amp;gt;X&amp;lt;/tt&amp;gt;, z którą wcześniej nie związano żadnej wartości. Po prostu przez pomyłkę napisaliśmy X wielką literą zamiast małą. &lt;br /&gt;
&lt;br /&gt;
Te przykłady pokazują, że przy wykorzystaniu treści wypisywanych komunikatów proces usunięcia z programu błędów składniowych i formalnych może być dość szybki i bezbolesny.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&lt;br /&gt;
Pojawiły się w komunikatach określenia: &amp;lt;tt&amp;gt;SyntaxError&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;NameError&amp;lt;/tt&amp;gt;. Są to przykłady nazw tzw. klas wyjątków, czyli ogólnie rozumianych kategorii błędów, jakie są sygnalizowane. Wkrótce spotkamy dalsze klasy wyjątków, takie jak: &amp;lt;tt&amp;gt;TypeError&amp;lt;/tt&amp;gt; - związana z przekazaniem wielkości niewłaściwego typu, czy &amp;lt;tt&amp;gt;ValueError&amp;lt;/tt&amp;gt; - gdy nie typ. ale wartość wielkości, na której usiłuje się operować, jest niewłaściwa dla danej operacji. Dowiemy się również, dlaczego klasy wyjątków są przydatne &amp;amp;mdash; pomimo tego, iż dla ludzkich oczu zwykle bardziej przydatna jest słowna informacja uszczegółowiająca (to co pojawia się po nazwie klasy wyjątku i dwukropku).&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Asercje ===&lt;br /&gt;
&lt;br /&gt;
Polecenie &amp;lt;tt&amp;gt;assert&amp;lt;/tt&amp;gt; ma następującą postać:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
assert wyrażenie1&lt;br /&gt;
# lub:&lt;br /&gt;
assert wyrażenie1, wyrażenie2&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
i jest to jak widać polecenie proste (nie zawierające bloku poleceń z wcięciem).&lt;br /&gt;
&lt;br /&gt;
Jego działanie jest takie, że: obliczona zostanie wartość &amp;lt;tt&amp;gt;wyrażenie1&amp;lt;/tt&amp;gt;; jeżeli jest ona prawdziwa, nie dzieje się nic (następuje natychmiastowe przejście do kolejnej linijki kodu). Jeżeli okaże się fałszywa, zostanie zasygnalizowany wyjątek, klasy &amp;lt;tt&amp;gt;AssertionError&amp;lt;/tt&amp;gt;, co domyślnie przerywa wykonywanie programu i powoduje wypisanie odpowiedniego komunikatu. Jeżeli zastosujemy drugą postać, obliczona zostanie również wartość &amp;lt;tt&amp;gt;wyrażenie2&amp;lt;/tt&amp;gt; i wypisana (dokładniej: jej reprezentacja napisowa) jako część komunikatu.&lt;br /&gt;
&lt;br /&gt;
Przyjęło się stosować asercje jako sposób kontroli poprawności działania programu &amp;amp;mdash; w tym sensie, aby wykluczyć sytuacje „niemożliwe&amp;quot;, tj. powstałe w wyniku błędu programisty. Ze względu na prostotę składni warto też z nich korzystać w kodzie służącym do testowania poprawności innego kodu (czyli np. w funkcjach testujących, czy inne, bardziej złożone funkcje dają poprawne wyniki w prostych sytuacjach próbnych).&lt;br /&gt;
&lt;br /&gt;
=== Wyjątki w trakcie pracy programu ===&lt;br /&gt;
&lt;br /&gt;
Wyjątki występujące w trakcie pracy programu można przechwycić i obsłużyć za pomocą następującej konstrukcji (polecenia złożonego):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
try:&lt;br /&gt;
    # operacje mogące spowodować wyjątek&lt;br /&gt;
except (KlasaWyjątku1, KlasaWyjątku2, ...):&lt;br /&gt;
    # co zrobić jeśli wyjątek jednej z tych klas wystąpił&lt;br /&gt;
else: &lt;br /&gt;
    # co zrobić jeśli nie było wyjątku&lt;br /&gt;
finally:&lt;br /&gt;
    # co zrobić w KAŻDYM przypadku&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*bloki &amp;lt;tt&amp;gt;else:&amp;lt;/tt&amp;gt; i &amp;lt;tt&amp;gt;finally:&amp;lt;/tt&amp;gt; są nieobowiązkowe, tj. możemy je pominąć (wraz z odp. linijką wprowadzającą)&lt;br /&gt;
*w bloku &amp;lt;tt&amp;gt;except:&amp;lt;/tt&amp;gt; można podać jedną klasę wyjątku (wtedy zbędne są nawiasy), lub żadnej &amp;amp;mdash; wtedy przechwycimy ''każdy'' wyjątek; jeśli jednak chcemy, jak w przykładzie, wymienić więcej niż jedną klasę, to nawiasy są konieczne&lt;br /&gt;
*skuteczne przechwycenie wyjątku sprawia, że wykonanie programu nie ulegnie przerwaniu w punkcie jego wystąpienia, tyko będzie kontynuowane, również po opuszczeniu bloku &amp;lt;tt&amp;gt;try:&amp;lt;/tt&amp;gt;&lt;br /&gt;
*można jednak spowodować, aby po wykonaniu czynności obsługi wyjątku, wyjątek został niejako ''wznowiony''; wystarczy w bloku &amp;lt;tt&amp;gt;except:&amp;lt;/tt&amp;gt; wywołać instrukcję &amp;lt;tt&amp;gt;raise&amp;lt;/tt&amp;gt;. Dla większości klas wyjątków skutkuje to zakończeniem programu&lt;br /&gt;
*instrukcję &amp;lt;tt&amp;gt;raise&amp;lt;/tt&amp;gt; można wywołać również w dowolnym innym punkcie programu, powinna wówczas w niej wystąpić nazwa klasy wyjątku, jaki chcemy wywołać. &lt;br /&gt;
&lt;br /&gt;
Przykłady:&lt;br /&gt;
&lt;br /&gt;
''CDN.''&lt;br /&gt;
&lt;br /&gt;
== Trochę więcej o klasach i obiektach ==&lt;br /&gt;
&lt;br /&gt;
Warto sobie zdawać sprawę, że każda wartość występująca w programie pythonowym jest obiektem &amp;amp;mdash; a więc jest wyposażona w zestaw atrybutów i metod. Dotyczy to nie tylko kolekcji (list, słowników, ...), obiektów takich jak otwarte pliki (wynik wywołania funkcji &amp;lt;tt&amp;gt;open()&amp;lt;/tt&amp;gt;), napisów &amp;amp;mdash; ale również np. liczb, czy to całkowitych, czy zmiennoprzecinkowych (i zespolonych, o których nie było tutaj mowy). &lt;br /&gt;
&lt;br /&gt;
Przykładowo:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
(17).bit_length()&lt;br /&gt;
→ 5&lt;br /&gt;
(17).bit_count()&lt;br /&gt;
→ 2&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Co to właściwie znaczy?&lt;br /&gt;
&lt;br /&gt;
Dla liczby 17 wywołaliśmy najpierw metodę, który mówi nam jaka jest długość w bitach reprezentacji dwójkowej tej liczby (&amp;lt;tt&amp;gt;17 == 0b10001&amp;lt;/tt&amp;gt;), a następnie metodę, zwracającą liczbę ''ustawionych'' (tj. równych jeden) bitów w tej reprezentacji. Nawiasy okrągłe są konieczne, ponieważ kropka po cyfrach oznaczałaby, że mamy do czynienia z zapisem liczby zmiennoprzecinkowej. Inaczej mówiąc, byłyby niepotrzebne gdybyśmy mieli do czynienia z nazwą oznaczającą liczbę całkowitą, a nie z jej zapisem dziesiętnym.&lt;br /&gt;
&lt;br /&gt;
Każdy obiekt w Pythonie jest ''instancją'' pewnej ''klasy''. Przykłady klas to: &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt; (liczby całkowite), &amp;lt;tt&amp;gt;str&amp;lt;/tt&amp;gt; (napisy), &amp;lt;tt&amp;gt;list&amp;lt;/tt&amp;gt; (listy), &amp;lt;tt&amp;gt;bool&amp;lt;/tt&amp;gt; (wartości logiczne), i wiele innych. Klasa to inaczej typ obiektów; charakteryzuje ona zestaw atrybutów i metod związanych z obiektami danej klasy.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&amp;lt;small&amp;gt;&lt;br /&gt;
Zazwyczaj różnych obiektów będących instancjami danej klasy może być wiele, potencjalnie nieskończenie wiele. Są jednak wyjątki. Np. klasa &amp;lt;tt&amp;gt;bool&amp;lt;/tt&amp;gt; posiada jedynie dwie instancje: (&amp;lt;tt&amp;gt;True&amp;lt;/tt&amp;gt; i &amp;lt;tt&amp;gt;False&amp;lt;/tt&amp;gt;). A obiekt &amp;lt;tt&amp;gt;None&amp;lt;/tt&amp;gt; jest wręcz jedyną instancją swojej klasy.&lt;br /&gt;
&amp;lt;/small&amp;gt;&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Niektóre klasy są ,,szczególnymi przypadkami&amp;quot; innych klas &amp;amp;mdash; mówi się, że klasa C ''dziedziczy'' z klasy B, lub że jest ''podklasą'' klasy B. Oznacza to tyle, że instancje klasy C posiadają wszystkie atrybuty i metody jakie posiadają instancje klasy B, ale być może pewne dodatkowe &amp;amp;mdash; a być może niektóre z nich zostały w jakiś sposób zmodyfikowane. Przykładowo, klasa &amp;lt;tt&amp;gt;bool&amp;lt;/tt&amp;gt; stanowi podklasę klasy &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;; jej jedyne instancje, &amp;lt;tt&amp;gt;True&amp;lt;/tt&amp;gt; i &amp;lt;tt&amp;gt;False&amp;lt;/tt&amp;gt;, to ,,tak naprawdę&amp;quot; liczby (odpowiednio) 1 i 0 ,,w przebraniu&amp;quot;. Są one więc również instancjami klasy &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt; i można do nich stosować te same operacje (np. arytmetyczne) co do liczb całkowitych.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&amp;lt;small&amp;gt;&lt;br /&gt;
Jeszcze inaczej: jeżeli klasa C jest podklasą klasy B, to każda instancja klasy C jest zarazem instancją klasy B &amp;amp;mdash; można to sprawdzić za pomocą funkcji &amp;lt;tt&amp;gt;isinstance(obiekt, klasa)&amp;lt;/tt&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Same klasy są również obiektami, instancjami klasy o nazwie &amp;lt;tt&amp;gt;type&amp;lt;/tt&amp;gt;. Wywołana jako funkcja, &amp;lt;tt&amp;gt;type(obiekt)&amp;lt;/tt&amp;gt; zwraca klasę danego obiektu.&lt;br /&gt;
&amp;lt;/small&amp;gt;&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Poza tym,że Python posiada całkiem sporo klas, czyli typów obiektów, wbudowanych &amp;amp;mdash; sporą część z nich, chociaż nie wszystkie, omówiliśmy w poprzednich rozdziałach &amp;amp;mdash; to jest wiele dalszych klas zdefiniowanych w bibliotece standardowej, do których można uzyskać dostęp importując odpowiednie moduły; oczywiście jest też bogactwo modułów i bibliotek poza biblioteką standardową. Większość z nich można znaleźć w dedykowanym ,,magazynie&amp;quot;, https://pypi.org/.  Pisząc kod w Pythonie można również definiować własne klasy; temat ten został pominięty w tym wstępnym kursie, ale na pewno zasługuje on na pierwsze miejsce w jego dalszym ciągu, kursie dla średnio zaawansowanych.&lt;br /&gt;
&lt;br /&gt;
''CDN''&lt;br /&gt;
&lt;br /&gt;
== O generatorach ==&lt;br /&gt;
&lt;br /&gt;
W jednym z poprzednich rozdziałów [[PPy3/Kolekcje#Przyk.C5.82ad:_suma_cyfr|poznaliśmy wyrażenia generatorowe]]. Przypomnijmy, że stanowią one uproszczony zapis iteracji, pozwalający na uniknięcie w wielu prostych przypadkach pętli &amp;lt;tt&amp;gt;for&amp;lt;/tt&amp;gt; i tworzenia zmiennych pomocniczych. Przykładowo:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;source lang=python&amp;gt;&lt;br /&gt;
 kwadraty = (x**2 for x in range(100))&lt;br /&gt;
 &amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
tworzy generator, ''produkujący'' w iteracji kwadraty kolejnych liczb naturalnych (od 0 do 99). &lt;br /&gt;
&lt;br /&gt;
Poważnym ograniczeniem wyrażeń generatorowych jest to, że można ich używać do przekształcenia jednego obiektu iterowalnego w drugi &amp;amp;mdash; w tym przypadku, ciągu liczb naturalnych w ciąg ich kwadratów, natomiast nie ma jak za pomocą wyrażenia generatorowego stworzyć obiektu iterowalnego ,,od zera&amp;quot;. Można to uzyskać, stosując ogólniejszą konstrukcję:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;source lang=python&amp;gt;&lt;br /&gt;
 def gen_kwadraty(start=0):&lt;br /&gt;
     k = start&lt;br /&gt;
     while True:&lt;br /&gt;
         yield k**2&lt;br /&gt;
         k += 1&lt;br /&gt;
&lt;br /&gt;
 kwadraty = gen_kwadraty()&lt;br /&gt;
 &amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To, co napisałem powyżej przypomina bardzo definicję funkcji; jedyną różnicą na poziomie składni jest wystąpienie w definicji słowa &amp;lt;tt&amp;gt;yield&amp;lt;/tt&amp;gt; (i brak wystąpienia słowa &amp;lt;tt&amp;gt;return&amp;lt;/tt&amp;gt;). W istocie &amp;lt;tt&amp;gt;gen_kwadraty&amp;lt;/tt&amp;gt; można uważać za funkcję &amp;amp;mdash; której wywołanie zwraca generator: obiekt, którego iteracja dostarczy kwadratów kolejnych liczb naturalnych, począwszy od liczby &amp;lt;tt&amp;gt;start&amp;lt;/tt&amp;gt;, argumentu wywołania, o domyślnej wartości zero. Zauważmy, że w budowie definicji nie użyliśmy obiektu &amp;lt;tt&amp;gt;range&amp;lt;/tt&amp;gt;; użyliśmy za to jawnej pętli &amp;lt;tt&amp;gt;while&amp;lt;/tt&amp;gt;, niejako opakowując ją w generator. Co więc w ten sposób zyskujemy?&lt;br /&gt;
&lt;br /&gt;
Przede wszystkim wielką elastyczność. W pokazanym przykładzie zysk jest niewielki, ale w definicji generatora możemy użyć jakiejkolwiek bądź reguły tworzenia kolejnych elementów iteracji. Nie potrzebujemy utworzyć ich wszystkich zanim zaczniemy z nich korzystać &amp;amp;mdash; tak jak byłoby w przypadku, gdybyśmy &amp;lt;tt&amp;gt;gen_kwadraty&amp;lt;/tt&amp;gt; zdefiniowali jako funkcję zwracającą listę kwadratów kolejnych liczb. Co więcej, iteracja zapewniona przez &amp;lt;tt&amp;gt;gen_kwadraty&amp;lt;/tt&amp;gt; może nam dostarczyć dowolnie wielu elementów (oczywiście w realnym komputerze po dostatecznie długim czasie osiągnięto by liczby, których wielkość przekroczyłaby pojemność dostępnej pamięci operacyjnej). Decyzja o tym, kiedy przerwać iterację pozostawiona jest ,,użytkownikowi&amp;quot;, tzn. kodowi odwołującemu się do obiektu &amp;lt;tt&amp;gt;kwadraty&amp;lt;/tt&amp;gt;.  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
[[PPy3/Matplotlib|poprzednie]] | [[&amp;quot;Programowanie z Pythonem3&amp;quot;|strona główna]] | [[PPy3/DobrePraktyki|dalej]]&lt;br /&gt;
&lt;br /&gt;
--[[Użytkownik:RobertJB|RobertJB]] ([[Dyskusja użytkownika:RobertJB|dyskusja]]) 14:26, 27 mar 2018 (CEST)&lt;/div&gt;</summary>
		<author><name>RobertJB</name></author>
		
	</entry>
	<entry>
		<id>http://brain.fuw.edu.pl/edu/index.php?title=PPy3/TematyDodatkowe&amp;diff=9474</id>
		<title>PPy3/TematyDodatkowe</title>
		<link rel="alternate" type="text/html" href="http://brain.fuw.edu.pl/edu/index.php?title=PPy3/TematyDodatkowe&amp;diff=9474"/>
		<updated>2023-06-30T10:53:44Z</updated>

		<summary type="html">&lt;p&gt;RobertJB: /* Trochę więcej o klasach i obiektach */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Tematy dodatkowe =&lt;br /&gt;
&lt;br /&gt;
== Błędy i wyjątki ==&lt;br /&gt;
&lt;br /&gt;
Każdy programista popełnia błędy &amp;amp;mdash; jest to nieunikniona część tej działalności. &lt;br /&gt;
&lt;br /&gt;
*Są błędy, które można nazwać banalnymi: literówka w nazwie lub słowie kluczowym, zapomniany dwukropek, niedomknięte nawiasy, itp. &lt;br /&gt;
*Są bardziej podstępne błędy logiczne: gdy algorytm, którego zapisem ma być tworzony kod, po prostu nie robi dokładnie tego, co nam się wydaje. &lt;br /&gt;
*I w końcu są sytuacje wyjątkowe: gdy w toku pracy programu zachodzą nieoczekiwane okoliczności &amp;amp;mdash; użytkownik podał błędną nazwę pliku z danymi, zawartość tego pliku nie jest zgodna z oczekiwaniami programu, połączenie sieciowe ulega przerwaniu w trakcie pobierania lub przesyłania danych, itp. &lt;br /&gt;
&lt;br /&gt;
Wszystkie te sytuacje nazywa się wyjątkami, i tym samym słowem określa się mechanizm, jakiego wiele współczesnych języków programowania (w tym Python) dostarcza programiście, aby mu pomóc określić działania jakie program miałby podjąć w sytuacjach wyjątkowych. Wyjątkowość takich sytuacji generalnie polega na tym, że w przypadku ich wystąpienia program po prostu nie może kontynuować przewidzianego toku działania:&lt;br /&gt;
&lt;br /&gt;
*błąd w składni programu oznacza, że kod nie daje się zinterpretować w sposób jednoznaczny; najlepsze co można zrobić, to w momencie wykrycia błędu przerwać działanie i spróbować dostarczyć programiście (w formie komunikatu) informację ułatwiającą określenie i naprawienie błędu;&lt;br /&gt;
*błędne działanie algorytmu można np. spróbować wykrywać za pomocą tzw. asercji (polecenie ''assert'') badających, czy pewne warunki, jakie powinny być spełnione przez dane przetwarzane w programie są istotnie spełnione;&lt;br /&gt;
*wyjątki powstałe na skutek okoliczności zachodzących w trakcie działania programu, uniemożliwiających jego normalną kontynuację, można spróbować przewidzieć i przygotować program do odpowiedniego zareagowania, czyli ''obsługi wyjątku''. Na przykład, można spróbować ponowić jeszcze raz (lub kilka razy) próbę łączności sieciowej, i poddać się dopiero po określonej liczbie niepowodzeń; natomiast w sytuacji błędu wynikającego z podania przez użytkownika programu niewłaściwych argumentów uruchomienia, warto postarać się o przekazanie użytkownikowi komunikatu informującego go w sposób dla niego zrozumiały, o właściwym sposobie uruchamiania programu.&lt;br /&gt;
&lt;br /&gt;
=== Błędy składniowe i podobne ===&lt;br /&gt;
&lt;br /&gt;
Jak wspomniano powyżej, w przypadku napotkania błędu składniowego w kodzie programu interpreter natychmiast przerwie wykonywanie programu i wypisze komunikat. Komunikaty te '''warto czytać uważnie''' &amp;amp;mdash; w większości przypadków znajduje się w nich cała informacja konieczna dla naprawienia błędu. Przykład: usiłujemy uruchomić program &amp;lt;tt&amp;gt;błąd.py&amp;lt;/tt&amp;gt;, którego treść to&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
x = (2 + 3) 4&lt;br /&gt;
print x&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wynik pierwszej próby to:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=bash&amp;gt;&lt;br /&gt;
$ python3 błąd.py &lt;br /&gt;
  File &amp;quot;błąd.py&amp;quot;, line 1&lt;br /&gt;
    x = (2 + 3) 4&lt;br /&gt;
                ^&lt;br /&gt;
SyntaxError: invalid syntax&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Z komunikatu całkiem jasno wynika, że napotkany został błąd składni (''SyntaxError''), że wykryto ten błąd w linijce 1, a nawet dokładnie &amp;amp;mdash; że miejscem, w którym interpreter stwierdził, że ma do czynienia z nieprawidłowy kodem, było wystąpienie cyfry 4 po zamykającym nawiasie. Po prostu zapomnieliśmy, że &amp;amp;mdash; inaczej niż w powszechnie stosowanej notacji matematycznej &amp;amp;mdash; w Pythonie aby uzyskać mnożenie, konieczne jest napisanie jawnie znaku operatora (gwiazdki).&lt;br /&gt;
&lt;br /&gt;
Po naprawieniu tej pomyłki próbujemy jeszcze raz, i wynik to:&lt;br /&gt;
&amp;lt;source lang=bash&amp;gt;&lt;br /&gt;
$ python3 błąd.py &lt;br /&gt;
  File &amp;quot;błąd.py&amp;quot;, line 2&lt;br /&gt;
    print x&lt;br /&gt;
          ^&lt;br /&gt;
SyntaxError: Missing parentheses in call to 'print'. Did you mean print(x)?&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Tutaj już jaśniej być nie może; interpreter nie tylko wskazał nam dokładne miejsce wystąpienia błędu, ale nawet dokładnie opisał, jak go naprawić.&lt;br /&gt;
&lt;br /&gt;
Oczywiście nie zawsze interpreter będzie w stanie wskazać nam błąd aż tak precyzyjnie. Jako przykład weźmy następujący plik:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
x, y, z = 3, 4, 5&lt;br /&gt;
print(max(x, y, z)&lt;br /&gt;
print(X * y * z)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
i wynik jego uruchomienia:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=bash&amp;gt;&lt;br /&gt;
$ python3 błąd.py &lt;br /&gt;
  File &amp;quot;błąd.py&amp;quot;, line 3&lt;br /&gt;
    print(X * y * z)&lt;br /&gt;
        ^&lt;br /&gt;
SyntaxError: invalid syntax&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dlaczego został wytknięty błąd składniowy w linijce 3? Przecież to w linijce 2 zapomnieliśmy zamknąć jeden z nawiasów.&lt;br /&gt;
&lt;br /&gt;
Otóż jeżeli z końcem linii Python stwierdza, że nie wszystkie dotąd otwarte nawiasy zostały zamknięte, to traktuje to jako oznaczające, że kolejną linijkę należy potraktować jako ciąg dalszy bieżącej. I w tym przypadku dopiero napotykając w kolejnej linijce nazwę &amp;lt;tt&amp;gt;print&amp;lt;/tt&amp;gt; &amp;amp;mdash; a nie np. przecinek, albo nawias zamykający &amp;amp;mdash; stwierdza, że coś musi być nie tak. Miejsce wykrycia błędu niestety nie zawsze się będzie pokrywało z miejscem jego faktycznego wystąpienia.&lt;br /&gt;
&lt;br /&gt;
Po poprawce, czyli zamknięciu nawiasu na linii 2, próbujemy jeszcze raz &amp;amp;mdash; z wynikiem&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=bash&amp;gt;&lt;br /&gt;
python3 błąd.py &lt;br /&gt;
5&lt;br /&gt;
Traceback (most recent call last):&lt;br /&gt;
  File &amp;quot;błąd.py&amp;quot;, line 3, in &amp;lt;module&amp;gt;&lt;br /&gt;
    print(X * y * z)&lt;br /&gt;
NameError: name 'X' is not defined&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
I tym razem chyba jest wszystko jasne: pojawiła się nazwa &amp;lt;tt&amp;gt;X&amp;lt;/tt&amp;gt;, z którą wcześniej nie związano żadnej wartości. Po prostu przez pomyłkę napisaliśmy X wielką literą zamiast małą. &lt;br /&gt;
&lt;br /&gt;
Te przykłady pokazują, że przy wykorzystaniu treści wypisywanych komunikatów proces usunięcia z programu błędów składniowych i formalnych może być dość szybki i bezbolesny.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&lt;br /&gt;
Pojawiły się w komunikatach określenia: &amp;lt;tt&amp;gt;SyntaxError&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;NameError&amp;lt;/tt&amp;gt;. Są to przykłady nazw tzw. klas wyjątków, czyli ogólnie rozumianych kategorii błędów, jakie są sygnalizowane. Wkrótce spotkamy dalsze klasy wyjątków, takie jak: &amp;lt;tt&amp;gt;TypeError&amp;lt;/tt&amp;gt; - związana z przekazaniem wielkości niewłaściwego typu, czy &amp;lt;tt&amp;gt;ValueError&amp;lt;/tt&amp;gt; - gdy nie typ. ale wartość wielkości, na której usiłuje się operować, jest niewłaściwa dla danej operacji. Dowiemy się również, dlaczego klasy wyjątków są przydatne &amp;amp;mdash; pomimo tego, iż dla ludzkich oczu zwykle bardziej przydatna jest słowna informacja uszczegółowiająca (to co pojawia się po nazwie klasy wyjątku i dwukropku).&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Asercje ===&lt;br /&gt;
&lt;br /&gt;
Polecenie &amp;lt;tt&amp;gt;assert&amp;lt;/tt&amp;gt; ma następującą postać:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
assert wyrażenie1&lt;br /&gt;
# lub:&lt;br /&gt;
assert wyrażenie1, wyrażenie2&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
i jest to jak widać polecenie proste (nie zawierające bloku poleceń z wcięciem).&lt;br /&gt;
&lt;br /&gt;
Jego działanie jest takie, że: obliczona zostanie wartość &amp;lt;tt&amp;gt;wyrażenie1&amp;lt;/tt&amp;gt;; jeżeli jest ona prawdziwa, nie dzieje się nic (następuje natychmiastowe przejście do kolejnej linijki kodu). Jeżeli okaże się fałszywa, zostanie zasygnalizowany wyjątek, klasy &amp;lt;tt&amp;gt;AssertionError&amp;lt;/tt&amp;gt;, co domyślnie przerywa wykonywanie programu i powoduje wypisanie odpowiedniego komunikatu. Jeżeli zastosujemy drugą postać, obliczona zostanie również wartość &amp;lt;tt&amp;gt;wyrażenie2&amp;lt;/tt&amp;gt; i wypisana (dokładniej: jej reprezentacja napisowa) jako część komunikatu.&lt;br /&gt;
&lt;br /&gt;
Przyjęło się stosować asercje jako sposób kontroli poprawności działania programu &amp;amp;mdash; w tym sensie, aby wykluczyć sytuacje „niemożliwe&amp;quot;, tj. powstałe w wyniku błędu programisty. Ze względu na prostotę składni warto też z nich korzystać w kodzie służącym do testowania poprawności innego kodu (czyli np. w funkcjach testujących, czy inne, bardziej złożone funkcje dają poprawne wyniki w prostych sytuacjach próbnych).&lt;br /&gt;
&lt;br /&gt;
=== Wyjątki w trakcie pracy programu ===&lt;br /&gt;
&lt;br /&gt;
Wyjątki występujące w trakcie pracy programu można przechwycić i obsłużyć za pomocą następującej konstrukcji (polecenia złożonego):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
try:&lt;br /&gt;
    # operacje mogące spowodować wyjątek&lt;br /&gt;
except (KlasaWyjątku1, KlasaWyjątku2, ...):&lt;br /&gt;
    # co zrobić jeśli wyjątek jednej z tych klas wystąpił&lt;br /&gt;
else: &lt;br /&gt;
    # co zrobić jeśli nie było wyjątku&lt;br /&gt;
finally:&lt;br /&gt;
    # co zrobić w KAŻDYM przypadku&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*bloki &amp;lt;tt&amp;gt;else:&amp;lt;/tt&amp;gt; i &amp;lt;tt&amp;gt;finally:&amp;lt;/tt&amp;gt; są nieobowiązkowe, tj. możemy je pominąć (wraz z odp. linijką wprowadzającą)&lt;br /&gt;
*w bloku &amp;lt;tt&amp;gt;except:&amp;lt;/tt&amp;gt; można podać jedną klasę wyjątku (wtedy zbędne są nawiasy), lub żadnej &amp;amp;mdash; wtedy przechwycimy ''każdy'' wyjątek; jeśli jednak chcemy, jak w przykładzie, wymienić więcej niż jedną klasę, to nawiasy są konieczne&lt;br /&gt;
*skuteczne przechwycenie wyjątku sprawia, że wykonanie programu nie ulegnie przerwaniu w punkcie jego wystąpienia, tyko będzie kontynuowane, również po opuszczeniu bloku &amp;lt;tt&amp;gt;try:&amp;lt;/tt&amp;gt;&lt;br /&gt;
*można jednak spowodować, aby po wykonaniu czynności obsługi wyjątku, wyjątek został niejako ''wznowiony''; wystarczy w bloku &amp;lt;tt&amp;gt;except:&amp;lt;/tt&amp;gt; wywołać instrukcję &amp;lt;tt&amp;gt;raise&amp;lt;/tt&amp;gt;. Dla większości klas wyjątków skutkuje to zakończeniem programu&lt;br /&gt;
*instrukcję &amp;lt;tt&amp;gt;raise&amp;lt;/tt&amp;gt; można wywołać również w dowolnym innym punkcie programu, powinna wówczas w niej wystąpić nazwa klasy wyjątku, jaki chcemy wywołać. &lt;br /&gt;
&lt;br /&gt;
Przykłady:&lt;br /&gt;
&lt;br /&gt;
''CDN.''&lt;br /&gt;
&lt;br /&gt;
== Trochę więcej o klasach i obiektach ==&lt;br /&gt;
&lt;br /&gt;
Warto sobie zdawać sprawę, że każda wartość występująca w programie pythonowym jest obiektem &amp;amp;mdash; a więc jest wyposażona w zestaw atrybutów i metod. Dotyczy to nie tylko kolekcji (list, słowników, ...), obiektów takich jak otwarte pliki (wynik wywołania funkcji &amp;lt;tt&amp;gt;open()&amp;lt;/tt&amp;gt;), napisów &amp;amp;mdash; ale również np. liczb, czy to całkowitych, czy zmiennoprzecinkowych (i zespolonych, o których nie było tutaj mowy). &lt;br /&gt;
&lt;br /&gt;
Przykładowo:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
(17).bit_length()&lt;br /&gt;
→ 5&lt;br /&gt;
(17).bit_count()&lt;br /&gt;
→ 2&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Co to właściwie znaczy?&lt;br /&gt;
&lt;br /&gt;
Dla liczby 17 wywołaliśmy najpierw metodę, który mówi nam jaka jest długość w bitach reprezentacji dwójkowej tej liczby (&amp;lt;tt&amp;gt;17 == 0b10001&amp;lt;/tt&amp;gt;), a następnie metodę, zwracającą liczbę ''ustawionych'' (tj. równych jeden) bitów w tej reprezentacji. Nawiasy okrągłe są konieczne, ponieważ kropka po cyfrach oznaczałaby, że mamy do czynienia z zapisem liczby zmiennoprzecinkowej. Inaczej mówiąc, byłyby niepotrzebne gdybyśmy mieli do czynienia z nazwą oznaczającą liczbę całkowitą, a nie z jej zapisem dziesiętnym.&lt;br /&gt;
&lt;br /&gt;
Każdy obiekt w Pythonie jest ''instancją'' pewnej ''klasy''. Przykłady klas to: &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt; (liczby całkowite), &amp;lt;tt&amp;gt;str&amp;lt;/tt&amp;gt; (napisy), &amp;lt;tt&amp;gt;list&amp;lt;/tt&amp;gt; (listy), &amp;lt;tt&amp;gt;bool&amp;lt;/tt&amp;gt; (wartości logiczne), i wiele innych. Klasa to inaczej typ obiektów; charakteryzuje ona zestaw atrybutów i metod związanych z obiektami danej klasy.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&amp;lt;small&amp;gt;&lt;br /&gt;
Zazwyczaj różnych obiektów będących instancjami danej klasy może być wiele, potencjalnie nieskończenie wiele. Są jednak wyjątki. Np. klasa &amp;lt;tt&amp;gt;bool&amp;lt;/tt&amp;gt; posiada jedynie dwie instancje: (&amp;lt;tt&amp;gt;True&amp;lt;/tt&amp;gt; i &amp;lt;tt&amp;gt;False&amp;lt;/tt&amp;gt;). A obiekt &amp;lt;tt&amp;gt;None&amp;lt;/tt&amp;gt; jest wręcz jedyną instancją swojej klasy.&lt;br /&gt;
&amp;lt;/small&amp;gt;&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Niektóre klasy są ,,szczególnymi przypadkami&amp;quot; innych klas &amp;amp;mdash; mówi się, że klasa C ''dziedziczy'' z klasy B, lub że jest ''podklasą'' klasy B. Oznacza to tyle, że instancje klasy C posiadają wszystkie atrybuty i metody jakie posiadają instancje klasy B, ale być może pewne dodatkowe &amp;amp;mdash; a być może niektóre z nich zostały w jakiś sposób zmodyfikowane. Przykładowo, klasa &amp;lt;tt&amp;gt;bool&amp;lt;/tt&amp;gt; stanowi podklasę klasy &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;; jej jedyne instancje, &amp;lt;tt&amp;gt;True&amp;lt;/tt&amp;gt; i &amp;lt;tt&amp;gt;False&amp;lt;/tt&amp;gt;, to ,,tak naprawdę&amp;quot; liczby (odpowiednio) 1 i 0 ,,w przebraniu&amp;quot;. Są one więc również instancjami klasy &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt; i można do nich stosować te same operacje (np. arytmetyczne) co do liczb całkowitych.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&amp;lt;small&amp;gt;&lt;br /&gt;
Jeszcze inaczej: jeżeli klasa C jest podklasą klasy B, to każda instancja klasy C jest zarazem instancją klasy B &amp;amp;mdash; można to sprawdzić za pomocą funkcji &amp;lt;tt&amp;gt;isinstance(obiekt, klasa)&amp;lt;/tt&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Same klasy są również obiektami, instancjami klasy o nazwie &amp;lt;tt&amp;gt;type&amp;lt;/tt&amp;gt;. Wywołana jako funkcja, &amp;lt;tt&amp;gt;type(obiekt)&amp;lt;/tt&amp;gt; zwraca klasę danego obiektu.&lt;br /&gt;
&amp;lt;/small&amp;gt;&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
''CDN''&lt;br /&gt;
&lt;br /&gt;
== O generatorach ==&lt;br /&gt;
&lt;br /&gt;
W jednym z poprzednich rozdziałów [[PPy3/Kolekcje#Przyk.C5.82ad:_suma_cyfr|poznaliśmy wyrażenia generatorowe]]. Przypomnijmy, że stanowią one uproszczony zapis iteracji, pozwalający na uniknięcie w wielu prostych przypadkach pętli &amp;lt;tt&amp;gt;for&amp;lt;/tt&amp;gt; i tworzenia zmiennych pomocniczych. Przykładowo:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;source lang=python&amp;gt;&lt;br /&gt;
 kwadraty = (x**2 for x in range(100))&lt;br /&gt;
 &amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
tworzy generator, ''produkujący'' w iteracji kwadraty kolejnych liczb naturalnych (od 0 do 99). &lt;br /&gt;
&lt;br /&gt;
Poważnym ograniczeniem wyrażeń generatorowych jest to, że można ich używać do przekształcenia jednego obiektu iterowalnego w drugi &amp;amp;mdash; w tym przypadku, ciągu liczb naturalnych w ciąg ich kwadratów, natomiast nie ma jak za pomocą wyrażenia generatorowego stworzyć obiektu iterowalnego ,,od zera&amp;quot;. Można to uzyskać, stosując ogólniejszą konstrukcję:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;source lang=python&amp;gt;&lt;br /&gt;
 def gen_kwadraty(start=0):&lt;br /&gt;
     k = start&lt;br /&gt;
     while True:&lt;br /&gt;
         yield k**2&lt;br /&gt;
         k += 1&lt;br /&gt;
&lt;br /&gt;
 kwadraty = gen_kwadraty()&lt;br /&gt;
 &amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To, co napisałem powyżej przypomina bardzo definicję funkcji; jedyną różnicą na poziomie składni jest wystąpienie w definicji słowa &amp;lt;tt&amp;gt;yield&amp;lt;/tt&amp;gt; (i brak wystąpienia słowa &amp;lt;tt&amp;gt;return&amp;lt;/tt&amp;gt;). W istocie &amp;lt;tt&amp;gt;gen_kwadraty&amp;lt;/tt&amp;gt; można uważać za funkcję &amp;amp;mdash; której wywołanie zwraca generator: obiekt, którego iteracja dostarczy kwadratów kolejnych liczb naturalnych, począwszy od liczby &amp;lt;tt&amp;gt;start&amp;lt;/tt&amp;gt;, argumentu wywołania, o domyślnej wartości zero. Zauważmy, że w budowie definicji nie użyliśmy obiektu &amp;lt;tt&amp;gt;range&amp;lt;/tt&amp;gt;; użyliśmy za to jawnej pętli &amp;lt;tt&amp;gt;while&amp;lt;/tt&amp;gt;, niejako opakowując ją w generator. Co więc w ten sposób zyskujemy?&lt;br /&gt;
&lt;br /&gt;
Przede wszystkim wielką elastyczność. W pokazanym przykładzie zysk jest niewielki, ale w definicji generatora możemy użyć jakiejkolwiek bądź reguły tworzenia kolejnych elementów iteracji. Nie potrzebujemy utworzyć ich wszystkich zanim zaczniemy z nich korzystać &amp;amp;mdash; tak jak byłoby w przypadku, gdybyśmy &amp;lt;tt&amp;gt;gen_kwadraty&amp;lt;/tt&amp;gt; zdefiniowali jako funkcję zwracającą listę kwadratów kolejnych liczb. Co więcej, iteracja zapewniona przez &amp;lt;tt&amp;gt;gen_kwadraty&amp;lt;/tt&amp;gt; może nam dostarczyć dowolnie wielu elementów (oczywiście w realnym komputerze po dostatecznie długim czasie osiągnięto by liczby, których wielkość przekroczyłaby pojemność dostępnej pamięci operacyjnej). Decyzja o tym, kiedy przerwać iterację pozostawiona jest ,,użytkownikowi&amp;quot;, tzn. kodowi odwołującemu się do obiektu &amp;lt;tt&amp;gt;kwadraty&amp;lt;/tt&amp;gt;.  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
[[PPy3/Matplotlib|poprzednie]] | [[&amp;quot;Programowanie z Pythonem3&amp;quot;|strona główna]] | [[PPy3/DobrePraktyki|dalej]]&lt;br /&gt;
&lt;br /&gt;
--[[Użytkownik:RobertJB|RobertJB]] ([[Dyskusja użytkownika:RobertJB|dyskusja]]) 14:26, 27 mar 2018 (CEST)&lt;/div&gt;</summary>
		<author><name>RobertJB</name></author>
		
	</entry>
	<entry>
		<id>http://brain.fuw.edu.pl/edu/index.php?title=PPy3/TematyDodatkowe&amp;diff=9473</id>
		<title>PPy3/TematyDodatkowe</title>
		<link rel="alternate" type="text/html" href="http://brain.fuw.edu.pl/edu/index.php?title=PPy3/TematyDodatkowe&amp;diff=9473"/>
		<updated>2023-06-29T12:32:01Z</updated>

		<summary type="html">&lt;p&gt;RobertJB: /* Trochę więcej o klasach i obiektach */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Tematy dodatkowe =&lt;br /&gt;
&lt;br /&gt;
== Błędy i wyjątki ==&lt;br /&gt;
&lt;br /&gt;
Każdy programista popełnia błędy &amp;amp;mdash; jest to nieunikniona część tej działalności. &lt;br /&gt;
&lt;br /&gt;
*Są błędy, które można nazwać banalnymi: literówka w nazwie lub słowie kluczowym, zapomniany dwukropek, niedomknięte nawiasy, itp. &lt;br /&gt;
*Są bardziej podstępne błędy logiczne: gdy algorytm, którego zapisem ma być tworzony kod, po prostu nie robi dokładnie tego, co nam się wydaje. &lt;br /&gt;
*I w końcu są sytuacje wyjątkowe: gdy w toku pracy programu zachodzą nieoczekiwane okoliczności &amp;amp;mdash; użytkownik podał błędną nazwę pliku z danymi, zawartość tego pliku nie jest zgodna z oczekiwaniami programu, połączenie sieciowe ulega przerwaniu w trakcie pobierania lub przesyłania danych, itp. &lt;br /&gt;
&lt;br /&gt;
Wszystkie te sytuacje nazywa się wyjątkami, i tym samym słowem określa się mechanizm, jakiego wiele współczesnych języków programowania (w tym Python) dostarcza programiście, aby mu pomóc określić działania jakie program miałby podjąć w sytuacjach wyjątkowych. Wyjątkowość takich sytuacji generalnie polega na tym, że w przypadku ich wystąpienia program po prostu nie może kontynuować przewidzianego toku działania:&lt;br /&gt;
&lt;br /&gt;
*błąd w składni programu oznacza, że kod nie daje się zinterpretować w sposób jednoznaczny; najlepsze co można zrobić, to w momencie wykrycia błędu przerwać działanie i spróbować dostarczyć programiście (w formie komunikatu) informację ułatwiającą określenie i naprawienie błędu;&lt;br /&gt;
*błędne działanie algorytmu można np. spróbować wykrywać za pomocą tzw. asercji (polecenie ''assert'') badających, czy pewne warunki, jakie powinny być spełnione przez dane przetwarzane w programie są istotnie spełnione;&lt;br /&gt;
*wyjątki powstałe na skutek okoliczności zachodzących w trakcie działania programu, uniemożliwiających jego normalną kontynuację, można spróbować przewidzieć i przygotować program do odpowiedniego zareagowania, czyli ''obsługi wyjątku''. Na przykład, można spróbować ponowić jeszcze raz (lub kilka razy) próbę łączności sieciowej, i poddać się dopiero po określonej liczbie niepowodzeń; natomiast w sytuacji błędu wynikającego z podania przez użytkownika programu niewłaściwych argumentów uruchomienia, warto postarać się o przekazanie użytkownikowi komunikatu informującego go w sposób dla niego zrozumiały, o właściwym sposobie uruchamiania programu.&lt;br /&gt;
&lt;br /&gt;
=== Błędy składniowe i podobne ===&lt;br /&gt;
&lt;br /&gt;
Jak wspomniano powyżej, w przypadku napotkania błędu składniowego w kodzie programu interpreter natychmiast przerwie wykonywanie programu i wypisze komunikat. Komunikaty te '''warto czytać uważnie''' &amp;amp;mdash; w większości przypadków znajduje się w nich cała informacja konieczna dla naprawienia błędu. Przykład: usiłujemy uruchomić program &amp;lt;tt&amp;gt;błąd.py&amp;lt;/tt&amp;gt;, którego treść to&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
x = (2 + 3) 4&lt;br /&gt;
print x&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wynik pierwszej próby to:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=bash&amp;gt;&lt;br /&gt;
$ python3 błąd.py &lt;br /&gt;
  File &amp;quot;błąd.py&amp;quot;, line 1&lt;br /&gt;
    x = (2 + 3) 4&lt;br /&gt;
                ^&lt;br /&gt;
SyntaxError: invalid syntax&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Z komunikatu całkiem jasno wynika, że napotkany został błąd składni (''SyntaxError''), że wykryto ten błąd w linijce 1, a nawet dokładnie &amp;amp;mdash; że miejscem, w którym interpreter stwierdził, że ma do czynienia z nieprawidłowy kodem, było wystąpienie cyfry 4 po zamykającym nawiasie. Po prostu zapomnieliśmy, że &amp;amp;mdash; inaczej niż w powszechnie stosowanej notacji matematycznej &amp;amp;mdash; w Pythonie aby uzyskać mnożenie, konieczne jest napisanie jawnie znaku operatora (gwiazdki).&lt;br /&gt;
&lt;br /&gt;
Po naprawieniu tej pomyłki próbujemy jeszcze raz, i wynik to:&lt;br /&gt;
&amp;lt;source lang=bash&amp;gt;&lt;br /&gt;
$ python3 błąd.py &lt;br /&gt;
  File &amp;quot;błąd.py&amp;quot;, line 2&lt;br /&gt;
    print x&lt;br /&gt;
          ^&lt;br /&gt;
SyntaxError: Missing parentheses in call to 'print'. Did you mean print(x)?&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Tutaj już jaśniej być nie może; interpreter nie tylko wskazał nam dokładne miejsce wystąpienia błędu, ale nawet dokładnie opisał, jak go naprawić.&lt;br /&gt;
&lt;br /&gt;
Oczywiście nie zawsze interpreter będzie w stanie wskazać nam błąd aż tak precyzyjnie. Jako przykład weźmy następujący plik:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
x, y, z = 3, 4, 5&lt;br /&gt;
print(max(x, y, z)&lt;br /&gt;
print(X * y * z)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
i wynik jego uruchomienia:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=bash&amp;gt;&lt;br /&gt;
$ python3 błąd.py &lt;br /&gt;
  File &amp;quot;błąd.py&amp;quot;, line 3&lt;br /&gt;
    print(X * y * z)&lt;br /&gt;
        ^&lt;br /&gt;
SyntaxError: invalid syntax&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dlaczego został wytknięty błąd składniowy w linijce 3? Przecież to w linijce 2 zapomnieliśmy zamknąć jeden z nawiasów.&lt;br /&gt;
&lt;br /&gt;
Otóż jeżeli z końcem linii Python stwierdza, że nie wszystkie dotąd otwarte nawiasy zostały zamknięte, to traktuje to jako oznaczające, że kolejną linijkę należy potraktować jako ciąg dalszy bieżącej. I w tym przypadku dopiero napotykając w kolejnej linijce nazwę &amp;lt;tt&amp;gt;print&amp;lt;/tt&amp;gt; &amp;amp;mdash; a nie np. przecinek, albo nawias zamykający &amp;amp;mdash; stwierdza, że coś musi być nie tak. Miejsce wykrycia błędu niestety nie zawsze się będzie pokrywało z miejscem jego faktycznego wystąpienia.&lt;br /&gt;
&lt;br /&gt;
Po poprawce, czyli zamknięciu nawiasu na linii 2, próbujemy jeszcze raz &amp;amp;mdash; z wynikiem&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=bash&amp;gt;&lt;br /&gt;
python3 błąd.py &lt;br /&gt;
5&lt;br /&gt;
Traceback (most recent call last):&lt;br /&gt;
  File &amp;quot;błąd.py&amp;quot;, line 3, in &amp;lt;module&amp;gt;&lt;br /&gt;
    print(X * y * z)&lt;br /&gt;
NameError: name 'X' is not defined&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
I tym razem chyba jest wszystko jasne: pojawiła się nazwa &amp;lt;tt&amp;gt;X&amp;lt;/tt&amp;gt;, z którą wcześniej nie związano żadnej wartości. Po prostu przez pomyłkę napisaliśmy X wielką literą zamiast małą. &lt;br /&gt;
&lt;br /&gt;
Te przykłady pokazują, że przy wykorzystaniu treści wypisywanych komunikatów proces usunięcia z programu błędów składniowych i formalnych może być dość szybki i bezbolesny.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&lt;br /&gt;
Pojawiły się w komunikatach określenia: &amp;lt;tt&amp;gt;SyntaxError&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;NameError&amp;lt;/tt&amp;gt;. Są to przykłady nazw tzw. klas wyjątków, czyli ogólnie rozumianych kategorii błędów, jakie są sygnalizowane. Wkrótce spotkamy dalsze klasy wyjątków, takie jak: &amp;lt;tt&amp;gt;TypeError&amp;lt;/tt&amp;gt; - związana z przekazaniem wielkości niewłaściwego typu, czy &amp;lt;tt&amp;gt;ValueError&amp;lt;/tt&amp;gt; - gdy nie typ. ale wartość wielkości, na której usiłuje się operować, jest niewłaściwa dla danej operacji. Dowiemy się również, dlaczego klasy wyjątków są przydatne &amp;amp;mdash; pomimo tego, iż dla ludzkich oczu zwykle bardziej przydatna jest słowna informacja uszczegółowiająca (to co pojawia się po nazwie klasy wyjątku i dwukropku).&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Asercje ===&lt;br /&gt;
&lt;br /&gt;
Polecenie &amp;lt;tt&amp;gt;assert&amp;lt;/tt&amp;gt; ma następującą postać:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
assert wyrażenie1&lt;br /&gt;
# lub:&lt;br /&gt;
assert wyrażenie1, wyrażenie2&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
i jest to jak widać polecenie proste (nie zawierające bloku poleceń z wcięciem).&lt;br /&gt;
&lt;br /&gt;
Jego działanie jest takie, że: obliczona zostanie wartość &amp;lt;tt&amp;gt;wyrażenie1&amp;lt;/tt&amp;gt;; jeżeli jest ona prawdziwa, nie dzieje się nic (następuje natychmiastowe przejście do kolejnej linijki kodu). Jeżeli okaże się fałszywa, zostanie zasygnalizowany wyjątek, klasy &amp;lt;tt&amp;gt;AssertionError&amp;lt;/tt&amp;gt;, co domyślnie przerywa wykonywanie programu i powoduje wypisanie odpowiedniego komunikatu. Jeżeli zastosujemy drugą postać, obliczona zostanie również wartość &amp;lt;tt&amp;gt;wyrażenie2&amp;lt;/tt&amp;gt; i wypisana (dokładniej: jej reprezentacja napisowa) jako część komunikatu.&lt;br /&gt;
&lt;br /&gt;
Przyjęło się stosować asercje jako sposób kontroli poprawności działania programu &amp;amp;mdash; w tym sensie, aby wykluczyć sytuacje „niemożliwe&amp;quot;, tj. powstałe w wyniku błędu programisty. Ze względu na prostotę składni warto też z nich korzystać w kodzie służącym do testowania poprawności innego kodu (czyli np. w funkcjach testujących, czy inne, bardziej złożone funkcje dają poprawne wyniki w prostych sytuacjach próbnych).&lt;br /&gt;
&lt;br /&gt;
=== Wyjątki w trakcie pracy programu ===&lt;br /&gt;
&lt;br /&gt;
Wyjątki występujące w trakcie pracy programu można przechwycić i obsłużyć za pomocą następującej konstrukcji (polecenia złożonego):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
try:&lt;br /&gt;
    # operacje mogące spowodować wyjątek&lt;br /&gt;
except (KlasaWyjątku1, KlasaWyjątku2, ...):&lt;br /&gt;
    # co zrobić jeśli wyjątek jednej z tych klas wystąpił&lt;br /&gt;
else: &lt;br /&gt;
    # co zrobić jeśli nie było wyjątku&lt;br /&gt;
finally:&lt;br /&gt;
    # co zrobić w KAŻDYM przypadku&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*bloki &amp;lt;tt&amp;gt;else:&amp;lt;/tt&amp;gt; i &amp;lt;tt&amp;gt;finally:&amp;lt;/tt&amp;gt; są nieobowiązkowe, tj. możemy je pominąć (wraz z odp. linijką wprowadzającą)&lt;br /&gt;
*w bloku &amp;lt;tt&amp;gt;except:&amp;lt;/tt&amp;gt; można podać jedną klasę wyjątku (wtedy zbędne są nawiasy), lub żadnej &amp;amp;mdash; wtedy przechwycimy ''każdy'' wyjątek; jeśli jednak chcemy, jak w przykładzie, wymienić więcej niż jedną klasę, to nawiasy są konieczne&lt;br /&gt;
*skuteczne przechwycenie wyjątku sprawia, że wykonanie programu nie ulegnie przerwaniu w punkcie jego wystąpienia, tyko będzie kontynuowane, również po opuszczeniu bloku &amp;lt;tt&amp;gt;try:&amp;lt;/tt&amp;gt;&lt;br /&gt;
*można jednak spowodować, aby po wykonaniu czynności obsługi wyjątku, wyjątek został niejako ''wznowiony''; wystarczy w bloku &amp;lt;tt&amp;gt;except:&amp;lt;/tt&amp;gt; wywołać instrukcję &amp;lt;tt&amp;gt;raise&amp;lt;/tt&amp;gt;. Dla większości klas wyjątków skutkuje to zakończeniem programu&lt;br /&gt;
*instrukcję &amp;lt;tt&amp;gt;raise&amp;lt;/tt&amp;gt; można wywołać również w dowolnym innym punkcie programu, powinna wówczas w niej wystąpić nazwa klasy wyjątku, jaki chcemy wywołać. &lt;br /&gt;
&lt;br /&gt;
Przykłady:&lt;br /&gt;
&lt;br /&gt;
''CDN.''&lt;br /&gt;
&lt;br /&gt;
== Trochę więcej o klasach i obiektach ==&lt;br /&gt;
&lt;br /&gt;
Warto sobie zdawać sprawę, że każda wartość występująca w programie pythonowym jest obiektem &amp;amp;mdash; a więc jest wyposażona w zestaw atrybutów i metod. Dotyczy to nie tylko kolekcji (list, słowników, ...), obiektów takich jak otwarte pliki (wynik wywołania funkcji &amp;lt;tt&amp;gt;open()&amp;lt;/tt&amp;gt;), napisów &amp;amp;mdash; ale również np. liczb, czy to całkowitych, czy zmiennoprzecinkowych (i zespolonych, o których nie było tutaj mowy). &lt;br /&gt;
&lt;br /&gt;
Przykładowo:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
(17).bit_length()&lt;br /&gt;
→ 5&lt;br /&gt;
(17).bit_count()&lt;br /&gt;
→ 2&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Co to właściwie znaczy?&lt;br /&gt;
&lt;br /&gt;
Dla liczby 17 wywołaliśmy najpierw metodę, który mówi nam jaka jest długość w bitach reprezentacji dwójkowej tej liczby (&amp;lt;tt&amp;gt;17 == 0b10001&amp;lt;/tt&amp;gt;), a następnie metodę, zwracającą liczbę ''ustawionych'' (tj. równych jeden) bitów w tej reprezentacji. Nawiasy okrągłe są konieczne, ponieważ kropka po cyfrach oznaczałaby, że mamy do czynienia z zapisem liczby zmiennoprzecinkowej. Inaczej mówiąc, byłyby niepotrzebne gdybyśmy mieli do czynienia z nazwą oznaczającą liczbę całkowitą, a nie z jej zapisem dziesiętnym.&lt;br /&gt;
&lt;br /&gt;
Każdy obiekt w Pythonie jest ''instancją'' pewnej ''klasy''. Przykłady klas to: &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt; (liczby całkowite), &amp;lt;tt&amp;gt;str&amp;lt;/tt&amp;gt; (napisy), &amp;lt;tt&amp;gt;list&amp;lt;/tt&amp;gt; (listy), &amp;lt;tt&amp;gt;bool&amp;lt;/tt&amp;gt; (wartości logiczne), i wiele innych. Klasa to inaczej typ obiektów; charakteryzuje ona zestaw atrybutów i metod związanych z obiektami danej klasy.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&amp;lt;small&amp;gt;&lt;br /&gt;
Zazwyczaj różnych obiektów będących instancjami danej klasy może być wiele, potencjalnie nieskończenie wiele. Są jednak wyjątki. Np. klasa &amp;lt;tt&amp;gt;bool&amp;lt;/tt&amp;gt; posiada jedynie dwie instancje: (&amp;lt;tt&amp;gt;True&amp;lt;/tt&amp;gt; i &amp;lt;tt&amp;gt;False&amp;lt;/tt&amp;gt;). A obiekt &amp;lt;tt&amp;gt;None&amp;lt;/tt&amp;gt; jest wręcz jedyną instancją swojej klasy.&lt;br /&gt;
&amp;lt;/small&amp;gt;&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Niektóre klasy są ,,szczególnymi przypadkami&amp;quot; innych klas &amp;amp;mdash; mówi się, że klasa C ''dziedziczy'' z klasy B, lub że jest ''podklasą'' klasy B. Oznacza to tyle, że instancje klasy C posiadają wszystkie atrybuty i metody jakie posiadają instancje klasy B, ale być może pewne dodatkowe &amp;amp;mdash; a być może niektóre z nich zostały w jakiś sposób zmodyfikowane. Przykładowo, klasa &amp;lt;tt&amp;gt;bool&amp;lt;/tt&amp;gt; stanowi podklasę klasy &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;; jej jedyne instancje, &amp;lt;tt&amp;gt;True&amp;lt;/tt&amp;gt; i &amp;lt;tt&amp;gt;False&amp;lt;/tt&amp;gt;, to ,,tak naprawdę&amp;quot; liczby (odpowiednio) 1 i 0 ,,w przebraniu&amp;quot;. Są one więc również instancjami klasy &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt; i można do nich stosować te same operacje (np. arytmetyczne) co do liczb całkowitych.&lt;br /&gt;
&lt;br /&gt;
''CDN''&lt;br /&gt;
&lt;br /&gt;
== O generatorach ==&lt;br /&gt;
&lt;br /&gt;
W jednym z poprzednich rozdziałów [[PPy3/Kolekcje#Przyk.C5.82ad:_suma_cyfr|poznaliśmy wyrażenia generatorowe]]. Przypomnijmy, że stanowią one uproszczony zapis iteracji, pozwalający na uniknięcie w wielu prostych przypadkach pętli &amp;lt;tt&amp;gt;for&amp;lt;/tt&amp;gt; i tworzenia zmiennych pomocniczych. Przykładowo:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;source lang=python&amp;gt;&lt;br /&gt;
 kwadraty = (x**2 for x in range(100))&lt;br /&gt;
 &amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
tworzy generator, ''produkujący'' w iteracji kwadraty kolejnych liczb naturalnych (od 0 do 99). &lt;br /&gt;
&lt;br /&gt;
Poważnym ograniczeniem wyrażeń generatorowych jest to, że można ich używać do przekształcenia jednego obiektu iterowalnego w drugi &amp;amp;mdash; w tym przypadku, ciągu liczb naturalnych w ciąg ich kwadratów, natomiast nie ma jak za pomocą wyrażenia generatorowego stworzyć obiektu iterowalnego ,,od zera&amp;quot;. Można to uzyskać, stosując ogólniejszą konstrukcję:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;source lang=python&amp;gt;&lt;br /&gt;
 def gen_kwadraty(start=0):&lt;br /&gt;
     k = start&lt;br /&gt;
     while True:&lt;br /&gt;
         yield k**2&lt;br /&gt;
         k += 1&lt;br /&gt;
&lt;br /&gt;
 kwadraty = gen_kwadraty()&lt;br /&gt;
 &amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To, co napisałem powyżej przypomina bardzo definicję funkcji; jedyną różnicą na poziomie składni jest wystąpienie w definicji słowa &amp;lt;tt&amp;gt;yield&amp;lt;/tt&amp;gt; (i brak wystąpienia słowa &amp;lt;tt&amp;gt;return&amp;lt;/tt&amp;gt;). W istocie &amp;lt;tt&amp;gt;gen_kwadraty&amp;lt;/tt&amp;gt; można uważać za funkcję &amp;amp;mdash; której wywołanie zwraca generator: obiekt, którego iteracja dostarczy kwadratów kolejnych liczb naturalnych, począwszy od liczby &amp;lt;tt&amp;gt;start&amp;lt;/tt&amp;gt;, argumentu wywołania, o domyślnej wartości zero. Zauważmy, że w budowie definicji nie użyliśmy obiektu &amp;lt;tt&amp;gt;range&amp;lt;/tt&amp;gt;; użyliśmy za to jawnej pętli &amp;lt;tt&amp;gt;while&amp;lt;/tt&amp;gt;, niejako opakowując ją w generator. Co więc w ten sposób zyskujemy?&lt;br /&gt;
&lt;br /&gt;
Przede wszystkim wielką elastyczność. W pokazanym przykładzie zysk jest niewielki, ale w definicji generatora możemy użyć jakiejkolwiek bądź reguły tworzenia kolejnych elementów iteracji. Nie potrzebujemy utworzyć ich wszystkich zanim zaczniemy z nich korzystać &amp;amp;mdash; tak jak byłoby w przypadku, gdybyśmy &amp;lt;tt&amp;gt;gen_kwadraty&amp;lt;/tt&amp;gt; zdefiniowali jako funkcję zwracającą listę kwadratów kolejnych liczb. Co więcej, iteracja zapewniona przez &amp;lt;tt&amp;gt;gen_kwadraty&amp;lt;/tt&amp;gt; może nam dostarczyć dowolnie wielu elementów (oczywiście w realnym komputerze po dostatecznie długim czasie osiągnięto by liczby, których wielkość przekroczyłaby pojemność dostępnej pamięci operacyjnej). Decyzja o tym, kiedy przerwać iterację pozostawiona jest ,,użytkownikowi&amp;quot;, tzn. kodowi odwołującemu się do obiektu &amp;lt;tt&amp;gt;kwadraty&amp;lt;/tt&amp;gt;.  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
[[PPy3/Matplotlib|poprzednie]] | [[&amp;quot;Programowanie z Pythonem3&amp;quot;|strona główna]] | [[PPy3/DobrePraktyki|dalej]]&lt;br /&gt;
&lt;br /&gt;
--[[Użytkownik:RobertJB|RobertJB]] ([[Dyskusja użytkownika:RobertJB|dyskusja]]) 14:26, 27 mar 2018 (CEST)&lt;/div&gt;</summary>
		<author><name>RobertJB</name></author>
		
	</entry>
	<entry>
		<id>http://brain.fuw.edu.pl/edu/index.php?title=PPy3/TematyDodatkowe&amp;diff=9472</id>
		<title>PPy3/TematyDodatkowe</title>
		<link rel="alternate" type="text/html" href="http://brain.fuw.edu.pl/edu/index.php?title=PPy3/TematyDodatkowe&amp;diff=9472"/>
		<updated>2023-06-29T12:30:10Z</updated>

		<summary type="html">&lt;p&gt;RobertJB: /* Trochę więcej o klasach i obiektach */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Tematy dodatkowe =&lt;br /&gt;
&lt;br /&gt;
== Błędy i wyjątki ==&lt;br /&gt;
&lt;br /&gt;
Każdy programista popełnia błędy &amp;amp;mdash; jest to nieunikniona część tej działalności. &lt;br /&gt;
&lt;br /&gt;
*Są błędy, które można nazwać banalnymi: literówka w nazwie lub słowie kluczowym, zapomniany dwukropek, niedomknięte nawiasy, itp. &lt;br /&gt;
*Są bardziej podstępne błędy logiczne: gdy algorytm, którego zapisem ma być tworzony kod, po prostu nie robi dokładnie tego, co nam się wydaje. &lt;br /&gt;
*I w końcu są sytuacje wyjątkowe: gdy w toku pracy programu zachodzą nieoczekiwane okoliczności &amp;amp;mdash; użytkownik podał błędną nazwę pliku z danymi, zawartość tego pliku nie jest zgodna z oczekiwaniami programu, połączenie sieciowe ulega przerwaniu w trakcie pobierania lub przesyłania danych, itp. &lt;br /&gt;
&lt;br /&gt;
Wszystkie te sytuacje nazywa się wyjątkami, i tym samym słowem określa się mechanizm, jakiego wiele współczesnych języków programowania (w tym Python) dostarcza programiście, aby mu pomóc określić działania jakie program miałby podjąć w sytuacjach wyjątkowych. Wyjątkowość takich sytuacji generalnie polega na tym, że w przypadku ich wystąpienia program po prostu nie może kontynuować przewidzianego toku działania:&lt;br /&gt;
&lt;br /&gt;
*błąd w składni programu oznacza, że kod nie daje się zinterpretować w sposób jednoznaczny; najlepsze co można zrobić, to w momencie wykrycia błędu przerwać działanie i spróbować dostarczyć programiście (w formie komunikatu) informację ułatwiającą określenie i naprawienie błędu;&lt;br /&gt;
*błędne działanie algorytmu można np. spróbować wykrywać za pomocą tzw. asercji (polecenie ''assert'') badających, czy pewne warunki, jakie powinny być spełnione przez dane przetwarzane w programie są istotnie spełnione;&lt;br /&gt;
*wyjątki powstałe na skutek okoliczności zachodzących w trakcie działania programu, uniemożliwiających jego normalną kontynuację, można spróbować przewidzieć i przygotować program do odpowiedniego zareagowania, czyli ''obsługi wyjątku''. Na przykład, można spróbować ponowić jeszcze raz (lub kilka razy) próbę łączności sieciowej, i poddać się dopiero po określonej liczbie niepowodzeń; natomiast w sytuacji błędu wynikającego z podania przez użytkownika programu niewłaściwych argumentów uruchomienia, warto postarać się o przekazanie użytkownikowi komunikatu informującego go w sposób dla niego zrozumiały, o właściwym sposobie uruchamiania programu.&lt;br /&gt;
&lt;br /&gt;
=== Błędy składniowe i podobne ===&lt;br /&gt;
&lt;br /&gt;
Jak wspomniano powyżej, w przypadku napotkania błędu składniowego w kodzie programu interpreter natychmiast przerwie wykonywanie programu i wypisze komunikat. Komunikaty te '''warto czytać uważnie''' &amp;amp;mdash; w większości przypadków znajduje się w nich cała informacja konieczna dla naprawienia błędu. Przykład: usiłujemy uruchomić program &amp;lt;tt&amp;gt;błąd.py&amp;lt;/tt&amp;gt;, którego treść to&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
x = (2 + 3) 4&lt;br /&gt;
print x&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wynik pierwszej próby to:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=bash&amp;gt;&lt;br /&gt;
$ python3 błąd.py &lt;br /&gt;
  File &amp;quot;błąd.py&amp;quot;, line 1&lt;br /&gt;
    x = (2 + 3) 4&lt;br /&gt;
                ^&lt;br /&gt;
SyntaxError: invalid syntax&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Z komunikatu całkiem jasno wynika, że napotkany został błąd składni (''SyntaxError''), że wykryto ten błąd w linijce 1, a nawet dokładnie &amp;amp;mdash; że miejscem, w którym interpreter stwierdził, że ma do czynienia z nieprawidłowy kodem, było wystąpienie cyfry 4 po zamykającym nawiasie. Po prostu zapomnieliśmy, że &amp;amp;mdash; inaczej niż w powszechnie stosowanej notacji matematycznej &amp;amp;mdash; w Pythonie aby uzyskać mnożenie, konieczne jest napisanie jawnie znaku operatora (gwiazdki).&lt;br /&gt;
&lt;br /&gt;
Po naprawieniu tej pomyłki próbujemy jeszcze raz, i wynik to:&lt;br /&gt;
&amp;lt;source lang=bash&amp;gt;&lt;br /&gt;
$ python3 błąd.py &lt;br /&gt;
  File &amp;quot;błąd.py&amp;quot;, line 2&lt;br /&gt;
    print x&lt;br /&gt;
          ^&lt;br /&gt;
SyntaxError: Missing parentheses in call to 'print'. Did you mean print(x)?&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Tutaj już jaśniej być nie może; interpreter nie tylko wskazał nam dokładne miejsce wystąpienia błędu, ale nawet dokładnie opisał, jak go naprawić.&lt;br /&gt;
&lt;br /&gt;
Oczywiście nie zawsze interpreter będzie w stanie wskazać nam błąd aż tak precyzyjnie. Jako przykład weźmy następujący plik:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
x, y, z = 3, 4, 5&lt;br /&gt;
print(max(x, y, z)&lt;br /&gt;
print(X * y * z)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
i wynik jego uruchomienia:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=bash&amp;gt;&lt;br /&gt;
$ python3 błąd.py &lt;br /&gt;
  File &amp;quot;błąd.py&amp;quot;, line 3&lt;br /&gt;
    print(X * y * z)&lt;br /&gt;
        ^&lt;br /&gt;
SyntaxError: invalid syntax&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dlaczego został wytknięty błąd składniowy w linijce 3? Przecież to w linijce 2 zapomnieliśmy zamknąć jeden z nawiasów.&lt;br /&gt;
&lt;br /&gt;
Otóż jeżeli z końcem linii Python stwierdza, że nie wszystkie dotąd otwarte nawiasy zostały zamknięte, to traktuje to jako oznaczające, że kolejną linijkę należy potraktować jako ciąg dalszy bieżącej. I w tym przypadku dopiero napotykając w kolejnej linijce nazwę &amp;lt;tt&amp;gt;print&amp;lt;/tt&amp;gt; &amp;amp;mdash; a nie np. przecinek, albo nawias zamykający &amp;amp;mdash; stwierdza, że coś musi być nie tak. Miejsce wykrycia błędu niestety nie zawsze się będzie pokrywało z miejscem jego faktycznego wystąpienia.&lt;br /&gt;
&lt;br /&gt;
Po poprawce, czyli zamknięciu nawiasu na linii 2, próbujemy jeszcze raz &amp;amp;mdash; z wynikiem&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=bash&amp;gt;&lt;br /&gt;
python3 błąd.py &lt;br /&gt;
5&lt;br /&gt;
Traceback (most recent call last):&lt;br /&gt;
  File &amp;quot;błąd.py&amp;quot;, line 3, in &amp;lt;module&amp;gt;&lt;br /&gt;
    print(X * y * z)&lt;br /&gt;
NameError: name 'X' is not defined&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
I tym razem chyba jest wszystko jasne: pojawiła się nazwa &amp;lt;tt&amp;gt;X&amp;lt;/tt&amp;gt;, z którą wcześniej nie związano żadnej wartości. Po prostu przez pomyłkę napisaliśmy X wielką literą zamiast małą. &lt;br /&gt;
&lt;br /&gt;
Te przykłady pokazują, że przy wykorzystaniu treści wypisywanych komunikatów proces usunięcia z programu błędów składniowych i formalnych może być dość szybki i bezbolesny.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&lt;br /&gt;
Pojawiły się w komunikatach określenia: &amp;lt;tt&amp;gt;SyntaxError&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;NameError&amp;lt;/tt&amp;gt;. Są to przykłady nazw tzw. klas wyjątków, czyli ogólnie rozumianych kategorii błędów, jakie są sygnalizowane. Wkrótce spotkamy dalsze klasy wyjątków, takie jak: &amp;lt;tt&amp;gt;TypeError&amp;lt;/tt&amp;gt; - związana z przekazaniem wielkości niewłaściwego typu, czy &amp;lt;tt&amp;gt;ValueError&amp;lt;/tt&amp;gt; - gdy nie typ. ale wartość wielkości, na której usiłuje się operować, jest niewłaściwa dla danej operacji. Dowiemy się również, dlaczego klasy wyjątków są przydatne &amp;amp;mdash; pomimo tego, iż dla ludzkich oczu zwykle bardziej przydatna jest słowna informacja uszczegółowiająca (to co pojawia się po nazwie klasy wyjątku i dwukropku).&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Asercje ===&lt;br /&gt;
&lt;br /&gt;
Polecenie &amp;lt;tt&amp;gt;assert&amp;lt;/tt&amp;gt; ma następującą postać:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
assert wyrażenie1&lt;br /&gt;
# lub:&lt;br /&gt;
assert wyrażenie1, wyrażenie2&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
i jest to jak widać polecenie proste (nie zawierające bloku poleceń z wcięciem).&lt;br /&gt;
&lt;br /&gt;
Jego działanie jest takie, że: obliczona zostanie wartość &amp;lt;tt&amp;gt;wyrażenie1&amp;lt;/tt&amp;gt;; jeżeli jest ona prawdziwa, nie dzieje się nic (następuje natychmiastowe przejście do kolejnej linijki kodu). Jeżeli okaże się fałszywa, zostanie zasygnalizowany wyjątek, klasy &amp;lt;tt&amp;gt;AssertionError&amp;lt;/tt&amp;gt;, co domyślnie przerywa wykonywanie programu i powoduje wypisanie odpowiedniego komunikatu. Jeżeli zastosujemy drugą postać, obliczona zostanie również wartość &amp;lt;tt&amp;gt;wyrażenie2&amp;lt;/tt&amp;gt; i wypisana (dokładniej: jej reprezentacja napisowa) jako część komunikatu.&lt;br /&gt;
&lt;br /&gt;
Przyjęło się stosować asercje jako sposób kontroli poprawności działania programu &amp;amp;mdash; w tym sensie, aby wykluczyć sytuacje „niemożliwe&amp;quot;, tj. powstałe w wyniku błędu programisty. Ze względu na prostotę składni warto też z nich korzystać w kodzie służącym do testowania poprawności innego kodu (czyli np. w funkcjach testujących, czy inne, bardziej złożone funkcje dają poprawne wyniki w prostych sytuacjach próbnych).&lt;br /&gt;
&lt;br /&gt;
=== Wyjątki w trakcie pracy programu ===&lt;br /&gt;
&lt;br /&gt;
Wyjątki występujące w trakcie pracy programu można przechwycić i obsłużyć za pomocą następującej konstrukcji (polecenia złożonego):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
try:&lt;br /&gt;
    # operacje mogące spowodować wyjątek&lt;br /&gt;
except (KlasaWyjątku1, KlasaWyjątku2, ...):&lt;br /&gt;
    # co zrobić jeśli wyjątek jednej z tych klas wystąpił&lt;br /&gt;
else: &lt;br /&gt;
    # co zrobić jeśli nie było wyjątku&lt;br /&gt;
finally:&lt;br /&gt;
    # co zrobić w KAŻDYM przypadku&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*bloki &amp;lt;tt&amp;gt;else:&amp;lt;/tt&amp;gt; i &amp;lt;tt&amp;gt;finally:&amp;lt;/tt&amp;gt; są nieobowiązkowe, tj. możemy je pominąć (wraz z odp. linijką wprowadzającą)&lt;br /&gt;
*w bloku &amp;lt;tt&amp;gt;except:&amp;lt;/tt&amp;gt; można podać jedną klasę wyjątku (wtedy zbędne są nawiasy), lub żadnej &amp;amp;mdash; wtedy przechwycimy ''każdy'' wyjątek; jeśli jednak chcemy, jak w przykładzie, wymienić więcej niż jedną klasę, to nawiasy są konieczne&lt;br /&gt;
*skuteczne przechwycenie wyjątku sprawia, że wykonanie programu nie ulegnie przerwaniu w punkcie jego wystąpienia, tyko będzie kontynuowane, również po opuszczeniu bloku &amp;lt;tt&amp;gt;try:&amp;lt;/tt&amp;gt;&lt;br /&gt;
*można jednak spowodować, aby po wykonaniu czynności obsługi wyjątku, wyjątek został niejako ''wznowiony''; wystarczy w bloku &amp;lt;tt&amp;gt;except:&amp;lt;/tt&amp;gt; wywołać instrukcję &amp;lt;tt&amp;gt;raise&amp;lt;/tt&amp;gt;. Dla większości klas wyjątków skutkuje to zakończeniem programu&lt;br /&gt;
*instrukcję &amp;lt;tt&amp;gt;raise&amp;lt;/tt&amp;gt; można wywołać również w dowolnym innym punkcie programu, powinna wówczas w niej wystąpić nazwa klasy wyjątku, jaki chcemy wywołać. &lt;br /&gt;
&lt;br /&gt;
Przykłady:&lt;br /&gt;
&lt;br /&gt;
''CDN.''&lt;br /&gt;
&lt;br /&gt;
== Trochę więcej o klasach i obiektach ==&lt;br /&gt;
&lt;br /&gt;
Warto sobie zdawać sprawę, że każda wartość występująca w programie pythonowym jest obiektem &amp;amp;mdash; a więc jest wyposażona w zestaw atrybutów i metod. Dotyczy to nie tylko kolekcji (list, słowników, ...), obiektów takich jak otwarte pliki (wynik wywołania funkcji &amp;lt;tt&amp;gt;open()&amp;lt;/tt&amp;gt;), napisów &amp;amp;mdash; ale również np. liczb, czy to całkowitych, czy zmiennoprzecinkowych (i zespolonych, o których nie było tutaj mowy). &lt;br /&gt;
&lt;br /&gt;
Przykładowo:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
(17).bit_length()&lt;br /&gt;
→ 5&lt;br /&gt;
(17).bit_count()&lt;br /&gt;
→ 2&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Co to właściwie znaczy?&lt;br /&gt;
&lt;br /&gt;
Dla liczby 17 wywołaliśmy najpierw metodę, który mówi nam jaka jest długość w bitach reprezentacji dwójkowej tej liczby (&amp;lt;tt&amp;gt;17 == 0b10001&amp;lt;/tt&amp;gt;), a następnie metodę, zwracającą liczbę ''ustawionych'' (tj. równych jeden) bitów w tej reprezentacji. Nawiasy okrągłe są konieczne, ponieważ kropka po cyfrach oznaczałaby, że mamy do czynienia z zapisem liczby zmiennoprzecinkowej. Inaczej mówiąc, byłyby niepotrzebne gdybyśmy mieli do czynienia z nazwą oznaczającą liczbę całkowitą, a nie z jej zapisem dziesiętnym.&lt;br /&gt;
&lt;br /&gt;
Każdy obiekt w Pythonie jest ''instancją'' pewnej ''klasy''. Przykłady klas to: &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt; (liczby całkowite), &amp;lt;tt&amp;gt;str&amp;lt;/tt&amp;gt; (napisy), &amp;lt;tt&amp;gt;list&amp;lt;/tt&amp;gt; (listy), &amp;lt;tt&amp;gt;bool&amp;lt;/tt&amp;gt; (wartości logiczne), i wiele innych. Klasa to inaczej typ obiektów; charakteryzuje ona zestaw atrybutów i metod związanych z obiektami danej klasy.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&amp;lt;small&amp;gt;&lt;br /&gt;
Zazwyczaj różnych obiektów będących instancjami danej klasy może być wiele, potencjalnie nieskończenie wiele. Są jednak wyjątki. Np. klasa &amp;lt;tt&amp;gt;bool&amp;lt;/tt&amp;gt; posiada jedynie dwie instancje: (&amp;lt;tt&amp;gt;True&amp;lt;/tt&amp;gt; i &amp;lt;tt&amp;gt;False&amp;lt;/tt&amp;gt;). A obiekt &amp;lt;tt&amp;gt;None&amp;lt;/tt&amp;gt; jest wręcz jedyną instancją swojej klasy.&lt;br /&gt;
&amp;lt;/small&amp;gt;&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Niektóre klasy są ,,szczególnymi przypadkami&amp;quot; innych klas &amp;amp;mdash; mówi się, że klasa C ''dziedziczy'' z klasy B, lub że jest ''podklasą'' klasy B. Oznacza to tyle, że instancje klasy C posiadają wszystkie atrybuty i metody jakie posiadają instancje klasy B, ale być może pewne dodatkowe &amp;amp;mdash; a być może niektóre z nich zostały w jakiś sposób zmodyfikowane. Przykładowo, klasa &amp;lt;tt&amp;gt;bool&amp;lt;/tt&amp;gt; stanowi podklasę klasy &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;; jej jedynie instancje, &amp;lt;tt&amp;gt;True&amp;lt;/tt&amp;gt; i &amp;lt;tt&amp;gt;False&amp;lt;/tt&amp;gt;, to ,,tak naprawdę&amp;quot; liczby (odpowiednio) 1 i 0 ,,w przebraniu&amp;quot;. Są one więc również instancjami klasy &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt; i można do nich stosować te same operacje (np. arytmetyczne) co do liczb całkowitych.&lt;br /&gt;
&lt;br /&gt;
''CDN''&lt;br /&gt;
&lt;br /&gt;
== O generatorach ==&lt;br /&gt;
&lt;br /&gt;
W jednym z poprzednich rozdziałów [[PPy3/Kolekcje#Przyk.C5.82ad:_suma_cyfr|poznaliśmy wyrażenia generatorowe]]. Przypomnijmy, że stanowią one uproszczony zapis iteracji, pozwalający na uniknięcie w wielu prostych przypadkach pętli &amp;lt;tt&amp;gt;for&amp;lt;/tt&amp;gt; i tworzenia zmiennych pomocniczych. Przykładowo:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;source lang=python&amp;gt;&lt;br /&gt;
 kwadraty = (x**2 for x in range(100))&lt;br /&gt;
 &amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
tworzy generator, ''produkujący'' w iteracji kwadraty kolejnych liczb naturalnych (od 0 do 99). &lt;br /&gt;
&lt;br /&gt;
Poważnym ograniczeniem wyrażeń generatorowych jest to, że można ich używać do przekształcenia jednego obiektu iterowalnego w drugi &amp;amp;mdash; w tym przypadku, ciągu liczb naturalnych w ciąg ich kwadratów, natomiast nie ma jak za pomocą wyrażenia generatorowego stworzyć obiektu iterowalnego ,,od zera&amp;quot;. Można to uzyskać, stosując ogólniejszą konstrukcję:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;source lang=python&amp;gt;&lt;br /&gt;
 def gen_kwadraty(start=0):&lt;br /&gt;
     k = start&lt;br /&gt;
     while True:&lt;br /&gt;
         yield k**2&lt;br /&gt;
         k += 1&lt;br /&gt;
&lt;br /&gt;
 kwadraty = gen_kwadraty()&lt;br /&gt;
 &amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To, co napisałem powyżej przypomina bardzo definicję funkcji; jedyną różnicą na poziomie składni jest wystąpienie w definicji słowa &amp;lt;tt&amp;gt;yield&amp;lt;/tt&amp;gt; (i brak wystąpienia słowa &amp;lt;tt&amp;gt;return&amp;lt;/tt&amp;gt;). W istocie &amp;lt;tt&amp;gt;gen_kwadraty&amp;lt;/tt&amp;gt; można uważać za funkcję &amp;amp;mdash; której wywołanie zwraca generator: obiekt, którego iteracja dostarczy kwadratów kolejnych liczb naturalnych, począwszy od liczby &amp;lt;tt&amp;gt;start&amp;lt;/tt&amp;gt;, argumentu wywołania, o domyślnej wartości zero. Zauważmy, że w budowie definicji nie użyliśmy obiektu &amp;lt;tt&amp;gt;range&amp;lt;/tt&amp;gt;; użyliśmy za to jawnej pętli &amp;lt;tt&amp;gt;while&amp;lt;/tt&amp;gt;, niejako opakowując ją w generator. Co więc w ten sposób zyskujemy?&lt;br /&gt;
&lt;br /&gt;
Przede wszystkim wielką elastyczność. W pokazanym przykładzie zysk jest niewielki, ale w definicji generatora możemy użyć jakiejkolwiek bądź reguły tworzenia kolejnych elementów iteracji. Nie potrzebujemy utworzyć ich wszystkich zanim zaczniemy z nich korzystać &amp;amp;mdash; tak jak byłoby w przypadku, gdybyśmy &amp;lt;tt&amp;gt;gen_kwadraty&amp;lt;/tt&amp;gt; zdefiniowali jako funkcję zwracającą listę kwadratów kolejnych liczb. Co więcej, iteracja zapewniona przez &amp;lt;tt&amp;gt;gen_kwadraty&amp;lt;/tt&amp;gt; może nam dostarczyć dowolnie wielu elementów (oczywiście w realnym komputerze po dostatecznie długim czasie osiągnięto by liczby, których wielkość przekroczyłaby pojemność dostępnej pamięci operacyjnej). Decyzja o tym, kiedy przerwać iterację pozostawiona jest ,,użytkownikowi&amp;quot;, tzn. kodowi odwołującemu się do obiektu &amp;lt;tt&amp;gt;kwadraty&amp;lt;/tt&amp;gt;.  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
[[PPy3/Matplotlib|poprzednie]] | [[&amp;quot;Programowanie z Pythonem3&amp;quot;|strona główna]] | [[PPy3/DobrePraktyki|dalej]]&lt;br /&gt;
&lt;br /&gt;
--[[Użytkownik:RobertJB|RobertJB]] ([[Dyskusja użytkownika:RobertJB|dyskusja]]) 14:26, 27 mar 2018 (CEST)&lt;/div&gt;</summary>
		<author><name>RobertJB</name></author>
		
	</entry>
	<entry>
		<id>http://brain.fuw.edu.pl/edu/index.php?title=PPy3/TematyDodatkowe&amp;diff=9471</id>
		<title>PPy3/TematyDodatkowe</title>
		<link rel="alternate" type="text/html" href="http://brain.fuw.edu.pl/edu/index.php?title=PPy3/TematyDodatkowe&amp;diff=9471"/>
		<updated>2023-06-29T12:29:25Z</updated>

		<summary type="html">&lt;p&gt;RobertJB: /* Trochę więcej o klasach i obiektach */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Tematy dodatkowe =&lt;br /&gt;
&lt;br /&gt;
== Błędy i wyjątki ==&lt;br /&gt;
&lt;br /&gt;
Każdy programista popełnia błędy &amp;amp;mdash; jest to nieunikniona część tej działalności. &lt;br /&gt;
&lt;br /&gt;
*Są błędy, które można nazwać banalnymi: literówka w nazwie lub słowie kluczowym, zapomniany dwukropek, niedomknięte nawiasy, itp. &lt;br /&gt;
*Są bardziej podstępne błędy logiczne: gdy algorytm, którego zapisem ma być tworzony kod, po prostu nie robi dokładnie tego, co nam się wydaje. &lt;br /&gt;
*I w końcu są sytuacje wyjątkowe: gdy w toku pracy programu zachodzą nieoczekiwane okoliczności &amp;amp;mdash; użytkownik podał błędną nazwę pliku z danymi, zawartość tego pliku nie jest zgodna z oczekiwaniami programu, połączenie sieciowe ulega przerwaniu w trakcie pobierania lub przesyłania danych, itp. &lt;br /&gt;
&lt;br /&gt;
Wszystkie te sytuacje nazywa się wyjątkami, i tym samym słowem określa się mechanizm, jakiego wiele współczesnych języków programowania (w tym Python) dostarcza programiście, aby mu pomóc określić działania jakie program miałby podjąć w sytuacjach wyjątkowych. Wyjątkowość takich sytuacji generalnie polega na tym, że w przypadku ich wystąpienia program po prostu nie może kontynuować przewidzianego toku działania:&lt;br /&gt;
&lt;br /&gt;
*błąd w składni programu oznacza, że kod nie daje się zinterpretować w sposób jednoznaczny; najlepsze co można zrobić, to w momencie wykrycia błędu przerwać działanie i spróbować dostarczyć programiście (w formie komunikatu) informację ułatwiającą określenie i naprawienie błędu;&lt;br /&gt;
*błędne działanie algorytmu można np. spróbować wykrywać za pomocą tzw. asercji (polecenie ''assert'') badających, czy pewne warunki, jakie powinny być spełnione przez dane przetwarzane w programie są istotnie spełnione;&lt;br /&gt;
*wyjątki powstałe na skutek okoliczności zachodzących w trakcie działania programu, uniemożliwiających jego normalną kontynuację, można spróbować przewidzieć i przygotować program do odpowiedniego zareagowania, czyli ''obsługi wyjątku''. Na przykład, można spróbować ponowić jeszcze raz (lub kilka razy) próbę łączności sieciowej, i poddać się dopiero po określonej liczbie niepowodzeń; natomiast w sytuacji błędu wynikającego z podania przez użytkownika programu niewłaściwych argumentów uruchomienia, warto postarać się o przekazanie użytkownikowi komunikatu informującego go w sposób dla niego zrozumiały, o właściwym sposobie uruchamiania programu.&lt;br /&gt;
&lt;br /&gt;
=== Błędy składniowe i podobne ===&lt;br /&gt;
&lt;br /&gt;
Jak wspomniano powyżej, w przypadku napotkania błędu składniowego w kodzie programu interpreter natychmiast przerwie wykonywanie programu i wypisze komunikat. Komunikaty te '''warto czytać uważnie''' &amp;amp;mdash; w większości przypadków znajduje się w nich cała informacja konieczna dla naprawienia błędu. Przykład: usiłujemy uruchomić program &amp;lt;tt&amp;gt;błąd.py&amp;lt;/tt&amp;gt;, którego treść to&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
x = (2 + 3) 4&lt;br /&gt;
print x&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wynik pierwszej próby to:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=bash&amp;gt;&lt;br /&gt;
$ python3 błąd.py &lt;br /&gt;
  File &amp;quot;błąd.py&amp;quot;, line 1&lt;br /&gt;
    x = (2 + 3) 4&lt;br /&gt;
                ^&lt;br /&gt;
SyntaxError: invalid syntax&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Z komunikatu całkiem jasno wynika, że napotkany został błąd składni (''SyntaxError''), że wykryto ten błąd w linijce 1, a nawet dokładnie &amp;amp;mdash; że miejscem, w którym interpreter stwierdził, że ma do czynienia z nieprawidłowy kodem, było wystąpienie cyfry 4 po zamykającym nawiasie. Po prostu zapomnieliśmy, że &amp;amp;mdash; inaczej niż w powszechnie stosowanej notacji matematycznej &amp;amp;mdash; w Pythonie aby uzyskać mnożenie, konieczne jest napisanie jawnie znaku operatora (gwiazdki).&lt;br /&gt;
&lt;br /&gt;
Po naprawieniu tej pomyłki próbujemy jeszcze raz, i wynik to:&lt;br /&gt;
&amp;lt;source lang=bash&amp;gt;&lt;br /&gt;
$ python3 błąd.py &lt;br /&gt;
  File &amp;quot;błąd.py&amp;quot;, line 2&lt;br /&gt;
    print x&lt;br /&gt;
          ^&lt;br /&gt;
SyntaxError: Missing parentheses in call to 'print'. Did you mean print(x)?&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Tutaj już jaśniej być nie może; interpreter nie tylko wskazał nam dokładne miejsce wystąpienia błędu, ale nawet dokładnie opisał, jak go naprawić.&lt;br /&gt;
&lt;br /&gt;
Oczywiście nie zawsze interpreter będzie w stanie wskazać nam błąd aż tak precyzyjnie. Jako przykład weźmy następujący plik:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
x, y, z = 3, 4, 5&lt;br /&gt;
print(max(x, y, z)&lt;br /&gt;
print(X * y * z)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
i wynik jego uruchomienia:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=bash&amp;gt;&lt;br /&gt;
$ python3 błąd.py &lt;br /&gt;
  File &amp;quot;błąd.py&amp;quot;, line 3&lt;br /&gt;
    print(X * y * z)&lt;br /&gt;
        ^&lt;br /&gt;
SyntaxError: invalid syntax&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dlaczego został wytknięty błąd składniowy w linijce 3? Przecież to w linijce 2 zapomnieliśmy zamknąć jeden z nawiasów.&lt;br /&gt;
&lt;br /&gt;
Otóż jeżeli z końcem linii Python stwierdza, że nie wszystkie dotąd otwarte nawiasy zostały zamknięte, to traktuje to jako oznaczające, że kolejną linijkę należy potraktować jako ciąg dalszy bieżącej. I w tym przypadku dopiero napotykając w kolejnej linijce nazwę &amp;lt;tt&amp;gt;print&amp;lt;/tt&amp;gt; &amp;amp;mdash; a nie np. przecinek, albo nawias zamykający &amp;amp;mdash; stwierdza, że coś musi być nie tak. Miejsce wykrycia błędu niestety nie zawsze się będzie pokrywało z miejscem jego faktycznego wystąpienia.&lt;br /&gt;
&lt;br /&gt;
Po poprawce, czyli zamknięciu nawiasu na linii 2, próbujemy jeszcze raz &amp;amp;mdash; z wynikiem&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=bash&amp;gt;&lt;br /&gt;
python3 błąd.py &lt;br /&gt;
5&lt;br /&gt;
Traceback (most recent call last):&lt;br /&gt;
  File &amp;quot;błąd.py&amp;quot;, line 3, in &amp;lt;module&amp;gt;&lt;br /&gt;
    print(X * y * z)&lt;br /&gt;
NameError: name 'X' is not defined&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
I tym razem chyba jest wszystko jasne: pojawiła się nazwa &amp;lt;tt&amp;gt;X&amp;lt;/tt&amp;gt;, z którą wcześniej nie związano żadnej wartości. Po prostu przez pomyłkę napisaliśmy X wielką literą zamiast małą. &lt;br /&gt;
&lt;br /&gt;
Te przykłady pokazują, że przy wykorzystaniu treści wypisywanych komunikatów proces usunięcia z programu błędów składniowych i formalnych może być dość szybki i bezbolesny.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&lt;br /&gt;
Pojawiły się w komunikatach określenia: &amp;lt;tt&amp;gt;SyntaxError&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;NameError&amp;lt;/tt&amp;gt;. Są to przykłady nazw tzw. klas wyjątków, czyli ogólnie rozumianych kategorii błędów, jakie są sygnalizowane. Wkrótce spotkamy dalsze klasy wyjątków, takie jak: &amp;lt;tt&amp;gt;TypeError&amp;lt;/tt&amp;gt; - związana z przekazaniem wielkości niewłaściwego typu, czy &amp;lt;tt&amp;gt;ValueError&amp;lt;/tt&amp;gt; - gdy nie typ. ale wartość wielkości, na której usiłuje się operować, jest niewłaściwa dla danej operacji. Dowiemy się również, dlaczego klasy wyjątków są przydatne &amp;amp;mdash; pomimo tego, iż dla ludzkich oczu zwykle bardziej przydatna jest słowna informacja uszczegółowiająca (to co pojawia się po nazwie klasy wyjątku i dwukropku).&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Asercje ===&lt;br /&gt;
&lt;br /&gt;
Polecenie &amp;lt;tt&amp;gt;assert&amp;lt;/tt&amp;gt; ma następującą postać:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
assert wyrażenie1&lt;br /&gt;
# lub:&lt;br /&gt;
assert wyrażenie1, wyrażenie2&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
i jest to jak widać polecenie proste (nie zawierające bloku poleceń z wcięciem).&lt;br /&gt;
&lt;br /&gt;
Jego działanie jest takie, że: obliczona zostanie wartość &amp;lt;tt&amp;gt;wyrażenie1&amp;lt;/tt&amp;gt;; jeżeli jest ona prawdziwa, nie dzieje się nic (następuje natychmiastowe przejście do kolejnej linijki kodu). Jeżeli okaże się fałszywa, zostanie zasygnalizowany wyjątek, klasy &amp;lt;tt&amp;gt;AssertionError&amp;lt;/tt&amp;gt;, co domyślnie przerywa wykonywanie programu i powoduje wypisanie odpowiedniego komunikatu. Jeżeli zastosujemy drugą postać, obliczona zostanie również wartość &amp;lt;tt&amp;gt;wyrażenie2&amp;lt;/tt&amp;gt; i wypisana (dokładniej: jej reprezentacja napisowa) jako część komunikatu.&lt;br /&gt;
&lt;br /&gt;
Przyjęło się stosować asercje jako sposób kontroli poprawności działania programu &amp;amp;mdash; w tym sensie, aby wykluczyć sytuacje „niemożliwe&amp;quot;, tj. powstałe w wyniku błędu programisty. Ze względu na prostotę składni warto też z nich korzystać w kodzie służącym do testowania poprawności innego kodu (czyli np. w funkcjach testujących, czy inne, bardziej złożone funkcje dają poprawne wyniki w prostych sytuacjach próbnych).&lt;br /&gt;
&lt;br /&gt;
=== Wyjątki w trakcie pracy programu ===&lt;br /&gt;
&lt;br /&gt;
Wyjątki występujące w trakcie pracy programu można przechwycić i obsłużyć za pomocą następującej konstrukcji (polecenia złożonego):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
try:&lt;br /&gt;
    # operacje mogące spowodować wyjątek&lt;br /&gt;
except (KlasaWyjątku1, KlasaWyjątku2, ...):&lt;br /&gt;
    # co zrobić jeśli wyjątek jednej z tych klas wystąpił&lt;br /&gt;
else: &lt;br /&gt;
    # co zrobić jeśli nie było wyjątku&lt;br /&gt;
finally:&lt;br /&gt;
    # co zrobić w KAŻDYM przypadku&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*bloki &amp;lt;tt&amp;gt;else:&amp;lt;/tt&amp;gt; i &amp;lt;tt&amp;gt;finally:&amp;lt;/tt&amp;gt; są nieobowiązkowe, tj. możemy je pominąć (wraz z odp. linijką wprowadzającą)&lt;br /&gt;
*w bloku &amp;lt;tt&amp;gt;except:&amp;lt;/tt&amp;gt; można podać jedną klasę wyjątku (wtedy zbędne są nawiasy), lub żadnej &amp;amp;mdash; wtedy przechwycimy ''każdy'' wyjątek; jeśli jednak chcemy, jak w przykładzie, wymienić więcej niż jedną klasę, to nawiasy są konieczne&lt;br /&gt;
*skuteczne przechwycenie wyjątku sprawia, że wykonanie programu nie ulegnie przerwaniu w punkcie jego wystąpienia, tyko będzie kontynuowane, również po opuszczeniu bloku &amp;lt;tt&amp;gt;try:&amp;lt;/tt&amp;gt;&lt;br /&gt;
*można jednak spowodować, aby po wykonaniu czynności obsługi wyjątku, wyjątek został niejako ''wznowiony''; wystarczy w bloku &amp;lt;tt&amp;gt;except:&amp;lt;/tt&amp;gt; wywołać instrukcję &amp;lt;tt&amp;gt;raise&amp;lt;/tt&amp;gt;. Dla większości klas wyjątków skutkuje to zakończeniem programu&lt;br /&gt;
*instrukcję &amp;lt;tt&amp;gt;raise&amp;lt;/tt&amp;gt; można wywołać również w dowolnym innym punkcie programu, powinna wówczas w niej wystąpić nazwa klasy wyjątku, jaki chcemy wywołać. &lt;br /&gt;
&lt;br /&gt;
Przykłady:&lt;br /&gt;
&lt;br /&gt;
''CDN.''&lt;br /&gt;
&lt;br /&gt;
== Trochę więcej o klasach i obiektach ==&lt;br /&gt;
&lt;br /&gt;
Warto sobie zdawać sprawę, że każda wartość występująca w programie pythonowym jest obiektem &amp;amp;mdash; a więc jest wyposażona w zestaw atrybutów i metod. Dotyczy to nie tylko kolekcji (list, słowników, ...), obiektów takich jak otwarte pliki (wynik wywołania funkcji &amp;lt;tt&amp;gt;open()&amp;lt;/tt&amp;gt;), napisów &amp;amp;mdash; ale również np. liczb, czy to całkowitych, czy zmiennoprzecinkowych (i zespolonych, o których nie było tutaj mowy). &lt;br /&gt;
&lt;br /&gt;
Przykładowo:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
(17).bit_length()&lt;br /&gt;
→ 5&lt;br /&gt;
(17).bit_count()&lt;br /&gt;
→ 2&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Co to właściwie znaczy?&lt;br /&gt;
&lt;br /&gt;
Dla liczby 17 wywołaliśmy najpierw metodę, który mówi nam jak jest długość w bitach reprezentacji dwójkowej tej liczby (&amp;lt;tt&amp;gt;17 == 0b10001&amp;lt;/tt&amp;gt;), a następnie metodę, zwracającą liczbę ''ustawionych'' (tj. równych jeden) bitów w tej reprezentacji. Nawiasy okrągłe są konieczne, ponieważ kropka po cyfrach oznaczałaby, że mamy do czynienia z zapisem liczby zmiennoprzecinkowej. Inaczej mówiąc, byłyby niepotrzebne gdybyśmy mieli do czynienia z nazwą oznaczającą liczbę całkowitą, a nie z jej zapisem dziesiętnym.&lt;br /&gt;
&lt;br /&gt;
Każdy obiekt w Pythonie jest ''instancją'' pewnej ''klasy''. Przykłady klas to: &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt; (liczby całkowite), &amp;lt;tt&amp;gt;str&amp;lt;/tt&amp;gt; (napisy), &amp;lt;tt&amp;gt;list&amp;lt;/tt&amp;gt; (listy), &amp;lt;tt&amp;gt;bool&amp;lt;/tt&amp;gt; (wartości logiczne), i wiele innych. Klasa to inaczej typ obiektów; charakteryzuje ona zestaw atrybutów i metod związanych z obiektami danej klasy.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&amp;lt;small&amp;gt;&lt;br /&gt;
Zazwyczaj różnych obiektów będących instancjami danej klasy może być wiele, potencjalnie nieskończenie wiele. Są jednak wyjątki. Np. klasa &amp;lt;tt&amp;gt;bool&amp;lt;/tt&amp;gt; posiada jedynie dwie instancje: (&amp;lt;tt&amp;gt;True&amp;lt;/tt&amp;gt; i &amp;lt;tt&amp;gt;False&amp;lt;/tt&amp;gt;). A obiekt &amp;lt;tt&amp;gt;None&amp;lt;/tt&amp;gt; jest wręcz jedyną instancją swojej klasy.&lt;br /&gt;
&amp;lt;/small&amp;gt;&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Niektóre klasy są ,,szczególnymi przypadkami&amp;quot; innych klas &amp;amp;mdash; mówi się, że klasa C ''dziedziczy'' z klasy B, lub że jest ''podklasą'' klasy B. Oznacza to tyle, że instancje klasy C posiadają wszystkie atrybuty i metody jakie posiadają instancje klasy B, ale być może pewne dodatkowe &amp;amp;mdash; a być może niektóre z nich zostały w jakiś sposób zmodyfikowane. Przykładowo, klasa &amp;lt;tt&amp;gt;bool&amp;lt;/tt&amp;gt; stanowi podklasę klasy &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt;; jej jedynie instancje, &amp;lt;tt&amp;gt;True&amp;lt;/tt&amp;gt; i &amp;lt;tt&amp;gt;False&amp;lt;/tt&amp;gt;, to ,,tak naprawdę&amp;quot; liczby (odpowiednio) 1 i 0 ,,w przebraniu&amp;quot;. Są one więc również instancjami klasy &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt; i można do nich stosować te same operacje (np. arytmetyczne) co do liczb całkowitych.&lt;br /&gt;
&lt;br /&gt;
''CDN''&lt;br /&gt;
&lt;br /&gt;
== O generatorach ==&lt;br /&gt;
&lt;br /&gt;
W jednym z poprzednich rozdziałów [[PPy3/Kolekcje#Przyk.C5.82ad:_suma_cyfr|poznaliśmy wyrażenia generatorowe]]. Przypomnijmy, że stanowią one uproszczony zapis iteracji, pozwalający na uniknięcie w wielu prostych przypadkach pętli &amp;lt;tt&amp;gt;for&amp;lt;/tt&amp;gt; i tworzenia zmiennych pomocniczych. Przykładowo:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;source lang=python&amp;gt;&lt;br /&gt;
 kwadraty = (x**2 for x in range(100))&lt;br /&gt;
 &amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
tworzy generator, ''produkujący'' w iteracji kwadraty kolejnych liczb naturalnych (od 0 do 99). &lt;br /&gt;
&lt;br /&gt;
Poważnym ograniczeniem wyrażeń generatorowych jest to, że można ich używać do przekształcenia jednego obiektu iterowalnego w drugi &amp;amp;mdash; w tym przypadku, ciągu liczb naturalnych w ciąg ich kwadratów, natomiast nie ma jak za pomocą wyrażenia generatorowego stworzyć obiektu iterowalnego ,,od zera&amp;quot;. Można to uzyskać, stosując ogólniejszą konstrukcję:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;source lang=python&amp;gt;&lt;br /&gt;
 def gen_kwadraty(start=0):&lt;br /&gt;
     k = start&lt;br /&gt;
     while True:&lt;br /&gt;
         yield k**2&lt;br /&gt;
         k += 1&lt;br /&gt;
&lt;br /&gt;
 kwadraty = gen_kwadraty()&lt;br /&gt;
 &amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To, co napisałem powyżej przypomina bardzo definicję funkcji; jedyną różnicą na poziomie składni jest wystąpienie w definicji słowa &amp;lt;tt&amp;gt;yield&amp;lt;/tt&amp;gt; (i brak wystąpienia słowa &amp;lt;tt&amp;gt;return&amp;lt;/tt&amp;gt;). W istocie &amp;lt;tt&amp;gt;gen_kwadraty&amp;lt;/tt&amp;gt; można uważać za funkcję &amp;amp;mdash; której wywołanie zwraca generator: obiekt, którego iteracja dostarczy kwadratów kolejnych liczb naturalnych, począwszy od liczby &amp;lt;tt&amp;gt;start&amp;lt;/tt&amp;gt;, argumentu wywołania, o domyślnej wartości zero. Zauważmy, że w budowie definicji nie użyliśmy obiektu &amp;lt;tt&amp;gt;range&amp;lt;/tt&amp;gt;; użyliśmy za to jawnej pętli &amp;lt;tt&amp;gt;while&amp;lt;/tt&amp;gt;, niejako opakowując ją w generator. Co więc w ten sposób zyskujemy?&lt;br /&gt;
&lt;br /&gt;
Przede wszystkim wielką elastyczność. W pokazanym przykładzie zysk jest niewielki, ale w definicji generatora możemy użyć jakiejkolwiek bądź reguły tworzenia kolejnych elementów iteracji. Nie potrzebujemy utworzyć ich wszystkich zanim zaczniemy z nich korzystać &amp;amp;mdash; tak jak byłoby w przypadku, gdybyśmy &amp;lt;tt&amp;gt;gen_kwadraty&amp;lt;/tt&amp;gt; zdefiniowali jako funkcję zwracającą listę kwadratów kolejnych liczb. Co więcej, iteracja zapewniona przez &amp;lt;tt&amp;gt;gen_kwadraty&amp;lt;/tt&amp;gt; może nam dostarczyć dowolnie wielu elementów (oczywiście w realnym komputerze po dostatecznie długim czasie osiągnięto by liczby, których wielkość przekroczyłaby pojemność dostępnej pamięci operacyjnej). Decyzja o tym, kiedy przerwać iterację pozostawiona jest ,,użytkownikowi&amp;quot;, tzn. kodowi odwołującemu się do obiektu &amp;lt;tt&amp;gt;kwadraty&amp;lt;/tt&amp;gt;.  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
[[PPy3/Matplotlib|poprzednie]] | [[&amp;quot;Programowanie z Pythonem3&amp;quot;|strona główna]] | [[PPy3/DobrePraktyki|dalej]]&lt;br /&gt;
&lt;br /&gt;
--[[Użytkownik:RobertJB|RobertJB]] ([[Dyskusja użytkownika:RobertJB|dyskusja]]) 14:26, 27 mar 2018 (CEST)&lt;/div&gt;</summary>
		<author><name>RobertJB</name></author>
		
	</entry>
	<entry>
		<id>http://brain.fuw.edu.pl/edu/index.php?title=PPy3/TematyDodatkowe&amp;diff=9470</id>
		<title>PPy3/TematyDodatkowe</title>
		<link rel="alternate" type="text/html" href="http://brain.fuw.edu.pl/edu/index.php?title=PPy3/TematyDodatkowe&amp;diff=9470"/>
		<updated>2023-06-29T12:02:41Z</updated>

		<summary type="html">&lt;p&gt;RobertJB: /* Trochę więcej o klasach i obiektach */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Tematy dodatkowe =&lt;br /&gt;
&lt;br /&gt;
== Błędy i wyjątki ==&lt;br /&gt;
&lt;br /&gt;
Każdy programista popełnia błędy &amp;amp;mdash; jest to nieunikniona część tej działalności. &lt;br /&gt;
&lt;br /&gt;
*Są błędy, które można nazwać banalnymi: literówka w nazwie lub słowie kluczowym, zapomniany dwukropek, niedomknięte nawiasy, itp. &lt;br /&gt;
*Są bardziej podstępne błędy logiczne: gdy algorytm, którego zapisem ma być tworzony kod, po prostu nie robi dokładnie tego, co nam się wydaje. &lt;br /&gt;
*I w końcu są sytuacje wyjątkowe: gdy w toku pracy programu zachodzą nieoczekiwane okoliczności &amp;amp;mdash; użytkownik podał błędną nazwę pliku z danymi, zawartość tego pliku nie jest zgodna z oczekiwaniami programu, połączenie sieciowe ulega przerwaniu w trakcie pobierania lub przesyłania danych, itp. &lt;br /&gt;
&lt;br /&gt;
Wszystkie te sytuacje nazywa się wyjątkami, i tym samym słowem określa się mechanizm, jakiego wiele współczesnych języków programowania (w tym Python) dostarcza programiście, aby mu pomóc określić działania jakie program miałby podjąć w sytuacjach wyjątkowych. Wyjątkowość takich sytuacji generalnie polega na tym, że w przypadku ich wystąpienia program po prostu nie może kontynuować przewidzianego toku działania:&lt;br /&gt;
&lt;br /&gt;
*błąd w składni programu oznacza, że kod nie daje się zinterpretować w sposób jednoznaczny; najlepsze co można zrobić, to w momencie wykrycia błędu przerwać działanie i spróbować dostarczyć programiście (w formie komunikatu) informację ułatwiającą określenie i naprawienie błędu;&lt;br /&gt;
*błędne działanie algorytmu można np. spróbować wykrywać za pomocą tzw. asercji (polecenie ''assert'') badających, czy pewne warunki, jakie powinny być spełnione przez dane przetwarzane w programie są istotnie spełnione;&lt;br /&gt;
*wyjątki powstałe na skutek okoliczności zachodzących w trakcie działania programu, uniemożliwiających jego normalną kontynuację, można spróbować przewidzieć i przygotować program do odpowiedniego zareagowania, czyli ''obsługi wyjątku''. Na przykład, można spróbować ponowić jeszcze raz (lub kilka razy) próbę łączności sieciowej, i poddać się dopiero po określonej liczbie niepowodzeń; natomiast w sytuacji błędu wynikającego z podania przez użytkownika programu niewłaściwych argumentów uruchomienia, warto postarać się o przekazanie użytkownikowi komunikatu informującego go w sposób dla niego zrozumiały, o właściwym sposobie uruchamiania programu.&lt;br /&gt;
&lt;br /&gt;
=== Błędy składniowe i podobne ===&lt;br /&gt;
&lt;br /&gt;
Jak wspomniano powyżej, w przypadku napotkania błędu składniowego w kodzie programu interpreter natychmiast przerwie wykonywanie programu i wypisze komunikat. Komunikaty te '''warto czytać uważnie''' &amp;amp;mdash; w większości przypadków znajduje się w nich cała informacja konieczna dla naprawienia błędu. Przykład: usiłujemy uruchomić program &amp;lt;tt&amp;gt;błąd.py&amp;lt;/tt&amp;gt;, którego treść to&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
x = (2 + 3) 4&lt;br /&gt;
print x&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wynik pierwszej próby to:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=bash&amp;gt;&lt;br /&gt;
$ python3 błąd.py &lt;br /&gt;
  File &amp;quot;błąd.py&amp;quot;, line 1&lt;br /&gt;
    x = (2 + 3) 4&lt;br /&gt;
                ^&lt;br /&gt;
SyntaxError: invalid syntax&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Z komunikatu całkiem jasno wynika, że napotkany został błąd składni (''SyntaxError''), że wykryto ten błąd w linijce 1, a nawet dokładnie &amp;amp;mdash; że miejscem, w którym interpreter stwierdził, że ma do czynienia z nieprawidłowy kodem, było wystąpienie cyfry 4 po zamykającym nawiasie. Po prostu zapomnieliśmy, że &amp;amp;mdash; inaczej niż w powszechnie stosowanej notacji matematycznej &amp;amp;mdash; w Pythonie aby uzyskać mnożenie, konieczne jest napisanie jawnie znaku operatora (gwiazdki).&lt;br /&gt;
&lt;br /&gt;
Po naprawieniu tej pomyłki próbujemy jeszcze raz, i wynik to:&lt;br /&gt;
&amp;lt;source lang=bash&amp;gt;&lt;br /&gt;
$ python3 błąd.py &lt;br /&gt;
  File &amp;quot;błąd.py&amp;quot;, line 2&lt;br /&gt;
    print x&lt;br /&gt;
          ^&lt;br /&gt;
SyntaxError: Missing parentheses in call to 'print'. Did you mean print(x)?&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Tutaj już jaśniej być nie może; interpreter nie tylko wskazał nam dokładne miejsce wystąpienia błędu, ale nawet dokładnie opisał, jak go naprawić.&lt;br /&gt;
&lt;br /&gt;
Oczywiście nie zawsze interpreter będzie w stanie wskazać nam błąd aż tak precyzyjnie. Jako przykład weźmy następujący plik:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
x, y, z = 3, 4, 5&lt;br /&gt;
print(max(x, y, z)&lt;br /&gt;
print(X * y * z)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
i wynik jego uruchomienia:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=bash&amp;gt;&lt;br /&gt;
$ python3 błąd.py &lt;br /&gt;
  File &amp;quot;błąd.py&amp;quot;, line 3&lt;br /&gt;
    print(X * y * z)&lt;br /&gt;
        ^&lt;br /&gt;
SyntaxError: invalid syntax&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dlaczego został wytknięty błąd składniowy w linijce 3? Przecież to w linijce 2 zapomnieliśmy zamknąć jeden z nawiasów.&lt;br /&gt;
&lt;br /&gt;
Otóż jeżeli z końcem linii Python stwierdza, że nie wszystkie dotąd otwarte nawiasy zostały zamknięte, to traktuje to jako oznaczające, że kolejną linijkę należy potraktować jako ciąg dalszy bieżącej. I w tym przypadku dopiero napotykając w kolejnej linijce nazwę &amp;lt;tt&amp;gt;print&amp;lt;/tt&amp;gt; &amp;amp;mdash; a nie np. przecinek, albo nawias zamykający &amp;amp;mdash; stwierdza, że coś musi być nie tak. Miejsce wykrycia błędu niestety nie zawsze się będzie pokrywało z miejscem jego faktycznego wystąpienia.&lt;br /&gt;
&lt;br /&gt;
Po poprawce, czyli zamknięciu nawiasu na linii 2, próbujemy jeszcze raz &amp;amp;mdash; z wynikiem&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=bash&amp;gt;&lt;br /&gt;
python3 błąd.py &lt;br /&gt;
5&lt;br /&gt;
Traceback (most recent call last):&lt;br /&gt;
  File &amp;quot;błąd.py&amp;quot;, line 3, in &amp;lt;module&amp;gt;&lt;br /&gt;
    print(X * y * z)&lt;br /&gt;
NameError: name 'X' is not defined&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
I tym razem chyba jest wszystko jasne: pojawiła się nazwa &amp;lt;tt&amp;gt;X&amp;lt;/tt&amp;gt;, z którą wcześniej nie związano żadnej wartości. Po prostu przez pomyłkę napisaliśmy X wielką literą zamiast małą. &lt;br /&gt;
&lt;br /&gt;
Te przykłady pokazują, że przy wykorzystaniu treści wypisywanych komunikatów proces usunięcia z programu błędów składniowych i formalnych może być dość szybki i bezbolesny.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&lt;br /&gt;
Pojawiły się w komunikatach określenia: &amp;lt;tt&amp;gt;SyntaxError&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;NameError&amp;lt;/tt&amp;gt;. Są to przykłady nazw tzw. klas wyjątków, czyli ogólnie rozumianych kategorii błędów, jakie są sygnalizowane. Wkrótce spotkamy dalsze klasy wyjątków, takie jak: &amp;lt;tt&amp;gt;TypeError&amp;lt;/tt&amp;gt; - związana z przekazaniem wielkości niewłaściwego typu, czy &amp;lt;tt&amp;gt;ValueError&amp;lt;/tt&amp;gt; - gdy nie typ. ale wartość wielkości, na której usiłuje się operować, jest niewłaściwa dla danej operacji. Dowiemy się również, dlaczego klasy wyjątków są przydatne &amp;amp;mdash; pomimo tego, iż dla ludzkich oczu zwykle bardziej przydatna jest słowna informacja uszczegółowiająca (to co pojawia się po nazwie klasy wyjątku i dwukropku).&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Asercje ===&lt;br /&gt;
&lt;br /&gt;
Polecenie &amp;lt;tt&amp;gt;assert&amp;lt;/tt&amp;gt; ma następującą postać:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
assert wyrażenie1&lt;br /&gt;
# lub:&lt;br /&gt;
assert wyrażenie1, wyrażenie2&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
i jest to jak widać polecenie proste (nie zawierające bloku poleceń z wcięciem).&lt;br /&gt;
&lt;br /&gt;
Jego działanie jest takie, że: obliczona zostanie wartość &amp;lt;tt&amp;gt;wyrażenie1&amp;lt;/tt&amp;gt;; jeżeli jest ona prawdziwa, nie dzieje się nic (następuje natychmiastowe przejście do kolejnej linijki kodu). Jeżeli okaże się fałszywa, zostanie zasygnalizowany wyjątek, klasy &amp;lt;tt&amp;gt;AssertionError&amp;lt;/tt&amp;gt;, co domyślnie przerywa wykonywanie programu i powoduje wypisanie odpowiedniego komunikatu. Jeżeli zastosujemy drugą postać, obliczona zostanie również wartość &amp;lt;tt&amp;gt;wyrażenie2&amp;lt;/tt&amp;gt; i wypisana (dokładniej: jej reprezentacja napisowa) jako część komunikatu.&lt;br /&gt;
&lt;br /&gt;
Przyjęło się stosować asercje jako sposób kontroli poprawności działania programu &amp;amp;mdash; w tym sensie, aby wykluczyć sytuacje „niemożliwe&amp;quot;, tj. powstałe w wyniku błędu programisty. Ze względu na prostotę składni warto też z nich korzystać w kodzie służącym do testowania poprawności innego kodu (czyli np. w funkcjach testujących, czy inne, bardziej złożone funkcje dają poprawne wyniki w prostych sytuacjach próbnych).&lt;br /&gt;
&lt;br /&gt;
=== Wyjątki w trakcie pracy programu ===&lt;br /&gt;
&lt;br /&gt;
Wyjątki występujące w trakcie pracy programu można przechwycić i obsłużyć za pomocą następującej konstrukcji (polecenia złożonego):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
try:&lt;br /&gt;
    # operacje mogące spowodować wyjątek&lt;br /&gt;
except (KlasaWyjątku1, KlasaWyjątku2, ...):&lt;br /&gt;
    # co zrobić jeśli wyjątek jednej z tych klas wystąpił&lt;br /&gt;
else: &lt;br /&gt;
    # co zrobić jeśli nie było wyjątku&lt;br /&gt;
finally:&lt;br /&gt;
    # co zrobić w KAŻDYM przypadku&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*bloki &amp;lt;tt&amp;gt;else:&amp;lt;/tt&amp;gt; i &amp;lt;tt&amp;gt;finally:&amp;lt;/tt&amp;gt; są nieobowiązkowe, tj. możemy je pominąć (wraz z odp. linijką wprowadzającą)&lt;br /&gt;
*w bloku &amp;lt;tt&amp;gt;except:&amp;lt;/tt&amp;gt; można podać jedną klasę wyjątku (wtedy zbędne są nawiasy), lub żadnej &amp;amp;mdash; wtedy przechwycimy ''każdy'' wyjątek; jeśli jednak chcemy, jak w przykładzie, wymienić więcej niż jedną klasę, to nawiasy są konieczne&lt;br /&gt;
*skuteczne przechwycenie wyjątku sprawia, że wykonanie programu nie ulegnie przerwaniu w punkcie jego wystąpienia, tyko będzie kontynuowane, również po opuszczeniu bloku &amp;lt;tt&amp;gt;try:&amp;lt;/tt&amp;gt;&lt;br /&gt;
*można jednak spowodować, aby po wykonaniu czynności obsługi wyjątku, wyjątek został niejako ''wznowiony''; wystarczy w bloku &amp;lt;tt&amp;gt;except:&amp;lt;/tt&amp;gt; wywołać instrukcję &amp;lt;tt&amp;gt;raise&amp;lt;/tt&amp;gt;. Dla większości klas wyjątków skutkuje to zakończeniem programu&lt;br /&gt;
*instrukcję &amp;lt;tt&amp;gt;raise&amp;lt;/tt&amp;gt; można wywołać również w dowolnym innym punkcie programu, powinna wówczas w niej wystąpić nazwa klasy wyjątku, jaki chcemy wywołać. &lt;br /&gt;
&lt;br /&gt;
Przykłady:&lt;br /&gt;
&lt;br /&gt;
''CDN.''&lt;br /&gt;
&lt;br /&gt;
== Trochę więcej o klasach i obiektach ==&lt;br /&gt;
&lt;br /&gt;
Warto sobie zdawać sprawę, że każda wartość występująca w programie pythonowym jest obiektem &amp;amp;mdash; a więc jest wyposażona w zestaw atrybutów i metod. Dotyczy to nie tylko kolekcji (list, słowników, ...), obiektów takich jak otwarte pliki (wynik wywołania funkcji &amp;lt;tt&amp;gt;open()&amp;lt;/tt&amp;gt;), napisów &amp;amp;mdash; ale również np. liczb, czy to całkowitych, czy zmiennoprzecinkowych (i zespolonych, o których nie było tutaj mowy). &lt;br /&gt;
&lt;br /&gt;
Przykładowo:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
(17).bit_length()&lt;br /&gt;
→ 5&lt;br /&gt;
(17).bit_count()&lt;br /&gt;
→ 2&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Co to właściwie znaczy?&lt;br /&gt;
&lt;br /&gt;
Dla liczby 17 wywołaliśmy najpierw metodę, który mówi nam jak jest długość w bitach reprezentacji dwójkowej tej liczby (&amp;lt;tt&amp;gt;17 == 0b10001&amp;lt;/tt&amp;gt;), a następnie metodę, zwracającą liczbę ''ustawionych'' (tj. równych jeden) bitów w tej reprezentacji. Nawiasy okrągłe są konieczne, ponieważ kropka po cyfrach oznaczałaby, że mamy do czynienia z zapisem liczby zmiennoprzecinkowej. Inaczej mówiąc, byłyby niepotrzebne gdybyśmy mieli do czynienia z nazwą oznaczającą liczbę całkowitą, a nie z jej zapisem dziesiętnym.&lt;br /&gt;
&lt;br /&gt;
== O generatorach ==&lt;br /&gt;
&lt;br /&gt;
W jednym z poprzednich rozdziałów [[PPy3/Kolekcje#Przyk.C5.82ad:_suma_cyfr|poznaliśmy wyrażenia generatorowe]]. Przypomnijmy, że stanowią one uproszczony zapis iteracji, pozwalający na uniknięcie w wielu prostych przypadkach pętli &amp;lt;tt&amp;gt;for&amp;lt;/tt&amp;gt; i tworzenia zmiennych pomocniczych. Przykładowo:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;source lang=python&amp;gt;&lt;br /&gt;
 kwadraty = (x**2 for x in range(100))&lt;br /&gt;
 &amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
tworzy generator, ''produkujący'' w iteracji kwadraty kolejnych liczb naturalnych (od 0 do 99). &lt;br /&gt;
&lt;br /&gt;
Poważnym ograniczeniem wyrażeń generatorowych jest to, że można ich używać do przekształcenia jednego obiektu iterowalnego w drugi &amp;amp;mdash; w tym przypadku, ciągu liczb naturalnych w ciąg ich kwadratów, natomiast nie ma jak za pomocą wyrażenia generatorowego stworzyć obiektu iterowalnego ,,od zera&amp;quot;. Można to uzyskać, stosując ogólniejszą konstrukcję:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;source lang=python&amp;gt;&lt;br /&gt;
 def gen_kwadraty(start=0):&lt;br /&gt;
     k = start&lt;br /&gt;
     while True:&lt;br /&gt;
         yield k**2&lt;br /&gt;
         k += 1&lt;br /&gt;
&lt;br /&gt;
 kwadraty = gen_kwadraty()&lt;br /&gt;
 &amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To, co napisałem powyżej przypomina bardzo definicję funkcji; jedyną różnicą na poziomie składni jest wystąpienie w definicji słowa &amp;lt;tt&amp;gt;yield&amp;lt;/tt&amp;gt; (i brak wystąpienia słowa &amp;lt;tt&amp;gt;return&amp;lt;/tt&amp;gt;). W istocie &amp;lt;tt&amp;gt;gen_kwadraty&amp;lt;/tt&amp;gt; można uważać za funkcję &amp;amp;mdash; której wywołanie zwraca generator: obiekt, którego iteracja dostarczy kwadratów kolejnych liczb naturalnych, począwszy od liczby &amp;lt;tt&amp;gt;start&amp;lt;/tt&amp;gt;, argumentu wywołania, o domyślnej wartości zero. Zauważmy, że w budowie definicji nie użyliśmy obiektu &amp;lt;tt&amp;gt;range&amp;lt;/tt&amp;gt;; użyliśmy za to jawnej pętli &amp;lt;tt&amp;gt;while&amp;lt;/tt&amp;gt;, niejako opakowując ją w generator. Co więc w ten sposób zyskujemy?&lt;br /&gt;
&lt;br /&gt;
Przede wszystkim wielką elastyczność. W pokazanym przykładzie zysk jest niewielki, ale w definicji generatora możemy użyć jakiejkolwiek bądź reguły tworzenia kolejnych elementów iteracji. Nie potrzebujemy utworzyć ich wszystkich zanim zaczniemy z nich korzystać &amp;amp;mdash; tak jak byłoby w przypadku, gdybyśmy &amp;lt;tt&amp;gt;gen_kwadraty&amp;lt;/tt&amp;gt; zdefiniowali jako funkcję zwracającą listę kwadratów kolejnych liczb. Co więcej, iteracja zapewniona przez &amp;lt;tt&amp;gt;gen_kwadraty&amp;lt;/tt&amp;gt; może nam dostarczyć dowolnie wielu elementów (oczywiście w realnym komputerze po dostatecznie długim czasie osiągnięto by liczby, których wielkość przekroczyłaby pojemność dostępnej pamięci operacyjnej). Decyzja o tym, kiedy przerwać iterację pozostawiona jest ,,użytkownikowi&amp;quot;, tzn. kodowi odwołującemu się do obiektu &amp;lt;tt&amp;gt;kwadraty&amp;lt;/tt&amp;gt;.  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
[[PPy3/Matplotlib|poprzednie]] | [[&amp;quot;Programowanie z Pythonem3&amp;quot;|strona główna]] | [[PPy3/DobrePraktyki|dalej]]&lt;br /&gt;
&lt;br /&gt;
--[[Użytkownik:RobertJB|RobertJB]] ([[Dyskusja użytkownika:RobertJB|dyskusja]]) 14:26, 27 mar 2018 (CEST)&lt;/div&gt;</summary>
		<author><name>RobertJB</name></author>
		
	</entry>
	<entry>
		<id>http://brain.fuw.edu.pl/edu/index.php?title=PPy3/TematyDodatkowe&amp;diff=9469</id>
		<title>PPy3/TematyDodatkowe</title>
		<link rel="alternate" type="text/html" href="http://brain.fuw.edu.pl/edu/index.php?title=PPy3/TematyDodatkowe&amp;diff=9469"/>
		<updated>2023-06-29T12:01:53Z</updated>

		<summary type="html">&lt;p&gt;RobertJB: /* Trochę więcej o klasach i obiektach */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Tematy dodatkowe =&lt;br /&gt;
&lt;br /&gt;
== Błędy i wyjątki ==&lt;br /&gt;
&lt;br /&gt;
Każdy programista popełnia błędy &amp;amp;mdash; jest to nieunikniona część tej działalności. &lt;br /&gt;
&lt;br /&gt;
*Są błędy, które można nazwać banalnymi: literówka w nazwie lub słowie kluczowym, zapomniany dwukropek, niedomknięte nawiasy, itp. &lt;br /&gt;
*Są bardziej podstępne błędy logiczne: gdy algorytm, którego zapisem ma być tworzony kod, po prostu nie robi dokładnie tego, co nam się wydaje. &lt;br /&gt;
*I w końcu są sytuacje wyjątkowe: gdy w toku pracy programu zachodzą nieoczekiwane okoliczności &amp;amp;mdash; użytkownik podał błędną nazwę pliku z danymi, zawartość tego pliku nie jest zgodna z oczekiwaniami programu, połączenie sieciowe ulega przerwaniu w trakcie pobierania lub przesyłania danych, itp. &lt;br /&gt;
&lt;br /&gt;
Wszystkie te sytuacje nazywa się wyjątkami, i tym samym słowem określa się mechanizm, jakiego wiele współczesnych języków programowania (w tym Python) dostarcza programiście, aby mu pomóc określić działania jakie program miałby podjąć w sytuacjach wyjątkowych. Wyjątkowość takich sytuacji generalnie polega na tym, że w przypadku ich wystąpienia program po prostu nie może kontynuować przewidzianego toku działania:&lt;br /&gt;
&lt;br /&gt;
*błąd w składni programu oznacza, że kod nie daje się zinterpretować w sposób jednoznaczny; najlepsze co można zrobić, to w momencie wykrycia błędu przerwać działanie i spróbować dostarczyć programiście (w formie komunikatu) informację ułatwiającą określenie i naprawienie błędu;&lt;br /&gt;
*błędne działanie algorytmu można np. spróbować wykrywać za pomocą tzw. asercji (polecenie ''assert'') badających, czy pewne warunki, jakie powinny być spełnione przez dane przetwarzane w programie są istotnie spełnione;&lt;br /&gt;
*wyjątki powstałe na skutek okoliczności zachodzących w trakcie działania programu, uniemożliwiających jego normalną kontynuację, można spróbować przewidzieć i przygotować program do odpowiedniego zareagowania, czyli ''obsługi wyjątku''. Na przykład, można spróbować ponowić jeszcze raz (lub kilka razy) próbę łączności sieciowej, i poddać się dopiero po określonej liczbie niepowodzeń; natomiast w sytuacji błędu wynikającego z podania przez użytkownika programu niewłaściwych argumentów uruchomienia, warto postarać się o przekazanie użytkownikowi komunikatu informującego go w sposób dla niego zrozumiały, o właściwym sposobie uruchamiania programu.&lt;br /&gt;
&lt;br /&gt;
=== Błędy składniowe i podobne ===&lt;br /&gt;
&lt;br /&gt;
Jak wspomniano powyżej, w przypadku napotkania błędu składniowego w kodzie programu interpreter natychmiast przerwie wykonywanie programu i wypisze komunikat. Komunikaty te '''warto czytać uważnie''' &amp;amp;mdash; w większości przypadków znajduje się w nich cała informacja konieczna dla naprawienia błędu. Przykład: usiłujemy uruchomić program &amp;lt;tt&amp;gt;błąd.py&amp;lt;/tt&amp;gt;, którego treść to&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
x = (2 + 3) 4&lt;br /&gt;
print x&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wynik pierwszej próby to:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=bash&amp;gt;&lt;br /&gt;
$ python3 błąd.py &lt;br /&gt;
  File &amp;quot;błąd.py&amp;quot;, line 1&lt;br /&gt;
    x = (2 + 3) 4&lt;br /&gt;
                ^&lt;br /&gt;
SyntaxError: invalid syntax&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Z komunikatu całkiem jasno wynika, że napotkany został błąd składni (''SyntaxError''), że wykryto ten błąd w linijce 1, a nawet dokładnie &amp;amp;mdash; że miejscem, w którym interpreter stwierdził, że ma do czynienia z nieprawidłowy kodem, było wystąpienie cyfry 4 po zamykającym nawiasie. Po prostu zapomnieliśmy, że &amp;amp;mdash; inaczej niż w powszechnie stosowanej notacji matematycznej &amp;amp;mdash; w Pythonie aby uzyskać mnożenie, konieczne jest napisanie jawnie znaku operatora (gwiazdki).&lt;br /&gt;
&lt;br /&gt;
Po naprawieniu tej pomyłki próbujemy jeszcze raz, i wynik to:&lt;br /&gt;
&amp;lt;source lang=bash&amp;gt;&lt;br /&gt;
$ python3 błąd.py &lt;br /&gt;
  File &amp;quot;błąd.py&amp;quot;, line 2&lt;br /&gt;
    print x&lt;br /&gt;
          ^&lt;br /&gt;
SyntaxError: Missing parentheses in call to 'print'. Did you mean print(x)?&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Tutaj już jaśniej być nie może; interpreter nie tylko wskazał nam dokładne miejsce wystąpienia błędu, ale nawet dokładnie opisał, jak go naprawić.&lt;br /&gt;
&lt;br /&gt;
Oczywiście nie zawsze interpreter będzie w stanie wskazać nam błąd aż tak precyzyjnie. Jako przykład weźmy następujący plik:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
x, y, z = 3, 4, 5&lt;br /&gt;
print(max(x, y, z)&lt;br /&gt;
print(X * y * z)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
i wynik jego uruchomienia:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=bash&amp;gt;&lt;br /&gt;
$ python3 błąd.py &lt;br /&gt;
  File &amp;quot;błąd.py&amp;quot;, line 3&lt;br /&gt;
    print(X * y * z)&lt;br /&gt;
        ^&lt;br /&gt;
SyntaxError: invalid syntax&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dlaczego został wytknięty błąd składniowy w linijce 3? Przecież to w linijce 2 zapomnieliśmy zamknąć jeden z nawiasów.&lt;br /&gt;
&lt;br /&gt;
Otóż jeżeli z końcem linii Python stwierdza, że nie wszystkie dotąd otwarte nawiasy zostały zamknięte, to traktuje to jako oznaczające, że kolejną linijkę należy potraktować jako ciąg dalszy bieżącej. I w tym przypadku dopiero napotykając w kolejnej linijce nazwę &amp;lt;tt&amp;gt;print&amp;lt;/tt&amp;gt; &amp;amp;mdash; a nie np. przecinek, albo nawias zamykający &amp;amp;mdash; stwierdza, że coś musi być nie tak. Miejsce wykrycia błędu niestety nie zawsze się będzie pokrywało z miejscem jego faktycznego wystąpienia.&lt;br /&gt;
&lt;br /&gt;
Po poprawce, czyli zamknięciu nawiasu na linii 2, próbujemy jeszcze raz &amp;amp;mdash; z wynikiem&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=bash&amp;gt;&lt;br /&gt;
python3 błąd.py &lt;br /&gt;
5&lt;br /&gt;
Traceback (most recent call last):&lt;br /&gt;
  File &amp;quot;błąd.py&amp;quot;, line 3, in &amp;lt;module&amp;gt;&lt;br /&gt;
    print(X * y * z)&lt;br /&gt;
NameError: name 'X' is not defined&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
I tym razem chyba jest wszystko jasne: pojawiła się nazwa &amp;lt;tt&amp;gt;X&amp;lt;/tt&amp;gt;, z którą wcześniej nie związano żadnej wartości. Po prostu przez pomyłkę napisaliśmy X wielką literą zamiast małą. &lt;br /&gt;
&lt;br /&gt;
Te przykłady pokazują, że przy wykorzystaniu treści wypisywanych komunikatów proces usunięcia z programu błędów składniowych i formalnych może być dość szybki i bezbolesny.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&lt;br /&gt;
Pojawiły się w komunikatach określenia: &amp;lt;tt&amp;gt;SyntaxError&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;NameError&amp;lt;/tt&amp;gt;. Są to przykłady nazw tzw. klas wyjątków, czyli ogólnie rozumianych kategorii błędów, jakie są sygnalizowane. Wkrótce spotkamy dalsze klasy wyjątków, takie jak: &amp;lt;tt&amp;gt;TypeError&amp;lt;/tt&amp;gt; - związana z przekazaniem wielkości niewłaściwego typu, czy &amp;lt;tt&amp;gt;ValueError&amp;lt;/tt&amp;gt; - gdy nie typ. ale wartość wielkości, na której usiłuje się operować, jest niewłaściwa dla danej operacji. Dowiemy się również, dlaczego klasy wyjątków są przydatne &amp;amp;mdash; pomimo tego, iż dla ludzkich oczu zwykle bardziej przydatna jest słowna informacja uszczegółowiająca (to co pojawia się po nazwie klasy wyjątku i dwukropku).&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Asercje ===&lt;br /&gt;
&lt;br /&gt;
Polecenie &amp;lt;tt&amp;gt;assert&amp;lt;/tt&amp;gt; ma następującą postać:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
assert wyrażenie1&lt;br /&gt;
# lub:&lt;br /&gt;
assert wyrażenie1, wyrażenie2&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
i jest to jak widać polecenie proste (nie zawierające bloku poleceń z wcięciem).&lt;br /&gt;
&lt;br /&gt;
Jego działanie jest takie, że: obliczona zostanie wartość &amp;lt;tt&amp;gt;wyrażenie1&amp;lt;/tt&amp;gt;; jeżeli jest ona prawdziwa, nie dzieje się nic (następuje natychmiastowe przejście do kolejnej linijki kodu). Jeżeli okaże się fałszywa, zostanie zasygnalizowany wyjątek, klasy &amp;lt;tt&amp;gt;AssertionError&amp;lt;/tt&amp;gt;, co domyślnie przerywa wykonywanie programu i powoduje wypisanie odpowiedniego komunikatu. Jeżeli zastosujemy drugą postać, obliczona zostanie również wartość &amp;lt;tt&amp;gt;wyrażenie2&amp;lt;/tt&amp;gt; i wypisana (dokładniej: jej reprezentacja napisowa) jako część komunikatu.&lt;br /&gt;
&lt;br /&gt;
Przyjęło się stosować asercje jako sposób kontroli poprawności działania programu &amp;amp;mdash; w tym sensie, aby wykluczyć sytuacje „niemożliwe&amp;quot;, tj. powstałe w wyniku błędu programisty. Ze względu na prostotę składni warto też z nich korzystać w kodzie służącym do testowania poprawności innego kodu (czyli np. w funkcjach testujących, czy inne, bardziej złożone funkcje dają poprawne wyniki w prostych sytuacjach próbnych).&lt;br /&gt;
&lt;br /&gt;
=== Wyjątki w trakcie pracy programu ===&lt;br /&gt;
&lt;br /&gt;
Wyjątki występujące w trakcie pracy programu można przechwycić i obsłużyć za pomocą następującej konstrukcji (polecenia złożonego):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
try:&lt;br /&gt;
    # operacje mogące spowodować wyjątek&lt;br /&gt;
except (KlasaWyjątku1, KlasaWyjątku2, ...):&lt;br /&gt;
    # co zrobić jeśli wyjątek jednej z tych klas wystąpił&lt;br /&gt;
else: &lt;br /&gt;
    # co zrobić jeśli nie było wyjątku&lt;br /&gt;
finally:&lt;br /&gt;
    # co zrobić w KAŻDYM przypadku&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*bloki &amp;lt;tt&amp;gt;else:&amp;lt;/tt&amp;gt; i &amp;lt;tt&amp;gt;finally:&amp;lt;/tt&amp;gt; są nieobowiązkowe, tj. możemy je pominąć (wraz z odp. linijką wprowadzającą)&lt;br /&gt;
*w bloku &amp;lt;tt&amp;gt;except:&amp;lt;/tt&amp;gt; można podać jedną klasę wyjątku (wtedy zbędne są nawiasy), lub żadnej &amp;amp;mdash; wtedy przechwycimy ''każdy'' wyjątek; jeśli jednak chcemy, jak w przykładzie, wymienić więcej niż jedną klasę, to nawiasy są konieczne&lt;br /&gt;
*skuteczne przechwycenie wyjątku sprawia, że wykonanie programu nie ulegnie przerwaniu w punkcie jego wystąpienia, tyko będzie kontynuowane, również po opuszczeniu bloku &amp;lt;tt&amp;gt;try:&amp;lt;/tt&amp;gt;&lt;br /&gt;
*można jednak spowodować, aby po wykonaniu czynności obsługi wyjątku, wyjątek został niejako ''wznowiony''; wystarczy w bloku &amp;lt;tt&amp;gt;except:&amp;lt;/tt&amp;gt; wywołać instrukcję &amp;lt;tt&amp;gt;raise&amp;lt;/tt&amp;gt;. Dla większości klas wyjątków skutkuje to zakończeniem programu&lt;br /&gt;
*instrukcję &amp;lt;tt&amp;gt;raise&amp;lt;/tt&amp;gt; można wywołać również w dowolnym innym punkcie programu, powinna wówczas w niej wystąpić nazwa klasy wyjątku, jaki chcemy wywołać. &lt;br /&gt;
&lt;br /&gt;
Przykłady:&lt;br /&gt;
&lt;br /&gt;
''CDN.''&lt;br /&gt;
&lt;br /&gt;
== Trochę więcej o klasach i obiektach ==&lt;br /&gt;
&lt;br /&gt;
Warto sobie zdawać sprawę, że każda wartość występująca w programie pythonowym jest obiektem &amp;amp;mdash; a więc jest wyposażona w zestaw atrybutów i metod. Dotyczy to nie tylko kolekcji (list, słowników, ...), obiektów takich jak otwarte pliki (wynik wywołania funkcji &amp;lt;tt&amp;gt;open()&amp;lt;/tt&amp;gt;), napisów &amp;amp;mdash; ale również np. liczb, czy to całkowitych, czy zmiennoprzecinkowych (i zespolonych, o których nie było tutaj mowy). &lt;br /&gt;
&lt;br /&gt;
Przykładowo:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
(17).bit_length()&lt;br /&gt;
→ 5&lt;br /&gt;
(17).bit_count()&lt;br /&gt;
→ 2&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Co to właściwie znaczy?&lt;br /&gt;
&lt;br /&gt;
Dla liczby 17 wywołaliśmy najpierw metodę, który mówi nam jak jest długość w bitach reprezentacji dwójkowej tej liczby (&amp;lt;tt&amp;gt;17 == 0b10001&amp;lt;/tt&amp;gt;), a następnie metodę, zwracającą liczbę *ustawionych* (tj. równych jeden) bitów w tej reprezentacji. Nawiasy okrągłe są konieczne, ponieważ kropka po cyfrach oznaczałaby, że mamy do czynienia z zapisem liczby zmiennoprzecinkowej. Inaczej mówiąc, byłyby niepotrzebne gdybyśmy mieli do czynienia z nazwą oznaczającą liczbę całkowitą, a nie z jej zapisem dziesiętnym.&lt;br /&gt;
&lt;br /&gt;
== O generatorach ==&lt;br /&gt;
&lt;br /&gt;
W jednym z poprzednich rozdziałów [[PPy3/Kolekcje#Przyk.C5.82ad:_suma_cyfr|poznaliśmy wyrażenia generatorowe]]. Przypomnijmy, że stanowią one uproszczony zapis iteracji, pozwalający na uniknięcie w wielu prostych przypadkach pętli &amp;lt;tt&amp;gt;for&amp;lt;/tt&amp;gt; i tworzenia zmiennych pomocniczych. Przykładowo:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;source lang=python&amp;gt;&lt;br /&gt;
 kwadraty = (x**2 for x in range(100))&lt;br /&gt;
 &amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
tworzy generator, ''produkujący'' w iteracji kwadraty kolejnych liczb naturalnych (od 0 do 99). &lt;br /&gt;
&lt;br /&gt;
Poważnym ograniczeniem wyrażeń generatorowych jest to, że można ich używać do przekształcenia jednego obiektu iterowalnego w drugi &amp;amp;mdash; w tym przypadku, ciągu liczb naturalnych w ciąg ich kwadratów, natomiast nie ma jak za pomocą wyrażenia generatorowego stworzyć obiektu iterowalnego ,,od zera&amp;quot;. Można to uzyskać, stosując ogólniejszą konstrukcję:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;source lang=python&amp;gt;&lt;br /&gt;
 def gen_kwadraty(start=0):&lt;br /&gt;
     k = start&lt;br /&gt;
     while True:&lt;br /&gt;
         yield k**2&lt;br /&gt;
         k += 1&lt;br /&gt;
&lt;br /&gt;
 kwadraty = gen_kwadraty()&lt;br /&gt;
 &amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To, co napisałem powyżej przypomina bardzo definicję funkcji; jedyną różnicą na poziomie składni jest wystąpienie w definicji słowa &amp;lt;tt&amp;gt;yield&amp;lt;/tt&amp;gt; (i brak wystąpienia słowa &amp;lt;tt&amp;gt;return&amp;lt;/tt&amp;gt;). W istocie &amp;lt;tt&amp;gt;gen_kwadraty&amp;lt;/tt&amp;gt; można uważać za funkcję &amp;amp;mdash; której wywołanie zwraca generator: obiekt, którego iteracja dostarczy kwadratów kolejnych liczb naturalnych, począwszy od liczby &amp;lt;tt&amp;gt;start&amp;lt;/tt&amp;gt;, argumentu wywołania, o domyślnej wartości zero. Zauważmy, że w budowie definicji nie użyliśmy obiektu &amp;lt;tt&amp;gt;range&amp;lt;/tt&amp;gt;; użyliśmy za to jawnej pętli &amp;lt;tt&amp;gt;while&amp;lt;/tt&amp;gt;, niejako opakowując ją w generator. Co więc w ten sposób zyskujemy?&lt;br /&gt;
&lt;br /&gt;
Przede wszystkim wielką elastyczność. W pokazanym przykładzie zysk jest niewielki, ale w definicji generatora możemy użyć jakiejkolwiek bądź reguły tworzenia kolejnych elementów iteracji. Nie potrzebujemy utworzyć ich wszystkich zanim zaczniemy z nich korzystać &amp;amp;mdash; tak jak byłoby w przypadku, gdybyśmy &amp;lt;tt&amp;gt;gen_kwadraty&amp;lt;/tt&amp;gt; zdefiniowali jako funkcję zwracającą listę kwadratów kolejnych liczb. Co więcej, iteracja zapewniona przez &amp;lt;tt&amp;gt;gen_kwadraty&amp;lt;/tt&amp;gt; może nam dostarczyć dowolnie wielu elementów (oczywiście w realnym komputerze po dostatecznie długim czasie osiągnięto by liczby, których wielkość przekroczyłaby pojemność dostępnej pamięci operacyjnej). Decyzja o tym, kiedy przerwać iterację pozostawiona jest ,,użytkownikowi&amp;quot;, tzn. kodowi odwołującemu się do obiektu &amp;lt;tt&amp;gt;kwadraty&amp;lt;/tt&amp;gt;.  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
[[PPy3/Matplotlib|poprzednie]] | [[&amp;quot;Programowanie z Pythonem3&amp;quot;|strona główna]] | [[PPy3/DobrePraktyki|dalej]]&lt;br /&gt;
&lt;br /&gt;
--[[Użytkownik:RobertJB|RobertJB]] ([[Dyskusja użytkownika:RobertJB|dyskusja]]) 14:26, 27 mar 2018 (CEST)&lt;/div&gt;</summary>
		<author><name>RobertJB</name></author>
		
	</entry>
	<entry>
		<id>http://brain.fuw.edu.pl/edu/index.php?title=PPy3/TematyDodatkowe&amp;diff=9468</id>
		<title>PPy3/TematyDodatkowe</title>
		<link rel="alternate" type="text/html" href="http://brain.fuw.edu.pl/edu/index.php?title=PPy3/TematyDodatkowe&amp;diff=9468"/>
		<updated>2023-06-29T12:01:28Z</updated>

		<summary type="html">&lt;p&gt;RobertJB: /* Trochę więcej o klasach i obiektach */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Tematy dodatkowe =&lt;br /&gt;
&lt;br /&gt;
== Błędy i wyjątki ==&lt;br /&gt;
&lt;br /&gt;
Każdy programista popełnia błędy &amp;amp;mdash; jest to nieunikniona część tej działalności. &lt;br /&gt;
&lt;br /&gt;
*Są błędy, które można nazwać banalnymi: literówka w nazwie lub słowie kluczowym, zapomniany dwukropek, niedomknięte nawiasy, itp. &lt;br /&gt;
*Są bardziej podstępne błędy logiczne: gdy algorytm, którego zapisem ma być tworzony kod, po prostu nie robi dokładnie tego, co nam się wydaje. &lt;br /&gt;
*I w końcu są sytuacje wyjątkowe: gdy w toku pracy programu zachodzą nieoczekiwane okoliczności &amp;amp;mdash; użytkownik podał błędną nazwę pliku z danymi, zawartość tego pliku nie jest zgodna z oczekiwaniami programu, połączenie sieciowe ulega przerwaniu w trakcie pobierania lub przesyłania danych, itp. &lt;br /&gt;
&lt;br /&gt;
Wszystkie te sytuacje nazywa się wyjątkami, i tym samym słowem określa się mechanizm, jakiego wiele współczesnych języków programowania (w tym Python) dostarcza programiście, aby mu pomóc określić działania jakie program miałby podjąć w sytuacjach wyjątkowych. Wyjątkowość takich sytuacji generalnie polega na tym, że w przypadku ich wystąpienia program po prostu nie może kontynuować przewidzianego toku działania:&lt;br /&gt;
&lt;br /&gt;
*błąd w składni programu oznacza, że kod nie daje się zinterpretować w sposób jednoznaczny; najlepsze co można zrobić, to w momencie wykrycia błędu przerwać działanie i spróbować dostarczyć programiście (w formie komunikatu) informację ułatwiającą określenie i naprawienie błędu;&lt;br /&gt;
*błędne działanie algorytmu można np. spróbować wykrywać za pomocą tzw. asercji (polecenie ''assert'') badających, czy pewne warunki, jakie powinny być spełnione przez dane przetwarzane w programie są istotnie spełnione;&lt;br /&gt;
*wyjątki powstałe na skutek okoliczności zachodzących w trakcie działania programu, uniemożliwiających jego normalną kontynuację, można spróbować przewidzieć i przygotować program do odpowiedniego zareagowania, czyli ''obsługi wyjątku''. Na przykład, można spróbować ponowić jeszcze raz (lub kilka razy) próbę łączności sieciowej, i poddać się dopiero po określonej liczbie niepowodzeń; natomiast w sytuacji błędu wynikającego z podania przez użytkownika programu niewłaściwych argumentów uruchomienia, warto postarać się o przekazanie użytkownikowi komunikatu informującego go w sposób dla niego zrozumiały, o właściwym sposobie uruchamiania programu.&lt;br /&gt;
&lt;br /&gt;
=== Błędy składniowe i podobne ===&lt;br /&gt;
&lt;br /&gt;
Jak wspomniano powyżej, w przypadku napotkania błędu składniowego w kodzie programu interpreter natychmiast przerwie wykonywanie programu i wypisze komunikat. Komunikaty te '''warto czytać uważnie''' &amp;amp;mdash; w większości przypadków znajduje się w nich cała informacja konieczna dla naprawienia błędu. Przykład: usiłujemy uruchomić program &amp;lt;tt&amp;gt;błąd.py&amp;lt;/tt&amp;gt;, którego treść to&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
x = (2 + 3) 4&lt;br /&gt;
print x&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wynik pierwszej próby to:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=bash&amp;gt;&lt;br /&gt;
$ python3 błąd.py &lt;br /&gt;
  File &amp;quot;błąd.py&amp;quot;, line 1&lt;br /&gt;
    x = (2 + 3) 4&lt;br /&gt;
                ^&lt;br /&gt;
SyntaxError: invalid syntax&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Z komunikatu całkiem jasno wynika, że napotkany został błąd składni (''SyntaxError''), że wykryto ten błąd w linijce 1, a nawet dokładnie &amp;amp;mdash; że miejscem, w którym interpreter stwierdził, że ma do czynienia z nieprawidłowy kodem, było wystąpienie cyfry 4 po zamykającym nawiasie. Po prostu zapomnieliśmy, że &amp;amp;mdash; inaczej niż w powszechnie stosowanej notacji matematycznej &amp;amp;mdash; w Pythonie aby uzyskać mnożenie, konieczne jest napisanie jawnie znaku operatora (gwiazdki).&lt;br /&gt;
&lt;br /&gt;
Po naprawieniu tej pomyłki próbujemy jeszcze raz, i wynik to:&lt;br /&gt;
&amp;lt;source lang=bash&amp;gt;&lt;br /&gt;
$ python3 błąd.py &lt;br /&gt;
  File &amp;quot;błąd.py&amp;quot;, line 2&lt;br /&gt;
    print x&lt;br /&gt;
          ^&lt;br /&gt;
SyntaxError: Missing parentheses in call to 'print'. Did you mean print(x)?&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Tutaj już jaśniej być nie może; interpreter nie tylko wskazał nam dokładne miejsce wystąpienia błędu, ale nawet dokładnie opisał, jak go naprawić.&lt;br /&gt;
&lt;br /&gt;
Oczywiście nie zawsze interpreter będzie w stanie wskazać nam błąd aż tak precyzyjnie. Jako przykład weźmy następujący plik:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
x, y, z = 3, 4, 5&lt;br /&gt;
print(max(x, y, z)&lt;br /&gt;
print(X * y * z)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
i wynik jego uruchomienia:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=bash&amp;gt;&lt;br /&gt;
$ python3 błąd.py &lt;br /&gt;
  File &amp;quot;błąd.py&amp;quot;, line 3&lt;br /&gt;
    print(X * y * z)&lt;br /&gt;
        ^&lt;br /&gt;
SyntaxError: invalid syntax&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dlaczego został wytknięty błąd składniowy w linijce 3? Przecież to w linijce 2 zapomnieliśmy zamknąć jeden z nawiasów.&lt;br /&gt;
&lt;br /&gt;
Otóż jeżeli z końcem linii Python stwierdza, że nie wszystkie dotąd otwarte nawiasy zostały zamknięte, to traktuje to jako oznaczające, że kolejną linijkę należy potraktować jako ciąg dalszy bieżącej. I w tym przypadku dopiero napotykając w kolejnej linijce nazwę &amp;lt;tt&amp;gt;print&amp;lt;/tt&amp;gt; &amp;amp;mdash; a nie np. przecinek, albo nawias zamykający &amp;amp;mdash; stwierdza, że coś musi być nie tak. Miejsce wykrycia błędu niestety nie zawsze się będzie pokrywało z miejscem jego faktycznego wystąpienia.&lt;br /&gt;
&lt;br /&gt;
Po poprawce, czyli zamknięciu nawiasu na linii 2, próbujemy jeszcze raz &amp;amp;mdash; z wynikiem&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=bash&amp;gt;&lt;br /&gt;
python3 błąd.py &lt;br /&gt;
5&lt;br /&gt;
Traceback (most recent call last):&lt;br /&gt;
  File &amp;quot;błąd.py&amp;quot;, line 3, in &amp;lt;module&amp;gt;&lt;br /&gt;
    print(X * y * z)&lt;br /&gt;
NameError: name 'X' is not defined&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
I tym razem chyba jest wszystko jasne: pojawiła się nazwa &amp;lt;tt&amp;gt;X&amp;lt;/tt&amp;gt;, z którą wcześniej nie związano żadnej wartości. Po prostu przez pomyłkę napisaliśmy X wielką literą zamiast małą. &lt;br /&gt;
&lt;br /&gt;
Te przykłady pokazują, że przy wykorzystaniu treści wypisywanych komunikatów proces usunięcia z programu błędów składniowych i formalnych może być dość szybki i bezbolesny.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&lt;br /&gt;
Pojawiły się w komunikatach określenia: &amp;lt;tt&amp;gt;SyntaxError&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;NameError&amp;lt;/tt&amp;gt;. Są to przykłady nazw tzw. klas wyjątków, czyli ogólnie rozumianych kategorii błędów, jakie są sygnalizowane. Wkrótce spotkamy dalsze klasy wyjątków, takie jak: &amp;lt;tt&amp;gt;TypeError&amp;lt;/tt&amp;gt; - związana z przekazaniem wielkości niewłaściwego typu, czy &amp;lt;tt&amp;gt;ValueError&amp;lt;/tt&amp;gt; - gdy nie typ. ale wartość wielkości, na której usiłuje się operować, jest niewłaściwa dla danej operacji. Dowiemy się również, dlaczego klasy wyjątków są przydatne &amp;amp;mdash; pomimo tego, iż dla ludzkich oczu zwykle bardziej przydatna jest słowna informacja uszczegółowiająca (to co pojawia się po nazwie klasy wyjątku i dwukropku).&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Asercje ===&lt;br /&gt;
&lt;br /&gt;
Polecenie &amp;lt;tt&amp;gt;assert&amp;lt;/tt&amp;gt; ma następującą postać:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
assert wyrażenie1&lt;br /&gt;
# lub:&lt;br /&gt;
assert wyrażenie1, wyrażenie2&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
i jest to jak widać polecenie proste (nie zawierające bloku poleceń z wcięciem).&lt;br /&gt;
&lt;br /&gt;
Jego działanie jest takie, że: obliczona zostanie wartość &amp;lt;tt&amp;gt;wyrażenie1&amp;lt;/tt&amp;gt;; jeżeli jest ona prawdziwa, nie dzieje się nic (następuje natychmiastowe przejście do kolejnej linijki kodu). Jeżeli okaże się fałszywa, zostanie zasygnalizowany wyjątek, klasy &amp;lt;tt&amp;gt;AssertionError&amp;lt;/tt&amp;gt;, co domyślnie przerywa wykonywanie programu i powoduje wypisanie odpowiedniego komunikatu. Jeżeli zastosujemy drugą postać, obliczona zostanie również wartość &amp;lt;tt&amp;gt;wyrażenie2&amp;lt;/tt&amp;gt; i wypisana (dokładniej: jej reprezentacja napisowa) jako część komunikatu.&lt;br /&gt;
&lt;br /&gt;
Przyjęło się stosować asercje jako sposób kontroli poprawności działania programu &amp;amp;mdash; w tym sensie, aby wykluczyć sytuacje „niemożliwe&amp;quot;, tj. powstałe w wyniku błędu programisty. Ze względu na prostotę składni warto też z nich korzystać w kodzie służącym do testowania poprawności innego kodu (czyli np. w funkcjach testujących, czy inne, bardziej złożone funkcje dają poprawne wyniki w prostych sytuacjach próbnych).&lt;br /&gt;
&lt;br /&gt;
=== Wyjątki w trakcie pracy programu ===&lt;br /&gt;
&lt;br /&gt;
Wyjątki występujące w trakcie pracy programu można przechwycić i obsłużyć za pomocą następującej konstrukcji (polecenia złożonego):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
try:&lt;br /&gt;
    # operacje mogące spowodować wyjątek&lt;br /&gt;
except (KlasaWyjątku1, KlasaWyjątku2, ...):&lt;br /&gt;
    # co zrobić jeśli wyjątek jednej z tych klas wystąpił&lt;br /&gt;
else: &lt;br /&gt;
    # co zrobić jeśli nie było wyjątku&lt;br /&gt;
finally:&lt;br /&gt;
    # co zrobić w KAŻDYM przypadku&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*bloki &amp;lt;tt&amp;gt;else:&amp;lt;/tt&amp;gt; i &amp;lt;tt&amp;gt;finally:&amp;lt;/tt&amp;gt; są nieobowiązkowe, tj. możemy je pominąć (wraz z odp. linijką wprowadzającą)&lt;br /&gt;
*w bloku &amp;lt;tt&amp;gt;except:&amp;lt;/tt&amp;gt; można podać jedną klasę wyjątku (wtedy zbędne są nawiasy), lub żadnej &amp;amp;mdash; wtedy przechwycimy ''każdy'' wyjątek; jeśli jednak chcemy, jak w przykładzie, wymienić więcej niż jedną klasę, to nawiasy są konieczne&lt;br /&gt;
*skuteczne przechwycenie wyjątku sprawia, że wykonanie programu nie ulegnie przerwaniu w punkcie jego wystąpienia, tyko będzie kontynuowane, również po opuszczeniu bloku &amp;lt;tt&amp;gt;try:&amp;lt;/tt&amp;gt;&lt;br /&gt;
*można jednak spowodować, aby po wykonaniu czynności obsługi wyjątku, wyjątek został niejako ''wznowiony''; wystarczy w bloku &amp;lt;tt&amp;gt;except:&amp;lt;/tt&amp;gt; wywołać instrukcję &amp;lt;tt&amp;gt;raise&amp;lt;/tt&amp;gt;. Dla większości klas wyjątków skutkuje to zakończeniem programu&lt;br /&gt;
*instrukcję &amp;lt;tt&amp;gt;raise&amp;lt;/tt&amp;gt; można wywołać również w dowolnym innym punkcie programu, powinna wówczas w niej wystąpić nazwa klasy wyjątku, jaki chcemy wywołać. &lt;br /&gt;
&lt;br /&gt;
Przykłady:&lt;br /&gt;
&lt;br /&gt;
''CDN.''&lt;br /&gt;
&lt;br /&gt;
== Trochę więcej o klasach i obiektach ==&lt;br /&gt;
&lt;br /&gt;
Warto sobie zdawać sprawę, że każda wartość występująca w programie pythonowym jest obiektem &amp;amp;mdash; a więc jest wyposażona w zestaw atrybutów i metod. Dotyczy to nie tylko kolekcji (list, słowników, ...), obiektów takich jak otwarte pliki (wynik wywołania funkcji &amp;lt;tt&amp;gt;open()&amp;lt;/tt&amp;gt;), napisów &amp;amp;mdash; ale również np. liczb, czy to całkowitych, czy zmiennoprzecinkowych (i zespolonych, o których nie było tutaj mowy). &lt;br /&gt;
&lt;br /&gt;
Przykładowo:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
(17).bit_length()&lt;br /&gt;
→ 5&lt;br /&gt;
(17).bit_count()&lt;br /&gt;
→ 2&lt;br /&gt;
&amp;lt;/src&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Co to właściwie znaczy?&lt;br /&gt;
&lt;br /&gt;
Dla liczby 17 wywołaliśmy najpierw metodę, który mówi nam jak jest długość w bitach reprezentacji dwójkowej tej liczby (&amp;lt;tt&amp;gt;17 == 0b10001&amp;lt;/tt&amp;gt;), a następnie metodę, zwracającą liczbę *ustawionych* (tj. równych jeden) bitów w tej reprezentacji. Nawiasy okrągłe są konieczne, ponieważ kropka po cyfrach oznaczałaby, że mamy do czynienia z zapisem liczby zmiennoprzecinkowej. Inaczej mówiąc, byłyby niepotrzebne gdybyśmy mieli do czynienia z nazwą oznaczającą liczbę całkowitą, a nie z jej zapisem dziesiętnym.&lt;br /&gt;
&lt;br /&gt;
== O generatorach ==&lt;br /&gt;
&lt;br /&gt;
W jednym z poprzednich rozdziałów [[PPy3/Kolekcje#Przyk.C5.82ad:_suma_cyfr|poznaliśmy wyrażenia generatorowe]]. Przypomnijmy, że stanowią one uproszczony zapis iteracji, pozwalający na uniknięcie w wielu prostych przypadkach pętli &amp;lt;tt&amp;gt;for&amp;lt;/tt&amp;gt; i tworzenia zmiennych pomocniczych. Przykładowo:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;source lang=python&amp;gt;&lt;br /&gt;
 kwadraty = (x**2 for x in range(100))&lt;br /&gt;
 &amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
tworzy generator, ''produkujący'' w iteracji kwadraty kolejnych liczb naturalnych (od 0 do 99). &lt;br /&gt;
&lt;br /&gt;
Poważnym ograniczeniem wyrażeń generatorowych jest to, że można ich używać do przekształcenia jednego obiektu iterowalnego w drugi &amp;amp;mdash; w tym przypadku, ciągu liczb naturalnych w ciąg ich kwadratów, natomiast nie ma jak za pomocą wyrażenia generatorowego stworzyć obiektu iterowalnego ,,od zera&amp;quot;. Można to uzyskać, stosując ogólniejszą konstrukcję:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;source lang=python&amp;gt;&lt;br /&gt;
 def gen_kwadraty(start=0):&lt;br /&gt;
     k = start&lt;br /&gt;
     while True:&lt;br /&gt;
         yield k**2&lt;br /&gt;
         k += 1&lt;br /&gt;
&lt;br /&gt;
 kwadraty = gen_kwadraty()&lt;br /&gt;
 &amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To, co napisałem powyżej przypomina bardzo definicję funkcji; jedyną różnicą na poziomie składni jest wystąpienie w definicji słowa &amp;lt;tt&amp;gt;yield&amp;lt;/tt&amp;gt; (i brak wystąpienia słowa &amp;lt;tt&amp;gt;return&amp;lt;/tt&amp;gt;). W istocie &amp;lt;tt&amp;gt;gen_kwadraty&amp;lt;/tt&amp;gt; można uważać za funkcję &amp;amp;mdash; której wywołanie zwraca generator: obiekt, którego iteracja dostarczy kwadratów kolejnych liczb naturalnych, począwszy od liczby &amp;lt;tt&amp;gt;start&amp;lt;/tt&amp;gt;, argumentu wywołania, o domyślnej wartości zero. Zauważmy, że w budowie definicji nie użyliśmy obiektu &amp;lt;tt&amp;gt;range&amp;lt;/tt&amp;gt;; użyliśmy za to jawnej pętli &amp;lt;tt&amp;gt;while&amp;lt;/tt&amp;gt;, niejako opakowując ją w generator. Co więc w ten sposób zyskujemy?&lt;br /&gt;
&lt;br /&gt;
Przede wszystkim wielką elastyczność. W pokazanym przykładzie zysk jest niewielki, ale w definicji generatora możemy użyć jakiejkolwiek bądź reguły tworzenia kolejnych elementów iteracji. Nie potrzebujemy utworzyć ich wszystkich zanim zaczniemy z nich korzystać &amp;amp;mdash; tak jak byłoby w przypadku, gdybyśmy &amp;lt;tt&amp;gt;gen_kwadraty&amp;lt;/tt&amp;gt; zdefiniowali jako funkcję zwracającą listę kwadratów kolejnych liczb. Co więcej, iteracja zapewniona przez &amp;lt;tt&amp;gt;gen_kwadraty&amp;lt;/tt&amp;gt; może nam dostarczyć dowolnie wielu elementów (oczywiście w realnym komputerze po dostatecznie długim czasie osiągnięto by liczby, których wielkość przekroczyłaby pojemność dostępnej pamięci operacyjnej). Decyzja o tym, kiedy przerwać iterację pozostawiona jest ,,użytkownikowi&amp;quot;, tzn. kodowi odwołującemu się do obiektu &amp;lt;tt&amp;gt;kwadraty&amp;lt;/tt&amp;gt;.  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
[[PPy3/Matplotlib|poprzednie]] | [[&amp;quot;Programowanie z Pythonem3&amp;quot;|strona główna]] | [[PPy3/DobrePraktyki|dalej]]&lt;br /&gt;
&lt;br /&gt;
--[[Użytkownik:RobertJB|RobertJB]] ([[Dyskusja użytkownika:RobertJB|dyskusja]]) 14:26, 27 mar 2018 (CEST)&lt;/div&gt;</summary>
		<author><name>RobertJB</name></author>
		
	</entry>
	<entry>
		<id>http://brain.fuw.edu.pl/edu/index.php?title=PPy3/TematyDodatkowe&amp;diff=9467</id>
		<title>PPy3/TematyDodatkowe</title>
		<link rel="alternate" type="text/html" href="http://brain.fuw.edu.pl/edu/index.php?title=PPy3/TematyDodatkowe&amp;diff=9467"/>
		<updated>2023-06-29T12:00:48Z</updated>

		<summary type="html">&lt;p&gt;RobertJB: /* Klasy własnej produkcji */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Tematy dodatkowe =&lt;br /&gt;
&lt;br /&gt;
== Błędy i wyjątki ==&lt;br /&gt;
&lt;br /&gt;
Każdy programista popełnia błędy &amp;amp;mdash; jest to nieunikniona część tej działalności. &lt;br /&gt;
&lt;br /&gt;
*Są błędy, które można nazwać banalnymi: literówka w nazwie lub słowie kluczowym, zapomniany dwukropek, niedomknięte nawiasy, itp. &lt;br /&gt;
*Są bardziej podstępne błędy logiczne: gdy algorytm, którego zapisem ma być tworzony kod, po prostu nie robi dokładnie tego, co nam się wydaje. &lt;br /&gt;
*I w końcu są sytuacje wyjątkowe: gdy w toku pracy programu zachodzą nieoczekiwane okoliczności &amp;amp;mdash; użytkownik podał błędną nazwę pliku z danymi, zawartość tego pliku nie jest zgodna z oczekiwaniami programu, połączenie sieciowe ulega przerwaniu w trakcie pobierania lub przesyłania danych, itp. &lt;br /&gt;
&lt;br /&gt;
Wszystkie te sytuacje nazywa się wyjątkami, i tym samym słowem określa się mechanizm, jakiego wiele współczesnych języków programowania (w tym Python) dostarcza programiście, aby mu pomóc określić działania jakie program miałby podjąć w sytuacjach wyjątkowych. Wyjątkowość takich sytuacji generalnie polega na tym, że w przypadku ich wystąpienia program po prostu nie może kontynuować przewidzianego toku działania:&lt;br /&gt;
&lt;br /&gt;
*błąd w składni programu oznacza, że kod nie daje się zinterpretować w sposób jednoznaczny; najlepsze co można zrobić, to w momencie wykrycia błędu przerwać działanie i spróbować dostarczyć programiście (w formie komunikatu) informację ułatwiającą określenie i naprawienie błędu;&lt;br /&gt;
*błędne działanie algorytmu można np. spróbować wykrywać za pomocą tzw. asercji (polecenie ''assert'') badających, czy pewne warunki, jakie powinny być spełnione przez dane przetwarzane w programie są istotnie spełnione;&lt;br /&gt;
*wyjątki powstałe na skutek okoliczności zachodzących w trakcie działania programu, uniemożliwiających jego normalną kontynuację, można spróbować przewidzieć i przygotować program do odpowiedniego zareagowania, czyli ''obsługi wyjątku''. Na przykład, można spróbować ponowić jeszcze raz (lub kilka razy) próbę łączności sieciowej, i poddać się dopiero po określonej liczbie niepowodzeń; natomiast w sytuacji błędu wynikającego z podania przez użytkownika programu niewłaściwych argumentów uruchomienia, warto postarać się o przekazanie użytkownikowi komunikatu informującego go w sposób dla niego zrozumiały, o właściwym sposobie uruchamiania programu.&lt;br /&gt;
&lt;br /&gt;
=== Błędy składniowe i podobne ===&lt;br /&gt;
&lt;br /&gt;
Jak wspomniano powyżej, w przypadku napotkania błędu składniowego w kodzie programu interpreter natychmiast przerwie wykonywanie programu i wypisze komunikat. Komunikaty te '''warto czytać uważnie''' &amp;amp;mdash; w większości przypadków znajduje się w nich cała informacja konieczna dla naprawienia błędu. Przykład: usiłujemy uruchomić program &amp;lt;tt&amp;gt;błąd.py&amp;lt;/tt&amp;gt;, którego treść to&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
x = (2 + 3) 4&lt;br /&gt;
print x&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wynik pierwszej próby to:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=bash&amp;gt;&lt;br /&gt;
$ python3 błąd.py &lt;br /&gt;
  File &amp;quot;błąd.py&amp;quot;, line 1&lt;br /&gt;
    x = (2 + 3) 4&lt;br /&gt;
                ^&lt;br /&gt;
SyntaxError: invalid syntax&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Z komunikatu całkiem jasno wynika, że napotkany został błąd składni (''SyntaxError''), że wykryto ten błąd w linijce 1, a nawet dokładnie &amp;amp;mdash; że miejscem, w którym interpreter stwierdził, że ma do czynienia z nieprawidłowy kodem, było wystąpienie cyfry 4 po zamykającym nawiasie. Po prostu zapomnieliśmy, że &amp;amp;mdash; inaczej niż w powszechnie stosowanej notacji matematycznej &amp;amp;mdash; w Pythonie aby uzyskać mnożenie, konieczne jest napisanie jawnie znaku operatora (gwiazdki).&lt;br /&gt;
&lt;br /&gt;
Po naprawieniu tej pomyłki próbujemy jeszcze raz, i wynik to:&lt;br /&gt;
&amp;lt;source lang=bash&amp;gt;&lt;br /&gt;
$ python3 błąd.py &lt;br /&gt;
  File &amp;quot;błąd.py&amp;quot;, line 2&lt;br /&gt;
    print x&lt;br /&gt;
          ^&lt;br /&gt;
SyntaxError: Missing parentheses in call to 'print'. Did you mean print(x)?&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Tutaj już jaśniej być nie może; interpreter nie tylko wskazał nam dokładne miejsce wystąpienia błędu, ale nawet dokładnie opisał, jak go naprawić.&lt;br /&gt;
&lt;br /&gt;
Oczywiście nie zawsze interpreter będzie w stanie wskazać nam błąd aż tak precyzyjnie. Jako przykład weźmy następujący plik:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
x, y, z = 3, 4, 5&lt;br /&gt;
print(max(x, y, z)&lt;br /&gt;
print(X * y * z)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
i wynik jego uruchomienia:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=bash&amp;gt;&lt;br /&gt;
$ python3 błąd.py &lt;br /&gt;
  File &amp;quot;błąd.py&amp;quot;, line 3&lt;br /&gt;
    print(X * y * z)&lt;br /&gt;
        ^&lt;br /&gt;
SyntaxError: invalid syntax&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dlaczego został wytknięty błąd składniowy w linijce 3? Przecież to w linijce 2 zapomnieliśmy zamknąć jeden z nawiasów.&lt;br /&gt;
&lt;br /&gt;
Otóż jeżeli z końcem linii Python stwierdza, że nie wszystkie dotąd otwarte nawiasy zostały zamknięte, to traktuje to jako oznaczające, że kolejną linijkę należy potraktować jako ciąg dalszy bieżącej. I w tym przypadku dopiero napotykając w kolejnej linijce nazwę &amp;lt;tt&amp;gt;print&amp;lt;/tt&amp;gt; &amp;amp;mdash; a nie np. przecinek, albo nawias zamykający &amp;amp;mdash; stwierdza, że coś musi być nie tak. Miejsce wykrycia błędu niestety nie zawsze się będzie pokrywało z miejscem jego faktycznego wystąpienia.&lt;br /&gt;
&lt;br /&gt;
Po poprawce, czyli zamknięciu nawiasu na linii 2, próbujemy jeszcze raz &amp;amp;mdash; z wynikiem&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=bash&amp;gt;&lt;br /&gt;
python3 błąd.py &lt;br /&gt;
5&lt;br /&gt;
Traceback (most recent call last):&lt;br /&gt;
  File &amp;quot;błąd.py&amp;quot;, line 3, in &amp;lt;module&amp;gt;&lt;br /&gt;
    print(X * y * z)&lt;br /&gt;
NameError: name 'X' is not defined&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
I tym razem chyba jest wszystko jasne: pojawiła się nazwa &amp;lt;tt&amp;gt;X&amp;lt;/tt&amp;gt;, z którą wcześniej nie związano żadnej wartości. Po prostu przez pomyłkę napisaliśmy X wielką literą zamiast małą. &lt;br /&gt;
&lt;br /&gt;
Te przykłady pokazują, że przy wykorzystaniu treści wypisywanych komunikatów proces usunięcia z programu błędów składniowych i formalnych może być dość szybki i bezbolesny.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&lt;br /&gt;
Pojawiły się w komunikatach określenia: &amp;lt;tt&amp;gt;SyntaxError&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;NameError&amp;lt;/tt&amp;gt;. Są to przykłady nazw tzw. klas wyjątków, czyli ogólnie rozumianych kategorii błędów, jakie są sygnalizowane. Wkrótce spotkamy dalsze klasy wyjątków, takie jak: &amp;lt;tt&amp;gt;TypeError&amp;lt;/tt&amp;gt; - związana z przekazaniem wielkości niewłaściwego typu, czy &amp;lt;tt&amp;gt;ValueError&amp;lt;/tt&amp;gt; - gdy nie typ. ale wartość wielkości, na której usiłuje się operować, jest niewłaściwa dla danej operacji. Dowiemy się również, dlaczego klasy wyjątków są przydatne &amp;amp;mdash; pomimo tego, iż dla ludzkich oczu zwykle bardziej przydatna jest słowna informacja uszczegółowiająca (to co pojawia się po nazwie klasy wyjątku i dwukropku).&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Asercje ===&lt;br /&gt;
&lt;br /&gt;
Polecenie &amp;lt;tt&amp;gt;assert&amp;lt;/tt&amp;gt; ma następującą postać:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
assert wyrażenie1&lt;br /&gt;
# lub:&lt;br /&gt;
assert wyrażenie1, wyrażenie2&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
i jest to jak widać polecenie proste (nie zawierające bloku poleceń z wcięciem).&lt;br /&gt;
&lt;br /&gt;
Jego działanie jest takie, że: obliczona zostanie wartość &amp;lt;tt&amp;gt;wyrażenie1&amp;lt;/tt&amp;gt;; jeżeli jest ona prawdziwa, nie dzieje się nic (następuje natychmiastowe przejście do kolejnej linijki kodu). Jeżeli okaże się fałszywa, zostanie zasygnalizowany wyjątek, klasy &amp;lt;tt&amp;gt;AssertionError&amp;lt;/tt&amp;gt;, co domyślnie przerywa wykonywanie programu i powoduje wypisanie odpowiedniego komunikatu. Jeżeli zastosujemy drugą postać, obliczona zostanie również wartość &amp;lt;tt&amp;gt;wyrażenie2&amp;lt;/tt&amp;gt; i wypisana (dokładniej: jej reprezentacja napisowa) jako część komunikatu.&lt;br /&gt;
&lt;br /&gt;
Przyjęło się stosować asercje jako sposób kontroli poprawności działania programu &amp;amp;mdash; w tym sensie, aby wykluczyć sytuacje „niemożliwe&amp;quot;, tj. powstałe w wyniku błędu programisty. Ze względu na prostotę składni warto też z nich korzystać w kodzie służącym do testowania poprawności innego kodu (czyli np. w funkcjach testujących, czy inne, bardziej złożone funkcje dają poprawne wyniki w prostych sytuacjach próbnych).&lt;br /&gt;
&lt;br /&gt;
=== Wyjątki w trakcie pracy programu ===&lt;br /&gt;
&lt;br /&gt;
Wyjątki występujące w trakcie pracy programu można przechwycić i obsłużyć za pomocą następującej konstrukcji (polecenia złożonego):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
try:&lt;br /&gt;
    # operacje mogące spowodować wyjątek&lt;br /&gt;
except (KlasaWyjątku1, KlasaWyjątku2, ...):&lt;br /&gt;
    # co zrobić jeśli wyjątek jednej z tych klas wystąpił&lt;br /&gt;
else: &lt;br /&gt;
    # co zrobić jeśli nie było wyjątku&lt;br /&gt;
finally:&lt;br /&gt;
    # co zrobić w KAŻDYM przypadku&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*bloki &amp;lt;tt&amp;gt;else:&amp;lt;/tt&amp;gt; i &amp;lt;tt&amp;gt;finally:&amp;lt;/tt&amp;gt; są nieobowiązkowe, tj. możemy je pominąć (wraz z odp. linijką wprowadzającą)&lt;br /&gt;
*w bloku &amp;lt;tt&amp;gt;except:&amp;lt;/tt&amp;gt; można podać jedną klasę wyjątku (wtedy zbędne są nawiasy), lub żadnej &amp;amp;mdash; wtedy przechwycimy ''każdy'' wyjątek; jeśli jednak chcemy, jak w przykładzie, wymienić więcej niż jedną klasę, to nawiasy są konieczne&lt;br /&gt;
*skuteczne przechwycenie wyjątku sprawia, że wykonanie programu nie ulegnie przerwaniu w punkcie jego wystąpienia, tyko będzie kontynuowane, również po opuszczeniu bloku &amp;lt;tt&amp;gt;try:&amp;lt;/tt&amp;gt;&lt;br /&gt;
*można jednak spowodować, aby po wykonaniu czynności obsługi wyjątku, wyjątek został niejako ''wznowiony''; wystarczy w bloku &amp;lt;tt&amp;gt;except:&amp;lt;/tt&amp;gt; wywołać instrukcję &amp;lt;tt&amp;gt;raise&amp;lt;/tt&amp;gt;. Dla większości klas wyjątków skutkuje to zakończeniem programu&lt;br /&gt;
*instrukcję &amp;lt;tt&amp;gt;raise&amp;lt;/tt&amp;gt; można wywołać również w dowolnym innym punkcie programu, powinna wówczas w niej wystąpić nazwa klasy wyjątku, jaki chcemy wywołać. &lt;br /&gt;
&lt;br /&gt;
Przykłady:&lt;br /&gt;
&lt;br /&gt;
''CDN.''&lt;br /&gt;
&lt;br /&gt;
== Trochę więcej o klasach i obiektach ==&lt;br /&gt;
&lt;br /&gt;
Warto sobie zdawać sprawę, że każda wartość występująca w programie pythonowym jest obiektem &amp;amp;mdash; a więc jest wyposażona w zestaw atrybutów i metod. Dotyczy to nie tylko kolekcji (list, słowników, ...), obiektów takich jak otwarte pliki (wynik wywołania funkcji &amp;lt;tt&amp;gt;open()&amp;lt;/tt&amp;gt;), napisów &amp;amp;mdash; ale również np. liczb, czy to całkowitych, czy zmiennoprzecinkowych (i zespolonych, o których nie było tutaj mowy). &lt;br /&gt;
&lt;br /&gt;
Przykładowo:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;src lang=python&amp;gt;&lt;br /&gt;
(17).bit_length()&lt;br /&gt;
→ 5&lt;br /&gt;
(17).bit_count()&lt;br /&gt;
→ 2&lt;br /&gt;
&amp;lt;/src&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Co to właściwie znaczy?&lt;br /&gt;
&lt;br /&gt;
Dla liczby 17 wywołaliśmy najpierw metodę, który mówi nam jak jest długość w bitach reprezentacji dwójkowej tej liczby (&amp;lt;tt&amp;gt;17 == 0b10001&amp;lt;/tt&amp;gt;), a następnie metodę, zwracającą liczbę *ustawionych* (tj. równych jeden) bitów w tej reprezentacji. Nawiasy okrągłe są konieczne, ponieważ kropka po cyfrach oznaczałaby, że mamy do czynienia z zapisem liczby zmiennoprzecinkowej. Inaczej mówiąc, byłyby niepotrzebne gdybyśmy mieli do czynienia z nazwą oznaczającą liczbę całkowitą, a nie z jej zapisem dziesiętnym.&lt;br /&gt;
&lt;br /&gt;
== O generatorach ==&lt;br /&gt;
&lt;br /&gt;
W jednym z poprzednich rozdziałów [[PPy3/Kolekcje#Przyk.C5.82ad:_suma_cyfr|poznaliśmy wyrażenia generatorowe]]. Przypomnijmy, że stanowią one uproszczony zapis iteracji, pozwalający na uniknięcie w wielu prostych przypadkach pętli &amp;lt;tt&amp;gt;for&amp;lt;/tt&amp;gt; i tworzenia zmiennych pomocniczych. Przykładowo:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;source lang=python&amp;gt;&lt;br /&gt;
 kwadraty = (x**2 for x in range(100))&lt;br /&gt;
 &amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
tworzy generator, ''produkujący'' w iteracji kwadraty kolejnych liczb naturalnych (od 0 do 99). &lt;br /&gt;
&lt;br /&gt;
Poważnym ograniczeniem wyrażeń generatorowych jest to, że można ich używać do przekształcenia jednego obiektu iterowalnego w drugi &amp;amp;mdash; w tym przypadku, ciągu liczb naturalnych w ciąg ich kwadratów, natomiast nie ma jak za pomocą wyrażenia generatorowego stworzyć obiektu iterowalnego ,,od zera&amp;quot;. Można to uzyskać, stosując ogólniejszą konstrukcję:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;source lang=python&amp;gt;&lt;br /&gt;
 def gen_kwadraty(start=0):&lt;br /&gt;
     k = start&lt;br /&gt;
     while True:&lt;br /&gt;
         yield k**2&lt;br /&gt;
         k += 1&lt;br /&gt;
&lt;br /&gt;
 kwadraty = gen_kwadraty()&lt;br /&gt;
 &amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To, co napisałem powyżej przypomina bardzo definicję funkcji; jedyną różnicą na poziomie składni jest wystąpienie w definicji słowa &amp;lt;tt&amp;gt;yield&amp;lt;/tt&amp;gt; (i brak wystąpienia słowa &amp;lt;tt&amp;gt;return&amp;lt;/tt&amp;gt;). W istocie &amp;lt;tt&amp;gt;gen_kwadraty&amp;lt;/tt&amp;gt; można uważać za funkcję &amp;amp;mdash; której wywołanie zwraca generator: obiekt, którego iteracja dostarczy kwadratów kolejnych liczb naturalnych, począwszy od liczby &amp;lt;tt&amp;gt;start&amp;lt;/tt&amp;gt;, argumentu wywołania, o domyślnej wartości zero. Zauważmy, że w budowie definicji nie użyliśmy obiektu &amp;lt;tt&amp;gt;range&amp;lt;/tt&amp;gt;; użyliśmy za to jawnej pętli &amp;lt;tt&amp;gt;while&amp;lt;/tt&amp;gt;, niejako opakowując ją w generator. Co więc w ten sposób zyskujemy?&lt;br /&gt;
&lt;br /&gt;
Przede wszystkim wielką elastyczność. W pokazanym przykładzie zysk jest niewielki, ale w definicji generatora możemy użyć jakiejkolwiek bądź reguły tworzenia kolejnych elementów iteracji. Nie potrzebujemy utworzyć ich wszystkich zanim zaczniemy z nich korzystać &amp;amp;mdash; tak jak byłoby w przypadku, gdybyśmy &amp;lt;tt&amp;gt;gen_kwadraty&amp;lt;/tt&amp;gt; zdefiniowali jako funkcję zwracającą listę kwadratów kolejnych liczb. Co więcej, iteracja zapewniona przez &amp;lt;tt&amp;gt;gen_kwadraty&amp;lt;/tt&amp;gt; może nam dostarczyć dowolnie wielu elementów (oczywiście w realnym komputerze po dostatecznie długim czasie osiągnięto by liczby, których wielkość przekroczyłaby pojemność dostępnej pamięci operacyjnej). Decyzja o tym, kiedy przerwać iterację pozostawiona jest ,,użytkownikowi&amp;quot;, tzn. kodowi odwołującemu się do obiektu &amp;lt;tt&amp;gt;kwadraty&amp;lt;/tt&amp;gt;.  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
[[PPy3/Matplotlib|poprzednie]] | [[&amp;quot;Programowanie z Pythonem3&amp;quot;|strona główna]] | [[PPy3/DobrePraktyki|dalej]]&lt;br /&gt;
&lt;br /&gt;
--[[Użytkownik:RobertJB|RobertJB]] ([[Dyskusja użytkownika:RobertJB|dyskusja]]) 14:26, 27 mar 2018 (CEST)&lt;/div&gt;</summary>
		<author><name>RobertJB</name></author>
		
	</entry>
	<entry>
		<id>http://brain.fuw.edu.pl/edu/index.php?title=PPy3/Kolekcje&amp;diff=9339</id>
		<title>PPy3/Kolekcje</title>
		<link rel="alternate" type="text/html" href="http://brain.fuw.edu.pl/edu/index.php?title=PPy3/Kolekcje&amp;diff=9339"/>
		<updated>2023-05-15T11:15:39Z</updated>

		<summary type="html">&lt;p&gt;RobertJB: /* Ćwiczenia */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=Kolekcje=&lt;br /&gt;
&lt;br /&gt;
'''Kolekcje''' to są takie typy danych, które składają się z elementów. Szczególnym przypadkiem, [[PPy3/SekwencjeIIteracja|omawianym już wcześniej]] przy okazji wprowadzenia pętli, są sekwencje - kolekcje uporządkowane. Rozmaite typy kolekcji różnią się sposobem dostępu do elementów, modyfikowalnością - lub przeciwnie, optymalizacją pod względem różnych zastosowań. &lt;br /&gt;
&lt;br /&gt;
*Szereg typów kolekcji jest ,,wbudowanych&amp;quot; w pythonie - to znaczy, że można z nich swobodnie korzystać bez żadnych dodatkowych zabiegów; &lt;br /&gt;
*niektóre inne są zaimplementowane w modułach biblioteki standardowej - a więc korzystanie z nich wymaga wcześniejszego polecenia &amp;lt;tt&amp;gt;import&amp;lt;/tt&amp;gt; (p. [[PPy3/Moduły|Moduły]]); &lt;br /&gt;
*ważne dla zastosowań do obliczeń naukowych typy tablicowe są zaimplementowane w bibliotece [[PPy3/NumPy|NumPy]], która '''nie''' jest częścią biblioteki standardowej, i na ogół np. nie znajdzie się w domyślnym zestawie pakietów typowej dystrybucji Linuxa. Na pewno będzie jednak dostępna jako opcjonalny element instalacji;&lt;br /&gt;
*na każdym typie kolekcji umie działać funkcja &amp;lt;tt&amp;gt;len&amp;lt;/tt&amp;gt;, zwracająca liczbę elementów kolekcji będącej jej argumentem.&lt;br /&gt;
&lt;br /&gt;
Omówimy tu kolejno w skrócie najważniejsze i najbardziej przydatne wg. nas typy kolekcji, z pominięciem tablic NumPy - którym będzie poświęcony [[PPy3/NumPy|osobny rozdział]].&lt;br /&gt;
&lt;br /&gt;
==Listy==&lt;br /&gt;
&lt;br /&gt;
O listach już nieco wiemy. Lista to kolekcja uporządkowana, i modyfikowalna. Elementem listy może być cokolwiek - również inna lista. A nawet ta sama lista - tak, lista może być elementem samej siebie, jednak sztuczka taka nie jest chyba przydatna, choć legalna.&lt;br /&gt;
&lt;br /&gt;
O adresowaniu elementów przez pozycję (lub ''indeks'') oraz o pobieraniu (i podstawianiu do) wycinków już było. Dodamy tu jeszcze parę użytecznych operacji na listach:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
L = [0, 1, 3]&lt;br /&gt;
L.append(5) # dołączamy element do końca, przedłużając listę&lt;br /&gt;
→ L == [0, 1, 3, 5]&lt;br /&gt;
L.extend(['a', 'b']) # przedłużamy od razu o całą listę dodatkowych elementów&lt;br /&gt;
→ L == [0, 1, 3, 5, 'a', 'b']&lt;br /&gt;
L.insert(2, 'dwa') # pierwszy argument to pozycja, drugi to element wstawiany; dalsze elementy przesuwają się&lt;br /&gt;
→ L == [0, 1, 'dwa', 3, 5, 'a', 'b']&lt;br /&gt;
x = L.pop() # usuwamy ostatni element i zwracamy go jako wynik&lt;br /&gt;
→ teraz x == 'b', a L == [0, 1, 'dwa', 3, 5, 'a']&lt;br /&gt;
y = L.pop(2) # możemy zrobić to samo, wskazując inną pozycję zamiast ostatniej&lt;br /&gt;
→ teraz y == 'dwa', a L == [0, 1, 3, 5, 'a']&lt;br /&gt;
L.reverse() # odwrócenie porządku elementów&lt;br /&gt;
→ teraz L == ['a', 5, 3, 1, 0]&lt;br /&gt;
L.sort() # uporządkowanie elementów listy&lt;br /&gt;
→ BŁĄD - nie zadziała, gdyż lista zawiera elementy nieporównywalne (liczby i napis)&lt;br /&gt;
L.pop(0) # usuwamy napis, stojący w pozycji 0&lt;br /&gt;
L.sort()&lt;br /&gt;
→ teraz L == [0, 1, 3, 5]&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Oprócz operacji &amp;lt;tt&amp;gt;L.sort()&amp;lt;/tt&amp;gt; istnieje jeszcze funkcja &amp;lt;tt&amp;gt;sorted(L)&amp;lt;/tt&amp;gt; - różniąca się tym, że pozostawia niezmienioną listę &amp;lt;tt&amp;gt;L&amp;lt;/tt&amp;gt;, zamiast tego tworząc '''nową''' listę uporządkowaną, zawierającą te same elementy, co &amp;lt;tt&amp;gt;L&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Notację postaci &amp;lt;tt&amp;gt;L.append(5)&amp;lt;/tt&amp;gt; można czytać tak: zastosuj ''metodę'' obiektu &amp;lt;tt&amp;gt;L&amp;lt;/tt&amp;gt;, o nazwie &amp;lt;tt&amp;gt;append&amp;lt;/tt&amp;gt;, do liczby 5. Metoda jest to operacja związana z pewnym obiektem (w tym przypadku - listą) - tym, do którego odnosi się nazwa stojąca przed kropką. Metodę można uważać za pewien rodzaj funkcji - takiej , która oprócz ewentualnych argumentów umieszczonych w nawiasach po jej nazwie, ,,wie&amp;quot; jeszcze o tym, z jakiego obiektu została wywołana.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&amp;lt;small&amp;gt;&lt;br /&gt;
W Pythonie każda dana jest obiektem jakiegoś rodzaju (''klasy''), nawet liczba; i każdy obiekt posiada właściwe sobie metody (na ogół wyznaczone przez klasę, do jakiej przynależy). Programista może zresztą sam tworzyć klasy obiektów na potrzeby swojego programu. Więcej na ten temat później.&lt;br /&gt;
&amp;lt;/small&amp;gt;&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Funkcja &amp;lt;tt&amp;gt;list&amp;lt;/tt&amp;gt; tworzy listę z dowolnej sekwencji (np. z napisu). Wywołanie bez argumentów &amp;lt;tt&amp;gt;list()&amp;lt;/tt&amp;gt; zwraca pustą listę; wywołanie &amp;lt;tt&amp;gt;list(s)&amp;lt;/tt&amp;gt;, gdzie &amp;lt;tt&amp;gt;s&amp;lt;/tt&amp;gt; jest napisem, zwraca listę znaków (napisów jednoelementowych), z których składa się napis &amp;lt;tt&amp;gt;s&amp;lt;/tt&amp;gt;. Wywołanie, gdzie argumentem jest lista, zwraca duplikat tej listy - tzn. listę o tych samych elementach (i w tym samym porządku), ale nie tożsamą.&lt;br /&gt;
&lt;br /&gt;
===Przykład: suma cyfr===&lt;br /&gt;
&lt;br /&gt;
Spróbujmy policzyć sumę cyfr, z jakich składa się zapis liczby naturalnej &amp;lt;tt&amp;gt;n&amp;lt;/tt&amp;gt; - a wyrażając się precyzyjniej, sumę liczb reprezentowanych przez cyfry zapisu dziesiętnego liczby &amp;lt;tt&amp;gt;n&amp;lt;/tt&amp;gt; (cyfra to znak, a więc w rozumieniu Pythona pewien napis jednoelementowy - a nie liczba; ponadto, ten sam problem można by postawić dla zapisu pozycyjnego o dowolnej podstawie, np. dwójkowego lub szesnastkowego).&lt;br /&gt;
&lt;br /&gt;
Pierwszym rozwiązaniem tego problemu jest takie, jakie można by nazwać arytmetycznym:&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;source lang=python&amp;gt;&lt;br /&gt;
  def sumacyfr(n):&lt;br /&gt;
      suma = 0&lt;br /&gt;
      while n:&lt;br /&gt;
          suma += n % 10&lt;br /&gt;
          n = n // 10&lt;br /&gt;
      return suma&lt;br /&gt;
  &amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Proste: ostatnią cyfrę zapisu liczby &amp;lt;tt&amp;gt;n&amp;lt;/tt&amp;gt; (a wyrażając się pedantycznie: odpowiadającą jej liczbę między 0 a 9) otrzymujemy jako resztę z dzielenia &amp;lt;tt&amp;gt;n&amp;lt;/tt&amp;gt; przez 10; następnie ,,skracamy&amp;quot; &amp;lt;tt&amp;gt;n&amp;lt;/tt&amp;gt; o tę ostatnią cyfrę, zastępując &amp;lt;tt&amp;gt;n&amp;lt;/tt&amp;gt; przez jej iloraz całkowitoliczbowy przez 10. I tak do skutku, aż zabraknie cyfr.&lt;br /&gt;
&lt;br /&gt;
Można jednak napisać znacznie krótszą wersję tej funkcji, korzystając z tego, że Python ,,sam&amp;quot; umie wyznaczyć cyfry zapisu dziesiętnego każdej liczby i nie musimy do tego pisać własnego kodu. Robi to funkcja &amp;lt;tt&amp;gt;str(n)&amp;lt;/tt&amp;gt; - zastosowana do liczby całkowitej, zwraca ona napis składający się z cyfr dziesiętnych, reprezentujący tę liczbę. Rozwiązanie uproszczone wygląda więc tak:&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;source lang=python&amp;gt;&lt;br /&gt;
  def sumacyfr(n):&lt;br /&gt;
      suma = 0&lt;br /&gt;
      for c in str(n):&lt;br /&gt;
          suma += int(c)&lt;br /&gt;
      return suma&lt;br /&gt;
  &amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dalsze uproszczenie otrzymujemy zastępując pętlę tzw. ''wyrażeniem generatorowym'', i korzystając z wbudowanej funkcji &amp;lt;tt&amp;gt;sum&amp;lt;/tt&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;source lang=python&amp;gt;&lt;br /&gt;
  def sumacyfr(n):&lt;br /&gt;
      return sum(int(c) for c in str(n))&lt;br /&gt;
  &amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wyrażenia generatorowe to jakby odwrotny zapis pętli &amp;lt;tt&amp;gt;for&amp;lt;/tt&amp;gt;. Notacja ta definiuje obiekt (''generator'') będący odpowiednikiem i uogólnieniem obiektu, jaki produkuje funkcja &amp;lt;tt&amp;gt;range&amp;lt;/tt&amp;gt;: jest to ''niby-sekwencja'', która może zastąpić sekwencję (np. listę) w pętli &amp;lt;tt&amp;gt;for&amp;lt;/tt&amp;gt;, a także w funkcjach (takich jak &amp;lt;tt&amp;gt;sum&amp;lt;/tt&amp;gt; lub &amp;lt;tt&amp;gt;sorted&amp;lt;/tt&amp;gt;), które jako argumentu oczekują sekwencji. W odróżnieniu od sekwencji, generator nie ma z góry ustalonego ciągu elementów, można powiedzieć, że produkuje kolejne elementy ,,na żądanie'', np. gdy są potrzebne dla kolejnego obiegu pętli &amp;lt;tt&amp;gt;for&amp;lt;/tt&amp;gt;. Wyrażenie generatorowe określa generator na podstawie elementów podawanych przez inny generator (lub sekwencję), poddając je jakiemuś przekształceniu i/lub selekcji:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;source lang=python&amp;gt;&lt;br /&gt;
 gen = (f(x) for x in elementy if w(x))&lt;br /&gt;
 &amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
tu: &amp;lt;tt&amp;gt;elementy&amp;lt;/tt&amp;gt; to sekwencja lub generator, &amp;lt;tt&amp;gt;w(x)&amp;lt;/tt&amp;gt; to warunek decydujący o uwzględnieniu lub pominięciu elementu &amp;lt;tt&amp;gt;x&amp;lt;/tt&amp;gt;, a &amp;lt;tt&amp;gt;f(x)&amp;lt;/tt&amp;gt; to w ogólności wyrażenie, którego wartość będzie kolejnym elementem podawanym przez generator &amp;lt;tt&amp;gt;gen&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
''Uwaga:'' nawiasy okrągłe otaczające wyrażenie generatorowe są obowiązkowe. Jeśli wyrażenie to wstawiamy bezpośrednio pod wywołanie funkcji jako jej jedyny argument, to wystarczają nawiasy zawarte w składni wywołania funkcji - nie potrzeba ich podwajać. Jeśli w miejsce nawiasów okrągłych napiszemy kwadratowe, otrzymamy nie generator - a listę o tych samych elementach.&lt;br /&gt;
&lt;br /&gt;
==Krotki==&lt;br /&gt;
&lt;br /&gt;
Krotki to prawie listy; zasadnicza różnica polega na tym, że krotki są '''niemodyfikowalne'''. Podobnie jak napisy - krotki raz stworzonej nie można zmienić, w sensie zmiany jej zawartości (elementów), a tym bardziej - jej długości. Można ją najwyżej zastąpić inną krotką. W związku z tym, krotki pozbawione są metod modyfikujących zawartość, jakie posiadają listy. Inne operacje, jak adresowanie elementów i wycinków, dodawanie (sklejanie) i mnożenie (powielanie) działają analogicznie jak dla list.&lt;br /&gt;
&lt;br /&gt;
Literalne krotki zapisuje się zwykle używając nawiasów okrągłych:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
T = (3, 5, 8)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
chociaż tak naprawdę, to nawiasy są opcjonalne, a krotkę tworzą ''przecinki'' stojące pomiędzy elementami. Pominięcie nawiasów powoduje jednak, że musimy pamiętać o tym jaka jest kolejność operacji, jeżeli literalny zapis krotki jest elementem większego wyrażenia. Zwykle prościej i czytelniej jest użyć nawiasów.&lt;br /&gt;
&lt;br /&gt;
Krotka może oczywiście składać się z jednego elementu, a nawet być pusta:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
T1 = 1, # krotka o jednym elemencie - liczbie 1&lt;br /&gt;
T0 = () # krotka pusta&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
w tym ostatnim przypadku nie można się obyć bez nawiasów. Oczywiście tworzenie takich krotek rzadko bywa przydatne; mogą się one jednak pojawiać jako wyniki rozmaitych operacji.&lt;br /&gt;
&lt;br /&gt;
Po co są w ogóle krotki, skoro to tylko jakby ,,słabsze&amp;quot; listy? &lt;br /&gt;
&lt;br /&gt;
*Czasami warto użyć typu niemodyfikowalnego, aby próba zmiany zawartości kolekcji (np. w wyniku błędu) nie mogła się udać;&lt;br /&gt;
*optymalizacja - krotki są ,,lżejsze&amp;quot; od list, co może mieć znaczenie jeśli potrzebujemy je tworzyć w dużej liczbie;&lt;br /&gt;
*w niektórych przypadkach użycie niemodyfikowalnego typu danych jest konieczne; o tym dalej.&lt;br /&gt;
&lt;br /&gt;
Warto jednak pamiętać, że choć sama krotka jest niemodyfikowalna - to jej elementem może być np. lista, której zawartość może być zmieniona niezależnie od tego, że jest elementem krotki.&lt;br /&gt;
&lt;br /&gt;
Każdą sekwencję (a i pewne inne obiekty &amp;amp;mdash; np. generatory) można ,,zrzutować&amp;quot; na krotkę, za pomocą funkcji &amp;lt;tt&amp;gt;tuple&amp;lt;/tt&amp;gt;. Wyrażając się precyzyjniej, wyrażenie &amp;lt;tt&amp;gt;tuple(s)&amp;lt;/tt&amp;gt; jest krotką o tej samej zawartości (i w tym samym porządku) co sekwencja (lub inny obiekt iterowalny) &amp;lt;tt&amp;gt;s&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==Słowniki==&lt;br /&gt;
&lt;br /&gt;
Słownik (''dictionary'') to taka kolekcja, której elementy - zamiast być uporządkowane - są powiązane z ''kluczami''. Kluczem może być liczba (całkowita lub ułamkowa), napis, ale również dana szeregu innych typów (chociaż nie każdego). Pobranie elementu słownika wiąże się z podaniem odpowiadającego mu klucza. Klucze w słowniku są niepowtarzalne - a więc każdy z nich jest związany z dokładnie jedną wartością. Wartości za to mogą się powtarzać, i nie podlegają żadnym ograniczeniom co do typu. Zapis literalny słowników posługuje się nawiasami klamrowymi:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
slownik = {'jeden' : 1, 'dwa' : 2, 'trzy' : 3}&lt;br /&gt;
slownik['dwa']&lt;br /&gt;
→ 2&lt;br /&gt;
slownik['cztery']&lt;br /&gt;
&lt;br /&gt;
KeyError                                  Traceback (most recent call last)&lt;br /&gt;
&amp;lt;ipython-input-2-22c7b016c2c6&amp;gt; in &amp;lt;module&amp;gt;()&lt;br /&gt;
----&amp;gt; 1 slownik['cztery']&lt;br /&gt;
&lt;br /&gt;
KeyError: 'cztery'&lt;br /&gt;
slownik['cztery'] = 4&lt;br /&gt;
slownik['cztery'] == 4&lt;br /&gt;
→ True&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
W notacji literalnej w nawiasach stoją, oddzielone przecinkami, pary klucz-wartość, a klucz od wartości oddziela dwukropek.&lt;br /&gt;
Nazwa ''słownik'' bierze się stąd, że jednym z możliwych zastosowań jest przekład kluczy (tu: słowa oznaczające liczby) na odpowiadające im wartości (tu: liczby). Widzimy też, że próba pobrania wartości odpowiadającej kluczowi, którego w słowniku nie ma, kończy się błędem. Z drugiej strony, w każdej chwili można do słownika dodać następną parę klucz-wartość; analogicznie, można wymienić wartość związaną z kluczem już istniejącym na inną.&lt;br /&gt;
&lt;br /&gt;
Warto podkreślić jeszcze raz, że pary klucz-wartość w słowniku nie charakteryzują się w zasadzie określonym porządkiem. Niemniej w nowszych wersjach Pythona obowiązuje zasada, że pozycje słownika zachowują porządek, w jakim były tworzone &amp;amp;mdash; i np. w iteracji będą się pojawiać zgodnie z tym porządkiem.&lt;br /&gt;
&lt;br /&gt;
Dalsze podstawowe operacje na słowniku to sprawdzenie występowania klucza, oraz iteracja:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
'cztery' in slownik # operator `in' sprawdza przynależność do zbioru kluczy&lt;br /&gt;
→ True&lt;br /&gt;
'zero' in slownik&lt;br /&gt;
→ False&lt;br /&gt;
for klucz in slownik:&lt;br /&gt;
    print(klucz, slownik[klucz])&lt;br /&gt;
→&lt;br /&gt;
jeden 1                                                                                                                              &lt;br /&gt;
dwa 2                                                                                                                                &lt;br /&gt;
trzy 3                                                                                                                               &lt;br /&gt;
cztery 4&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Jak widać, w iteracji klucze słownika pojawiają się w porządku, w którym je dodawano. Takie zachowanie jest przepisane w definicji języka Python od wersji 3.7. Mając do czynienia z wersjami wcześniejszymi należy się liczyć z tym, że ten porządek nie będzie zachowany. Natomiast gwarantuje się, że każdy klucz pojawi się w iteracji dokładnie jeden raz.&lt;br /&gt;
&lt;br /&gt;
W iteracjach (tzn. pętlach &amp;lt;tt&amp;gt;for&amp;lt;/tt&amp;gt;) bardzo przydatne są kolekcje zwracane przez metody słowników: &amp;lt;tt&amp;gt;items&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;values&amp;lt;/tt&amp;gt; i (rzadziej przydatna) &amp;lt;tt&amp;gt;keys&amp;lt;/tt&amp;gt;. Zwracają one obiekty ,,listo-podobne&amp;quot;; jeżeli potrzebne są nam one w postaci dosłownych list, to wystarczy zastosować do nich funkcję &amp;lt;tt&amp;gt;list&amp;lt;/tt&amp;gt;; jeżeli natomiast zamierzamy je wykorzystać w pętli &amp;lt;tt&amp;gt;for&amp;lt;/tt&amp;gt;, to nie jest to potrzebne. Zawartość to odpowiednio:&lt;br /&gt;
&lt;br /&gt;
*&amp;lt;tt&amp;gt;slownik.items()&amp;lt;/tt&amp;gt;: pary (dwuelementowe krotki) postaci ''(klucz, wartość)''&lt;br /&gt;
*&amp;lt;tt&amp;gt;slownik.values()&amp;lt;/tt&amp;gt;: same wartości występujące w słowniku&lt;br /&gt;
*&amp;lt;tt&amp;gt;slownik.keys()&amp;lt;/tt&amp;gt;: same klucze występujące w słowniku.&lt;br /&gt;
&lt;br /&gt;
Uwaga dotycząca porządku pozycji słownika stosuje się również do wyników zwracanych przez te metody.&lt;br /&gt;
&lt;br /&gt;
Funkcją - konstruktorem słownika jest funkcja &amp;lt;tt&amp;gt;dict&amp;lt;/tt&amp;gt;. Zamienia ona np. sekwencję par ''(klucz, wartość)'' w odpowiedni słownik. Jeżeli klucze w tej sekwencji się powtarzają, ,,wygrywa&amp;quot; ostatnie wystąpienie.&lt;br /&gt;
&lt;br /&gt;
Wspomnieliśmy wcześniej, że nie każdy typ wartości może być kluczem słownika. Dokładniej - kluczami w słowniku mogą być tylko wartości typów niemodyfikowalnych, a więc nie listy ani same słowniki. Mogą nimi natomiast być napisy, liczby i krotki. ''Nota bene'': ponieważ liczby ułamkowe należy traktować jako przybliżone, używanie ich jako kluczy słownika na ogół nie jest dobrym pomysłem. Nie ma ograniczeń co do mieszania różnych typów kluczy (ani wartości) w jednym słowniku.&lt;br /&gt;
&lt;br /&gt;
==Zbiory==&lt;br /&gt;
&lt;br /&gt;
Zbiory w Pythonie mają sens taki, jak zbiory w matematyce (teorii mnogości). Mówiąc po prostu, zbiór jest kolekcją nieuporządkowaną i nie dopuszczającą powtórzeń: dany element albo do zbioru należy, albo nie; nie może należeć ''dwukrotnie'' (ani więcej razy). Standardowe zbiory są obiektami modyfikowalnymi.&lt;br /&gt;
&lt;br /&gt;
Zbiór literalny zapisuje się za pomocą nawiasów klamrowych &amp;amp;mdash; łatwo odróżnić, że nie chodzi o słownik, gdyż zapis dla zbiorów nie zawiera dwukropków.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&amp;lt;small&amp;gt;&lt;br /&gt;
Wiąże się z tym jednak jeden problem: czy &amp;lt;tt&amp;gt;{}&amp;lt;/tt&amp;gt; oznacza zbiór pusty, czy pusty słownik? Dość arbitralnie przyjęto, że jednak pusty słownik (notację dla zbiorów wprowadzono później niż dla słowników).&amp;lt;/small&amp;gt;&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Przykłady:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
zbior = {'a', 'b', 'c'}&lt;br /&gt;
'a' in zbior&lt;br /&gt;
→ True&lt;br /&gt;
6 in zbior&lt;br /&gt;
→ False&lt;br /&gt;
zbior.add('d')&lt;br /&gt;
→ zbior == {'a', 'b', 'c', 'd'}&lt;br /&gt;
zbior.remove('a')&lt;br /&gt;
→ zbior == {'b', 'c', 'd'}&lt;br /&gt;
innyzb = {1, 2, 'b'}&lt;br /&gt;
zbior | innyzb  # suma zbiorów&lt;br /&gt;
→ {'a', 1, 2, 'c', 'd', 'b'}&lt;br /&gt;
zbior &amp;amp; innyzb  # iloczyn (część wspólna) zbiorów&lt;br /&gt;
→ {'b'}&lt;br /&gt;
zbior - innyzb  # różnica zbiorów&lt;br /&gt;
→ {'a', 'c', 'd'}&lt;br /&gt;
zbior ^ innyzb == (zbior | innyzb) - (zbior &amp;amp; innyzb)  # definicja różnicy symetrycznej zbiorów&lt;br /&gt;
→ True&lt;br /&gt;
innyzb &amp;lt;= zbior # pierwszy jest podzbiorem drugiego?&lt;br /&gt;
→ False&lt;br /&gt;
{'b', 'c'} &amp;lt;= zbior&lt;br /&gt;
→ True&lt;br /&gt;
{'b', 'c'} &amp;lt; zbior  # podzbiór właściwy?&lt;br /&gt;
→ True&lt;br /&gt;
# znaki nierówności mogą być skierowane odwrotnie, z odp. zamianą argumentów&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Elementy zbiorów podlegają analogicznemu ograniczeniu co do typów danych, co klucze słownika: nie mogą być to obiekty modyfikowalne.&lt;br /&gt;
&lt;br /&gt;
Konstruktorem zbioru jest funkcja &amp;lt;tt&amp;gt;set&amp;lt;/tt&amp;gt;: można jej podać jako argument dowolną kolekcję, a ona zwróci zbiór jej elementów (z dokładnością do ograniczeń co do typów danych tych elementów). Na przykład, typowy chwyt na usunięcie powtórzeń elementów: aby uzyskać uporządkowaną listę znaków, z jaki składa się napis &amp;lt;tt&amp;gt;s&amp;lt;/tt&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
znaki = sorted(set(napis))&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Podobnie jak lista ma swój odpowiednik niemodyfikowalny (krotkę), tak niemodyfikowalnym odpowiednikiem zbioru jest ''zbiór zamrożony'' (''frozenset''). Można taki wyprodukować za pomocą funkcji &amp;lt;tt&amp;gt;frozenset&amp;lt;/tt&amp;gt;, analogu funkcji &amp;lt;tt&amp;gt;set&amp;lt;/tt&amp;gt;. Zbiory zamrożone dopuszczają wszystkie te same operacje, co zwykłe zbiory - za wyjątkiem operacji zmieniających skład (jak &amp;lt;tt&amp;gt;add&amp;lt;/tt&amp;gt; i &amp;lt;tt&amp;gt;remove&amp;lt;/tt&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
==Napisy (jeszcze raz)==&lt;br /&gt;
&lt;br /&gt;
O napisach już nieco było wcześniej, ale dla kompletności przypomnijmy.&lt;br /&gt;
&lt;br /&gt;
*Napis to niemodyfikowalna sekwencja&lt;br /&gt;
*Jej elementami są znaki - napisy o długości 1&lt;br /&gt;
*Operatorem &amp;lt;tt&amp;gt;in&amp;lt;/tt&amp;gt; można badać nie tylko, czy dany znak występuje w napisie, ale również czy jeden napis jest fragmentem drugiego:&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
s = 'abc XYZ'&lt;br /&gt;
'abc' in s&lt;br /&gt;
→ True&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
*Napisy mają szereg użytecznych metod; ale ''żadna z tych metod nie zmienia napisu, którego dotyczy'' - może jedynie tworzyć (i zwracać) nowy napis, utworzony na podstawie istniejącego. Przykłady:&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
s.lower()&lt;br /&gt;
→ 'abc xyz'&lt;br /&gt;
s.upper()&lt;br /&gt;
→ 'ABC XYZ'&lt;br /&gt;
s.replace(' ', ';')&lt;br /&gt;
→ 'abc;XYZ'&lt;br /&gt;
s.find('XY') # znajduje pozycję, na jakiej występuje podany fragment w napisie s&lt;br /&gt;
→ 4&lt;br /&gt;
s.find('q')  # szukamy fragmentu, którego w s nie ma..&lt;br /&gt;
→ -1 &lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
*Metod tych jest więcej, poznamy je w przykładach&lt;br /&gt;
*Funkcją - konstruktorem napisu jest &amp;lt;tt&amp;gt;str&amp;lt;/tt&amp;gt;; np. liczbę - zamienia w napis będący jej zapisem (najbardziej ,,standardowym&amp;quot;), i podobnie z innymi typami danych - zwraca najbardziej ,,standardową&amp;quot; ich reprezentację za pomocą napisu&lt;br /&gt;
*Szczególnie ważną i przydatną operacją napisową jest metoda &amp;lt;tt&amp;gt;format&amp;lt;/tt&amp;gt;, o niej zaraz.&lt;br /&gt;
&lt;br /&gt;
===Formatowanie===&lt;br /&gt;
&lt;br /&gt;
Idea formatowania jest następująca: mamy pewien napis, który służy jako szablon do tworzenia napisów, w ten sposób, że określone miejsca w szablonie wypełniane są wartościami (a dokładniej - ich przedstawieniami napisowymi), które zazwyczaj nie są z góry znane i są wyliczane dopiero w wyniku działania programu. Najczęściej chodzi po prostu o przedstawienie uzyskanych wyników w postaci komunikatów lub zapisów w plikach, o określonej przez programistę postaci.&lt;br /&gt;
&lt;br /&gt;
Gdy korzystamy z metody &amp;lt;tt&amp;gt;format&amp;lt;/tt&amp;gt;, napis pełniący rolę szablonu (literalny lub przywołany poprzez nazwę) stoi przed kropką, tzn. wywołujemy metodę &amp;lt;tt&amp;gt;format&amp;lt;/tt&amp;gt; tegoż napisu - szablonu, natomiast argumentami tego wywołania są wartości, które mają być wstawione w przeznaczone na to pozycje w szablonie.&lt;br /&gt;
&lt;br /&gt;
Język opisu szablonów jest stosunkowo złożony i kryje w sobie szereg możliwości, na razie wprowadzimy najprostsze przypadki.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
# Najprostsze formatowanie: wartości wstawiane są kolejno w miejsca zaznaczone poprzez {}&lt;br /&gt;
'x = {}, y = {}'.format(1.2, 9) &lt;br /&gt;
→ 'x = 1.2, y = 9'&lt;br /&gt;
# Numerowanie pozycji (ten sam numerek może występować więcej niż raz w szablonie&lt;br /&gt;
'x1 = {1}, x0 = {0}'.format(3, 15)&lt;br /&gt;
→ 'x1 = 15, x0 = 3'&lt;br /&gt;
# Obcięcie przedstawienia liczby ułamkowej do określonej liczby cyfr po kropce&lt;br /&gt;
'{0:.4f}'.format(3.141592653589793) &lt;br /&gt;
→ '3.1416'&lt;br /&gt;
# Bardziej szczegółowa kontrola formatowania&lt;br /&gt;
'{:4s}{:4s}{:*&amp;gt;4s}'.format('a', 'b', 'c')&lt;br /&gt;
→ 'a   b   ***c'&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
W tym ostatnim przykładzie, liczby 4 specyfikują ''minimalną'' szerokość pól przeznaczonych na wypełnienie podanymi wartościami, natomiast &amp;lt;tt&amp;gt;*&amp;gt;&amp;lt;/tt&amp;gt; oznacza, że gwiazdka ma być ,,wypełniaczem&amp;quot; pustego miejsca, jeżeli takie pozostanie w zadanej wielkości pola po wstawieniu wartości, a znak &amp;lt;tt&amp;gt;&amp;gt;&amp;lt;/tt&amp;gt; oznacza wyrównanie (wewnątrz pola) do strony prawej. Więcej szczegółów - w [https://docs.python.org/3/library/string.html#formatstrings dokumentacji].&lt;br /&gt;
&lt;br /&gt;
Począwszy od wersji 3.6 języka Python wprowadzono uproszczoną składnię formatowania napisów. Poprzedzając w zapisie napisu literalnego otwierający cudzysłów (lub apostrof) literą &amp;lt;tt&amp;gt;f&amp;lt;/tt&amp;gt; (lub &amp;lt;tt&amp;gt;F&amp;lt;/tt&amp;gt;), możemy w tym napisie skorzystać z sekwencji w parach nawiasów klamrowych, gdzie wewnątrz nawiasów umieszczamy (zamiast jak wyżej &amp;amp;mdash; numeru pozycji w liście argumentów wywołania &amp;lt;tt&amp;gt;format()&amp;lt;/tt&amp;gt;) po prostu zapis wyrażenia w Pythonie, którego aktualna wartość znajdzie się w tym miejscu w wyniku ewaluacji, plus ewentualnie dwukropek a po nim dyrektywy formatowania, jak wyżej. Przykłady:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
x, y = 1.2, 9&lt;br /&gt;
f'x = {x}, y = {y}'&lt;br /&gt;
→ x = 1.2, y = 9&lt;br /&gt;
f'wynik działania arytmetycznego: {2 * x + y}'&lt;br /&gt;
→ wynik działania arytmetycznego: 11.4&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Jeżeli chcemy, aby w wyniku wystąpiły dosłowne nawiasy klamrowe, a nie zostały one zinterpretowane jako pole do wypełnienia wartością wyrażenia, to musimy je podwoić (&amp;lt;tt&amp;gt;f'{{'&amp;lt;/tt&amp;gt; → { itd.)&lt;br /&gt;
&lt;br /&gt;
=Ćwiczenia=&lt;br /&gt;
&lt;br /&gt;
1. Napisz funkcję, która wśród elementów sekwencji (lub generatora) napisów (drugi argument wywołania) znajdzie i zwróci te, które są permutacjami danego napisu (pierwszy argument), ale nie są z nim identyczne - bez rozróżniania wielkości liter. Przykładowo:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
permutacje('Three', ['Ether', 'one', 'there', 'two', 'three'])&lt;br /&gt;
→ ['Ether', 'there']&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
2. Napisz funkcję &amp;lt;tt&amp;gt;czy_palindrom(s)&amp;lt;/tt&amp;gt;, która dla napisu &amp;lt;tt&amp;gt;s&amp;lt;/tt&amp;gt; stwierdzi, czy jest on palindromem - tzn. czy pisany wspak jest identyczny z oryginałem, i zwróci wynik tego badania (&amp;lt;tt&amp;gt;True&amp;lt;/tt&amp;gt; lub &amp;lt;tt&amp;gt;False&amp;lt;/tt&amp;gt;); oraz drugą funkcję &amp;lt;tt&amp;gt;palindromy(words)&amp;lt;/tt&amp;gt;, która mając daną sekwencję (lub generator) &amp;lt;tt&amp;gt;words&amp;lt;/tt&amp;gt; zwróci generator zawierający jedynie palindromy występujące wśród elementów &amp;lt;tt&amp;gt;words&amp;lt;/tt&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
for word in palindromy(['Ala', 'ma', 'psa', 'Asa']):&lt;br /&gt;
    print(word)&lt;br /&gt;
→&lt;br /&gt;
Ala&lt;br /&gt;
Asa&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
3. Napisz funkcję &amp;lt;tt&amp;gt;slowa_podobne(s, words)&amp;lt;/tt&amp;gt;, która podobnie jak funkcja z poprzedniego przykładu ,,przefiltruje&amp;quot; sekwencję lub generator &amp;lt;tt&amp;gt;words&amp;lt;/tt&amp;gt;, ale pozostawiając w wyniku jedynie napisy ,,podobne&amp;quot; do napisu &amp;lt;tt&amp;gt;s&amp;lt;/tt&amp;gt; w tym sensie, że składające się z tych samych znaków &amp;amp;mdash; ale ewentualnie występujących inną liczbę razy (lecz nie identyczne z &amp;lt;tt&amp;gt;s&amp;lt;/s&amp;gt;):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
for word in slowa_podobne('one', ['one', 'two', 'None', 'three', 'neon', 'eon']):&lt;br /&gt;
    print(word)&lt;br /&gt;
→&lt;br /&gt;
None&lt;br /&gt;
neon&lt;br /&gt;
eon&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
''CDN''&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
[[PPy3/Funkcje|poprzednie]] | [[&amp;quot;Programowanie z Pythonem3&amp;quot;|strona główna]] | [[PPy3/Moduły|dalej]]&lt;br /&gt;
&lt;br /&gt;
[[Użytkownik:RobertJB|RobertJB]] ([[Dyskusja użytkownika:RobertJB|dyskusja]]) 16:06, 5 lip 2016 (CEST)&lt;/div&gt;</summary>
		<author><name>RobertJB</name></author>
		
	</entry>
	<entry>
		<id>http://brain.fuw.edu.pl/edu/index.php?title=PPy3/Wej%C5%9BcieWyj%C5%9Bcie&amp;diff=9337</id>
		<title>PPy3/WejścieWyjście</title>
		<link rel="alternate" type="text/html" href="http://brain.fuw.edu.pl/edu/index.php?title=PPy3/Wej%C5%9BcieWyj%C5%9Bcie&amp;diff=9337"/>
		<updated>2023-05-11T09:33:49Z</updated>

		<summary type="html">&lt;p&gt;RobertJB: /* Odczyt linii poleceń */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=Obsługa wejścia i wyjścia=&lt;br /&gt;
&lt;br /&gt;
Większość sensownych programów służy do przetworzenia jakichś informacji uzyskanych z zewnątrz programu: w najprostszym przypadku,&lt;br /&gt;
z pliku na dysku, lub z danych wprowadzonych przez użytkownika za pomocą klawiatury. W przypadku programów wywoływanych z linii poleceń, istnieje też poręczny i łatwy do wykorzystania mechanizm by wskazać programowi, co ma robić - za pomocą tzw. opcji i/lub wartości parametrów wpisanych na linii poleceń, po nazwie wywoływanego programu. Często też chcemy, by wyniki działania programu, np. przetworzone dane lub wyniki obliczeń, znalazły się w pliku na dysku - choć czasami możemy woleć, aby również (lub zamiast tego) zostały one wyświetlone na ekranie. Omówimy teraz krótko, jak to osiągnąć.&lt;br /&gt;
&lt;br /&gt;
==Pliki tekstowe vs. binarne==&lt;br /&gt;
&lt;br /&gt;
Zawartość każdego pliku na dysku to tak naprawdę ''strumień bajtów'' - bajt, czyli grupa ośmiu bitów, może być traktowany jako reprezentacja (w zapisie dwójkowym), jakiejś liczby całkowitej dodatniej z zakresu 0-255. Często jednak zawartość ta ma być traktowana jako reprezentacja tekstu, czyli ciągu znaków stosowanych w zapisie jakiegoś języka - może to być język naturalny (polski, angielski, chiński, ...) lub np. język programowania (Python, Java, C++, ...), język tworzenia stron WWW (HTML), itd. W tym celu stworzono tzw. ''kodowania'', czyli standardy reprezentowania znaków stosowanych w systemach zapisu języków naturalnych za pomocą bajtów lub grup bajtów (języki programowania itp. zasadniczo posługują się tymi samymi zestawami znaków, co języki naturalne - a zwłaszcza angielski).&lt;br /&gt;
&lt;br /&gt;
Nie wchodząc za bardzo w szczegóły, obecnie stosowane reprezentacje cyfrowe tekstu oparte są na standardzie ''Unicode'', który m. in. definiuje tzw. uniwersalny zestaw znaków (UCS) - tablicę, zawierającą wszystkie znaki (alfanumeryczne, przestankowe, ideogramy - właściwe dla języków dalekowschodnich, i szeregu innych kategorii) stosowane w systemach pisma wszystkich żywych języków świata (i wielu języków martwych). Wewnętrzna reprezentacja danych napisowych w Pythonie oparta jest na standardzie Unicode - zatem pythonowy napis może zawierać znaki z wszelkiego rodzaju systemów pisma, w dowolnej kombinacji. Zapis tych danych w pliku dyskowym - i odwrotne, zinterpretowanie strumienia bajtów odczytanego z pliku dyskowego jako reprezentacji pewnego napisu - wymaga przyjęcia jakiegoś konkretnego kodowania. Unicode nie stanowi sam w sobie kodowania - określa on repertuar znaków oraz pozycję każdego z nich w tablicy UCS, nie zaś bajt lub grupę bajtów go reprezentującą. &lt;br /&gt;
&lt;br /&gt;
W Pythonie problem ten rozwiązany jest w sposób następujący: domyślnie, zawartość wczytywana z plików interpretowana jest jako dane tekstowe (chyba, że zażyczymy sobie inaczej), zgodnie z pewnym domyślnym kodowaniem, właściwym dla systemu operacyjnego (chyba, że wskażemy że ma być stosowane inne) - w przypadku Linuxa będzie to prawie zawsze kodowanie o nazwie UTF-8, które się dobrze nadaje do zastosowania dla języków zachodnich, posługujących się systemem pisma opartym na alfabecie łacińskim. Inaczej może być w środowiskach języków posługujących się np. cyrylicą, czy języków azjatyckich (pismo arabskie lub ideograficzne - chińskie, japońskie, koreańskie, itd.). W środowiskach Windows może być inaczej...&lt;br /&gt;
&lt;br /&gt;
Z powyższego widać, że rozróżnienie - plik tekstowy czy binarny - jest dość umowne, i dotyczy raczej interpretacji zawartości pliku (plik zapisany zgodnie z nieznanym nam i/lub nieoczekiwanym kodowaniem jest nie do odróżnienia od pliku binarnego). Co więcej, pliki zapisywane przez programy takie, jak MS Word, lub pliki PDF, nawet zawierające wyłącznie tekst, nie są w tym rozumieniu plikami tekstowymi, tylko binarnymi. W przykładach będziemy mieli do czynienia prawie wyłącznie z plikami tekstowymi - warto jednak wiedzieć, że w Pythonie jest osobny typ danych - ciągi bajtów (''bytes''), o własnościach nieco podobnych do napisów, ale o elementach będących bajtami, a nie znakami pisma.&lt;br /&gt;
&lt;br /&gt;
==Czytanie tekstu z pliku==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
&lt;br /&gt;
f = open('nazwa_pliku.txt')&lt;br /&gt;
for linia in f:&lt;br /&gt;
    przetworz(linia)&lt;br /&gt;
f.close()&lt;br /&gt;
&lt;br /&gt;
# albo może lepiej:&lt;br /&gt;
&lt;br /&gt;
with open('nazwa_pliku.txt') as f:&lt;br /&gt;
    for linia in f:&lt;br /&gt;
        przetworz(linia)&lt;br /&gt;
&lt;br /&gt;
# jeszcze inaczej&lt;br /&gt;
&lt;br /&gt;
tresc = open('nazwa_pliku.txt').read() # wczytujemy od razu całą treść pliku&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*Otwarty do odczytu plik tekstowy dopuszcza iterację, w której kolejnymi elementami są linie tekstu - wraz z kończącym je kodem przejścia do nowej linii; w ostatniej linijce pliku kodu tego może brakować (lub nie);&lt;br /&gt;
*Wartość zmiennej &amp;lt;tt&amp;gt;linia&amp;lt;/tt&amp;gt; to w każdym obiegu pętli, treść kolejnej linii tekstu jako napis; zawartość (bajtowa) pliku jest interpretowana jako napis zgodnie z domyślnym kodowaniem systemowym (można to zmienić poprzez dodatkowy parametr wywołania &amp;lt;tt&amp;gt;open&amp;lt;/tt&amp;gt;);&lt;br /&gt;
*Jeżeli zawartość pliku ''nie'' jest zgodna z założeniem, że można go interpretować jako tekst w przyjętym kodowaniu, to w trakcie przetwarzania może wystąpić błąd (wyjątek);&lt;br /&gt;
*Po zakończeniu przetwarzania plik należy zamknąć, wywołując metodę &amp;lt;tt&amp;gt;close&amp;lt;/tt&amp;gt;; ewentualnie można to pominąć, jeśli wiemy '''na pewno''' że wraz z końcem przetwarzania pliku kończy się cały program - wraz z zakończeniem działania programu otwarte pliki zostaną zamknięte;&lt;br /&gt;
*Druga postać wprowadza nową instrukcję złożoną - blok &amp;lt;tt&amp;gt;with&amp;lt;/tt&amp;gt;; to, jak on dokładnie działa, zależy od typu obiektu do jakiego odwołujemy się po słowie &amp;lt;tt&amp;gt;with&amp;lt;/tt&amp;gt; - jeżeli jest nim otwarty plik, to zostanie on automatycznie zamknięty wraz z końcem bloku;&lt;br /&gt;
*Odwoływanie się do pliku, który już został zamknięty, będzie nieskuteczne; żadne operacje się nie powiodą.&lt;br /&gt;
*Ostatnia wersja jest odrobinę ryzykowna - jeśli plik jest ''bardzo'' duży, to na jego treść może nie wystarczyć pamięci RAM, i program się wywróci. W dzisiejszych czasach oznacza to jednak, że rozmiar pliku sięga wielu gigabajtów.&lt;br /&gt;
&lt;br /&gt;
==Czytanie dowolnych danych z pliku==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
&lt;br /&gt;
f = open('nazwa_pliku', mode='b')&lt;br /&gt;
dane = f.read(1024*1024) # wczytujemy 1 MB danych (lub mniej, jeśli tylu już nie ma)&lt;br /&gt;
(...)&lt;br /&gt;
f.seek(0) # &amp;quot;przewinąć&amp;quot; do początku pliku (lub innej pozycji, względem początku)&lt;br /&gt;
(...)&lt;br /&gt;
pos = f.tell() # uzyskać aktualną pozycję&lt;br /&gt;
(...)&lt;br /&gt;
f.close()&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*To, co odczytamy - czyli &amp;lt;tt&amp;gt;dane&amp;lt;/tt&amp;gt;, to będzie łańcuch bajtów;&lt;br /&gt;
*Można odpowiednio wykorzystać blok &amp;lt;tt&amp;gt;with&amp;lt;/tt&amp;gt;, aby uniknąć ręcznego zamykania pliku;&lt;br /&gt;
*Wywołanie &amp;lt;tt&amp;gt;read()&amp;lt;/tt&amp;gt; bez argumentu oznacza: wczytaj wszystko;&lt;br /&gt;
*Jeśli wywołanie &amp;lt;tt&amp;gt;read&amp;lt;/tt&amp;gt; z dodatnim argumentem zwróci łańcuch o długości zero - to dotarliśmy do końca pliku.&lt;br /&gt;
&lt;br /&gt;
==Zapis danych do pliku==&lt;br /&gt;
&lt;br /&gt;
Aby był możliwy zapis danych do pliku dyskowego, należy go otworzyć w trybie do zapisu:&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
&lt;br /&gt;
f = open('nazwa_pliku.txt', 'w')&lt;br /&gt;
(...)&lt;br /&gt;
f.write(dane)&lt;br /&gt;
(...)&lt;br /&gt;
f.close()&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''UWAGA:''' otwarcie pliku w trybie do zapisu (&amp;lt;tt&amp;gt;'w'&amp;lt;/tt&amp;gt;) spowoduje usunięcie poprzedniej zawartości pliku - o ile dotyczy pliku już istniejącego. Jeżeli nazwa odnosi się do pliku jeszcze nieistniejącego, to zostanie on utworzony. Jeżeli chcemy zachować poprzednie dane, dopisując nowe do końca pliku, należy plik otworzyć w trybie &amp;lt;tt&amp;gt;'a'&amp;lt;/tt&amp;gt; (''append'').&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&amp;lt;small&amp;gt;&lt;br /&gt;
Domyślnie plik jest otwierany w trybie zapisu tekstu, zgodnie z domyślnym kodowaniem. A więc &amp;lt;tt&amp;gt;dane&amp;lt;/tt&amp;gt; powinny być napisem. Jeżeli chcemy zapisywać surowe bajty, należy użyć trybu &amp;lt;tt&amp;gt;'wb'&amp;lt;/tt&amp;gt;. Jeżeli chcemy użyć kodowania innego niż domyślne, możemy w funkcji &amp;lt;tt&amp;gt;open&amp;lt;/tt&amp;gt; użyć parametru ''encoding'', w postaci:&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
&lt;br /&gt;
f = open('nazwa_pliku.txt', 'w', encoding='cp1250')&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
w tym przykładzie użyto nazwy kodowania stosowanego do języka polskiego w Windows.&lt;br /&gt;
&amp;lt;/small&amp;gt;&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Standardowe strumienie i przekierowania==&lt;br /&gt;
&lt;br /&gt;
===Wprowadzenie===&lt;br /&gt;
&lt;br /&gt;
System operacyjny z rodziny unixów (np. Linux lub MacOS) udostępnia każdemu procesowi (uruchomionemu programowi) trzy tzw. standardowe strumienie, mogące być źródłem danych (tzw. standardowy strumień wejściowy, ''stdin'') lub kanałem przekazywania wyników, komunikatów itp. (standardowy strumień wyjściowy, ''stdout'' i standardowy strumień błędów, ''stderr'').&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&amp;lt;small&amp;gt;&lt;br /&gt;
W systemach z rodziny Windows jest podobnie, w odniesieniu do programów uruchamianych z linii poleceń, czyli okna programu ''cmd.exe''.&lt;br /&gt;
&amp;lt;/small&amp;gt;&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Co to konkretnie znaczy? Domyślnie, zawartością ''stdin'' są dane wprowadzane z klawiatury, natomiast dane wypisywane na ''stdout'' i ''stderr'' pojawiają się na ekranie - w oknie terminalowym, z którego uruchomiono dany program. Przyjęto umowę, że na ''stdout'' wypisuje się dane, stanowiące wynik zgodnej z przewidywaniami pracy programu (oczywiście o ile nie przewidziano zapisu tych wyników bezpośrednio do pliku na dysku), natomiast na ''stderr'' - jedynie komunikaty dotyczące sytuacji nieprzewidzianych, a więc błędów przetwarzania, lub ostrzeżenia - pojawiające się w sytuacjach, gdy wprawdzie kontynuacja pracy programu jest możliwa, ale okoliczności wskazują, że jej wyniki mogą być pod jakimś względem wątpliwe.&lt;br /&gt;
&lt;br /&gt;
Powyższe ma sens, ponieważ domyślne powiązania - ''stdin'' z klawiaturą, a ''stdout'' i ''stderr'' z ekranem można zmienić - poprzez mechanizmy tzw. przekierowania. W szczególności, strumienie wyjścia i błędu można rozdzielić, np. przekierowując treść ''stdout'' do pliku, a pozostawiając ''stderr'' jako związany z ekranem.&lt;br /&gt;
&lt;br /&gt;
W środowisku Python standardowe strumienie dostępne są jako elementy modułu &amp;lt;tt&amp;gt;sys&amp;lt;/tt&amp;gt;: &amp;lt;tt&amp;gt;sys.stdin&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;sys.stdout&amp;lt;/tt&amp;gt; i &amp;lt;tt&amp;gt;sys.stderr&amp;lt;/tt&amp;gt;. Mają one właściwości plików tekstowych, choć bez możliwości przewijania (&amp;lt;tt&amp;gt;seek&amp;lt;/tt&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
'''Funkcja &amp;lt;tt&amp;gt;print&amp;lt;/tt&amp;gt; w Pythonie domyślnie wypisuje dane do strumienia ''stdout''; można to zmienić, używając parametru wywołania ''file'', którego wartością powinien być plik otwarty do zapisu w trybie tekstowym.'''&lt;br /&gt;
&lt;br /&gt;
===Sposoby przekierowania===&lt;br /&gt;
&lt;br /&gt;
Przekierowanie strumieni dokonuje się na poziomie systemu operacyjnego, całkowicie poza środowiskiem Pythona - program nie ma możliwości wykrycia, czy strumienie standardowe na jakich operuje zostały przekierowane. Przekierowania określa się na linii poleceń w momencie uruchomienia programu.&lt;br /&gt;
&lt;br /&gt;
Przekierowanie ''stdin'' z pliku:&lt;br /&gt;
&amp;lt;source lang=bash&amp;gt;&lt;br /&gt;
$ program.py &amp;lt; plik_wejsciowy.txt&lt;br /&gt;
$ &amp;lt; plik_wejsciowy.txt program.py&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Oba powyższe polecenia są równoważne i skutkują tym, że dane czytane przez program z &amp;lt;tt&amp;gt;sys.stdin&amp;lt;/tt&amp;gt; będą tak na prawdę pochodzić z pliku o podanej nazwie (a treść wprowadzana z klawiatury będzie w programie niedostępna).&lt;br /&gt;
&lt;br /&gt;
Przekierowanie ''stdout'' do pliku:&lt;br /&gt;
&amp;lt;source lang=bash&amp;gt;&lt;br /&gt;
$ program.py &amp;gt; plik_wyjscia.txt&lt;br /&gt;
$ &amp;gt; plik_wyjscia.txt program.py&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dane pisane do &amp;lt;tt&amp;gt;sys.stdout&amp;lt;/tt&amp;gt; nie pojawią się w oknie terminala, tylko znajdą się w pliku. Dane pisane do &amp;lt;tt&amp;gt;sys.stderr&amp;lt;/tt&amp;gt; dalej będą trafiać na ekran.&lt;br /&gt;
&lt;br /&gt;
Przekierowania równoczesne:&lt;br /&gt;
&amp;lt;source lang=bash&amp;gt;&lt;br /&gt;
$ program.py &amp;lt; plik_wejsciowy.txt &amp;gt; plik_wyjscia.txt&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Oba poprzednio opisane przekierowania można również wykonać równocześnie. Elementy polecenia również mogą wystąpić w innym porządku.&lt;br /&gt;
&lt;br /&gt;
Przekierowanie ''stderr'':&lt;br /&gt;
&amp;lt;source lang=bash&amp;gt;&lt;br /&gt;
$ program.py 2&amp;gt; plik_bledow.txt&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Komunikaty o błędach i ostrzeżenia znajdą się w pliku o podanej nazwie, zamiast na ekranie. Analogicznie do &amp;lt;tt&amp;gt;2&amp;gt;&amp;lt;/tt&amp;gt;, strumieniom ''stdout'' i ''stdin'' przypisane są numerki 1 i 0 - można więc pisać odpowiednio &amp;lt;tt&amp;gt;1&amp;gt;&amp;lt;/tt&amp;gt; i &amp;lt;tt&amp;gt;0&amp;amp;lt;&amp;lt;/tt&amp;gt;, ale tu te wartości numerów strumieni przekierowanych (naprawdę - ''deskryptorów plików'') są domyślne i niemal zawsze się je pomija.&lt;br /&gt;
&lt;br /&gt;
===Potoki===&lt;br /&gt;
&lt;br /&gt;
Oprócz przekierowania do i z plików, istnieje jeszcze analogiczny mechanizm, gdzie np. strumień ''stdout'' jednego procesu łączy się z strumieniem ''stdin'' innego procesu - skutkiem czego dane wyjściowe pierwszego są wprowadzane do drugiego jako dane wejściowe, tworząc to co się nazywa ''potokiem''. Najprostszy przykład:&lt;br /&gt;
&amp;lt;source lang=bash&amp;gt;&lt;br /&gt;
$ program1.py | program2.py&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
tu ''operatorem potoku'' w systemowej linii poleceń jest znak kreski pionowej (&amp;lt;tt&amp;gt;|&amp;lt;/tt&amp;gt;), a &amp;lt;tt&amp;gt;program1.py&amp;lt;/tt&amp;gt; przekazuje wyniki swojej pracy do dalszego przetwarzania kolejnemu, &amp;lt;tt&amp;gt;program2.py&amp;lt;/tt&amp;gt;. Taki potok może mieć więcej niż dwa etapy i może łączyć się z zastosowaniem przekierowań do plików, np.&lt;br /&gt;
&amp;lt;source lang=bash&amp;gt;&lt;br /&gt;
$ &amp;lt; plik_wejsciowy.txt program1.py 2&amp;gt;bledy.txt | program2.py &amp;gt; plik_wynikow.txt&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Pożytecznym narzędziem do stosowania w potokach jest polecenie (program) o nazwie &amp;lt;tt&amp;gt;tee&amp;lt;/tt&amp;gt;:&lt;br /&gt;
&amp;lt;source lang=bash&amp;gt;&lt;br /&gt;
$ program.py &amp;lt; dane.txt | tee wynik.txt&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
w tym przypadku program wczyta zawartość pliku &amp;lt;tt&amp;gt;dane.txt&amp;lt;/tt&amp;gt;, a wynik wypisany do &amp;lt;tt&amp;gt;sys.stdout&amp;lt;/tt&amp;gt; zarówno pojawi się na ekranie (w oknie terminala, jak i zostanie zapisany w pliku &amp;lt;tt&amp;gt;wynik.txt&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==Odczyt linii poleceń==&lt;br /&gt;
&lt;br /&gt;
Zawartość linii poleceń dostępna jest w obiekcie &amp;lt;tt&amp;gt;sys.argv&amp;lt;/tt&amp;gt; - czyli moduł (standardowy) &amp;lt;tt&amp;gt;sys&amp;lt;/tt&amp;gt;, element &amp;lt;tt&amp;gt;argv&amp;lt;/tt&amp;gt;. Jest to lista argumentów - ,,słów&amp;quot; jakie wywołujący program umieścił w linii poleceń. Inaczej mówiąc, treść linii poleceń ulega wstępnemu rozbiorowi - na słowa, według reguł zależnych od systemu operacyjnego. Najczęściej poszczególne słowa oddzielają spacje (jedna lub więcej), jeśli chcemy, by ciąg zawierający spacje był potraktowany jako pojedyncze słowo (np. nazwa pliku zawierająca spacje), należy ciąg ten np. umieścić w cudzysłowach (które zostaną usunięte z treści argumentu). Treść linii poleceń na ogół ulega jeszcze innym formom obróbki przez system operacyjny (np. rozwijanie rozmaitych skrótów), ale dzieje się to poza kontrolą Pythona.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
&lt;br /&gt;
from sys import argv&lt;br /&gt;
for arg in argv:&lt;br /&gt;
    print(arg)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Korzystając z powyższego kodu możemy dowiedzieć się, jak wygląda lista argumentów już ''po'' jej obróbce przez system operacyjny.&lt;br /&gt;
&lt;br /&gt;
Na początku listy &amp;lt;tt&amp;gt;argv&amp;lt;/tt&amp;gt; czyli w pozycji &amp;lt;tt&amp;gt;argv[0]&amp;lt;/tt&amp;gt; znajduje się nazwa uruchomionego programu (tj. nazwa pliku z kodem uruchomionego jako program główny).&lt;br /&gt;
&lt;br /&gt;
===Przykłady===&lt;br /&gt;
&lt;br /&gt;
=1.=&lt;br /&gt;
Jeśli przewidujemy, że jedynymi argumentami wywołania naszego programu będą nazwy plików, na każdym z których należy wykonać jakąś czynność, to można to zrealizować tak:&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
&lt;br /&gt;
#! /usr/bin/python3&lt;br /&gt;
&lt;br /&gt;
from sys import argv&lt;br /&gt;
&lt;br /&gt;
def przetwarzaj(plik):&lt;br /&gt;
    # tu określamy na czym polega &amp;quot;przetworzenie&amp;quot; pliku&lt;br /&gt;
&lt;br /&gt;
for plik in argv[1:]:&lt;br /&gt;
    przetwarzaj(plik)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*Wzięcie wycinku z &amp;lt;tt&amp;gt;argv&amp;lt;/tt&amp;gt; służy pominięciu pliku zawierającego kod programu;&lt;br /&gt;
*Elementami &amp;lt;tt&amp;gt;argv&amp;lt;/tt&amp;gt; są ''nazwy'' plików - napisy.&lt;br /&gt;
&lt;br /&gt;
=2.=&lt;br /&gt;
Nieraz jest pożądane, aby program przetwarzający strumień danych mógł działać na dwa sposoby: albo wywołany z argumentami będącymi nazwami plików z danymi wejściowymi wczytuje kolejno zawartość tych plików; albo wywołany bez takich argumentów, czyta dane wejściowe ze standardowego strumienia wejściowego, w którym one znajdują się zazwyczaj w wyniku poprzedniego kroku przetwarzania potokowego. Nota bene w ten sposób działa wiele tradycyjnych narzędzi systemowych w Linuxie. &lt;br /&gt;
&lt;br /&gt;
W standardowej bibliotece Pythona jest moduł &amp;lt;tt&amp;gt;fileinput&amp;lt;/tt&amp;gt;, który ułatwia realizację takiego podejścia. W najprostszym przypadku:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
#! /usr/bin/python3&lt;br /&gt;
&lt;br /&gt;
import fileinput&lt;br /&gt;
&lt;br /&gt;
def przetwarzaj(linia):&lt;br /&gt;
    # tu określamy na czym polega przetworzenie linii treści&lt;br /&gt;
&lt;br /&gt;
for linia in fileinput.input():&lt;br /&gt;
    przetwarzaj(linia)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
W pętli w powyższym przykładzie wystąpią kolejno wszystkie linie w treści plików wymienionych na linii poleceń (z pominięciem pliku samego programu), lub jeśli linia poleceń jest pusta &amp;amp;mdash; linie w treści &amp;lt;tt&amp;gt;sys.stdin&amp;lt;/tt&amp;gt;. Ewentualnie można wywołać funkcję &amp;lt;tt&amp;gt;fileinput.input(pliki)&amp;lt;/tt&amp;gt;, tj. zamiast bez argumentów to z argumentem będącym sekwencją nazw plików zawierających dane wejściowe. Może to być np. lista argumentów programu, ale po usunięciu z niej pozycji będących opcjami, a nie nazwami plików. Oczywiście w dokumentacji znajdziemy jeszcze dalsze możliwości.&lt;br /&gt;
&lt;br /&gt;
=Ćwiczenia=&lt;br /&gt;
&lt;br /&gt;
1. Napisać program, który wczyta dany plik linia po linii i znajdzie wśród nich podzbiór linii o maksymalnej długości (w znakach) oraz wartość tej maksymalnej długości. Niech wynikiem działania programu będzie wypisanie liczby oznaczającej maksymalną długość linii występujących w badanym pliku, a następnie - treść tych linii, w kolejności w jakiej pojawiały się w pliku. Wypróbować ten program na pliku ''/usr/share/dict/words''. W końcowej wersji program powinien operować na pliku, którego nazwę podamy jako argument na linii poleceń.&lt;br /&gt;
&lt;br /&gt;
''Wskazówka:'' długość linii nie powinna uwzględniać kodu przejścia do nowej linii, zapisywanego symbolicznie jako &amp;lt;tt&amp;gt;'\n'&amp;lt;/tt&amp;gt; kończącego (prawie) każdą linię. &lt;br /&gt;
&lt;br /&gt;
2. Napisać program, który wczyta dany plik linia po linii i znajdzie wśród nich podzbiór linii o danej długości w znakach. Niech wynikiem działania programu będzie wypisanie linii o żądanej długości występujących w treści pliku w takiej kolejności, w jakiej pojawiały się w pliku. Długość szukanych linii podajemy jako pierwszy, a nazwę badanego pliku jako drugi argument na linii poleceń.&lt;br /&gt;
&lt;br /&gt;
3. Napisać program, który wyznaczy rozkład długości linii w treści danego pliku - nazwę pliku podajemy na linii poleceń. Wynikiem działania programu jest wypisanie ciągu linijek postaci &amp;lt;tt&amp;gt;''długość'' : ''ile''&amp;lt;/tt&amp;gt;, gdzie liczba ''ile'' opisuje, ile linii o danej długości wystąpiło w treści pliku. Pozycje, w których ''ile'' wynosiłoby 0 nie pojawiają się.&lt;br /&gt;
&lt;br /&gt;
4. Napisać program, który wyznacza częstości występowania w treści pliku określonych znaków. Zestaw znaków, których wystąpienia zamierzamy zliczać podajemy jako pierwszy argument na linii poleceń, nazwę badanego pliku jako drugi. Wynikiem działania programu jest wypisanie ciągu linijek postaci &amp;lt;tt&amp;gt;''znak'' : ''częstość''&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
5. Napisać program, który znajduje w pliku ''/usr/share/dict/words'' wszystkie słowa, składające się z tych samych liter co słowo, podane jako argument na linii poleceń - choć niekoniecznie występujących tę samą liczbę razy. Inaczej mówiąc, każda z liter występujących w podanym słowie występuje również w słowach szukanych, a nie występują w nich żadne inne znaki. Program wypisuje na ekran znalezione słowa, po jednym na linijkę.&lt;br /&gt;
 &lt;br /&gt;
6. Niech program znajduje wszystkie słowa, jakie można utworzyć korzystając z danego zestawu liter (podanego jako pierwszy argument na linii poleceń); tzn. tak jak w ''Scrabble'' dysponujemy takimi literami i w takiej liczbie, jakie składają się na to słowo (lub ,,słowo&amp;quot;). Źródłem słów jakie można utworzyć jest plik podany jako drugi argument (domyślnie - ''/usr/share/dict/words'').&amp;lt;br&amp;gt;&lt;br /&gt;
''Wskazówka:'' może się tu przydać operacja &amp;lt;tt&amp;gt;L.remove(x)&amp;lt;/tt&amp;gt;, gdzie &amp;lt;tt&amp;gt;L&amp;lt;/tt&amp;gt; jest listą; usuwa ona z listy pierwsze z kolei znalezione w niej wystąpienie elementu &amp;lt;tt&amp;gt;x&amp;lt;/tt&amp;gt;. &amp;lt;br&amp;gt;&lt;br /&gt;
''Uwaga:'' operacja ta zwróci błąd, jeśli element &amp;lt;tt&amp;gt;x&amp;lt;/tt&amp;gt; ''nie'' występuje w &amp;lt;tt&amp;gt;L&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
[[PPy3/Moduły|poprzednie]] | [[&amp;quot;Programowanie z Pythonem3&amp;quot;|strona główna]] | [[PPy3/NumPy|dalej]]&lt;br /&gt;
&lt;br /&gt;
[[Użytkownik:RobertJB|RobertJB]] ([[Dyskusja użytkownika:RobertJB|dyskusja]]) 13:26, 4 sie 2016 (CEST)&lt;/div&gt;</summary>
		<author><name>RobertJB</name></author>
		
	</entry>
	<entry>
		<id>http://brain.fuw.edu.pl/edu/index.php?title=PPy3/Wej%C5%9BcieWyj%C5%9Bcie&amp;diff=9336</id>
		<title>PPy3/WejścieWyjście</title>
		<link rel="alternate" type="text/html" href="http://brain.fuw.edu.pl/edu/index.php?title=PPy3/Wej%C5%9BcieWyj%C5%9Bcie&amp;diff=9336"/>
		<updated>2023-05-11T09:32:42Z</updated>

		<summary type="html">&lt;p&gt;RobertJB: /* Przykład */ https://wyborcza.pl/duzyformat/7,127290,25087636,co-kozacy-maja-wspolnego-z-anna-walentynowicz.html#S.embed_article-K.C-B.1-L.1.zw&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=Obsługa wejścia i wyjścia=&lt;br /&gt;
&lt;br /&gt;
Większość sensownych programów służy do przetworzenia jakichś informacji uzyskanych z zewnątrz programu: w najprostszym przypadku,&lt;br /&gt;
z pliku na dysku, lub z danych wprowadzonych przez użytkownika za pomocą klawiatury. W przypadku programów wywoływanych z linii poleceń, istnieje też poręczny i łatwy do wykorzystania mechanizm by wskazać programowi, co ma robić - za pomocą tzw. opcji i/lub wartości parametrów wpisanych na linii poleceń, po nazwie wywoływanego programu. Często też chcemy, by wyniki działania programu, np. przetworzone dane lub wyniki obliczeń, znalazły się w pliku na dysku - choć czasami możemy woleć, aby również (lub zamiast tego) zostały one wyświetlone na ekranie. Omówimy teraz krótko, jak to osiągnąć.&lt;br /&gt;
&lt;br /&gt;
==Pliki tekstowe vs. binarne==&lt;br /&gt;
&lt;br /&gt;
Zawartość każdego pliku na dysku to tak naprawdę ''strumień bajtów'' - bajt, czyli grupa ośmiu bitów, może być traktowany jako reprezentacja (w zapisie dwójkowym), jakiejś liczby całkowitej dodatniej z zakresu 0-255. Często jednak zawartość ta ma być traktowana jako reprezentacja tekstu, czyli ciągu znaków stosowanych w zapisie jakiegoś języka - może to być język naturalny (polski, angielski, chiński, ...) lub np. język programowania (Python, Java, C++, ...), język tworzenia stron WWW (HTML), itd. W tym celu stworzono tzw. ''kodowania'', czyli standardy reprezentowania znaków stosowanych w systemach zapisu języków naturalnych za pomocą bajtów lub grup bajtów (języki programowania itp. zasadniczo posługują się tymi samymi zestawami znaków, co języki naturalne - a zwłaszcza angielski).&lt;br /&gt;
&lt;br /&gt;
Nie wchodząc za bardzo w szczegóły, obecnie stosowane reprezentacje cyfrowe tekstu oparte są na standardzie ''Unicode'', który m. in. definiuje tzw. uniwersalny zestaw znaków (UCS) - tablicę, zawierającą wszystkie znaki (alfanumeryczne, przestankowe, ideogramy - właściwe dla języków dalekowschodnich, i szeregu innych kategorii) stosowane w systemach pisma wszystkich żywych języków świata (i wielu języków martwych). Wewnętrzna reprezentacja danych napisowych w Pythonie oparta jest na standardzie Unicode - zatem pythonowy napis może zawierać znaki z wszelkiego rodzaju systemów pisma, w dowolnej kombinacji. Zapis tych danych w pliku dyskowym - i odwrotne, zinterpretowanie strumienia bajtów odczytanego z pliku dyskowego jako reprezentacji pewnego napisu - wymaga przyjęcia jakiegoś konkretnego kodowania. Unicode nie stanowi sam w sobie kodowania - określa on repertuar znaków oraz pozycję każdego z nich w tablicy UCS, nie zaś bajt lub grupę bajtów go reprezentującą. &lt;br /&gt;
&lt;br /&gt;
W Pythonie problem ten rozwiązany jest w sposób następujący: domyślnie, zawartość wczytywana z plików interpretowana jest jako dane tekstowe (chyba, że zażyczymy sobie inaczej), zgodnie z pewnym domyślnym kodowaniem, właściwym dla systemu operacyjnego (chyba, że wskażemy że ma być stosowane inne) - w przypadku Linuxa będzie to prawie zawsze kodowanie o nazwie UTF-8, które się dobrze nadaje do zastosowania dla języków zachodnich, posługujących się systemem pisma opartym na alfabecie łacińskim. Inaczej może być w środowiskach języków posługujących się np. cyrylicą, czy języków azjatyckich (pismo arabskie lub ideograficzne - chińskie, japońskie, koreańskie, itd.). W środowiskach Windows może być inaczej...&lt;br /&gt;
&lt;br /&gt;
Z powyższego widać, że rozróżnienie - plik tekstowy czy binarny - jest dość umowne, i dotyczy raczej interpretacji zawartości pliku (plik zapisany zgodnie z nieznanym nam i/lub nieoczekiwanym kodowaniem jest nie do odróżnienia od pliku binarnego). Co więcej, pliki zapisywane przez programy takie, jak MS Word, lub pliki PDF, nawet zawierające wyłącznie tekst, nie są w tym rozumieniu plikami tekstowymi, tylko binarnymi. W przykładach będziemy mieli do czynienia prawie wyłącznie z plikami tekstowymi - warto jednak wiedzieć, że w Pythonie jest osobny typ danych - ciągi bajtów (''bytes''), o własnościach nieco podobnych do napisów, ale o elementach będących bajtami, a nie znakami pisma.&lt;br /&gt;
&lt;br /&gt;
==Czytanie tekstu z pliku==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
&lt;br /&gt;
f = open('nazwa_pliku.txt')&lt;br /&gt;
for linia in f:&lt;br /&gt;
    przetworz(linia)&lt;br /&gt;
f.close()&lt;br /&gt;
&lt;br /&gt;
# albo może lepiej:&lt;br /&gt;
&lt;br /&gt;
with open('nazwa_pliku.txt') as f:&lt;br /&gt;
    for linia in f:&lt;br /&gt;
        przetworz(linia)&lt;br /&gt;
&lt;br /&gt;
# jeszcze inaczej&lt;br /&gt;
&lt;br /&gt;
tresc = open('nazwa_pliku.txt').read() # wczytujemy od razu całą treść pliku&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*Otwarty do odczytu plik tekstowy dopuszcza iterację, w której kolejnymi elementami są linie tekstu - wraz z kończącym je kodem przejścia do nowej linii; w ostatniej linijce pliku kodu tego może brakować (lub nie);&lt;br /&gt;
*Wartość zmiennej &amp;lt;tt&amp;gt;linia&amp;lt;/tt&amp;gt; to w każdym obiegu pętli, treść kolejnej linii tekstu jako napis; zawartość (bajtowa) pliku jest interpretowana jako napis zgodnie z domyślnym kodowaniem systemowym (można to zmienić poprzez dodatkowy parametr wywołania &amp;lt;tt&amp;gt;open&amp;lt;/tt&amp;gt;);&lt;br /&gt;
*Jeżeli zawartość pliku ''nie'' jest zgodna z założeniem, że można go interpretować jako tekst w przyjętym kodowaniu, to w trakcie przetwarzania może wystąpić błąd (wyjątek);&lt;br /&gt;
*Po zakończeniu przetwarzania plik należy zamknąć, wywołując metodę &amp;lt;tt&amp;gt;close&amp;lt;/tt&amp;gt;; ewentualnie można to pominąć, jeśli wiemy '''na pewno''' że wraz z końcem przetwarzania pliku kończy się cały program - wraz z zakończeniem działania programu otwarte pliki zostaną zamknięte;&lt;br /&gt;
*Druga postać wprowadza nową instrukcję złożoną - blok &amp;lt;tt&amp;gt;with&amp;lt;/tt&amp;gt;; to, jak on dokładnie działa, zależy od typu obiektu do jakiego odwołujemy się po słowie &amp;lt;tt&amp;gt;with&amp;lt;/tt&amp;gt; - jeżeli jest nim otwarty plik, to zostanie on automatycznie zamknięty wraz z końcem bloku;&lt;br /&gt;
*Odwoływanie się do pliku, który już został zamknięty, będzie nieskuteczne; żadne operacje się nie powiodą.&lt;br /&gt;
*Ostatnia wersja jest odrobinę ryzykowna - jeśli plik jest ''bardzo'' duży, to na jego treść może nie wystarczyć pamięci RAM, i program się wywróci. W dzisiejszych czasach oznacza to jednak, że rozmiar pliku sięga wielu gigabajtów.&lt;br /&gt;
&lt;br /&gt;
==Czytanie dowolnych danych z pliku==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
&lt;br /&gt;
f = open('nazwa_pliku', mode='b')&lt;br /&gt;
dane = f.read(1024*1024) # wczytujemy 1 MB danych (lub mniej, jeśli tylu już nie ma)&lt;br /&gt;
(...)&lt;br /&gt;
f.seek(0) # &amp;quot;przewinąć&amp;quot; do początku pliku (lub innej pozycji, względem początku)&lt;br /&gt;
(...)&lt;br /&gt;
pos = f.tell() # uzyskać aktualną pozycję&lt;br /&gt;
(...)&lt;br /&gt;
f.close()&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*To, co odczytamy - czyli &amp;lt;tt&amp;gt;dane&amp;lt;/tt&amp;gt;, to będzie łańcuch bajtów;&lt;br /&gt;
*Można odpowiednio wykorzystać blok &amp;lt;tt&amp;gt;with&amp;lt;/tt&amp;gt;, aby uniknąć ręcznego zamykania pliku;&lt;br /&gt;
*Wywołanie &amp;lt;tt&amp;gt;read()&amp;lt;/tt&amp;gt; bez argumentu oznacza: wczytaj wszystko;&lt;br /&gt;
*Jeśli wywołanie &amp;lt;tt&amp;gt;read&amp;lt;/tt&amp;gt; z dodatnim argumentem zwróci łańcuch o długości zero - to dotarliśmy do końca pliku.&lt;br /&gt;
&lt;br /&gt;
==Zapis danych do pliku==&lt;br /&gt;
&lt;br /&gt;
Aby był możliwy zapis danych do pliku dyskowego, należy go otworzyć w trybie do zapisu:&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
&lt;br /&gt;
f = open('nazwa_pliku.txt', 'w')&lt;br /&gt;
(...)&lt;br /&gt;
f.write(dane)&lt;br /&gt;
(...)&lt;br /&gt;
f.close()&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''UWAGA:''' otwarcie pliku w trybie do zapisu (&amp;lt;tt&amp;gt;'w'&amp;lt;/tt&amp;gt;) spowoduje usunięcie poprzedniej zawartości pliku - o ile dotyczy pliku już istniejącego. Jeżeli nazwa odnosi się do pliku jeszcze nieistniejącego, to zostanie on utworzony. Jeżeli chcemy zachować poprzednie dane, dopisując nowe do końca pliku, należy plik otworzyć w trybie &amp;lt;tt&amp;gt;'a'&amp;lt;/tt&amp;gt; (''append'').&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&amp;lt;small&amp;gt;&lt;br /&gt;
Domyślnie plik jest otwierany w trybie zapisu tekstu, zgodnie z domyślnym kodowaniem. A więc &amp;lt;tt&amp;gt;dane&amp;lt;/tt&amp;gt; powinny być napisem. Jeżeli chcemy zapisywać surowe bajty, należy użyć trybu &amp;lt;tt&amp;gt;'wb'&amp;lt;/tt&amp;gt;. Jeżeli chcemy użyć kodowania innego niż domyślne, możemy w funkcji &amp;lt;tt&amp;gt;open&amp;lt;/tt&amp;gt; użyć parametru ''encoding'', w postaci:&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
&lt;br /&gt;
f = open('nazwa_pliku.txt', 'w', encoding='cp1250')&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
w tym przykładzie użyto nazwy kodowania stosowanego do języka polskiego w Windows.&lt;br /&gt;
&amp;lt;/small&amp;gt;&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Standardowe strumienie i przekierowania==&lt;br /&gt;
&lt;br /&gt;
===Wprowadzenie===&lt;br /&gt;
&lt;br /&gt;
System operacyjny z rodziny unixów (np. Linux lub MacOS) udostępnia każdemu procesowi (uruchomionemu programowi) trzy tzw. standardowe strumienie, mogące być źródłem danych (tzw. standardowy strumień wejściowy, ''stdin'') lub kanałem przekazywania wyników, komunikatów itp. (standardowy strumień wyjściowy, ''stdout'' i standardowy strumień błędów, ''stderr'').&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&amp;lt;small&amp;gt;&lt;br /&gt;
W systemach z rodziny Windows jest podobnie, w odniesieniu do programów uruchamianych z linii poleceń, czyli okna programu ''cmd.exe''.&lt;br /&gt;
&amp;lt;/small&amp;gt;&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Co to konkretnie znaczy? Domyślnie, zawartością ''stdin'' są dane wprowadzane z klawiatury, natomiast dane wypisywane na ''stdout'' i ''stderr'' pojawiają się na ekranie - w oknie terminalowym, z którego uruchomiono dany program. Przyjęto umowę, że na ''stdout'' wypisuje się dane, stanowiące wynik zgodnej z przewidywaniami pracy programu (oczywiście o ile nie przewidziano zapisu tych wyników bezpośrednio do pliku na dysku), natomiast na ''stderr'' - jedynie komunikaty dotyczące sytuacji nieprzewidzianych, a więc błędów przetwarzania, lub ostrzeżenia - pojawiające się w sytuacjach, gdy wprawdzie kontynuacja pracy programu jest możliwa, ale okoliczności wskazują, że jej wyniki mogą być pod jakimś względem wątpliwe.&lt;br /&gt;
&lt;br /&gt;
Powyższe ma sens, ponieważ domyślne powiązania - ''stdin'' z klawiaturą, a ''stdout'' i ''stderr'' z ekranem można zmienić - poprzez mechanizmy tzw. przekierowania. W szczególności, strumienie wyjścia i błędu można rozdzielić, np. przekierowując treść ''stdout'' do pliku, a pozostawiając ''stderr'' jako związany z ekranem.&lt;br /&gt;
&lt;br /&gt;
W środowisku Python standardowe strumienie dostępne są jako elementy modułu &amp;lt;tt&amp;gt;sys&amp;lt;/tt&amp;gt;: &amp;lt;tt&amp;gt;sys.stdin&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;sys.stdout&amp;lt;/tt&amp;gt; i &amp;lt;tt&amp;gt;sys.stderr&amp;lt;/tt&amp;gt;. Mają one właściwości plików tekstowych, choć bez możliwości przewijania (&amp;lt;tt&amp;gt;seek&amp;lt;/tt&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
'''Funkcja &amp;lt;tt&amp;gt;print&amp;lt;/tt&amp;gt; w Pythonie domyślnie wypisuje dane do strumienia ''stdout''; można to zmienić, używając parametru wywołania ''file'', którego wartością powinien być plik otwarty do zapisu w trybie tekstowym.'''&lt;br /&gt;
&lt;br /&gt;
===Sposoby przekierowania===&lt;br /&gt;
&lt;br /&gt;
Przekierowanie strumieni dokonuje się na poziomie systemu operacyjnego, całkowicie poza środowiskiem Pythona - program nie ma możliwości wykrycia, czy strumienie standardowe na jakich operuje zostały przekierowane. Przekierowania określa się na linii poleceń w momencie uruchomienia programu.&lt;br /&gt;
&lt;br /&gt;
Przekierowanie ''stdin'' z pliku:&lt;br /&gt;
&amp;lt;source lang=bash&amp;gt;&lt;br /&gt;
$ program.py &amp;lt; plik_wejsciowy.txt&lt;br /&gt;
$ &amp;lt; plik_wejsciowy.txt program.py&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Oba powyższe polecenia są równoważne i skutkują tym, że dane czytane przez program z &amp;lt;tt&amp;gt;sys.stdin&amp;lt;/tt&amp;gt; będą tak na prawdę pochodzić z pliku o podanej nazwie (a treść wprowadzana z klawiatury będzie w programie niedostępna).&lt;br /&gt;
&lt;br /&gt;
Przekierowanie ''stdout'' do pliku:&lt;br /&gt;
&amp;lt;source lang=bash&amp;gt;&lt;br /&gt;
$ program.py &amp;gt; plik_wyjscia.txt&lt;br /&gt;
$ &amp;gt; plik_wyjscia.txt program.py&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dane pisane do &amp;lt;tt&amp;gt;sys.stdout&amp;lt;/tt&amp;gt; nie pojawią się w oknie terminala, tylko znajdą się w pliku. Dane pisane do &amp;lt;tt&amp;gt;sys.stderr&amp;lt;/tt&amp;gt; dalej będą trafiać na ekran.&lt;br /&gt;
&lt;br /&gt;
Przekierowania równoczesne:&lt;br /&gt;
&amp;lt;source lang=bash&amp;gt;&lt;br /&gt;
$ program.py &amp;lt; plik_wejsciowy.txt &amp;gt; plik_wyjscia.txt&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Oba poprzednio opisane przekierowania można również wykonać równocześnie. Elementy polecenia również mogą wystąpić w innym porządku.&lt;br /&gt;
&lt;br /&gt;
Przekierowanie ''stderr'':&lt;br /&gt;
&amp;lt;source lang=bash&amp;gt;&lt;br /&gt;
$ program.py 2&amp;gt; plik_bledow.txt&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Komunikaty o błędach i ostrzeżenia znajdą się w pliku o podanej nazwie, zamiast na ekranie. Analogicznie do &amp;lt;tt&amp;gt;2&amp;gt;&amp;lt;/tt&amp;gt;, strumieniom ''stdout'' i ''stdin'' przypisane są numerki 1 i 0 - można więc pisać odpowiednio &amp;lt;tt&amp;gt;1&amp;gt;&amp;lt;/tt&amp;gt; i &amp;lt;tt&amp;gt;0&amp;amp;lt;&amp;lt;/tt&amp;gt;, ale tu te wartości numerów strumieni przekierowanych (naprawdę - ''deskryptorów plików'') są domyślne i niemal zawsze się je pomija.&lt;br /&gt;
&lt;br /&gt;
===Potoki===&lt;br /&gt;
&lt;br /&gt;
Oprócz przekierowania do i z plików, istnieje jeszcze analogiczny mechanizm, gdzie np. strumień ''stdout'' jednego procesu łączy się z strumieniem ''stdin'' innego procesu - skutkiem czego dane wyjściowe pierwszego są wprowadzane do drugiego jako dane wejściowe, tworząc to co się nazywa ''potokiem''. Najprostszy przykład:&lt;br /&gt;
&amp;lt;source lang=bash&amp;gt;&lt;br /&gt;
$ program1.py | program2.py&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
tu ''operatorem potoku'' w systemowej linii poleceń jest znak kreski pionowej (&amp;lt;tt&amp;gt;|&amp;lt;/tt&amp;gt;), a &amp;lt;tt&amp;gt;program1.py&amp;lt;/tt&amp;gt; przekazuje wyniki swojej pracy do dalszego przetwarzania kolejnemu, &amp;lt;tt&amp;gt;program2.py&amp;lt;/tt&amp;gt;. Taki potok może mieć więcej niż dwa etapy i może łączyć się z zastosowaniem przekierowań do plików, np.&lt;br /&gt;
&amp;lt;source lang=bash&amp;gt;&lt;br /&gt;
$ &amp;lt; plik_wejsciowy.txt program1.py 2&amp;gt;bledy.txt | program2.py &amp;gt; plik_wynikow.txt&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Pożytecznym narzędziem do stosowania w potokach jest polecenie (program) o nazwie &amp;lt;tt&amp;gt;tee&amp;lt;/tt&amp;gt;:&lt;br /&gt;
&amp;lt;source lang=bash&amp;gt;&lt;br /&gt;
$ program.py &amp;lt; dane.txt | tee wynik.txt&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
w tym przypadku program wczyta zawartość pliku &amp;lt;tt&amp;gt;dane.txt&amp;lt;/tt&amp;gt;, a wynik wypisany do &amp;lt;tt&amp;gt;sys.stdout&amp;lt;/tt&amp;gt; zarówno pojawi się na ekranie (w oknie terminala, jak i zostanie zapisany w pliku &amp;lt;tt&amp;gt;wynik.txt&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==Odczyt linii poleceń==&lt;br /&gt;
&lt;br /&gt;
Zawartość linii poleceń dostępna jest w obiekcie &amp;lt;tt&amp;gt;sys.argv&amp;lt;/tt&amp;gt; - czyli moduł (standardowy) &amp;lt;tt&amp;gt;sys&amp;lt;/tt&amp;gt;, element &amp;lt;tt&amp;gt;argv&amp;lt;/tt&amp;gt;. Jest to lista argumentów - ,,słów&amp;quot; jakie wywołujący program umieścił w linii poleceń. Inaczej mówiąc, treść linii poleceń ulega wstępnemu rozbiorowi - na słowa, według reguł zależnych od systemu operacyjnego. Najczęściej poszczególne słowa oddzielają spacje (jedna lub więcej), jeśli chcemy, by ciąg zawierający spacje był potraktowany jako pojedyncze słowo (np. nazwa pliku zawierająca spacje), należy ciąg ten np. umieścić w cudzysłowach (które zostaną usunięte z treści argumentu). Treść linii poleceń na ogół ulega jeszcze innym formom obróbki przez system operacyjny (np. rozwijanie rozmaitych skrótów), ale dzieje się to poza kontrolą Pythona.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
&lt;br /&gt;
from sys import argv&lt;br /&gt;
for arg in argv:&lt;br /&gt;
    print(arg)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Korzystając z powyższego kodu możemy dowiedzieć się, jak wygląda lista argumentów już ''po'' jej obróbce przez system operacyjny.&lt;br /&gt;
&lt;br /&gt;
Na początku listy &amp;lt;tt&amp;gt;argv&amp;lt;/tt&amp;gt; czyli w pozycji &amp;lt;tt&amp;gt;arv[0]&amp;lt;/tt&amp;gt; znajduje się nazwa uruchomionego programu (tj. nazwa pliku z kodem uruchomionego jako program główny).&lt;br /&gt;
&lt;br /&gt;
===Przykłady===&lt;br /&gt;
&lt;br /&gt;
=1.=&lt;br /&gt;
Jeśli przewidujemy, że jedynymi argumentami wywołania naszego programu będą nazwy plików, na każdym z których należy wykonać jakąś czynność, to można to zrealizować tak:&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
&lt;br /&gt;
#! /usr/bin/python3&lt;br /&gt;
&lt;br /&gt;
from sys import argv&lt;br /&gt;
&lt;br /&gt;
def przetwarzaj(plik):&lt;br /&gt;
    # tu określamy na czym polega &amp;quot;przetworzenie&amp;quot; pliku&lt;br /&gt;
&lt;br /&gt;
for plik in argv[1:]:&lt;br /&gt;
    przetwarzaj(plik)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*Wzięcie wycinku z &amp;lt;tt&amp;gt;argv&amp;lt;/tt&amp;gt; służy pominięciu pliku zawierającego kod programu;&lt;br /&gt;
*Elementami &amp;lt;tt&amp;gt;argv&amp;lt;/tt&amp;gt; są ''nazwy'' plików - napisy.&lt;br /&gt;
&lt;br /&gt;
=2.=&lt;br /&gt;
Nieraz jest pożądane, aby program przetwarzający strumień danych mógł działać na dwa sposoby: albo wywołany z argumentami będącymi nazwami plików z danymi wejściowymi wczytuje kolejno zawartość tych plików; albo wywołany bez takich argumentów, czyta dane wejściowe ze standardowego strumienia wejściowego, w którym one znajdują się zazwyczaj w wyniku poprzedniego kroku przetwarzania potokowego. Nota bene w ten sposób działa wiele tradycyjnych narzędzi systemowych w Linuxie. &lt;br /&gt;
&lt;br /&gt;
W standardowej bibliotece Pythona jest moduł &amp;lt;tt&amp;gt;fileinput&amp;lt;/tt&amp;gt;, który ułatwia realizację takiego podejścia. W najprostszym przypadku:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
#! /usr/bin/python3&lt;br /&gt;
&lt;br /&gt;
import fileinput&lt;br /&gt;
&lt;br /&gt;
def przetwarzaj(linia):&lt;br /&gt;
    # tu określamy na czym polega przetworzenie linii treści&lt;br /&gt;
&lt;br /&gt;
for linia in fileinput.input():&lt;br /&gt;
    przetwarzaj(linia)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
W pętli w powyższym przykładzie wystąpią kolejno wszystkie linie w treści plików wymienionych na linii poleceń (z pominięciem pliku samego programu), lub jeśli linia poleceń jest pusta &amp;amp;mdash; linie w treści &amp;lt;tt&amp;gt;sys.stdin&amp;lt;/tt&amp;gt;. Ewentualnie można wywołać funkcję &amp;lt;tt&amp;gt;fileinput.input(pliki)&amp;lt;/tt&amp;gt;, tj. zamiast bez argumentów to z argumentem będącym sekwencją nazw plików zawierających dane wejściowe. Może to być np. lista argumentów programu, ale po usunięciu z niej pozycji będących opcjami, a nie nazwami plików. Oczywiście w dokumentacji znajdziemy jeszcze dalsze możliwości.&lt;br /&gt;
&lt;br /&gt;
=Ćwiczenia=&lt;br /&gt;
&lt;br /&gt;
1. Napisać program, który wczyta dany plik linia po linii i znajdzie wśród nich podzbiór linii o maksymalnej długości (w znakach) oraz wartość tej maksymalnej długości. Niech wynikiem działania programu będzie wypisanie liczby oznaczającej maksymalną długość linii występujących w badanym pliku, a następnie - treść tych linii, w kolejności w jakiej pojawiały się w pliku. Wypróbować ten program na pliku ''/usr/share/dict/words''. W końcowej wersji program powinien operować na pliku, którego nazwę podamy jako argument na linii poleceń.&lt;br /&gt;
&lt;br /&gt;
''Wskazówka:'' długość linii nie powinna uwzględniać kodu przejścia do nowej linii, zapisywanego symbolicznie jako &amp;lt;tt&amp;gt;'\n'&amp;lt;/tt&amp;gt; kończącego (prawie) każdą linię. &lt;br /&gt;
&lt;br /&gt;
2. Napisać program, który wczyta dany plik linia po linii i znajdzie wśród nich podzbiór linii o danej długości w znakach. Niech wynikiem działania programu będzie wypisanie linii o żądanej długości występujących w treści pliku w takiej kolejności, w jakiej pojawiały się w pliku. Długość szukanych linii podajemy jako pierwszy, a nazwę badanego pliku jako drugi argument na linii poleceń.&lt;br /&gt;
&lt;br /&gt;
3. Napisać program, który wyznaczy rozkład długości linii w treści danego pliku - nazwę pliku podajemy na linii poleceń. Wynikiem działania programu jest wypisanie ciągu linijek postaci &amp;lt;tt&amp;gt;''długość'' : ''ile''&amp;lt;/tt&amp;gt;, gdzie liczba ''ile'' opisuje, ile linii o danej długości wystąpiło w treści pliku. Pozycje, w których ''ile'' wynosiłoby 0 nie pojawiają się.&lt;br /&gt;
&lt;br /&gt;
4. Napisać program, który wyznacza częstości występowania w treści pliku określonych znaków. Zestaw znaków, których wystąpienia zamierzamy zliczać podajemy jako pierwszy argument na linii poleceń, nazwę badanego pliku jako drugi. Wynikiem działania programu jest wypisanie ciągu linijek postaci &amp;lt;tt&amp;gt;''znak'' : ''częstość''&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
5. Napisać program, który znajduje w pliku ''/usr/share/dict/words'' wszystkie słowa, składające się z tych samych liter co słowo, podane jako argument na linii poleceń - choć niekoniecznie występujących tę samą liczbę razy. Inaczej mówiąc, każda z liter występujących w podanym słowie występuje również w słowach szukanych, a nie występują w nich żadne inne znaki. Program wypisuje na ekran znalezione słowa, po jednym na linijkę.&lt;br /&gt;
 &lt;br /&gt;
6. Niech program znajduje wszystkie słowa, jakie można utworzyć korzystając z danego zestawu liter (podanego jako pierwszy argument na linii poleceń); tzn. tak jak w ''Scrabble'' dysponujemy takimi literami i w takiej liczbie, jakie składają się na to słowo (lub ,,słowo&amp;quot;). Źródłem słów jakie można utworzyć jest plik podany jako drugi argument (domyślnie - ''/usr/share/dict/words'').&amp;lt;br&amp;gt;&lt;br /&gt;
''Wskazówka:'' może się tu przydać operacja &amp;lt;tt&amp;gt;L.remove(x)&amp;lt;/tt&amp;gt;, gdzie &amp;lt;tt&amp;gt;L&amp;lt;/tt&amp;gt; jest listą; usuwa ona z listy pierwsze z kolei znalezione w niej wystąpienie elementu &amp;lt;tt&amp;gt;x&amp;lt;/tt&amp;gt;. &amp;lt;br&amp;gt;&lt;br /&gt;
''Uwaga:'' operacja ta zwróci błąd, jeśli element &amp;lt;tt&amp;gt;x&amp;lt;/tt&amp;gt; ''nie'' występuje w &amp;lt;tt&amp;gt;L&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
[[PPy3/Moduły|poprzednie]] | [[&amp;quot;Programowanie z Pythonem3&amp;quot;|strona główna]] | [[PPy3/NumPy|dalej]]&lt;br /&gt;
&lt;br /&gt;
[[Użytkownik:RobertJB|RobertJB]] ([[Dyskusja użytkownika:RobertJB|dyskusja]]) 13:26, 4 sie 2016 (CEST)&lt;/div&gt;</summary>
		<author><name>RobertJB</name></author>
		
	</entry>
	<entry>
		<id>http://brain.fuw.edu.pl/edu/index.php?title=PPy3/Funkcje&amp;diff=9335</id>
		<title>PPy3/Funkcje</title>
		<link rel="alternate" type="text/html" href="http://brain.fuw.edu.pl/edu/index.php?title=PPy3/Funkcje&amp;diff=9335"/>
		<updated>2023-05-10T13:32:11Z</updated>

		<summary type="html">&lt;p&gt;RobertJB: /* Definiowanie funkcji */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=Funkcje=&lt;br /&gt;
&lt;br /&gt;
Gdy raz wymyślimy jakiś sprytny algorytm, to nie ma co go za każdym razem odkrywać na nowo. Żeby było łatwiej pisać raz, a korzystać wielokrotnie - wymyślono funkcje.&lt;br /&gt;
&lt;br /&gt;
==Definiowanie funkcji==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
def funkcja(x, y):&lt;br /&gt;
    BLOK INSTRUKCJI&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*Definicja funkcji to instrukcja złożona, podobna w strukturze do tych, które już znamy - instrukcji warunkowej i pętli.&lt;br /&gt;
*Wykonanie definicji funkcji ''nie wiąże się z natychmiastowym wykonaniem zawartego w niej bloku''.&lt;br /&gt;
*W definicji funkcji (przykładowej) &amp;lt;tt&amp;gt;x&amp;lt;/tt&amp;gt; i &amp;lt;tt&amp;gt;y&amp;lt;/tt&amp;gt; to ''parametry formalne''; nie mają one w tym momencie określonych wartości, są miejscami do wypełnienia konkretnymi wartościami, gdy funkcję postanowimy użyć. Może ich być (niemal) dowolnie wiele, w tym &amp;amp;mdash; zero. W tym ostatnim przypadku piszemy pustą parę nawiasów.&lt;br /&gt;
*Wykonanie definicji funkcji polega na nadaniu znaczenia jej nazwie, która odtąd będzie oznaczała ciąg instrukcji stanowiących wewnętrzny blok.&lt;br /&gt;
*Użycie czyli ''wywołanie'' funkcji to wyrażenie postaci&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
funkcja(x, y)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
gdzie &amp;lt;tt&amp;gt;x&amp;lt;/tt&amp;gt; i &amp;lt;tt&amp;gt;y&amp;lt;/tt&amp;gt; mają już konkretne wartości (w tym miejscu mogą stać również wyrażenia złożone), które będą użyte w instrukcjach stanowiących definicję.&lt;br /&gt;
&lt;br /&gt;
*W definicji na ogół występuje (raz lub więcej razy) słowo (instrukcja) &amp;lt;tt&amp;gt;return&amp;lt;/tt&amp;gt;. Oznacza ono, że w tym miejscu wykonanie funkcji się kończy - funkcja powraca. Wartość wyrażenia po słowie &amp;lt;tt&amp;gt;return&amp;lt;/tt&amp;gt; stanowi wynik zwracany przez funkcję - czyli wartość wyrażenia, będącego wywołaniem funkcji.&lt;br /&gt;
*Jeśli &amp;lt;tt&amp;gt;return&amp;lt;/tt&amp;gt; nie ma, albo nie ma po nim wartości zwracanej, albo wykonanie funkcji kończy się ,,wypadnięciem&amp;quot; przez koniec bloku, wartością zwracaną jest &amp;lt;tt&amp;gt;None&amp;lt;/tt&amp;gt; &amp;amp;mdash; która w zasadzie do niczego się specjalnie nie nadaje, poza sprawdzeniem, czy mamy do czynienia z właśnie tą wartością.&lt;br /&gt;
*''funkcja'' w Pythonie (i większości języków programowania) to coś nieco podobnego do funkcji (odwzorowania) w matematyce, ale '''to nie jest to samo pojęcie''':&lt;br /&gt;
**w Pythonie wywołanie funkcji może mieć skutki uboczne;&lt;br /&gt;
**wynik funkcji, w tym skutki uboczne, może zależeć nie tylko od argumentów wywołania.&lt;br /&gt;
Skutkami ubocznymi wywołania nazywamy jakiekolwiek efekty tej instrukcji, które nie sprowadzają się do wartości zwracanej. A więc, zmianę wartości innych zmiennych, czy np. wysłanie jakichś danych siecią, lub wypisanie czegoś na ekran.&lt;br /&gt;
*Funkcja może być wartością zmiennej; inaczej mówiąc, funkcja może być znana pod dodatkowymi nazwami (aliasami), może być włożona do listy na którąś z jej pozycji itp.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
ff = funkcja&lt;br /&gt;
...&lt;br /&gt;
wynik = ff(x)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*,,Oryginalna&amp;quot; nazwa funkcji, czyli występująca w jej definicji, jest jednak w pewnym sensie uprzywilejowana.&lt;br /&gt;
*Zmienne (nazwy) '''powołane do życia''' wewnątrz funkcji są lokalne; ich wartości ,,żyją&amp;quot; tylko póki wykonuje się funkcja.&lt;br /&gt;
*Zmienne lokalne powielające nazwy ,,zewnętrzne&amp;quot; względem funkcji przesłaniają te zewnętrzne. Chyba, że użyjemy deklaracji &amp;lt;tt&amp;gt;global&amp;lt;/tt&amp;gt;:&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
x = 1&lt;br /&gt;
def podwojx():  # to nie zadziała:&lt;br /&gt;
    x = x * 2&lt;br /&gt;
podwojx()&lt;br /&gt;
UnboundLocalError                         Traceback (most recent call last)&lt;br /&gt;
&amp;lt;ipython-input-3-6edd575e5cda&amp;gt; in &amp;lt;module&amp;gt;()&lt;br /&gt;
----&amp;gt; 1 podwojx()&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ipython-input-1-1da635f42ffa&amp;gt; in podwojx()&lt;br /&gt;
      1 def podwojx():&lt;br /&gt;
----&amp;gt; 2     x *= 2&lt;br /&gt;
      3 &lt;br /&gt;
&lt;br /&gt;
UnboundLocalError: local variable 'x' referenced before assignment&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Jak widzimy, komunikat o błędzie pojawił się dopiero w wyniku wywołania błędnej funkcji.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
x = 1&lt;br /&gt;
def podwojx():  # to zadziała - co nie znaczy, że jest mądre...&lt;br /&gt;
    global x&lt;br /&gt;
    x = x * 2&lt;br /&gt;
podwojx()&lt;br /&gt;
print x&lt;br /&gt;
→ 2&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Należy unikać takich sztuczek, jak powyżej; jeśli już, to:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
def podwoj(x):&lt;br /&gt;
    return 2 * x&lt;br /&gt;
liczba = 1&lt;br /&gt;
print podwoj(liczba)&lt;br /&gt;
→ 2&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
''Wskazówka:'' każde użycie deklaracji &amp;lt;tt&amp;gt;global&amp;lt;/tt&amp;gt; w programie powinno być dobrze uzasadnione. Jeżeli używamy jej więcej niż sporadycznie, to coś jest nie tak.&lt;br /&gt;
&lt;br /&gt;
Funkcja może być &lt;br /&gt;
&lt;br /&gt;
*zeroargumentowa &amp;amp;mdash; wówczas zarówno w definicji, jak i w wywołaniu po nazwie występuje pusta para nawiasów,&lt;br /&gt;
*jednoargumentowa (jak powyższa &amp;lt;tt&amp;gt;podwoj&amp;lt;/tt&amp;gt;), &lt;br /&gt;
*dwuargumentowa (jak przykładowa),&lt;br /&gt;
*trzy-, cztero-, ... itd.&lt;br /&gt;
*o zmiennej liczbie argumentów, z wartościami domyślnymi dla brakujących:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
def dodaj(x, y=1):&lt;br /&gt;
    return x + y&lt;br /&gt;
dodaj(2, 3)&lt;br /&gt;
→ 5&lt;br /&gt;
dodaj(2)&lt;br /&gt;
→ 3&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Parametry z wartościami domyślnymi muszą występować na końcu listy parametrów.&lt;br /&gt;
*o zmiennej liczbie argumentów, ale bez wartości domyślnych, np.:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
def ile(*args):&lt;br /&gt;
    return len(args)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Działa to tak: &amp;lt;tt&amp;gt;'*'&amp;lt;/tt&amp;gt; postawiona przed nazwą argumentu oznacza, że wszystkie (ew. dalsze) argumenty&lt;br /&gt;
zostaną zebrane w jedną listę, która dostępna jest wewnątrz funkcji pod nazwą, jaką postawiliśmy po gwiazdce. W powyższym przykładzie, funkcja &amp;lt;tt&amp;gt;ile&amp;lt;/tt&amp;gt; zwraca jako swój wynik po prostu liczbę argumentów, z jakimi funkcja została wywołana. Operator &amp;lt;tt&amp;gt;'*'&amp;lt;/tt&amp;gt; nie ma tu wiele wspólnego z mnożeniem. Odróżniamy go od mnożenia po tym, że po jego lewej stronie nie stoi żaden czynnik. Ten sam operator może wystąpić również w roli poniekąd odwrotnej, np.:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
lista = [*range(5)]&lt;br /&gt;
print(*lista)&lt;br /&gt;
→ 0 1 2 3 4 &lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
W pierwszej linii, gwiazdka niejako ,,rozwija&amp;quot; sekwencję &amp;lt;tt&amp;gt;range(5)&amp;lt;/tt&amp;gt; w ciąg wartości (kolejnych liczb) wstawionych pod operator &amp;lt;tt&amp;gt;[...]&amp;lt;/tt&amp;gt;; w linii drugiej, &amp;lt;tt&amp;gt;lista&amp;lt;/tt&amp;gt; jest również ,,rozpakowana&amp;quot; w &lt;br /&gt;
ciąg oddzielnych argumentów wywołania funkcji &amp;lt;tt&amp;gt;print&amp;lt;/tt&amp;gt; &amp;amp;mdash; sprawdź, że wynik &amp;lt;tt&amp;gt;print(lista)&amp;lt;/tt&amp;gt; wyglądałby nieco inaczej.&lt;br /&gt;
&lt;br /&gt;
=Ćwiczenia=&lt;br /&gt;
&lt;br /&gt;
1. Napisz funkcję &amp;lt;tt&amp;gt;pierwiastki(a, b, c)&amp;lt;/tt&amp;gt;, która wypisuje na ekran (za pomocą wywołania &amp;lt;tt&amp;gt;print&amp;lt;/tt&amp;gt;) pierwiastki równania kwadratowego o wspołczynnikach ''a'', ''b'' i ''c'': &amp;lt;tt&amp;gt;a * x**2 + b * x + c == 0&amp;lt;/tt&amp;gt;. W przypadku, gdy pierwiastków nie ma, wypisuje komunikat ''Równanie nie ma pierwiastków.'' W przypadku, gdy ''a=0'', wypisuje komunikat ''Błędne dane: a==0'' i kończy działanie.&lt;br /&gt;
&lt;br /&gt;
2. Napisz analogiczną funkcję, która zamiast bezpośrednio wypisywać rozwiązania, zwraca je jako wynik swojego działania. Wypisaniem ich na ekran zajmuje się odrębna instrukcja. W przypadku, gdy pierwiastków nie ma, zwraca wartość &amp;lt;tt&amp;gt;None&amp;lt;/tt&amp;gt;. Nie sprawdzaj warunku ''a!=0'' - co się dzieje, gdy nie jest spełniony przez argumenty wywołania funkcji?&lt;br /&gt;
&lt;br /&gt;
3. Napisz funkcję &amp;lt;tt&amp;gt;silnia(n)&amp;lt;/tt&amp;gt;, która oblicza i zwraca wartość silni: &amp;lt;tt&amp;gt;n! := 1 * 2 * 3 * ... (n - 1) * n&amp;lt;/tt&amp;gt;. Uwzględnij, że przyjmuje się że &amp;lt;tt&amp;gt;0! = 1&amp;lt;/tt&amp;gt;, natomiast dla liczb ujemnych silnia nie jest określona - co można zasygnalizować zwracając jako wynik &amp;lt;tt&amp;gt;None&amp;lt;/tt&amp;gt;. Użyj pętli &amp;lt;tt&amp;gt;for&amp;lt;/tt&amp;gt; i funkcji &amp;lt;tt&amp;gt;range&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
4. Funkcję silnia można zdefiniować w sposób rekurencyjny - za pomocą następujących warunków:&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;n! == None&amp;lt;/tt&amp;gt; dla &amp;lt;tt&amp;gt;n &amp;lt; 0&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;0! == 1&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;n! == n * (n - 1)!&amp;lt;/tt&amp;gt;&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
Napisz kod funkcji &amp;lt;tt&amp;gt;silnia(n)&amp;lt;/tt&amp;gt; realizujący powyższą definicję. Porównaj działanie tego kodu z realizacją tej funkcji z poprzedniego przykładu dla dużych wartości &amp;lt;tt&amp;gt;n&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
[[PPy3/SekwencjeIIteracja|poprzednie]] | [[&amp;quot;Programowanie z Pythonem3&amp;quot;|strona główna]] | [[PPy3/Kolekcje|dalej]]&lt;br /&gt;
&lt;br /&gt;
[[Użytkownik:RobertJB|RobertJB]] ([[Dyskusja użytkownika:RobertJB|dyskusja]]) 16:10, 30 cze 2016 (CEST)&lt;/div&gt;</summary>
		<author><name>RobertJB</name></author>
		
	</entry>
	<entry>
		<id>http://brain.fuw.edu.pl/edu/index.php?title=PPy3/InstrukcjaWarunkowa&amp;diff=9334</id>
		<title>PPy3/InstrukcjaWarunkowa</title>
		<link rel="alternate" type="text/html" href="http://brain.fuw.edu.pl/edu/index.php?title=PPy3/InstrukcjaWarunkowa&amp;diff=9334"/>
		<updated>2023-05-10T11:20:13Z</updated>

		<summary type="html">&lt;p&gt;RobertJB: /* Wyrażenie warunkowe */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=Instrukcja warunkowa=&lt;br /&gt;
&lt;br /&gt;
Zasadniczo każdy program w Pythonie składa się z ciągu instrukcji, które są wykonywane w kolejności, w jakiej zostały zapisane. W programowaniu potrzebna jest jednak możliwość podejmowania decyzji o przyjęciu różnych kursów postępowania, w zależności od danych z jakimi mamy do czynienia. Umożliwiają to instrukcje złożone, a szczególnie - instrukcja warunkowa.&lt;br /&gt;
&lt;br /&gt;
Instrukcja warunkowa to pierwszy przykład instrukcji złożonej. W najprostszej postaci składa się ona z ciągu (jednej lub więcej) instrukcji ujętych w blok, który jako całość będzie wykonany lub nie, w zależności od tego, czy spełniony jest pewien warunek - co zależy zazwyczaj od aktualnych wartości pewnych zmiennych. Warunek ten zapisuje się w postaci wyrażenia logicznego.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&amp;lt;small&amp;gt;&lt;br /&gt;
Wśród instrukcji tworzących blok warunkowy mogą oczywiście się pojawić również instrukcje złożone, nie tylko instrukcje proste. Na przykład, kolejne instrukcje warunkowe.&lt;br /&gt;
&amp;lt;/small&amp;gt;&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Przykład minimalny:==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
x1, x2 = None, None&lt;br /&gt;
if delta &amp;gt; 0 and not a == 0:&lt;br /&gt;
    x1 = (-b + delta) / 2 / a&lt;br /&gt;
    x2 = (-b - delta) / 2 / a&lt;br /&gt;
print(x1, x2)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Linijka z wywołaniem &amp;lt;tt&amp;gt;print&amp;lt;/tt&amp;gt; nie jest już częścią instrukcji warunkowej, tylko kolejną instrukcją.&lt;br /&gt;
&lt;br /&gt;
'''Do zapamiętania''':&lt;br /&gt;
*wiersz otwierający instrukcję złożoną (czyli tu: zaczynająca się od &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt;) zawsze kończy się dwukropkiem&lt;br /&gt;
*instrukcje tworzące blok w instrukcji złożonej są pisane z wcięciem, które musi być jednolite &amp;amp;mdash; oczywiście jeżeli częścią bloku jest kolejna instrukcja złożona, to dodaje ona swoje, kolejne wcięcie&lt;br /&gt;
*koniec bloku rozpoznaje się po powrocie do uprzedniego poziomu wcięcia&lt;br /&gt;
*blok instrukcji pod &amp;lt;tt&amp;gt;if ...&amp;lt;/tt&amp;gt; nie może być pusty. Instrukcja &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt; z pustym blokiem warunkowym jest nie tylko nieprzydatna, ale jest również błędem składniowym. Jeżeli (tymczasowo?) chcemy pozostawić instrukcję warunkową bez wnętrza, to możemy tam wpisać instrukcję &amp;lt;tt&amp;gt;pass&amp;lt;/tt&amp;gt; &amp;amp;mdash; jest to instrukcja pusta (,,nie rób nic&amp;quot;).&lt;br /&gt;
&lt;br /&gt;
==Przykład bardziej złożony:==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
if a == 0:&lt;br /&gt;
    print('Równanie nie jest kwadratowe.')&lt;br /&gt;
elif delta &amp;gt; 0 and not a == 0:&lt;br /&gt;
    x1 = (-b + delta) / 2 / a&lt;br /&gt;
    x2 = (-b - delta) / 2 / a&lt;br /&gt;
    print('Są dwa pierwiastki: x1 =', x1, 'x2 =', x2)&lt;br /&gt;
elif delta == 0:&lt;br /&gt;
    x = -b / 2 / a&lt;br /&gt;
    print('Jest tylko jeden pierwiastek: x =', x)&lt;br /&gt;
else: # delta &amp;lt; 0:&lt;br /&gt;
    print('Nie ma pierwiastków rzeczywistych.')&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Jak to działa?&lt;br /&gt;
&lt;br /&gt;
*Jeżeli spełniony jest warunek &amp;lt;tt&amp;gt;a == 0&amp;lt;/tt&amp;gt;, wykonany zostanie blok poniżej &amp;lt;tt&amp;gt;if ...&amp;lt;/tt&amp;gt;, a reszta instrukcji zostanie pominięta;&lt;br /&gt;
*Jeżeli warunek ten jest nieprawdziwy (i tylko wtedy), to sprawdzane są kolejno warunki umieszczone w wierszach zaczynających się od &amp;lt;tt&amp;gt;elif&amp;lt;/tt&amp;gt;. Jeśli któryś z nich okaże się prawdziwy, to blok poniżej tej linijki zostanie wykonany, a cała reszta - pominięta;&lt;br /&gt;
*Jeżeli żaden z warunków - tych po &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt;, i tych po wszystkich &amp;lt;tt&amp;gt;elif&amp;lt;/tt&amp;gt; - nie okazał się prawdziwy, wykonany zostanie blok związany z &amp;lt;tt&amp;gt;else&amp;lt;/tt&amp;gt;.&lt;br /&gt;
*Bloków &amp;lt;tt&amp;gt;elif&amp;lt;/tt&amp;gt; może być w instrukcji dowolnie wiele (w tym - wcale), &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt; jest obowiązkowy (inaczej nie byłoby instrukcji warunkowej) i tylko jeden, &amp;lt;tt&amp;gt;else&amp;lt;/tt&amp;gt; może wystąpić wyłącznie na końcu - jeden raz, lub wcale.&lt;br /&gt;
*Komentarz po &amp;lt;tt&amp;gt;else:&amp;lt;/tt&amp;gt; jest podpowiedzią dla czytającego, że skoro już zbadano warunki &amp;lt;tt&amp;gt;delta == 0&amp;lt;/tt&amp;gt; oraz &amp;lt;tt&amp;gt;delta &amp;gt; 0&amp;lt;/tt&amp;gt;, a wykonanie dotarło do tej linijki, to &amp;lt;tt&amp;gt;delta &amp;lt; 0&amp;lt;/tt&amp;gt; jest jedyną pozostałą możliwością (o ile możemy założyć, że &amp;lt;tt&amp;gt;delta&amp;lt;/tt&amp;gt; jest na pewno liczbą!). Jest on przeznaczony wyłącznie dla ludzkich oczu - interpreter go zignoruje, jak każdy komentarz.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&amp;lt;small&amp;gt;&lt;br /&gt;
Mam nadzieję, że czytający już zauważył, że &amp;lt;tt&amp;gt;and not a == 0&amp;lt;/tt&amp;gt; w trzeciej linijce jest niepotrzebne. Dlaczego?&lt;br /&gt;
&amp;lt;/small&amp;gt;&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Wyrażenie warunkowe==&lt;br /&gt;
&lt;br /&gt;
Innym sposobem uzależnienia wyniku działania od jakiegoś warunku jest tzw. ''wyrażenie warunkowe''. Jest ono szczególnie wygodne w prostych przypadkach, i pozwala zapisać pewne działania w bardziej zwięzły sposób. &lt;br /&gt;
&lt;br /&gt;
Przykład: chcemy, aby z nazwą &amp;lt;tt&amp;gt;wbx&amp;lt;/tt&amp;gt; wiązała się wartość bezwzględna (moduł) aktualnej wartości (liczby) &amp;lt;tt&amp;gt;x&amp;lt;/tt&amp;gt;. Za pomocą instrukcji warunkowej można to zrealizować tak:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
if x &amp;lt; 0:&lt;br /&gt;
    wbx = -x&lt;br /&gt;
else:&lt;br /&gt;
    wbx = x&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ten sam wynik można osiągnąć za pomocą wyrażenia warunkowego:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
wbx = -x if x &amp;lt; 0 else x&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
W wyrażeniu warunkowym nie ma opcji uwzględnienia dodatkowych możliwości za pomocą &amp;lt;tt&amp;gt;elif&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=Ćwiczenia=&lt;br /&gt;
&lt;br /&gt;
W programach ćwiczebnych nieraz przyda nam się funkcja &amp;lt;tt&amp;gt;input()&amp;lt;/tt&amp;gt;. Działa ona w sposób następujący: argumentem wywołania powinien być jakiś napis (np. w postaci stałej napisowej): &amp;lt;tt&amp;gt;input('podaj jakąś liczbę całkowitą: ')&amp;lt;/tt&amp;gt;. Gdy w programie przyjdzie kolej na wykonanie takiego wywołania, program wypisze ten napis do terminalu i będzie oczekiwał na reakcję użytkownika, czyli wpisanie czegoś z klawiatury (i zakończenie naciśnięciem klawisza ''Enter''). Gdy to nastąpi, wynikiem wywołania funkcji &amp;lt;tt&amp;gt;input&amp;lt;/tt&amp;gt; w programie będzie treść wpisana prze użytkownika (bez końcowego znaku nowej linii).&lt;br /&gt;
&lt;br /&gt;
''Uwaga:'' wartość zwracana przez &amp;lt;tt&amp;gt;input()&amp;lt;/tt&amp;gt; zawsze jest napisem, a nie liczbą - choćby się składał z samych cyfr.&lt;br /&gt;
&lt;br /&gt;
1. Napisz program, którego uruchomienie ma następujący skutek:&lt;br /&gt;
*program wita użytkownika (komunikatem w terminalu),&lt;br /&gt;
*prosi o wprowadzenie liczby całkowitej,&lt;br /&gt;
*sprawdza, czy liczba ta jest podzielna przez 7, i informuje o wyniku tego sprawdzenia&lt;br /&gt;
&lt;br /&gt;
2. Napisz program, którego uruchomienie ma następujący skutek:&lt;br /&gt;
* program prosi użytkownika o podanie swojego (lub czyjegoś) wieku w latach&lt;br /&gt;
* jeśli wiek jest ujemny, odpowiada ,,Nieprawidłowy wiek&amp;quot;&lt;br /&gt;
* jeśli wiek wynosi 0, odpowiada ,,niemowlę&amp;quot;&lt;br /&gt;
* jeśli wiek jest poniżej 18, odpowiada ,,dziecko&amp;quot;&lt;br /&gt;
* jeśli wiek jest pomiędzy 18 a 120 (włącznie), odpowiada ,,dorosły&amp;quot;&lt;br /&gt;
* jeśli wiek przekracza 120, odpowiada ,,ludzie tyle nie żyją&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
''CDN''&lt;br /&gt;
&lt;br /&gt;
---- &lt;br /&gt;
&lt;br /&gt;
[[PPy3/StałeIZmienne|poprzednia]] | [[&amp;quot;Programowanie z Pythonem3&amp;quot;|Strona główna]] | [[PPy3/SekwencjeIIteracja|dalej]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Użytkownik:RobertJB|RobertJB]] ([[Dyskusja użytkownika:RobertJB|dyskusja]]) 15:42, 28 cze 2016 (CEST)&lt;/div&gt;</summary>
		<author><name>RobertJB</name></author>
		
	</entry>
	<entry>
		<id>http://brain.fuw.edu.pl/edu/index.php?title=PPy3/InstrukcjaWarunkowa&amp;diff=9333</id>
		<title>PPy3/InstrukcjaWarunkowa</title>
		<link rel="alternate" type="text/html" href="http://brain.fuw.edu.pl/edu/index.php?title=PPy3/InstrukcjaWarunkowa&amp;diff=9333"/>
		<updated>2023-05-10T11:18:55Z</updated>

		<summary type="html">&lt;p&gt;RobertJB: /* Przykład minimalny: */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=Instrukcja warunkowa=&lt;br /&gt;
&lt;br /&gt;
Zasadniczo każdy program w Pythonie składa się z ciągu instrukcji, które są wykonywane w kolejności, w jakiej zostały zapisane. W programowaniu potrzebna jest jednak możliwość podejmowania decyzji o przyjęciu różnych kursów postępowania, w zależności od danych z jakimi mamy do czynienia. Umożliwiają to instrukcje złożone, a szczególnie - instrukcja warunkowa.&lt;br /&gt;
&lt;br /&gt;
Instrukcja warunkowa to pierwszy przykład instrukcji złożonej. W najprostszej postaci składa się ona z ciągu (jednej lub więcej) instrukcji ujętych w blok, który jako całość będzie wykonany lub nie, w zależności od tego, czy spełniony jest pewien warunek - co zależy zazwyczaj od aktualnych wartości pewnych zmiennych. Warunek ten zapisuje się w postaci wyrażenia logicznego.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&amp;lt;small&amp;gt;&lt;br /&gt;
Wśród instrukcji tworzących blok warunkowy mogą oczywiście się pojawić również instrukcje złożone, nie tylko instrukcje proste. Na przykład, kolejne instrukcje warunkowe.&lt;br /&gt;
&amp;lt;/small&amp;gt;&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Przykład minimalny:==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
x1, x2 = None, None&lt;br /&gt;
if delta &amp;gt; 0 and not a == 0:&lt;br /&gt;
    x1 = (-b + delta) / 2 / a&lt;br /&gt;
    x2 = (-b - delta) / 2 / a&lt;br /&gt;
print(x1, x2)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Linijka z wywołaniem &amp;lt;tt&amp;gt;print&amp;lt;/tt&amp;gt; nie jest już częścią instrukcji warunkowej, tylko kolejną instrukcją.&lt;br /&gt;
&lt;br /&gt;
'''Do zapamiętania''':&lt;br /&gt;
*wiersz otwierający instrukcję złożoną (czyli tu: zaczynająca się od &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt;) zawsze kończy się dwukropkiem&lt;br /&gt;
*instrukcje tworzące blok w instrukcji złożonej są pisane z wcięciem, które musi być jednolite &amp;amp;mdash; oczywiście jeżeli częścią bloku jest kolejna instrukcja złożona, to dodaje ona swoje, kolejne wcięcie&lt;br /&gt;
*koniec bloku rozpoznaje się po powrocie do uprzedniego poziomu wcięcia&lt;br /&gt;
*blok instrukcji pod &amp;lt;tt&amp;gt;if ...&amp;lt;/tt&amp;gt; nie może być pusty. Instrukcja &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt; z pustym blokiem warunkowym jest nie tylko nieprzydatna, ale jest również błędem składniowym. Jeżeli (tymczasowo?) chcemy pozostawić instrukcję warunkową bez wnętrza, to możemy tam wpisać instrukcję &amp;lt;tt&amp;gt;pass&amp;lt;/tt&amp;gt; &amp;amp;mdash; jest to instrukcja pusta (,,nie rób nic&amp;quot;).&lt;br /&gt;
&lt;br /&gt;
==Przykład bardziej złożony:==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
if a == 0:&lt;br /&gt;
    print('Równanie nie jest kwadratowe.')&lt;br /&gt;
elif delta &amp;gt; 0 and not a == 0:&lt;br /&gt;
    x1 = (-b + delta) / 2 / a&lt;br /&gt;
    x2 = (-b - delta) / 2 / a&lt;br /&gt;
    print('Są dwa pierwiastki: x1 =', x1, 'x2 =', x2)&lt;br /&gt;
elif delta == 0:&lt;br /&gt;
    x = -b / 2 / a&lt;br /&gt;
    print('Jest tylko jeden pierwiastek: x =', x)&lt;br /&gt;
else: # delta &amp;lt; 0:&lt;br /&gt;
    print('Nie ma pierwiastków rzeczywistych.')&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Jak to działa?&lt;br /&gt;
&lt;br /&gt;
*Jeżeli spełniony jest warunek &amp;lt;tt&amp;gt;a == 0&amp;lt;/tt&amp;gt;, wykonany zostanie blok poniżej &amp;lt;tt&amp;gt;if ...&amp;lt;/tt&amp;gt;, a reszta instrukcji zostanie pominięta;&lt;br /&gt;
*Jeżeli warunek ten jest nieprawdziwy (i tylko wtedy), to sprawdzane są kolejno warunki umieszczone w wierszach zaczynających się od &amp;lt;tt&amp;gt;elif&amp;lt;/tt&amp;gt;. Jeśli któryś z nich okaże się prawdziwy, to blok poniżej tej linijki zostanie wykonany, a cała reszta - pominięta;&lt;br /&gt;
*Jeżeli żaden z warunków - tych po &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt;, i tych po wszystkich &amp;lt;tt&amp;gt;elif&amp;lt;/tt&amp;gt; - nie okazał się prawdziwy, wykonany zostanie blok związany z &amp;lt;tt&amp;gt;else&amp;lt;/tt&amp;gt;.&lt;br /&gt;
*Bloków &amp;lt;tt&amp;gt;elif&amp;lt;/tt&amp;gt; może być w instrukcji dowolnie wiele (w tym - wcale), &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt; jest obowiązkowy (inaczej nie byłoby instrukcji warunkowej) i tylko jeden, &amp;lt;tt&amp;gt;else&amp;lt;/tt&amp;gt; może wystąpić wyłącznie na końcu - jeden raz, lub wcale.&lt;br /&gt;
*Komentarz po &amp;lt;tt&amp;gt;else:&amp;lt;/tt&amp;gt; jest podpowiedzią dla czytającego, że skoro już zbadano warunki &amp;lt;tt&amp;gt;delta == 0&amp;lt;/tt&amp;gt; oraz &amp;lt;tt&amp;gt;delta &amp;gt; 0&amp;lt;/tt&amp;gt;, a wykonanie dotarło do tej linijki, to &amp;lt;tt&amp;gt;delta &amp;lt; 0&amp;lt;/tt&amp;gt; jest jedyną pozostałą możliwością (o ile możemy założyć, że &amp;lt;tt&amp;gt;delta&amp;lt;/tt&amp;gt; jest na pewno liczbą!). Jest on przeznaczony wyłącznie dla ludzkich oczu - interpreter go zignoruje, jak każdy komentarz.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&amp;lt;small&amp;gt;&lt;br /&gt;
Mam nadzieję, że czytający już zauważył, że &amp;lt;tt&amp;gt;and not a == 0&amp;lt;/tt&amp;gt; w trzeciej linijce jest niepotrzebne. Dlaczego?&lt;br /&gt;
&amp;lt;/small&amp;gt;&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Wyrażenie warunkowe==&lt;br /&gt;
&lt;br /&gt;
Innym sposobem uzależnienia wyniku działania od jakiegoś warunku jest tzw. ''wyrażenie warunkowe''. Jest ono szczególnie wygodne w prostych przypadkach, i pozwala zapisać pewne działania w bardziej zwięzły sposób. &lt;br /&gt;
&lt;br /&gt;
Przykład: chcemy, aby z nazwą &amp;lt;tt&amp;gt;wbx&amp;lt;/tt&amp;gt; wiązała się wartość bezwzględna (moduł) aktualnej wartości (liczby) &amp;lt;tt&amp;gt;x&amp;lt;/tt&amp;gt;. Za pomocą instrukcji warunkowej można to zrealizować tak:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
if x &amp;lt; 0:&lt;br /&gt;
    wbx = -x&lt;br /&gt;
else:&lt;br /&gt;
    wbx = x&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ten sam wynik można osiągnąć za pomocą wyrażenia warunkowego:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
wbx = -x if x &amp;lt; 0 else x&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
W wyrażeniu warunkowym nie ma opcji uwzględnienie dodatkowych możliwości za pomocą &amp;lt;tt&amp;gt;elif&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=Ćwiczenia=&lt;br /&gt;
&lt;br /&gt;
W programach ćwiczebnych nieraz przyda nam się funkcja &amp;lt;tt&amp;gt;input()&amp;lt;/tt&amp;gt;. Działa ona w sposób następujący: argumentem wywołania powinien być jakiś napis (np. w postaci stałej napisowej): &amp;lt;tt&amp;gt;input('podaj jakąś liczbę całkowitą: ')&amp;lt;/tt&amp;gt;. Gdy w programie przyjdzie kolej na wykonanie takiego wywołania, program wypisze ten napis do terminalu i będzie oczekiwał na reakcję użytkownika, czyli wpisanie czegoś z klawiatury (i zakończenie naciśnięciem klawisza ''Enter''). Gdy to nastąpi, wynikiem wywołania funkcji &amp;lt;tt&amp;gt;input&amp;lt;/tt&amp;gt; w programie będzie treść wpisana prze użytkownika (bez końcowego znaku nowej linii).&lt;br /&gt;
&lt;br /&gt;
''Uwaga:'' wartość zwracana przez &amp;lt;tt&amp;gt;input()&amp;lt;/tt&amp;gt; zawsze jest napisem, a nie liczbą - choćby się składał z samych cyfr.&lt;br /&gt;
&lt;br /&gt;
1. Napisz program, którego uruchomienie ma następujący skutek:&lt;br /&gt;
*program wita użytkownika (komunikatem w terminalu),&lt;br /&gt;
*prosi o wprowadzenie liczby całkowitej,&lt;br /&gt;
*sprawdza, czy liczba ta jest podzielna przez 7, i informuje o wyniku tego sprawdzenia&lt;br /&gt;
&lt;br /&gt;
2. Napisz program, którego uruchomienie ma następujący skutek:&lt;br /&gt;
* program prosi użytkownika o podanie swojego (lub czyjegoś) wieku w latach&lt;br /&gt;
* jeśli wiek jest ujemny, odpowiada ,,Nieprawidłowy wiek&amp;quot;&lt;br /&gt;
* jeśli wiek wynosi 0, odpowiada ,,niemowlę&amp;quot;&lt;br /&gt;
* jeśli wiek jest poniżej 18, odpowiada ,,dziecko&amp;quot;&lt;br /&gt;
* jeśli wiek jest pomiędzy 18 a 120 (włącznie), odpowiada ,,dorosły&amp;quot;&lt;br /&gt;
* jeśli wiek przekracza 120, odpowiada ,,ludzie tyle nie żyją&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
''CDN''&lt;br /&gt;
&lt;br /&gt;
---- &lt;br /&gt;
&lt;br /&gt;
[[PPy3/StałeIZmienne|poprzednia]] | [[&amp;quot;Programowanie z Pythonem3&amp;quot;|Strona główna]] | [[PPy3/SekwencjeIIteracja|dalej]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Użytkownik:RobertJB|RobertJB]] ([[Dyskusja użytkownika:RobertJB|dyskusja]]) 15:42, 28 cze 2016 (CEST)&lt;/div&gt;</summary>
		<author><name>RobertJB</name></author>
		
	</entry>
	<entry>
		<id>http://brain.fuw.edu.pl/edu/index.php?title=PPy3/Sta%C5%82eIZmienne&amp;diff=9332</id>
		<title>PPy3/StałeIZmienne</title>
		<link rel="alternate" type="text/html" href="http://brain.fuw.edu.pl/edu/index.php?title=PPy3/Sta%C5%82eIZmienne&amp;diff=9332"/>
		<updated>2023-05-10T11:11:23Z</updated>

		<summary type="html">&lt;p&gt;RobertJB: /* Inne wyrażenia */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=Stałe i zmienne=&lt;br /&gt;
&lt;br /&gt;
==Stałe dosłowne (literalne)==&lt;br /&gt;
&lt;br /&gt;
Stałe dosłowne to takie, których wartości wprost wpisano do pliku z kodem (lub w linii poleceń interpretera). Mogą to być liczby (paru rodzajów) lub napisy, ale również różne złożone rodzaje (typy) danych, z którymi zapoznamy się nieco później.&lt;br /&gt;
&lt;br /&gt;
'''Zapamiętajmy''' od razu: ''liczba'' dla komputera to zupełnie co innego, niż ''napis'' składający się z cyfr. Na napisie nie wykonamy operacji arytmetycznych - a na liczbie, operacji właściwych dla napisów (takich jak np. wyjęcie z niego znaku stojącego na określonej pozycji). Istnieją jednak operacje przekształcające każdy z tych typów danych w drugi.&lt;br /&gt;
&lt;br /&gt;
===Liczby===&lt;br /&gt;
&lt;br /&gt;
Dobrze jest pamiętać, że nieco odmiennie traktowane są liczby całkowite, a inaczej - liczby ułamkowe, zwykle zwane ''zmiennoprzecinkowymi'' (po angielsku ''floating point'', jako że Amerykanie piszą kropkę dziesiętną a nie - jak my - przecinek, przez co i w Pythonie używa się w tym celu kropki).&lt;br /&gt;
&lt;br /&gt;
*Liczby całkowite w zapisie dziesiętnym: &amp;lt;tt&amp;gt;1024&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;-666&amp;lt;/tt&amp;gt;, ...&lt;br /&gt;
*Liczby ułamkowe: &amp;lt;tt&amp;gt;1.0&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;.99&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;98.6&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;-37.43&amp;lt;/tt&amp;gt;, ...&lt;br /&gt;
*Liczby ułamkowe w zapisie wykładniczym: &amp;lt;tt&amp;gt;1.024e3&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;96.9E-12&amp;lt;/tt&amp;gt;, ...&lt;br /&gt;
&lt;br /&gt;
Notacja &amp;lt;tt&amp;gt;e3&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;E-12&amp;lt;/tt&amp;gt; itp. (wielka i mała litera &amp;lt;tt&amp;gt;e&amp;lt;/tt&amp;gt; są tu równoważne) oznacza pomnożenie poprzedzającej liczby przez odpowiednio 10&amp;lt;sup&amp;gt;3&amp;lt;/sup&amp;gt;, 10&amp;lt;sup&amp;gt;-12&amp;lt;/sup&amp;gt;, ... i służy ułatwieniu zapisu liczb bardzo dużych lub bardzo małych. Nie można tam wtrącać dodatkowych odstępów, podobnie jak pomiędzy cyframi.&lt;br /&gt;
&lt;br /&gt;
Jeśli część całkowita (lub ułamkowa) liczby zmiennoprzecinkowej wynosi zero, to można to zero pominąć. Oczywiście nie można pominąć obu, zapisując liczbę zero! (można napisać: &amp;lt;tt&amp;gt;0.&amp;lt;/tt&amp;gt; albo &amp;lt;tt&amp;gt;.0&amp;lt;/tt&amp;gt;, ale nie samotną kropkę).&lt;br /&gt;
&lt;br /&gt;
Podstawowa różnica pomiędzy sposobem traktowania liczb całkowitych i zmiennoprzecinkowych polega na tym, że:&lt;br /&gt;
&lt;br /&gt;
*liczby całkowite mogą być dowolnie duże, a rachunki całkowitoliczbowe wykonywane są dokładnie,&lt;br /&gt;
*liczby ułamkowe oraz wyniki rachunków na liczbach ułamkowych należy zawsze traktować jako przybliżone (oczywiście dla szczególnych wartości zdarza się, że są one dokładne); zakres wielkości liczb ułamkowych jest ograniczony.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&amp;lt;small&amp;gt;&lt;br /&gt;
Python zna też liczby ''zespolone'' oraz operacje na nich, ale tego zdaje się nie było w szkole...&lt;br /&gt;
&amp;lt;/small&amp;gt;&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Liczby całkowite można pisać również w podstawach innych niż 10:&lt;br /&gt;
&lt;br /&gt;
*dwójkowe: &amp;lt;tt&amp;gt;0b101 == 5&amp;lt;/tt&amp;gt;&lt;br /&gt;
*ósemkowe: &amp;lt;tt&amp;gt;0o123 == 83&amp;lt;/tt&amp;gt;&lt;br /&gt;
*szesnastkowe: &amp;lt;tt&amp;gt;0x1f == 31&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
(podwojony znak równości oznacza: lewa strona jest równa prawej; litery b, o, x mogą być zarówno małe jak i wielkie).&lt;br /&gt;
&lt;br /&gt;
W zapisie szesnastkowym, wymagającym 16 różnych cyfr, w roli &amp;quot;brakujących&amp;quot; cyfr oznaczających liczby od 10 do 15 przyjmuje się początkowe litery alfabetu (a-f), można równoważnie używać liter małych lub wielkich.&lt;br /&gt;
&lt;br /&gt;
===Napisy===&lt;br /&gt;
&lt;br /&gt;
Napis (ang. ''string'') to po prostu ciąg znaków.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&amp;lt;small&amp;gt;&lt;br /&gt;
OK, nic nie jest tak proste, jak się wydaje. Pytanie: co to jest znak? Odpowiedzi dostarcza standard ''Unicode'', w skład którego chodzi m. in. katalog wszystkich znaków, używanych przez systemy pisma wszystkich w zasadzie języków świata (języków żywych, i co ważniejszych spośród martwych). Nie będziemy się w tej chwili zastanawiać nad tym, jak dokładnie znaki te są reprezentowane w komputerze. Warto jednak pamiętać, że napisy nie muszą ograniczać się do znaków znanych z zapisu języków europejskich.&lt;br /&gt;
&amp;lt;/small&amp;gt;&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Literalne stałe napisowe, czyli napisy &amp;quot;na twardo&amp;quot; wpisane do kodu, mogą być podane w paru różnych postaciach:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
napis1 = 'jedna z postaci napisu'&lt;br /&gt;
napis2 = &amp;quot;nieco inna postać napisu&amp;quot;&lt;br /&gt;
napis3 = '''tak też może wyglądać napis,&lt;br /&gt;
i w tej postaci może zawierać przejścia do nowego wiersza&lt;br /&gt;
(w poprzednich nie może)'''&lt;br /&gt;
napis4 = &amp;quot;&amp;quot;&amp;quot;zamiast apostrofów, mogą być cudzysłowy - wychodzi na to samo,&lt;br /&gt;
również w postaci takiej, jak napis1 i napis2 są one równoważne&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
napis5 = &amp;quot;korzyść z tego pojawia się np. gdy w treści napisu potrzebujemy umieścić znak taki jak ' &amp;quot;&lt;br /&gt;
napis6 = 'w treści napisów można użyć kilku specjalnych sekwencji:\nTo powoduje przejście do nowego wiersza..'&lt;br /&gt;
napis7 = 'jeśli dwa napisy (lub więcej) postawimy ' 'jeden obok drugiego ' 'to zostaną połączone w jeden'&lt;br /&gt;
napis8 = 'lecz uwaga: pomiędzy sklejone napisy nie zostanie wstawiona żadna spacja ani w ogóle nic.'&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Sekwencje specjalne w napisach'''&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;\\&amp;lt;/tt&amp;gt;||dosłowny znak &amp;lt;tt&amp;gt;\&amp;lt;/tt&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;\'&amp;lt;/tt&amp;gt;||apostrof: &amp;lt;tt&amp;gt;'&amp;lt;/tt&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;\&amp;quot;&amp;lt;/tt&amp;gt;||cudzysłów: &amp;lt;tt&amp;gt;&amp;quot;&amp;lt;/tt&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;\a&amp;lt;/tt&amp;gt;||kod BEL&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;\b&amp;lt;/tt&amp;gt;||kod BS ('backspace')&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;\f&amp;lt;/tt&amp;gt;||kod FF ('formfeed')&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;\n&amp;lt;/tt&amp;gt;||kod LF ('linefeed')&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;\r&amp;lt;/tt&amp;gt;||kod CR ('carriage return')&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;\t&amp;lt;/tt&amp;gt;||kod HT ('horizontal tab')&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;\v&amp;lt;/tt&amp;gt;||kod VT ('vertical tab')&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;\nnn&amp;lt;/tt&amp;gt;||znak o kodzie 'nnn' w zapisie ósemkowym&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;\xnn&amp;lt;/tt&amp;gt;||znak o kodzie 'nn' w zapisie szesnastkowym&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;\N{nazwa}&amp;lt;/tt&amp;gt;||znak o danej nazwie symbolicznej w tabeli Unicode&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;\unnnn&amp;lt;/tt&amp;gt;||znak o pozycji '0xnnnn' w 16-bitowej tabeli Unicode&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;\Unnnnnnnn&amp;lt;/tt&amp;gt;||znak o pozycji '0xnnnnnnnn' w 32-bitowej tabeli Unicode&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
To co określam tutaj nazwą ''kod'' to są szczególne ,,znaki&amp;quot;, które nie posiadają reprezentacji graficznej, ale mogą wystąpić w strumieniu tekstowym pełniąc jakiegoś rodzaju rolę sterującą (p. poniżej). Czasami stosuje się określenie ''znaki niedrukowalne''. Jest ich więcej, niż występuje w powyższej tabeli &amp;amp;mdash; pozostałym nie nadano specjalnego zapisu i dostępne są np. przez notację &amp;lt;tt&amp;gt;\nnn&amp;lt;/tt&amp;gt; albo &amp;lt;tt&amp;gt;\xnn&amp;lt;/tt&amp;gt;, ale niezwykle rzadko bywają potrzebne.&lt;br /&gt;
&lt;br /&gt;
* Wypisanie kodu BEL na terminal najczęściej skutkuje sygnałem akustycznym (''BIP!'') lub wizualnym (błysk), zależy to od ustawień emulatora terminala&lt;br /&gt;
* Kod BS cofa kursor o jedną pozycję, umożliwiając nadpisanie ostatniego wypisanego znaku&lt;br /&gt;
* Kod FF stosowano w tekście przeznaczonym do wydrukowania na drukarce wierszowej, powodował przejście do następnej strony. Obecnie ze względu na wymarcie drukarek wierszowych w zasadzie nie ma zastosowania&lt;br /&gt;
* Kod LF to przejście do nowej linii, inaczej - znacznik końca linii w strumieniu tekstowym&lt;br /&gt;
* Kod CR czyli powrót karetki cofa kursor do początku aktualnej linii&lt;br /&gt;
* Kod HT to ten, który zwykle nazywa się po prostu kodem tabulacji. Jego interpretacja zależy od ustawień terminala lub innego programu renderującego tekst, zwykle oznacza przeskok do pozycji będącej kolejną całkowitą wielokrotnością 4 lub 8 w bieżącej linii&lt;br /&gt;
* Kod VT z założenia działa analogicznie jak HT, ale w kierunku pionowym. Obecnie rzadko stosowany&lt;br /&gt;
* W zapisie &amp;lt;tt&amp;gt;\nnn&amp;lt;/tt&amp;gt; może wystąpić jedna, dwie lub trzy cyfry ósemkowe ''n''&lt;br /&gt;
* W zapisie &amp;lt;tt&amp;gt;\xnn&amp;lt;/tt&amp;gt; należy użyć dokładnie dwóch cyfr szesnatkowych ''n''&lt;br /&gt;
* W zapisie &amp;lt;tt&amp;gt;\unnnn&amp;lt;/tt&amp;gt; należy użyć dokładnie czterech cyfr szesnastkowych ''n''&lt;br /&gt;
* W zapisie &amp;lt;tt&amp;gt;\Unnnnnnnn&amp;lt;/tt&amp;gt; należy użyć dokładnie ośmiu cyfr szesnastkowych ''n''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&lt;br /&gt;
'''Uwaga:''' w plikach tekstowych utworzonych w systemie Windows linie zwykle kończą się sekwencją dwuznakową CR LF (&amp;lt;tt&amp;gt;'\r\n'&amp;lt;/tt&amp;gt;) - inaczej niż w systemie Linux, gdzie znakiem końca linii jest LF. Python nie ma z tym problemu, interpretując pliki z kodem ,,łyka&amp;quot; obie konwencje. Ale np. jeśli w systemie Windows zapiszemy plik zaczynający się ,,magiczną&amp;quot; sekwencją &amp;lt;tt&amp;gt;#!&amp;amp;nbsp;/usr/bin/python3&amp;lt;/tt&amp;gt;, to po przeniesieniu go na Linux nie będzie się on uruchamiał zgodnie z oczekiwaniami, gdyż Linux odczyta nazwę interpretera jak &amp;lt;tt&amp;gt;'python3\r'&amp;lt;/tt&amp;gt;... Co inteligentniejsze edytory tekstu pozwalają na wybór konwencji końca linii.&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Jeżeli chcemy zapisać napis obfitujący w znaki &amp;lt;tt&amp;gt;\&amp;lt;/tt&amp;gt;, możemy użyć notacji takiej:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
napis1 = r'oto\napis\z\bakslaszami'&lt;br /&gt;
napis2 = R'tu\znak&amp;quot;\&amp;quot;nie\będzie\nigdy\oznaczał\początku\specjalnej\sekwencji'&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wielkość użytej na początku litery &amp;lt;tt&amp;gt;R&amp;lt;/tt&amp;gt; nie ma znaczenia.&lt;br /&gt;
&lt;br /&gt;
==Zmienne, czyli nazwy==&lt;br /&gt;
&lt;br /&gt;
Programy oczywiście nie operują jedynie na stałych. Potrzebny jest w nich sposób odnoszenia się do wartości, które nie są znane z góry (w chwili pisania programu) - albo dlatego, że zostaną dostarczone dopiero przy uruchomieniu lub w trakcie pracy programu, jako dane wejściowe (później zobaczymy, na jakie sposoby można tego dokonać), albo dlatego, że będą wynikiem obliczeń lub przekształceń danych wykonywanych przez program.&lt;br /&gt;
&lt;br /&gt;
Do tego w Pythonie służą ''zmienne'' - można je uważać za nazwy, z jakimi wiążemy pewne wartości (liczby, napisy, itd.), poprzez ''instrukcję podstawienia''. Do zapisu instrukcji podstawienia służy znak równości (&amp;lt;tt&amp;gt;=&amp;lt;/tt&amp;gt;), po jego lewej stronie stawiamy nazwę (zmiennej), po drugiej - ''wyrażenie'', np. literalną stałą, ale również może być to wyrażenie zbudowane ze stałych, operatorów (np. arytmetycznych), nazw zmiennych (reprezentujących w wyrażeniu związane z nimi aktualnie wartości), i szereg innych elementów które dopiero poznamy.&lt;br /&gt;
&lt;br /&gt;
'''Do zapamiętania''': pojedynczy znak równości &amp;lt;tt&amp;gt;=&amp;lt;/tt&amp;gt; w Pythonie (i wielu innych językach programowania) nie tworzy ''równania'', czyli stwierdzenia, że lewa strona jest równa prawej; tylko ''podstawienie'', a więc operację powodującą, że z nazwą stojącą po stronie lewej zostaje związana obliczona wartość wyrażenie stojącego po prawej. Zauważmy, że jest to operacja niesymetryczna (stron nie można bezkarne zamienić miejscami):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
i = 0 # pierwsze użycie nazwy, w tym przypadku 'i', tworzy zmienną i wiąże z nią wartość&lt;br /&gt;
i = i + 2 # to jest legalne, i oznacza, że wartość związana z 'i' rośnie o 2&lt;br /&gt;
i + 2 = i # to jest błędne, po lewej stronie nie może stać wyrażenie złożone&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Pojawienie się w wyrażeniu stojącym po prawej stronie podstawienia tej samej nazwy, która stoi po lewej stronie, nie tworzy jakiejkolwiek niejednoznaczności: zasadą jest, że ''wpierw'' obliczana jest wartość wyrażenia z prawej strony, z wykorzystaniem aktualnych wartości zmiennych, a ''potem'' następuje związanie nazwy zmiennej stojącej po lewej z wynikiem.&lt;br /&gt;
&lt;br /&gt;
Zauważmy, że błędem byłoby użycie nazwy po raz pierwszy ''bez'' uprzedniego nadania jej wartości, np. w wyrażeniu arytmetycznym.&lt;br /&gt;
&lt;br /&gt;
===Reguły tworzenia nazw===&lt;br /&gt;
&lt;br /&gt;
Aktualnie reguły określające, co jest poprawną nazwą w Pythonie, dopuszczają użycie całkiem szerokiego podzbioru znaków Unicode i są dość trudne do opisania w zrozumiały sposób. Pomijając jednak taką możliwość, że ktoś zechce użyć w nazwie zmiennej znaków pisma Kanji lub perskiego, można w dużym uproszczeniu powiedzieć tak:&lt;br /&gt;
&lt;br /&gt;
*nazwy można budować z liter (wielkich i małych), cyfr, i znaku podkreślenia (&amp;lt;tt&amp;gt;_&amp;lt;/tt&amp;gt;)&lt;br /&gt;
*z zastrzeżeniem, że pierwszym znakiem nazwy nie może być cyfra&lt;br /&gt;
*litery wielkie i małe są rozróżniane, tak więc nazwy różniące się jedynie wielkością liter ''są różne''&lt;br /&gt;
*długość nazwy nie podlega ograniczeniu&lt;br /&gt;
*zabronione jest użycie jako nazwy któregokolwiek z tzw. słów zastrzeżonych, które mają specjalne znaczenie w składni języka Python.[https://docs.python.org/3/reference/lexical_analysis.html#keywords Tutaj można znaleźć ich wykaz].&lt;br /&gt;
&lt;br /&gt;
W szczególności, nazwy (zmiennych i innych obiektów) mogą jak najbardziej zawierać litery właściwe dla języka polskiego (oraz dla innych języków). Z rozmaitych względów nie jest to jednak szczególnie rekomendowane, lepiej (przynajmniej na razie) ograniczyć się do liter podstawowego alfabetu łacińskiego. &lt;br /&gt;
&lt;br /&gt;
Oprócz twardych reguł zawartych w definicji języka, w tworzeniu nazw programiści trzymają się na ogół pewnych konwencji - które nie są w żaden sposób egzekwowane przez interpreter, ale ułatwiają czytanie kodu &amp;amp;mdash; zwłaszcza, gdy się nim dzielimy z innymi:&lt;br /&gt;
&lt;br /&gt;
*w nazwach zmiennych używamy małych liter (a nie wielkich)&lt;br /&gt;
*wielkie litery rezerwujemy dla nazw oznaczających wartości stałe, które nie mają prawa się zmienić w trakcie pracy programu&lt;br /&gt;
*staramy się, by nazwy coś znaczyły i ułatwiały zrozumienie kodu programu&lt;br /&gt;
*nie unikamy nazw składających się z dwóch lub nawet kilku słów; ponieważ spacja jako składnik nazwy nie jest dozwolona, zastępujemy ją znakiem podkreślenia&lt;br /&gt;
*unikamy jednak nazw przesadnie długich, a nazwy zmiennych, które są potrzebne jedynie &amp;quot;chwilowo&amp;quot; mogą wręcz być jednoliterowe&lt;br /&gt;
*nazwy zaczynające się od podkreślenia (&amp;lt;tt&amp;gt;_&amp;lt;/tt&amp;gt;) mają pewne specjalne znaczenia i nie tworzymy takich nazw, chyba że całkiem świadomie.&lt;br /&gt;
&lt;br /&gt;
=Wyrażenia=&lt;br /&gt;
&lt;br /&gt;
==Arytmetyczne==&lt;br /&gt;
&lt;br /&gt;
Wyrażenia arytmetyczne tworzymy z udziałem znanych już operatorów arytmetycznych &amp;lt;tt&amp;gt;+, -, /, *, **, //, %, ...&amp;lt;/tt&amp;gt;, ale również wywołań funkcji zwracających wartości liczbowe (więcej o tym dalej), z wykorzystaniem literalnych liczb i nazw oznaczających zmienne, których aktualne wartości powinny być liczbami. Możemy również używać nawiasów (wyłącznie okrągłych!) do grupowania podwyrażeń, aby wymusić określoną kolejność operacji. Każdy na ogół pamięta, że dzielenie i mnożenie mają pierwszeństwo przed dodawaniem i odejmowaniem; potęgowanie ma jeszcze wyższy priorytet. Gdy mamy do czynienia z operatorami o równym priorytecie, to operacje wykonywane są zgodnie z kolejnością czytania, od lewej do prawej. Jeżeli mamy wątpliwości, to użycie nawiasów nie będzie błędem. Przykłady:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
a + b * c == a + (b * c)&lt;br /&gt;
a / b / c == (a / b) / c&lt;br /&gt;
a * b ** c == a * (b ** c)&lt;br /&gt;
a ** b ** c == a ** (b ** c)&lt;br /&gt;
a ** - b == a ** (-b)&lt;br /&gt;
a ** b / c == (a ** b) / c&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Zachowanie operatora potęgowania jest tu nieco szczególne, i zgadza się z umową przyjętą w matematyce.&lt;br /&gt;
&lt;br /&gt;
Operatory arytmetyczne znajdują również czasem zastosowanie do obiektów nie będących liczbami, mają wtedy oczywiście nieco inne znaczenie. Np. suma dwóch napisów jest ich sklejeniem (mówi się też: ''konkatenacją''). &lt;br /&gt;
&lt;br /&gt;
W przypadku, gdy będziemy mieszać w jednym wyrażeniu liczby całkowite i zmiennoprzecinkowe, to wynik będzie liczbą zmiennoprzecinkową. Wyjątkiem jest dzielenie: &amp;lt;tt&amp;gt;a / b&amp;lt;/tt&amp;gt; zawsze da w wyniku liczbę zmiennoprzecinkową, natomiast &amp;lt;tt&amp;gt;a // b&amp;lt;/tt&amp;gt; - całkowitą, jeśli oba argumenty są całkowite; w przeciwnym razie, zmiennoprzecinkową (ale o zerowej części ułamkowej).&lt;br /&gt;
&lt;br /&gt;
===Rozszerzone operatory przypisania===&lt;br /&gt;
&lt;br /&gt;
Z dwuargumentowymi operatorami arytmetycznymi związane są tzw. ''rozszerzone operatory przypisania'', stanowiące drobne udogodnienie pozwalające w sposób bardziej zwięzły zapisać dość często występujące operacje - takie, jak powiększenie aktualnej wartości &amp;lt;tt&amp;gt;x&amp;lt;/tt&amp;gt; o 1 i zapamiętanie tej nowej, powiększonej wartości pod nazwą &amp;lt;tt&amp;gt;x&amp;lt;/tt&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
# poniższe instrukcje są parami równoważne&lt;br /&gt;
x = x + a &lt;br /&gt;
x += a &lt;br /&gt;
#&lt;br /&gt;
x = x * a&lt;br /&gt;
x *= a&lt;br /&gt;
#&lt;br /&gt;
x = x - a&lt;br /&gt;
x -= a&lt;br /&gt;
#&lt;br /&gt;
x = x / a&lt;br /&gt;
x /= a&lt;br /&gt;
#&lt;br /&gt;
x **= a&lt;br /&gt;
x = x**a&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wersja np. z potęgowaniem może jest niezbyt często przydatna, ale wprowadzono ją choćby po to, by było konsekwentnie.&lt;br /&gt;
&lt;br /&gt;
==Logiczne==&lt;br /&gt;
&lt;br /&gt;
Wyrażenia logiczne mogą mieć jedną z dwu wartości: Prawda (&amp;lt;tt&amp;gt;True&amp;lt;/tt&amp;gt;) lub Fałsz (&amp;lt;tt&amp;gt;False&amp;lt;/tt&amp;gt;). Literalne wartości &amp;lt;tt&amp;gt;True&amp;lt;/tt&amp;gt; i &amp;lt;tt&amp;gt;False&amp;lt;/tt&amp;gt; są też przykładami wyrażeń logicznych, choć dość mało przydatnymi. Prawdziwe lub fałszywe mogą być np. porównania dwóch wartości, tworzone za pomocą operatorów &amp;lt;tt&amp;gt;&amp;amp;gt;&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;&amp;amp;lt;&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;&amp;amp;gt;=&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;&amp;amp;lt;=&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;==&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;!=&amp;lt;/tt&amp;gt; (to ostatnie, to sposób w jaki w Pythonie pisze się znak nierówności). Jak już wspomniano, podwojony znak równości jest operatorem porównania (w odróżnieniu od pojedynczego - przypisania). Porównywać można przede wszystkim liczby (a więc - dowolne wyrażenia o wartościach liczbowych), ale również np. napisy - wówczas większy oznacza tyle, co dalszy w porządku leksykograficznym. Porównania mają priorytet niższy, niż operatory arytmetyczne.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&amp;lt;small&amp;gt;&lt;br /&gt;
Przy bliższym poznaniu okazuje się, że wartości &amp;lt;tt&amp;gt;True&amp;lt;/tt&amp;gt; i &amp;lt;tt&amp;gt;False&amp;lt;/tt&amp;gt; są tak naprawdę w pewnym sensie liczbami: odpowiednio 1 i 0. Dozwolone jest więc np. stosowanie do nich operacji arytmetycznych.&lt;br /&gt;
&amp;lt;/small&amp;gt;&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Z elementarnych wyrażeń logicznych (porównań) można tworzyć złożone wyrażenia logiczne za pomocą operatorów (spójników) logicznych, pisanych &amp;lt;tt&amp;gt;and&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;or&amp;lt;/tt&amp;gt; i &amp;lt;tt&amp;gt;not&amp;lt;/tt&amp;gt;. Mają one następujące właśności:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
(a and b) == (b and a)&lt;br /&gt;
(False and False) == False&lt;br /&gt;
(False and True) == False&lt;br /&gt;
(True and True) == True&lt;br /&gt;
(a or b) == (b or a)&lt;br /&gt;
(False or False) == False&lt;br /&gt;
(False or True) == True&lt;br /&gt;
(True or True) == True&lt;br /&gt;
(not True) == False&lt;br /&gt;
(not False) == True &lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Spójniki logiczne mają priorytet jeszcze niższy, niż porównania - stąd nawiasy w powyższym. Wśród nich najwyższy priorytet ma &amp;lt;tt&amp;gt;not&amp;lt;/tt&amp;gt;, następnie &amp;lt;tt&amp;gt;and&amp;lt;/tt&amp;gt;, na końcu &amp;lt;tt&amp;gt;or&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Wyrażenia logiczne mają tę szczególną własność, że wartość wyrażenia można często określić obliczając jedynie część jego elementów. Np. &amp;lt;tt&amp;gt;a and b&amp;lt;/tt&amp;gt;, jeżeli wartością &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; jest &amp;lt;tt&amp;gt;False&amp;lt;/tt&amp;gt;, jest na pewno &amp;lt;tt&amp;gt;False&amp;lt;/tt&amp;gt; - niezależnie od wartości &amp;lt;tt&amp;gt;b&amp;lt;/tt&amp;gt;. W takich przypadkach Python przerywa obliczanie (od lewej do prawej, z uwzględnieniem nawiasów) gdy tylko wartość jest określona. Fakt ten czasami może mieć znaczenie - jeżeli np. obliczenie któregoś z członów wyrażenia logicznego jest szczególnie czasochłonne, lub ma tzw. skutki uboczne.&lt;br /&gt;
&lt;br /&gt;
Wyrażenia logiczne znajdują zastosowanie przede wszystkim w instrukcji warunkowej - pozwalają określić warunki, pod jakimi pewne operacje będą wykonane, lub nie - o tym dalej.&lt;br /&gt;
&lt;br /&gt;
Warto wiedzieć, że w Pythonie '''każde wyrażenie może służyć jako wyrażenie logiczne'''. Inaczej mówiąc, każda wartość (napis, liczba, lista, itd.) może być wykorzystana w charakterze wartości logicznej. Obowiązują tu proste reguły:&lt;br /&gt;
&lt;br /&gt;
* liczba &amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt; jest fałszywa (równoważna &amp;lt;tt&amp;gt;False&amp;lt;/tt&amp;gt;); obojętne, czy całkowita czy zmiennoprzecinkowa;&lt;br /&gt;
* każda liczba różna od zera jest prawdziwa (równoważna &amp;lt;tt&amp;gt;True&amp;lt;/tt&amp;gt;);&lt;br /&gt;
* napis pusty (o długości 0) jest fałszywy, każdy inny napis jest prawdziwy (również np. zawierający wyłącznie spacje);&lt;br /&gt;
* ogólniej &amp;amp;mdash; dowolnego typu kolekcja (lista, słownik, zbiór, ...) jest prawdziwa, o ile jest niepusta; każda kolekcja pusta (0-elementowa) jest fałszywa;&lt;br /&gt;
* wartość pusta czyli &amp;lt;tt&amp;gt;None&amp;lt;/tt&amp;gt; jest, jak nietrudno zgadnąć, fałszywa.&lt;br /&gt;
&lt;br /&gt;
W przypadku ogólniejszych typów danych (obiektów klas złożonych) sytuacja może już nie być taka prosta, ponieważ twórca klasy ma moc określenia reguły decydującej o prawdziwości / nieprawdziwości obiektów danej klasy. Ten temat jest na razie poza zakresem naszego kursu.&lt;br /&gt;
&lt;br /&gt;
Jeżeli chcemy wymusić, aby dana wartość stała się dosłownie wartością logiczną, tzn. jedną z (&amp;lt;tt&amp;gt;True&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;False&amp;lt;/tt&amp;gt;) w sposób zgodny z powyższymi regułami, można to osiągnąć przykładając funkcję &amp;lt;tt&amp;gt;bool&amp;lt;/tt&amp;gt;: a więc &amp;lt;tt&amp;gt;bool(wyrażenie)&amp;lt;/tt&amp;gt;. Rzadko jednak bywa to potrzebne.&lt;br /&gt;
&lt;br /&gt;
Reguła „skrótowej&amp;quot; ewaluacji wyrażeń logicznych, w połączeniu z regułami prawdziwości innych typów danych, pozwala na dość popularne idiomy, jak np.:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
# jeśli `wynik' jest niepustą listą to wypisze jej zawartość&lt;br /&gt;
# jeśli natomiast pustą, pojawi się komunikat&lt;br /&gt;
print(wynik or &amp;quot;wynik jest pusty!&amp;quot;)&lt;br /&gt;
&amp;lt;/source&amp;gt; &lt;br /&gt;
&lt;br /&gt;
które pozwalają uniknąć używania instrukcji złożonych w wielu prostych przypadkach. Działa to dzięki temu, że spójniki &amp;lt;tt&amp;gt;and&amp;lt;/tt&amp;gt; i &amp;lt;tt&amp;gt;or&amp;lt;/tt&amp;gt; nie wymuszają aby wynik był wartością logiczną:&lt;br /&gt;
&lt;br /&gt;
* jeżeli &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; jest prawdziwe, to &amp;lt;tt&amp;gt;a or b == a&amp;lt;/tt&amp;gt;, i &amp;lt;tt&amp;gt;a and b == b&amp;lt;/tt&amp;gt; dla każdego &amp;lt;tt&amp;gt;b&amp;lt;/tt&amp;gt;;&lt;br /&gt;
* jeżeli &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; jest fałszywe, to &amp;lt;tt&amp;gt;a and b == a&amp;lt;/tt&amp;gt;, i &amp;lt;tt&amp;gt;a or b == b&amp;lt;/tt&amp;gt; dla każdego &amp;lt;tt&amp;gt;b&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Inaczej w przypadku operatora &amp;lt;tt&amp;gt;not&amp;lt;/tt&amp;gt;: wynikiem jego działania jest zawsze jedna z wartości logicznych, podobnie jak w przypadku funkcji &amp;lt;tt&amp;gt;bool()&amp;lt;/tt&amp;gt; &amp;amp;mdash; tyle, że przeciwna.&lt;br /&gt;
&lt;br /&gt;
==Napisowe==&lt;br /&gt;
&lt;br /&gt;
Wartością wyrażenia może być również napis. Na przykład, &amp;lt;tt&amp;gt;a + b&amp;lt;/tt&amp;gt;, jeżeli &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; i &amp;lt;tt&amp;gt;b&amp;lt;/tt&amp;gt; są napisami, jest napisem utworzonym przez ich sklejenie (zauważmy, że w odróżnieniu od dodawania liczb nie jest to operacja przemienna). &lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&amp;lt;small&amp;gt;&lt;br /&gt;
Wcześniej wspomniano, że dwa napisy literalne postawione obok siebie zostaną automatycznie sklejone w jeden: np. &amp;lt;tt&amp;gt;'abc' &amp;quot;123&amp;quot;&amp;lt;/tt&amp;gt; jest równoważne &amp;lt;tt&amp;gt;'abc123'&amp;lt;/tt&amp;gt;. Nie stosuje się to jednak np. do zmiennych o wartościach napisowych: napisanie dwóch nazw obok siebie bez operatora pomiędzy nimi jest błędem składniowym. Jest tak, ponieważ wspomniane sklejenie napisów literalnych ma miejsce na etapie ''kompilacji'' kodu - tzn. wtedy, gdy interpreter analizuje zapis programu i przekłada go na instrukcje, jakie zostaną wykonane w etapie uruchomienia - a wartości stojące za nazwami zmiennych nie są na tym etapie jednoznacznie określone. &lt;br /&gt;
&amp;lt;/small&amp;gt;&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Bogatszy repertuar operacji tworzących wyrażenia o wartościach będących napisami poznamy dalej.&lt;br /&gt;
&lt;br /&gt;
==Inne wyrażenia==&lt;br /&gt;
&lt;br /&gt;
Oprócz liczb, napisów i wartości logicznych, Python posiada szereg dalszych, złożonych typów danych, które również mogą być wartościami wyrażeń. Wspomniano już przelotnie o kolekcjach (listy, słowniki, zbiory, ...) &amp;amp;mdash; służą one jako ,,pojemniki&amp;quot; do gromadzenia obiektów w zasadzie dowolnych typów, i zostaną omówione w dalszym ciągu. Istnieje też specjalny typ ''obiektu pustego'', mający dokładnie jednego reprezentanta: wartość specjalną &amp;lt;tt&amp;gt;None&amp;lt;/tt&amp;gt;. Jeszcze innym typem danych są funkcje, z którymi się już zaraz zapoznamy.&lt;br /&gt;
&lt;br /&gt;
Każdy typ obiektu w Pythonie może być wartością odpowiednio zbudowanego wyrażenia. Gdy poznamy kolejne typy danych, wprowadzimy również operacje tworzące takie wyrażenia.&lt;br /&gt;
&lt;br /&gt;
=Ćwiczenia=&lt;br /&gt;
&lt;br /&gt;
1. Które z następujących są poprawnymi nazwami według reguł Pythona:&lt;br /&gt;
   nazwa1&lt;br /&gt;
   9sił&lt;br /&gt;
   dluga-nazwa&lt;br /&gt;
   wykonaj_rachunki&lt;br /&gt;
   _&lt;br /&gt;
   to&amp;amp;owo&lt;br /&gt;
   if &lt;br /&gt;
&lt;br /&gt;
2. Wykazać, że poniższe równości są równoważnościami -- tzn. że zachodzą dla dowolnej kombinacji wartości &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; i &amp;lt;tt&amp;gt;b&amp;lt;/tt&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
   not (a or b) == not a and not b&lt;br /&gt;
   not (a and b) == not a or not b&lt;br /&gt;
   a or not a == True&lt;br /&gt;
&lt;br /&gt;
''Wskazówka:'' stworzyć tabelki wartości wyrażeń po lewej i prawej stronie operatora porównania &amp;lt;tt&amp;gt;==&amp;lt;/tt&amp;gt; dla wszystkich możliwych kombinacji wartości &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; i &amp;lt;tt&amp;gt;b&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
3. Które z poniższych równości są tożsamościami, w wyniku działania reguł pierwszeństwa operatorów?&lt;br /&gt;
&lt;br /&gt;
   a / b / c == a / (b / c)&lt;br /&gt;
   a ** b / c == (a ** b) / c&lt;br /&gt;
   -a ** b == (-a) ** b&lt;br /&gt;
&lt;br /&gt;
''CDN...''&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
[[PPy3/PierwszeKroki|poprzednia]] | [[&amp;quot;Programowanie z Pythonem3&amp;quot;|Strona główna]] | [[PPy3/InstrukcjaWarunkowa|dalej]]&lt;br /&gt;
&lt;br /&gt;
--[[Użytkownik:RobertJB|RobertJB]] ([[Dyskusja użytkownika:RobertJB|dyskusja]]) 14:22, 21 cze 2016 (CEST)&lt;/div&gt;</summary>
		<author><name>RobertJB</name></author>
		
	</entry>
	<entry>
		<id>http://brain.fuw.edu.pl/edu/index.php?title=PPy3/Sta%C5%82eIZmienne&amp;diff=9331</id>
		<title>PPy3/StałeIZmienne</title>
		<link rel="alternate" type="text/html" href="http://brain.fuw.edu.pl/edu/index.php?title=PPy3/Sta%C5%82eIZmienne&amp;diff=9331"/>
		<updated>2023-05-10T10:51:40Z</updated>

		<summary type="html">&lt;p&gt;RobertJB: /* Napisy */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=Stałe i zmienne=&lt;br /&gt;
&lt;br /&gt;
==Stałe dosłowne (literalne)==&lt;br /&gt;
&lt;br /&gt;
Stałe dosłowne to takie, których wartości wprost wpisano do pliku z kodem (lub w linii poleceń interpretera). Mogą to być liczby (paru rodzajów) lub napisy, ale również różne złożone rodzaje (typy) danych, z którymi zapoznamy się nieco później.&lt;br /&gt;
&lt;br /&gt;
'''Zapamiętajmy''' od razu: ''liczba'' dla komputera to zupełnie co innego, niż ''napis'' składający się z cyfr. Na napisie nie wykonamy operacji arytmetycznych - a na liczbie, operacji właściwych dla napisów (takich jak np. wyjęcie z niego znaku stojącego na określonej pozycji). Istnieją jednak operacje przekształcające każdy z tych typów danych w drugi.&lt;br /&gt;
&lt;br /&gt;
===Liczby===&lt;br /&gt;
&lt;br /&gt;
Dobrze jest pamiętać, że nieco odmiennie traktowane są liczby całkowite, a inaczej - liczby ułamkowe, zwykle zwane ''zmiennoprzecinkowymi'' (po angielsku ''floating point'', jako że Amerykanie piszą kropkę dziesiętną a nie - jak my - przecinek, przez co i w Pythonie używa się w tym celu kropki).&lt;br /&gt;
&lt;br /&gt;
*Liczby całkowite w zapisie dziesiętnym: &amp;lt;tt&amp;gt;1024&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;-666&amp;lt;/tt&amp;gt;, ...&lt;br /&gt;
*Liczby ułamkowe: &amp;lt;tt&amp;gt;1.0&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;.99&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;98.6&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;-37.43&amp;lt;/tt&amp;gt;, ...&lt;br /&gt;
*Liczby ułamkowe w zapisie wykładniczym: &amp;lt;tt&amp;gt;1.024e3&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;96.9E-12&amp;lt;/tt&amp;gt;, ...&lt;br /&gt;
&lt;br /&gt;
Notacja &amp;lt;tt&amp;gt;e3&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;E-12&amp;lt;/tt&amp;gt; itp. (wielka i mała litera &amp;lt;tt&amp;gt;e&amp;lt;/tt&amp;gt; są tu równoważne) oznacza pomnożenie poprzedzającej liczby przez odpowiednio 10&amp;lt;sup&amp;gt;3&amp;lt;/sup&amp;gt;, 10&amp;lt;sup&amp;gt;-12&amp;lt;/sup&amp;gt;, ... i służy ułatwieniu zapisu liczb bardzo dużych lub bardzo małych. Nie można tam wtrącać dodatkowych odstępów, podobnie jak pomiędzy cyframi.&lt;br /&gt;
&lt;br /&gt;
Jeśli część całkowita (lub ułamkowa) liczby zmiennoprzecinkowej wynosi zero, to można to zero pominąć. Oczywiście nie można pominąć obu, zapisując liczbę zero! (można napisać: &amp;lt;tt&amp;gt;0.&amp;lt;/tt&amp;gt; albo &amp;lt;tt&amp;gt;.0&amp;lt;/tt&amp;gt;, ale nie samotną kropkę).&lt;br /&gt;
&lt;br /&gt;
Podstawowa różnica pomiędzy sposobem traktowania liczb całkowitych i zmiennoprzecinkowych polega na tym, że:&lt;br /&gt;
&lt;br /&gt;
*liczby całkowite mogą być dowolnie duże, a rachunki całkowitoliczbowe wykonywane są dokładnie,&lt;br /&gt;
*liczby ułamkowe oraz wyniki rachunków na liczbach ułamkowych należy zawsze traktować jako przybliżone (oczywiście dla szczególnych wartości zdarza się, że są one dokładne); zakres wielkości liczb ułamkowych jest ograniczony.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&amp;lt;small&amp;gt;&lt;br /&gt;
Python zna też liczby ''zespolone'' oraz operacje na nich, ale tego zdaje się nie było w szkole...&lt;br /&gt;
&amp;lt;/small&amp;gt;&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Liczby całkowite można pisać również w podstawach innych niż 10:&lt;br /&gt;
&lt;br /&gt;
*dwójkowe: &amp;lt;tt&amp;gt;0b101 == 5&amp;lt;/tt&amp;gt;&lt;br /&gt;
*ósemkowe: &amp;lt;tt&amp;gt;0o123 == 83&amp;lt;/tt&amp;gt;&lt;br /&gt;
*szesnastkowe: &amp;lt;tt&amp;gt;0x1f == 31&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
(podwojony znak równości oznacza: lewa strona jest równa prawej; litery b, o, x mogą być zarówno małe jak i wielkie).&lt;br /&gt;
&lt;br /&gt;
W zapisie szesnastkowym, wymagającym 16 różnych cyfr, w roli &amp;quot;brakujących&amp;quot; cyfr oznaczających liczby od 10 do 15 przyjmuje się początkowe litery alfabetu (a-f), można równoważnie używać liter małych lub wielkich.&lt;br /&gt;
&lt;br /&gt;
===Napisy===&lt;br /&gt;
&lt;br /&gt;
Napis (ang. ''string'') to po prostu ciąg znaków.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&amp;lt;small&amp;gt;&lt;br /&gt;
OK, nic nie jest tak proste, jak się wydaje. Pytanie: co to jest znak? Odpowiedzi dostarcza standard ''Unicode'', w skład którego chodzi m. in. katalog wszystkich znaków, używanych przez systemy pisma wszystkich w zasadzie języków świata (języków żywych, i co ważniejszych spośród martwych). Nie będziemy się w tej chwili zastanawiać nad tym, jak dokładnie znaki te są reprezentowane w komputerze. Warto jednak pamiętać, że napisy nie muszą ograniczać się do znaków znanych z zapisu języków europejskich.&lt;br /&gt;
&amp;lt;/small&amp;gt;&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Literalne stałe napisowe, czyli napisy &amp;quot;na twardo&amp;quot; wpisane do kodu, mogą być podane w paru różnych postaciach:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
napis1 = 'jedna z postaci napisu'&lt;br /&gt;
napis2 = &amp;quot;nieco inna postać napisu&amp;quot;&lt;br /&gt;
napis3 = '''tak też może wyglądać napis,&lt;br /&gt;
i w tej postaci może zawierać przejścia do nowego wiersza&lt;br /&gt;
(w poprzednich nie może)'''&lt;br /&gt;
napis4 = &amp;quot;&amp;quot;&amp;quot;zamiast apostrofów, mogą być cudzysłowy - wychodzi na to samo,&lt;br /&gt;
również w postaci takiej, jak napis1 i napis2 są one równoważne&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
napis5 = &amp;quot;korzyść z tego pojawia się np. gdy w treści napisu potrzebujemy umieścić znak taki jak ' &amp;quot;&lt;br /&gt;
napis6 = 'w treści napisów można użyć kilku specjalnych sekwencji:\nTo powoduje przejście do nowego wiersza..'&lt;br /&gt;
napis7 = 'jeśli dwa napisy (lub więcej) postawimy ' 'jeden obok drugiego ' 'to zostaną połączone w jeden'&lt;br /&gt;
napis8 = 'lecz uwaga: pomiędzy sklejone napisy nie zostanie wstawiona żadna spacja ani w ogóle nic.'&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Sekwencje specjalne w napisach'''&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;\\&amp;lt;/tt&amp;gt;||dosłowny znak &amp;lt;tt&amp;gt;\&amp;lt;/tt&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;\'&amp;lt;/tt&amp;gt;||apostrof: &amp;lt;tt&amp;gt;'&amp;lt;/tt&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;\&amp;quot;&amp;lt;/tt&amp;gt;||cudzysłów: &amp;lt;tt&amp;gt;&amp;quot;&amp;lt;/tt&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;\a&amp;lt;/tt&amp;gt;||kod BEL&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;\b&amp;lt;/tt&amp;gt;||kod BS ('backspace')&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;\f&amp;lt;/tt&amp;gt;||kod FF ('formfeed')&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;\n&amp;lt;/tt&amp;gt;||kod LF ('linefeed')&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;\r&amp;lt;/tt&amp;gt;||kod CR ('carriage return')&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;\t&amp;lt;/tt&amp;gt;||kod HT ('horizontal tab')&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;\v&amp;lt;/tt&amp;gt;||kod VT ('vertical tab')&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;\nnn&amp;lt;/tt&amp;gt;||znak o kodzie 'nnn' w zapisie ósemkowym&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;\xnn&amp;lt;/tt&amp;gt;||znak o kodzie 'nn' w zapisie szesnastkowym&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;\N{nazwa}&amp;lt;/tt&amp;gt;||znak o danej nazwie symbolicznej w tabeli Unicode&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;\unnnn&amp;lt;/tt&amp;gt;||znak o pozycji '0xnnnn' w 16-bitowej tabeli Unicode&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;\Unnnnnnnn&amp;lt;/tt&amp;gt;||znak o pozycji '0xnnnnnnnn' w 32-bitowej tabeli Unicode&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
To co określam tutaj nazwą ''kod'' to są szczególne ,,znaki&amp;quot;, które nie posiadają reprezentacji graficznej, ale mogą wystąpić w strumieniu tekstowym pełniąc jakiegoś rodzaju rolę sterującą (p. poniżej). Czasami stosuje się określenie ''znaki niedrukowalne''. Jest ich więcej, niż występuje w powyższej tabeli &amp;amp;mdash; pozostałym nie nadano specjalnego zapisu i dostępne są np. przez notację &amp;lt;tt&amp;gt;\nnn&amp;lt;/tt&amp;gt; albo &amp;lt;tt&amp;gt;\xnn&amp;lt;/tt&amp;gt;, ale niezwykle rzadko bywają potrzebne.&lt;br /&gt;
&lt;br /&gt;
* Wypisanie kodu BEL na terminal najczęściej skutkuje sygnałem akustycznym (''BIP!'') lub wizualnym (błysk), zależy to od ustawień emulatora terminala&lt;br /&gt;
* Kod BS cofa kursor o jedną pozycję, umożliwiając nadpisanie ostatniego wypisanego znaku&lt;br /&gt;
* Kod FF stosowano w tekście przeznaczonym do wydrukowania na drukarce wierszowej, powodował przejście do następnej strony. Obecnie ze względu na wymarcie drukarek wierszowych w zasadzie nie ma zastosowania&lt;br /&gt;
* Kod LF to przejście do nowej linii, inaczej - znacznik końca linii w strumieniu tekstowym&lt;br /&gt;
* Kod CR czyli powrót karetki cofa kursor do początku aktualnej linii&lt;br /&gt;
* Kod HT to ten, który zwykle nazywa się po prostu kodem tabulacji. Jego interpretacja zależy od ustawień terminala lub innego programu renderującego tekst, zwykle oznacza przeskok do pozycji będącej kolejną całkowitą wielokrotnością 4 lub 8 w bieżącej linii&lt;br /&gt;
* Kod VT z założenia działa analogicznie jak HT, ale w kierunku pionowym. Obecnie rzadko stosowany&lt;br /&gt;
* W zapisie &amp;lt;tt&amp;gt;\nnn&amp;lt;/tt&amp;gt; może wystąpić jedna, dwie lub trzy cyfry ósemkowe ''n''&lt;br /&gt;
* W zapisie &amp;lt;tt&amp;gt;\xnn&amp;lt;/tt&amp;gt; należy użyć dokładnie dwóch cyfr szesnatkowych ''n''&lt;br /&gt;
* W zapisie &amp;lt;tt&amp;gt;\unnnn&amp;lt;/tt&amp;gt; należy użyć dokładnie czterech cyfr szesnastkowych ''n''&lt;br /&gt;
* W zapisie &amp;lt;tt&amp;gt;\Unnnnnnnn&amp;lt;/tt&amp;gt; należy użyć dokładnie ośmiu cyfr szesnastkowych ''n''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&lt;br /&gt;
'''Uwaga:''' w plikach tekstowych utworzonych w systemie Windows linie zwykle kończą się sekwencją dwuznakową CR LF (&amp;lt;tt&amp;gt;'\r\n'&amp;lt;/tt&amp;gt;) - inaczej niż w systemie Linux, gdzie znakiem końca linii jest LF. Python nie ma z tym problemu, interpretując pliki z kodem ,,łyka&amp;quot; obie konwencje. Ale np. jeśli w systemie Windows zapiszemy plik zaczynający się ,,magiczną&amp;quot; sekwencją &amp;lt;tt&amp;gt;#!&amp;amp;nbsp;/usr/bin/python3&amp;lt;/tt&amp;gt;, to po przeniesieniu go na Linux nie będzie się on uruchamiał zgodnie z oczekiwaniami, gdyż Linux odczyta nazwę interpretera jak &amp;lt;tt&amp;gt;'python3\r'&amp;lt;/tt&amp;gt;... Co inteligentniejsze edytory tekstu pozwalają na wybór konwencji końca linii.&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Jeżeli chcemy zapisać napis obfitujący w znaki &amp;lt;tt&amp;gt;\&amp;lt;/tt&amp;gt;, możemy użyć notacji takiej:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
napis1 = r'oto\napis\z\bakslaszami'&lt;br /&gt;
napis2 = R'tu\znak&amp;quot;\&amp;quot;nie\będzie\nigdy\oznaczał\początku\specjalnej\sekwencji'&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wielkość użytej na początku litery &amp;lt;tt&amp;gt;R&amp;lt;/tt&amp;gt; nie ma znaczenia.&lt;br /&gt;
&lt;br /&gt;
==Zmienne, czyli nazwy==&lt;br /&gt;
&lt;br /&gt;
Programy oczywiście nie operują jedynie na stałych. Potrzebny jest w nich sposób odnoszenia się do wartości, które nie są znane z góry (w chwili pisania programu) - albo dlatego, że zostaną dostarczone dopiero przy uruchomieniu lub w trakcie pracy programu, jako dane wejściowe (później zobaczymy, na jakie sposoby można tego dokonać), albo dlatego, że będą wynikiem obliczeń lub przekształceń danych wykonywanych przez program.&lt;br /&gt;
&lt;br /&gt;
Do tego w Pythonie służą ''zmienne'' - można je uważać za nazwy, z jakimi wiążemy pewne wartości (liczby, napisy, itd.), poprzez ''instrukcję podstawienia''. Do zapisu instrukcji podstawienia służy znak równości (&amp;lt;tt&amp;gt;=&amp;lt;/tt&amp;gt;), po jego lewej stronie stawiamy nazwę (zmiennej), po drugiej - ''wyrażenie'', np. literalną stałą, ale również może być to wyrażenie zbudowane ze stałych, operatorów (np. arytmetycznych), nazw zmiennych (reprezentujących w wyrażeniu związane z nimi aktualnie wartości), i szereg innych elementów które dopiero poznamy.&lt;br /&gt;
&lt;br /&gt;
'''Do zapamiętania''': pojedynczy znak równości &amp;lt;tt&amp;gt;=&amp;lt;/tt&amp;gt; w Pythonie (i wielu innych językach programowania) nie tworzy ''równania'', czyli stwierdzenia, że lewa strona jest równa prawej; tylko ''podstawienie'', a więc operację powodującą, że z nazwą stojącą po stronie lewej zostaje związana obliczona wartość wyrażenie stojącego po prawej. Zauważmy, że jest to operacja niesymetryczna (stron nie można bezkarne zamienić miejscami):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
i = 0 # pierwsze użycie nazwy, w tym przypadku 'i', tworzy zmienną i wiąże z nią wartość&lt;br /&gt;
i = i + 2 # to jest legalne, i oznacza, że wartość związana z 'i' rośnie o 2&lt;br /&gt;
i + 2 = i # to jest błędne, po lewej stronie nie może stać wyrażenie złożone&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Pojawienie się w wyrażeniu stojącym po prawej stronie podstawienia tej samej nazwy, która stoi po lewej stronie, nie tworzy jakiejkolwiek niejednoznaczności: zasadą jest, że ''wpierw'' obliczana jest wartość wyrażenia z prawej strony, z wykorzystaniem aktualnych wartości zmiennych, a ''potem'' następuje związanie nazwy zmiennej stojącej po lewej z wynikiem.&lt;br /&gt;
&lt;br /&gt;
Zauważmy, że błędem byłoby użycie nazwy po raz pierwszy ''bez'' uprzedniego nadania jej wartości, np. w wyrażeniu arytmetycznym.&lt;br /&gt;
&lt;br /&gt;
===Reguły tworzenia nazw===&lt;br /&gt;
&lt;br /&gt;
Aktualnie reguły określające, co jest poprawną nazwą w Pythonie, dopuszczają użycie całkiem szerokiego podzbioru znaków Unicode i są dość trudne do opisania w zrozumiały sposób. Pomijając jednak taką możliwość, że ktoś zechce użyć w nazwie zmiennej znaków pisma Kanji lub perskiego, można w dużym uproszczeniu powiedzieć tak:&lt;br /&gt;
&lt;br /&gt;
*nazwy można budować z liter (wielkich i małych), cyfr, i znaku podkreślenia (&amp;lt;tt&amp;gt;_&amp;lt;/tt&amp;gt;)&lt;br /&gt;
*z zastrzeżeniem, że pierwszym znakiem nazwy nie może być cyfra&lt;br /&gt;
*litery wielkie i małe są rozróżniane, tak więc nazwy różniące się jedynie wielkością liter ''są różne''&lt;br /&gt;
*długość nazwy nie podlega ograniczeniu&lt;br /&gt;
*zabronione jest użycie jako nazwy któregokolwiek z tzw. słów zastrzeżonych, które mają specjalne znaczenie w składni języka Python.[https://docs.python.org/3/reference/lexical_analysis.html#keywords Tutaj można znaleźć ich wykaz].&lt;br /&gt;
&lt;br /&gt;
W szczególności, nazwy (zmiennych i innych obiektów) mogą jak najbardziej zawierać litery właściwe dla języka polskiego (oraz dla innych języków). Z rozmaitych względów nie jest to jednak szczególnie rekomendowane, lepiej (przynajmniej na razie) ograniczyć się do liter podstawowego alfabetu łacińskiego. &lt;br /&gt;
&lt;br /&gt;
Oprócz twardych reguł zawartych w definicji języka, w tworzeniu nazw programiści trzymają się na ogół pewnych konwencji - które nie są w żaden sposób egzekwowane przez interpreter, ale ułatwiają czytanie kodu &amp;amp;mdash; zwłaszcza, gdy się nim dzielimy z innymi:&lt;br /&gt;
&lt;br /&gt;
*w nazwach zmiennych używamy małych liter (a nie wielkich)&lt;br /&gt;
*wielkie litery rezerwujemy dla nazw oznaczających wartości stałe, które nie mają prawa się zmienić w trakcie pracy programu&lt;br /&gt;
*staramy się, by nazwy coś znaczyły i ułatwiały zrozumienie kodu programu&lt;br /&gt;
*nie unikamy nazw składających się z dwóch lub nawet kilku słów; ponieważ spacja jako składnik nazwy nie jest dozwolona, zastępujemy ją znakiem podkreślenia&lt;br /&gt;
*unikamy jednak nazw przesadnie długich, a nazwy zmiennych, które są potrzebne jedynie &amp;quot;chwilowo&amp;quot; mogą wręcz być jednoliterowe&lt;br /&gt;
*nazwy zaczynające się od podkreślenia (&amp;lt;tt&amp;gt;_&amp;lt;/tt&amp;gt;) mają pewne specjalne znaczenia i nie tworzymy takich nazw, chyba że całkiem świadomie.&lt;br /&gt;
&lt;br /&gt;
=Wyrażenia=&lt;br /&gt;
&lt;br /&gt;
==Arytmetyczne==&lt;br /&gt;
&lt;br /&gt;
Wyrażenia arytmetyczne tworzymy z udziałem znanych już operatorów arytmetycznych &amp;lt;tt&amp;gt;+, -, /, *, **, //, %, ...&amp;lt;/tt&amp;gt;, ale również wywołań funkcji zwracających wartości liczbowe (więcej o tym dalej), z wykorzystaniem literalnych liczb i nazw oznaczających zmienne, których aktualne wartości powinny być liczbami. Możemy również używać nawiasów (wyłącznie okrągłych!) do grupowania podwyrażeń, aby wymusić określoną kolejność operacji. Każdy na ogół pamięta, że dzielenie i mnożenie mają pierwszeństwo przed dodawaniem i odejmowaniem; potęgowanie ma jeszcze wyższy priorytet. Gdy mamy do czynienia z operatorami o równym priorytecie, to operacje wykonywane są zgodnie z kolejnością czytania, od lewej do prawej. Jeżeli mamy wątpliwości, to użycie nawiasów nie będzie błędem. Przykłady:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
a + b * c == a + (b * c)&lt;br /&gt;
a / b / c == (a / b) / c&lt;br /&gt;
a * b ** c == a * (b ** c)&lt;br /&gt;
a ** b ** c == a ** (b ** c)&lt;br /&gt;
a ** - b == a ** (-b)&lt;br /&gt;
a ** b / c == (a ** b) / c&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Zachowanie operatora potęgowania jest tu nieco szczególne, i zgadza się z umową przyjętą w matematyce.&lt;br /&gt;
&lt;br /&gt;
Operatory arytmetyczne znajdują również czasem zastosowanie do obiektów nie będących liczbami, mają wtedy oczywiście nieco inne znaczenie. Np. suma dwóch napisów jest ich sklejeniem (mówi się też: ''konkatenacją''). &lt;br /&gt;
&lt;br /&gt;
W przypadku, gdy będziemy mieszać w jednym wyrażeniu liczby całkowite i zmiennoprzecinkowe, to wynik będzie liczbą zmiennoprzecinkową. Wyjątkiem jest dzielenie: &amp;lt;tt&amp;gt;a / b&amp;lt;/tt&amp;gt; zawsze da w wyniku liczbę zmiennoprzecinkową, natomiast &amp;lt;tt&amp;gt;a // b&amp;lt;/tt&amp;gt; - całkowitą, jeśli oba argumenty są całkowite; w przeciwnym razie, zmiennoprzecinkową (ale o zerowej części ułamkowej).&lt;br /&gt;
&lt;br /&gt;
===Rozszerzone operatory przypisania===&lt;br /&gt;
&lt;br /&gt;
Z dwuargumentowymi operatorami arytmetycznymi związane są tzw. ''rozszerzone operatory przypisania'', stanowiące drobne udogodnienie pozwalające w sposób bardziej zwięzły zapisać dość często występujące operacje - takie, jak powiększenie aktualnej wartości &amp;lt;tt&amp;gt;x&amp;lt;/tt&amp;gt; o 1 i zapamiętanie tej nowej, powiększonej wartości pod nazwą &amp;lt;tt&amp;gt;x&amp;lt;/tt&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
# poniższe instrukcje są parami równoważne&lt;br /&gt;
x = x + a &lt;br /&gt;
x += a &lt;br /&gt;
#&lt;br /&gt;
x = x * a&lt;br /&gt;
x *= a&lt;br /&gt;
#&lt;br /&gt;
x = x - a&lt;br /&gt;
x -= a&lt;br /&gt;
#&lt;br /&gt;
x = x / a&lt;br /&gt;
x /= a&lt;br /&gt;
#&lt;br /&gt;
x **= a&lt;br /&gt;
x = x**a&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wersja np. z potęgowaniem może jest niezbyt często przydatna, ale wprowadzono ją choćby po to, by było konsekwentnie.&lt;br /&gt;
&lt;br /&gt;
==Logiczne==&lt;br /&gt;
&lt;br /&gt;
Wyrażenia logiczne mogą mieć jedną z dwu wartości: Prawda (&amp;lt;tt&amp;gt;True&amp;lt;/tt&amp;gt;) lub Fałsz (&amp;lt;tt&amp;gt;False&amp;lt;/tt&amp;gt;). Literalne wartości &amp;lt;tt&amp;gt;True&amp;lt;/tt&amp;gt; i &amp;lt;tt&amp;gt;False&amp;lt;/tt&amp;gt; są też przykładami wyrażeń logicznych, choć dość mało przydatnymi. Prawdziwe lub fałszywe mogą być np. porównania dwóch wartości, tworzone za pomocą operatorów &amp;lt;tt&amp;gt;&amp;amp;gt;&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;&amp;amp;lt;&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;&amp;amp;gt;=&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;&amp;amp;lt;=&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;==&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;!=&amp;lt;/tt&amp;gt; (to ostatnie, to sposób w jaki w Pythonie pisze się znak nierówności). Jak już wspomniano, podwojony znak równości jest operatorem porównania (w odróżnieniu od pojedynczego - przypisania). Porównywać można przede wszystkim liczby (a więc - dowolne wyrażenia o wartościach liczbowych), ale również np. napisy - wówczas większy oznacza tyle, co dalszy w porządku leksykograficznym. Porównania mają priorytet niższy, niż operatory arytmetyczne.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&amp;lt;small&amp;gt;&lt;br /&gt;
Przy bliższym poznaniu okazuje się, że wartości &amp;lt;tt&amp;gt;True&amp;lt;/tt&amp;gt; i &amp;lt;tt&amp;gt;False&amp;lt;/tt&amp;gt; są tak naprawdę w pewnym sensie liczbami: odpowiednio 1 i 0. Dozwolone jest więc np. stosowanie do nich operacji arytmetycznych.&lt;br /&gt;
&amp;lt;/small&amp;gt;&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Z elementarnych wyrażeń logicznych (porównań) można tworzyć złożone wyrażenia logiczne za pomocą operatorów (spójników) logicznych, pisanych &amp;lt;tt&amp;gt;and&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;or&amp;lt;/tt&amp;gt; i &amp;lt;tt&amp;gt;not&amp;lt;/tt&amp;gt;. Mają one następujące właśności:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
(a and b) == (b and a)&lt;br /&gt;
(False and False) == False&lt;br /&gt;
(False and True) == False&lt;br /&gt;
(True and True) == True&lt;br /&gt;
(a or b) == (b or a)&lt;br /&gt;
(False or False) == False&lt;br /&gt;
(False or True) == True&lt;br /&gt;
(True or True) == True&lt;br /&gt;
(not True) == False&lt;br /&gt;
(not False) == True &lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Spójniki logiczne mają priorytet jeszcze niższy, niż porównania - stąd nawiasy w powyższym. Wśród nich najwyższy priorytet ma &amp;lt;tt&amp;gt;not&amp;lt;/tt&amp;gt;, następnie &amp;lt;tt&amp;gt;and&amp;lt;/tt&amp;gt;, na końcu &amp;lt;tt&amp;gt;or&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Wyrażenia logiczne mają tę szczególną własność, że wartość wyrażenia można często określić obliczając jedynie część jego elementów. Np. &amp;lt;tt&amp;gt;a and b&amp;lt;/tt&amp;gt;, jeżeli wartością &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; jest &amp;lt;tt&amp;gt;False&amp;lt;/tt&amp;gt;, jest na pewno &amp;lt;tt&amp;gt;False&amp;lt;/tt&amp;gt; - niezależnie od wartości &amp;lt;tt&amp;gt;b&amp;lt;/tt&amp;gt;. W takich przypadkach Python przerywa obliczanie (od lewej do prawej, z uwzględnieniem nawiasów) gdy tylko wartość jest określona. Fakt ten czasami może mieć znaczenie - jeżeli np. obliczenie któregoś z członów wyrażenia logicznego jest szczególnie czasochłonne, lub ma tzw. skutki uboczne.&lt;br /&gt;
&lt;br /&gt;
Wyrażenia logiczne znajdują zastosowanie przede wszystkim w instrukcji warunkowej - pozwalają określić warunki, pod jakimi pewne operacje będą wykonane, lub nie - o tym dalej.&lt;br /&gt;
&lt;br /&gt;
Warto wiedzieć, że w Pythonie '''każde wyrażenie może służyć jako wyrażenie logiczne'''. Inaczej mówiąc, każda wartość (napis, liczba, lista, itd.) może być wykorzystana w charakterze wartości logicznej. Obowiązują tu proste reguły:&lt;br /&gt;
&lt;br /&gt;
* liczba &amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt; jest fałszywa (równoważna &amp;lt;tt&amp;gt;False&amp;lt;/tt&amp;gt;); obojętne, czy całkowita czy zmiennoprzecinkowa;&lt;br /&gt;
* każda liczba różna od zera jest prawdziwa (równoważna &amp;lt;tt&amp;gt;True&amp;lt;/tt&amp;gt;);&lt;br /&gt;
* napis pusty (o długości 0) jest fałszywy, każdy inny napis jest prawdziwy (również np. zawierający wyłącznie spacje);&lt;br /&gt;
* ogólniej &amp;amp;mdash; dowolnego typu kolekcja (lista, słownik, zbiór, ...) jest prawdziwa, o ile jest niepusta; każda kolekcja pusta (0-elementowa) jest fałszywa;&lt;br /&gt;
* wartość pusta czyli &amp;lt;tt&amp;gt;None&amp;lt;/tt&amp;gt; jest, jak nietrudno zgadnąć, fałszywa.&lt;br /&gt;
&lt;br /&gt;
W przypadku ogólniejszych typów danych (obiektów klas złożonych) sytuacja może już nie być taka prosta, ponieważ twórca klasy ma moc określenia reguły decydującej o prawdziwości / nieprawdziwości obiektów danej klasy. Ten temat jest na razie poza zakresem naszego kursu.&lt;br /&gt;
&lt;br /&gt;
Jeżeli chcemy wymusić, aby dana wartość stała się dosłownie wartością logiczną, tzn. jedną z (&amp;lt;tt&amp;gt;True&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;False&amp;lt;/tt&amp;gt;) w sposób zgodny z powyższymi regułami, można to osiągnąć przykładając funkcję &amp;lt;tt&amp;gt;bool&amp;lt;/tt&amp;gt;: a więc &amp;lt;tt&amp;gt;bool(wyrażenie)&amp;lt;/tt&amp;gt;. Rzadko jednak bywa to potrzebne.&lt;br /&gt;
&lt;br /&gt;
Reguła „skrótowej&amp;quot; ewaluacji wyrażeń logicznych, w połączeniu z regułami prawdziwości innych typów danych, pozwala na dość popularne idiomy, jak np.:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
# jeśli `wynik' jest niepustą listą to wypisze jej zawartość&lt;br /&gt;
# jeśli natomiast pustą, pojawi się komunikat&lt;br /&gt;
print(wynik or &amp;quot;wynik jest pusty!&amp;quot;)&lt;br /&gt;
&amp;lt;/source&amp;gt; &lt;br /&gt;
&lt;br /&gt;
które pozwalają uniknąć używania instrukcji złożonych w wielu prostych przypadkach. Działa to dzięki temu, że spójniki &amp;lt;tt&amp;gt;and&amp;lt;/tt&amp;gt; i &amp;lt;tt&amp;gt;or&amp;lt;/tt&amp;gt; nie wymuszają aby wynik był wartością logiczną:&lt;br /&gt;
&lt;br /&gt;
* jeżeli &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; jest prawdziwe, to &amp;lt;tt&amp;gt;a or b == a&amp;lt;/tt&amp;gt;, i &amp;lt;tt&amp;gt;a and b == b&amp;lt;/tt&amp;gt; dla każdego &amp;lt;tt&amp;gt;b&amp;lt;/tt&amp;gt;;&lt;br /&gt;
* jeżeli &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; jest fałszywe, to &amp;lt;tt&amp;gt;a and b == a&amp;lt;/tt&amp;gt;, i &amp;lt;tt&amp;gt;a or b == b&amp;lt;/tt&amp;gt; dla każdego &amp;lt;tt&amp;gt;b&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Inaczej w przypadku operatora &amp;lt;tt&amp;gt;not&amp;lt;/tt&amp;gt;: wynikiem jego działania jest zawsze jedna z wartości logicznych, podobnie jak w przypadku funkcji &amp;lt;tt&amp;gt;bool()&amp;lt;/tt&amp;gt; &amp;amp;mdash; tyle, że przeciwna.&lt;br /&gt;
&lt;br /&gt;
==Napisowe==&lt;br /&gt;
&lt;br /&gt;
Wartością wyrażenia może być również napis. Na przykład, &amp;lt;tt&amp;gt;a + b&amp;lt;/tt&amp;gt;, jeżeli &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; i &amp;lt;tt&amp;gt;b&amp;lt;/tt&amp;gt; są napisami, jest napisem utworzonym przez ich sklejenie (zauważmy, że w odróżnieniu od dodawania liczb nie jest to operacja przemienna). &lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&amp;lt;small&amp;gt;&lt;br /&gt;
Wcześniej wspomniano, że dwa napisy literalne postawione obok siebie zostaną automatycznie sklejone w jeden: np. &amp;lt;tt&amp;gt;'abc' &amp;quot;123&amp;quot;&amp;lt;/tt&amp;gt; jest równoważne &amp;lt;tt&amp;gt;'abc123'&amp;lt;/tt&amp;gt;. Nie stosuje się to jednak np. do zmiennych o wartościach napisowych: napisanie dwóch nazw obok siebie bez operatora pomiędzy nimi jest błędem składniowym. Jest tak, ponieważ wspomniane sklejenie napisów literalnych ma miejsce na etapie ''kompilacji'' kodu - tzn. wtedy, gdy interpreter analizuje zapis programu i przekłada go na instrukcje, jakie zostaną wykonane w etapie uruchomienia - a wartości stojące za nazwami zmiennych nie są na tym etapie jednoznacznie określone. &lt;br /&gt;
&amp;lt;/small&amp;gt;&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Bogatszy repertuar operacji tworzących wyrażenia o wartościach będących napisami poznamy dalej.&lt;br /&gt;
&lt;br /&gt;
==Inne wyrażenia==&lt;br /&gt;
&lt;br /&gt;
Oprócz liczb, napisów i wartości logicznych, Python posiada szereg dalszych, złożonych typów danych, które również mogą być wartościami wyrażeń. Wspomniano już przelotnie o kolekcjach (listy, słowniki, zbiory, ...) &amp;amp;mdash; służą one jako ,,pojemniki&amp;quot; do gromadzenia obiektów w zasadzie dowolnych typów, i zostaną omówione w dalszym ciągu. Istnieje też specjalny typ ''obiektu pustego'', mający dokładnie jednego reprezentanta: wartość specjalną &amp;lt;tt&amp;gt;None&amp;lt;/tt&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Każdy typ obiektu w Pythonie może być wartością odpowiednio zbudowanego wyrażenia. Gdy poznamy kolejne typy danych, wprowadzimy również operacje tworzące takie wyrażenia.&lt;br /&gt;
&lt;br /&gt;
=Ćwiczenia=&lt;br /&gt;
&lt;br /&gt;
1. Które z następujących są poprawnymi nazwami według reguł Pythona:&lt;br /&gt;
   nazwa1&lt;br /&gt;
   9sił&lt;br /&gt;
   dluga-nazwa&lt;br /&gt;
   wykonaj_rachunki&lt;br /&gt;
   _&lt;br /&gt;
   to&amp;amp;owo&lt;br /&gt;
   if &lt;br /&gt;
&lt;br /&gt;
2. Wykazać, że poniższe równości są równoważnościami -- tzn. że zachodzą dla dowolnej kombinacji wartości &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; i &amp;lt;tt&amp;gt;b&amp;lt;/tt&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
   not (a or b) == not a and not b&lt;br /&gt;
   not (a and b) == not a or not b&lt;br /&gt;
   a or not a == True&lt;br /&gt;
&lt;br /&gt;
''Wskazówka:'' stworzyć tabelki wartości wyrażeń po lewej i prawej stronie operatora porównania &amp;lt;tt&amp;gt;==&amp;lt;/tt&amp;gt; dla wszystkich możliwych kombinacji wartości &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; i &amp;lt;tt&amp;gt;b&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
3. Które z poniższych równości są tożsamościami, w wyniku działania reguł pierwszeństwa operatorów?&lt;br /&gt;
&lt;br /&gt;
   a / b / c == a / (b / c)&lt;br /&gt;
   a ** b / c == (a ** b) / c&lt;br /&gt;
   -a ** b == (-a) ** b&lt;br /&gt;
&lt;br /&gt;
''CDN...''&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
[[PPy3/PierwszeKroki|poprzednia]] | [[&amp;quot;Programowanie z Pythonem3&amp;quot;|Strona główna]] | [[PPy3/InstrukcjaWarunkowa|dalej]]&lt;br /&gt;
&lt;br /&gt;
--[[Użytkownik:RobertJB|RobertJB]] ([[Dyskusja użytkownika:RobertJB|dyskusja]]) 14:22, 21 cze 2016 (CEST)&lt;/div&gt;</summary>
		<author><name>RobertJB</name></author>
		
	</entry>
	<entry>
		<id>http://brain.fuw.edu.pl/edu/index.php?title=PPy3/PierwszeKroki&amp;diff=9330</id>
		<title>PPy3/PierwszeKroki</title>
		<link rel="alternate" type="text/html" href="http://brain.fuw.edu.pl/edu/index.php?title=PPy3/PierwszeKroki&amp;diff=9330"/>
		<updated>2023-05-10T10:07:07Z</updated>

		<summary type="html">&lt;p&gt;RobertJB: /* Używanie linii poleceń interpretera */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
= Pierwsze kroki =&lt;br /&gt;
&lt;br /&gt;
==Podstawowe cegiełki==&lt;br /&gt;
&lt;br /&gt;
*Program w Pythonie to tekst, stanowiący ciąg instrukcji; są one wykonywane przez ''interpreter'' (zasadniczo) kolejno jedna po drugiej.&lt;br /&gt;
*''Prosta'' instrukcja to (zasadniczo) jedna linijka, kończy się wraz z przejściem do kolejnej linii.&lt;br /&gt;
*Instrukcja złożona, to linijka otwierająca '''zawsze zakończona dwukropkiem''', a po niej - '''blok wcięty''', tj. ciąg instrukcji (prostych i/lub złożonych) pisanych z dodatkowym ''wcięciem'' w stosunku do linijki otwierającej; mogą to być dodatkowe (np. dwie lub cztery) spacje, lub kod tabulacji, na początku każdej linijki. Koniec instrukcji złożonej następuje wraz z powrotem do poprzedniego ''poziomu wcięcia''.&lt;br /&gt;
*W tekście programu można umieszczać komentarze; komentarz zaczyna się od znaku &amp;lt;tt&amp;gt;#&amp;lt;/tt&amp;gt;, a kończy się wraz z końcem bieżącej linii. Komentarze nie są częścią programu, tzn. są ignorowane przy jego wykonaniu.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&lt;br /&gt;
*Wyjątki od podanych reguł, istnienie których sygnalizuje słowo ''zasadniczo'', będą przedstawione później.&lt;br /&gt;
*Należy się raz zdecydować, jak dokładnie będziemy tworzyć poziomy wcięcia, i konsekwentnie się tego trzymać. Najlepiej po dwie lub cztery spacje (wg. upodobań), i ustawić w opcjach edytora kodu, żeby wciśnięcie klawisza ''Tab'' skutkowało odpowiednią liczbą spacji. Mieszanie w tekście kodu spacji i tabulacji zawsze prowadzi do kłopotów.&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Przykłady instrukcji prostych:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
x = 1 + 2&lt;br /&gt;
y = 2 * x&lt;br /&gt;
x = x + 1&lt;br /&gt;
print(x, y)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Przykłady instrukcji złożonych:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
if x &amp;gt; 0:&lt;br /&gt;
    print(x)&lt;br /&gt;
&lt;br /&gt;
def dodaj1(x):&lt;br /&gt;
    return x + 1&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ważnym elementem są komentarze:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
# a teraz, powiększę x o 1&lt;br /&gt;
x = x + 1&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*Instrukcje budowane są z wyrażeń, a wyrażenia - z nazw, stałych i operatorów.&lt;br /&gt;
*'''Nazwa''' może składać się z liter, cyfr i znaku podkreślenia (_). Nie może zaczynać się od cyfry. Litery małe i wielkie są rozróżniane.&lt;br /&gt;
*Przykładem stałych są liczby - całkowite i ułamki dziesiętne. Zamiast przecinkiem, część ułamkową oddziela się kropką.&lt;br /&gt;
*Inny rodzaj stałych to napisy. Można je budować na kilka sposobów:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
'to jest napis'&lt;br /&gt;
&amp;quot;to jest drugi napis&amp;quot;&lt;br /&gt;
'''a to jest...&lt;br /&gt;
jeszcze jeden napis'''&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*Ostatni przypadek to wyjątek od zasady że koniec linii kończy instrukcję. Napis podany w pierwszych dwóch postaciach nie może zawierać przejścia do nowej linii.&lt;br /&gt;
*Nazwy są po to, aby oznaczać nimi wartości. Wartościami mogą być np. liczby i napisy:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
pi = 3.14159&lt;br /&gt;
komunikat = 'Uwaga!!!'&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''UWAGA:''' znak równości to nie porównanie, a ''operator przypisania''. Powoduje on, że nazwa po jego lewej stronie będzie odtąd oznaczać wartość zapisaną po prawej. W szczególności, po lewej stronie znaku równości nie może występować np. stała liczba.&lt;br /&gt;
&lt;br /&gt;
*Więcej o stałych i nazwach na następnej stronie, na razie tyle nam wystarczy.&lt;br /&gt;
*Inne operatory, to w szczególności arytmetyka:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
+ - * /  // % **&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'*' to mnożenie, '//' to dzielenie całkowitoliczbowe, '%' to reszta z dzielenia (na ogół stosowana do liczb całkowitych, ale niekoniecznie), '**' to potęgowanie.&lt;br /&gt;
&lt;br /&gt;
*Napisy też można &amp;quot;dodawać&amp;quot;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
imie = 'Jacek'&lt;br /&gt;
powitanie = 'witaj ' + imie&lt;br /&gt;
print(powitanie)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;small&amp;gt;Czemu właściwie operację ,,sklejania&amp;quot; napisów oznaczono plusem? W matematyce zazwyczaj plus stosuje się na oznaczenie operacji przemiennych, tzn. takich, których wynik nie zależy od kolejności składników &amp;amp;mdash; a sklejanie napisów ewidentnie taką operacją nie jest. Ale cóż, tak się przyjęło.&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Używanie linii poleceń interpretera==&lt;br /&gt;
&lt;br /&gt;
''Interpreter'' to aplikacja, która potrafi czytać tekst kodu w języku Python i wykonać zapisane w nim polecenia. Może on być używany jako samodzielne polecenie, wywoływane w oknie terminala, lub zintegrowany z środowiskiem programistycznym w rodzaju ''Spyder'' lub ''Visual Studio Code''. &lt;br /&gt;
&lt;br /&gt;
Zanim zaczniemy pisać &amp;quot;poważne&amp;quot; programy, nauczymy się korzystać z ''trybu interaktywnego'' interpretera, który pozwala na wpisywanie po jednym poleceniu i natychmiastowe uzyskanie wyniku jego wykonania. Można go używać do podręcznych rachunków - zamiast kalkulatora -- i do eksperymentowania z kodem w Pythonie. Do pracy interaktywnej warto używać &amp;quot;wzbogaconej&amp;quot; wersji interpretera, wywoływanej poleceniem&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=bash&amp;gt;&lt;br /&gt;
$ ipython3&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
w najprostszych zastosowaniach niewiele się on różni od &amp;quot;zwykłego&amp;quot; interpretera, wywoływanego przez &amp;lt;tt&amp;gt;python3&amp;lt;/tt&amp;gt;, ale posiada pewne dodatkowe możliwości, które niedługo się nam przydadzą.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&lt;br /&gt;
'''UWAGA:''' polecenie &amp;lt;tt&amp;gt;ipython&amp;lt;/tt&amp;gt; (bez 3) wywoła starszą wersję Pythona. I odpowiednio - &amp;lt;tt&amp;gt;python&amp;lt;/tt&amp;gt; wywołuje starszą wersję &amp;quot;zwykłego&amp;quot; interpretera, a &amp;lt;tt&amp;gt;python3&amp;lt;/tt&amp;gt; - wersję aktualną. &lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Wykonywanie rachunków===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
$ ipython3&lt;br /&gt;
Python 3.5.1+ (default, Mar 30 2016, 22:46:26) &lt;br /&gt;
Type &amp;quot;copyright&amp;quot;, &amp;quot;credits&amp;quot; or &amp;quot;license&amp;quot; for more information.&lt;br /&gt;
&lt;br /&gt;
IPython 2.4.1 -- An enhanced Interactive Python.&lt;br /&gt;
?         -&amp;gt; Introduction and overview of IPython's features.&lt;br /&gt;
%quickref -&amp;gt; Quick reference.&lt;br /&gt;
help      -&amp;gt; Python's own help system.&lt;br /&gt;
object?   -&amp;gt; Details about 'object', use 'object??' for extra details.&lt;br /&gt;
&lt;br /&gt;
In [1]: 7 * (3 + 5)&lt;br /&gt;
Out[1]: 56&lt;br /&gt;
&lt;br /&gt;
In [2]: 2.81 / (1.25 - .33)&lt;br /&gt;
Out[2]: 3.054347826086957&lt;br /&gt;
&lt;br /&gt;
In [3]: 2**128&lt;br /&gt;
Out[3]: 340282366920938463463374607431768211456&lt;br /&gt;
&lt;br /&gt;
In [4]: 1/9&lt;br /&gt;
Out[4]: 0.1111111111111111&lt;br /&gt;
&lt;br /&gt;
In [5]: 11//9, 11%9&lt;br /&gt;
Out[5]: (1, 2)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Zapis wyrażeń arytmetycznych raczej nie zaskakuje. Drobne uwagi:&lt;br /&gt;
&lt;br /&gt;
*spacje w zapisie wyrażenia, pomiędzy liczbami a operatorami (lub ich brak), nie mają znaczenia&lt;br /&gt;
*reguły pierwszeństwa operatorów (najpierw potęgowanie, potem mnożenie i dzielenie, potem odejmowanie i dodawanie,...) są w zasadzie takie, jak należy się spodziewać; kolejność operacji możemy narzucić nawiasami - ale tylko okrągłymi, które można wielokrotnie zagnieżdżać&lt;br /&gt;
*pisząc ułamek dziesiętny (liczbę z kropką), można pominąć część całkowitą lub ułamkową, o ile ma ona być zero (nie można jednak pominąć obu);&lt;br /&gt;
*liczby całkowite mogą być dowolnie duże (w ramach fizycznych ograniczeń komputera)&lt;br /&gt;
*operacje na ułamkach należy zawsze traktować jako przybliżone - w operacjach na liczbach ułamkowych komputer może ogarnąć tylko skończoną liczbę cyfr&lt;br /&gt;
*zwykłe dzielenie da zawsze wynik ułamkowy; istnieje jednak operator &amp;lt;tt&amp;gt;//&amp;lt;/tt&amp;gt; dzielenia całkowitego, który odrzuca resztę&lt;br /&gt;
*gdy chcemy zakończyć &amp;quot;rozmowę&amp;quot; z interpreterem, piszemy &amp;lt;tt&amp;gt;exit()&amp;lt;/tt&amp;gt;; jeżeli pracujemy w Linuxie, zadziała również dwukrotne &amp;lt;tt&amp;gt;Ctrl-D&amp;lt;/tt&amp;gt; (tzn. trzymając naciśnięty klawisz &amp;lt;tt&amp;gt;Ctrl&amp;lt;/tt&amp;gt; stukamy dwukrotnie w klawisz &amp;lt;tt&amp;gt;D&amp;lt;/tt&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
==Jak uzyskać pomoc==&lt;br /&gt;
&lt;br /&gt;
W programie IPython mamy w każdej chwili dostęp do pomocy na temat poleceń, funkcji itd. Pythona:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
In [8]: print?&lt;br /&gt;
Type:        builtin_function_or_method&lt;br /&gt;
String form: &amp;lt;built-in function print&amp;gt;&lt;br /&gt;
Namespace:   Python builtin&lt;br /&gt;
Docstring:&lt;br /&gt;
print(value, ..., sep=' ', end='\n', file=sys.stdout, flush=False)&lt;br /&gt;
&lt;br /&gt;
Prints the values to a stream, or to sys.stdout by default.&lt;br /&gt;
Optional keyword arguments:&lt;br /&gt;
file:  a file-like object (stream); defaults to the current sys.stdout.&lt;br /&gt;
sep:   string inserted between values, default a space.&lt;br /&gt;
end:   string appended after the last value, default a newline.&lt;br /&gt;
flush: whether to forcibly flush the stream.&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
W tym przykładzie uzyskaliśmy szczegółowy opis zastosowania funkcji wbudowanej &amp;lt;tt&amp;gt;print&amp;lt;/tt&amp;gt;. Wprawdzie po angielsku, ale mam nadzieję, że nie jest to przeszkoda nie do przeskoczenia. Już niedługo będziemy dokładnie rozumieli to, co jest tu napisane.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&lt;br /&gt;
Jeżeli tekst pomocy jest dłuższy, to będzie wyświetlany w trybie pozwalającym m. in. na jego przewijanie z użyciem klawiszy strzałek czy &amp;lt;tt&amp;gt;PgUp&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;PgDn&amp;lt;/tt&amp;gt;. Aby wyjść z tego trybu i powrócić do interpretera, wystarczy nacisnąć &amp;lt;tt&amp;gt;q&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Najprostszy program==&lt;br /&gt;
&lt;br /&gt;
Za pomocą ulubionego edytora tekstowego stwórzmy plik o nazwie &amp;lt;tt&amp;gt;hello.py&amp;lt;/tt&amp;gt; i następującej treści:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
#! /usr/bin/python3&lt;br /&gt;
&lt;br /&gt;
print('Witaj świecie!')&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Zgodnie z tradycją, będzie to program wykonujący jedno banalne zadanie: wypisanie komunikatu o ustalonej treści. Zgodnie z zasadą, że programowanie w Pythonie ma być maksymalnie proste - jedynym niezbędnym elementem tego programu jest linijka wywołująca funkcję &amp;lt;tt&amp;gt;print&amp;lt;/tt&amp;gt;. W tym przykładzie, uzupełniłem treść programu o pierwszą linijkę, zaczynającą się od znaku kratki (&amp;lt;tt&amp;gt;#&amp;lt;/tt&amp;gt;) - istotne jest, aby była to dokładnie pierwsza linijka w pliku, i by zaczynała się od pierwszej pozycji w wierszu. Czyli, aby &amp;lt;tt&amp;gt;#!&amp;lt;/tt&amp;gt; były dokładnie dwoma pierwszymi znakami w treści pliku. Z punktu widzenia Pythona, linijka ta jest komentarzem, i przy uruchamianiu pliku jest ignorowana. Pozwala ona jednak, by plik ten był automatycznie rozpoznawany przez system operacyjny (Linux) jako zawierający program w języku Python. Jaki z tego pożytek, dowiemy się za chwilę.&lt;br /&gt;
&lt;br /&gt;
Aby ten program uruchomić, jest parę sposobów. Najprościej:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=bash&amp;gt;&lt;br /&gt;
$ python3 hello.py&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
powyższe polecenie wpisujemy w terminalu, w trybie powłoki systemowej (''nie w programie IPython!''). Tutaj musieliśmy jawnie wywołać interpreter Pythona i wskazać mu plik &amp;lt;tt&amp;gt;hello.py&amp;lt;/tt&amp;gt; jako zawierający kod do uruchomienia.&lt;br /&gt;
&lt;br /&gt;
Zamiast tego, możemy nadać plikowi &amp;lt;tt&amp;gt;hello.py&amp;lt;/tt&amp;gt; atrybut pliku wykonywalnego, czyli programu, i uruchomić go bezpośrednio:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=bash&amp;gt;&lt;br /&gt;
$ chmod +x hello.py&lt;br /&gt;
$ ./hello.py&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*Polecenie z pierwszej linijki wystarczy wykonać raz dla danego pliku&lt;br /&gt;
*Zamiast z linii poleceń, można w okienku ''Właściwości'' pliku znaleźć odpowiednie pole do kliknięcia&lt;br /&gt;
*Postać drugiej linijki tłumaczy się tym, że nasz program &amp;lt;tt&amp;gt;hello.py&amp;lt;/tt&amp;gt; nie jest zainstalowany w systemie i nie zostanie odnaleziony przez przeszukanie standardowych lokalizacji programów na dysku. Należy wyraźnie wskazać, że chodzi o plik znajdujący się w bieżącym folderze - i to tu robimy.&lt;br /&gt;
*Plik z kodem w Pythonie nie musi mieć nazwy kończącej się na &amp;lt;tt&amp;gt;.py&amp;lt;/tt&amp;gt; - jest to jednak wygodne, bo np. edytory tekstu traktują to jako sugestię co do zawartości pliku, i mogą dostosować do tego swoje działanie (np. &amp;lt;tt&amp;gt;gedit&amp;lt;/tt&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
==Ćwiczenia==&lt;br /&gt;
&lt;br /&gt;
===Rachunki w linii poleceń===&lt;br /&gt;
&lt;br /&gt;
#Ile wynosi reszta z dzielenia 2&amp;lt;sup&amp;gt;999&amp;lt;/sup&amp;gt; przez 7?&lt;br /&gt;
#Która z tych liczb mniej się różni od pierwiastka kwadratowego z 2: 721/510 czy 722/510?&lt;br /&gt;
#Oblicz pierwiastek kwadratowy z 2, a następnie - podnieś go do kwadratu; ile wynosi względny błąd wyniku?&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
''CDN''&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
[[PPy3/Wprowadzenie|poprzednia]] | [[&amp;quot;Programowanie z Pythonem3&amp;quot;|Strona główna]] | [[PPy3/StałeIZmienne|dalej]]&lt;br /&gt;
&lt;br /&gt;
--[[Użytkownik:RobertJB|RobertJB]] ([[Dyskusja użytkownika:RobertJB|dyskusja]]) 13:53, 15 cze 2016 (CEST)&lt;/div&gt;</summary>
		<author><name>RobertJB</name></author>
		
	</entry>
	<entry>
		<id>http://brain.fuw.edu.pl/edu/index.php?title=PPy3/PierwszeKroki&amp;diff=9329</id>
		<title>PPy3/PierwszeKroki</title>
		<link rel="alternate" type="text/html" href="http://brain.fuw.edu.pl/edu/index.php?title=PPy3/PierwszeKroki&amp;diff=9329"/>
		<updated>2023-05-10T09:55:43Z</updated>

		<summary type="html">&lt;p&gt;RobertJB: /* Podstawowe cegiełki */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
= Pierwsze kroki =&lt;br /&gt;
&lt;br /&gt;
==Podstawowe cegiełki==&lt;br /&gt;
&lt;br /&gt;
*Program w Pythonie to tekst, stanowiący ciąg instrukcji; są one wykonywane przez ''interpreter'' (zasadniczo) kolejno jedna po drugiej.&lt;br /&gt;
*''Prosta'' instrukcja to (zasadniczo) jedna linijka, kończy się wraz z przejściem do kolejnej linii.&lt;br /&gt;
*Instrukcja złożona, to linijka otwierająca '''zawsze zakończona dwukropkiem''', a po niej - '''blok wcięty''', tj. ciąg instrukcji (prostych i/lub złożonych) pisanych z dodatkowym ''wcięciem'' w stosunku do linijki otwierającej; mogą to być dodatkowe (np. dwie lub cztery) spacje, lub kod tabulacji, na początku każdej linijki. Koniec instrukcji złożonej następuje wraz z powrotem do poprzedniego ''poziomu wcięcia''.&lt;br /&gt;
*W tekście programu można umieszczać komentarze; komentarz zaczyna się od znaku &amp;lt;tt&amp;gt;#&amp;lt;/tt&amp;gt;, a kończy się wraz z końcem bieżącej linii. Komentarze nie są częścią programu, tzn. są ignorowane przy jego wykonaniu.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&lt;br /&gt;
*Wyjątki od podanych reguł, istnienie których sygnalizuje słowo ''zasadniczo'', będą przedstawione później.&lt;br /&gt;
*Należy się raz zdecydować, jak dokładnie będziemy tworzyć poziomy wcięcia, i konsekwentnie się tego trzymać. Najlepiej po dwie lub cztery spacje (wg. upodobań), i ustawić w opcjach edytora kodu, żeby wciśnięcie klawisza ''Tab'' skutkowało odpowiednią liczbą spacji. Mieszanie w tekście kodu spacji i tabulacji zawsze prowadzi do kłopotów.&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Przykłady instrukcji prostych:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
x = 1 + 2&lt;br /&gt;
y = 2 * x&lt;br /&gt;
x = x + 1&lt;br /&gt;
print(x, y)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Przykłady instrukcji złożonych:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
if x &amp;gt; 0:&lt;br /&gt;
    print(x)&lt;br /&gt;
&lt;br /&gt;
def dodaj1(x):&lt;br /&gt;
    return x + 1&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ważnym elementem są komentarze:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
# a teraz, powiększę x o 1&lt;br /&gt;
x = x + 1&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*Instrukcje budowane są z wyrażeń, a wyrażenia - z nazw, stałych i operatorów.&lt;br /&gt;
*'''Nazwa''' może składać się z liter, cyfr i znaku podkreślenia (_). Nie może zaczynać się od cyfry. Litery małe i wielkie są rozróżniane.&lt;br /&gt;
*Przykładem stałych są liczby - całkowite i ułamki dziesiętne. Zamiast przecinkiem, część ułamkową oddziela się kropką.&lt;br /&gt;
*Inny rodzaj stałych to napisy. Można je budować na kilka sposobów:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
'to jest napis'&lt;br /&gt;
&amp;quot;to jest drugi napis&amp;quot;&lt;br /&gt;
'''a to jest...&lt;br /&gt;
jeszcze jeden napis'''&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*Ostatni przypadek to wyjątek od zasady że koniec linii kończy instrukcję. Napis podany w pierwszych dwóch postaciach nie może zawierać przejścia do nowej linii.&lt;br /&gt;
*Nazwy są po to, aby oznaczać nimi wartości. Wartościami mogą być np. liczby i napisy:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
pi = 3.14159&lt;br /&gt;
komunikat = 'Uwaga!!!'&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''UWAGA:''' znak równości to nie porównanie, a ''operator przypisania''. Powoduje on, że nazwa po jego lewej stronie będzie odtąd oznaczać wartość zapisaną po prawej. W szczególności, po lewej stronie znaku równości nie może występować np. stała liczba.&lt;br /&gt;
&lt;br /&gt;
*Więcej o stałych i nazwach na następnej stronie, na razie tyle nam wystarczy.&lt;br /&gt;
*Inne operatory, to w szczególności arytmetyka:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
+ - * /  // % **&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'*' to mnożenie, '//' to dzielenie całkowitoliczbowe, '%' to reszta z dzielenia (na ogół stosowana do liczb całkowitych, ale niekoniecznie), '**' to potęgowanie.&lt;br /&gt;
&lt;br /&gt;
*Napisy też można &amp;quot;dodawać&amp;quot;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
imie = 'Jacek'&lt;br /&gt;
powitanie = 'witaj ' + imie&lt;br /&gt;
print(powitanie)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;small&amp;gt;Czemu właściwie operację ,,sklejania&amp;quot; napisów oznaczono plusem? W matematyce zazwyczaj plus stosuje się na oznaczenie operacji przemiennych, tzn. takich, których wynik nie zależy od kolejności składników &amp;amp;mdash; a sklejanie napisów ewidentnie taką operacją nie jest. Ale cóż, tak się przyjęło.&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Używanie linii poleceń interpretera==&lt;br /&gt;
&lt;br /&gt;
''Interpreter'' to aplikacja, która potrafi czytać tekst kodu w języku Python i wykonać zapisane w nim polecenia. Może on być używany jako samodzielne polecenie, wywoływane w oknie terminala, lub zintegrowany z środowiskiem programistycznym w rodzaju ''Spyder''. &lt;br /&gt;
&lt;br /&gt;
Zanim zaczniemy pisać &amp;quot;poważne&amp;quot; programy, nauczymy się korzystać z ''trybu interaktywnego'' interpretera, który pozwala na wpisywanie po jednym poleceniu i natychmiastowe uzyskanie wyniku jego wykonania. Można go używać do podręcznych rachunków - zamiast kalkulatora -- i do eksperymentowania z kodem w Pythonie. Do pracy interaktywnej warto używać &amp;quot;wzbogaconej&amp;quot; wersji interpretera, wywoływanej poleceniem&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=bash&amp;gt;&lt;br /&gt;
$ ipython3&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
w najprostszych zastosowaniach niewiele się on różni od &amp;quot;zwykłego&amp;quot; interpretera, wywoływanego przez &amp;lt;tt&amp;gt;python3&amp;lt;/tt&amp;gt;, ale posiada pewne dodatkowe możliwości, które niedługo się nam przydadzą.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&lt;br /&gt;
'''UWAGA:''' polecenie &amp;lt;tt&amp;gt;ipython&amp;lt;/tt&amp;gt; (bez 3) wywoła starszą wersję Pythona. I odpowiednio - &amp;lt;tt&amp;gt;python&amp;lt;/tt&amp;gt; wywołuje starszą wersję &amp;quot;zwykłego&amp;quot; interpretera, a &amp;lt;tt&amp;gt;python3&amp;lt;/tt&amp;gt; - wersję aktualną. &lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Wykonywanie rachunków===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
$ ipython3&lt;br /&gt;
Python 3.5.1+ (default, Mar 30 2016, 22:46:26) &lt;br /&gt;
Type &amp;quot;copyright&amp;quot;, &amp;quot;credits&amp;quot; or &amp;quot;license&amp;quot; for more information.&lt;br /&gt;
&lt;br /&gt;
IPython 2.4.1 -- An enhanced Interactive Python.&lt;br /&gt;
?         -&amp;gt; Introduction and overview of IPython's features.&lt;br /&gt;
%quickref -&amp;gt; Quick reference.&lt;br /&gt;
help      -&amp;gt; Python's own help system.&lt;br /&gt;
object?   -&amp;gt; Details about 'object', use 'object??' for extra details.&lt;br /&gt;
&lt;br /&gt;
In [1]: 7 * (3 + 5)&lt;br /&gt;
Out[1]: 56&lt;br /&gt;
&lt;br /&gt;
In [2]: 2.81 / (1.25 - .33)&lt;br /&gt;
Out[2]: 3.054347826086957&lt;br /&gt;
&lt;br /&gt;
In [3]: 2**128&lt;br /&gt;
Out[3]: 340282366920938463463374607431768211456&lt;br /&gt;
&lt;br /&gt;
In [4]: 1/9&lt;br /&gt;
Out[4]: 0.1111111111111111&lt;br /&gt;
&lt;br /&gt;
In [5]: 11//9, 11%9&lt;br /&gt;
Out[5]: (1, 2)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Zapis wyrażeń arytmetycznych raczej nie zaskakuje. Drobne uwagi:&lt;br /&gt;
&lt;br /&gt;
*spacje w zapisie wyrażenia, pomiędzy liczbami a operatorami (lub ich brak), nie mają znaczenia&lt;br /&gt;
*reguły pierwszeństwa operatorów (najpierw potęgowanie, potem mnożenie i dzielenie, potem odejmowanie i dodawanie,...) są w zasadzie takie, jak należy się spodziewać; kolejność operacji możemy narzucić nawiasami - ale tylko okrągłymi, które można wielokrotnie zagnieżdżać&lt;br /&gt;
*pisząc ułamek dziesiętny (liczbę z kropką), można pominąć część całkowitą lub ułamkową, o ile ma ona być zero (nie można jednak pominąć obu);&lt;br /&gt;
*liczby całkowite mogą być dowolnie duże (w ramach fizycznych ograniczeń komputera)&lt;br /&gt;
*operacje na ułamkach należy zawsze traktować jako przybliżone - komputer może ogarnąć tylko skończoną liczbę cyfr&lt;br /&gt;
*zwykłe dzielenie da zawsze wynik ułamkowy; istnieje jednak operator &amp;lt;tt&amp;gt;//&amp;lt;/tt&amp;gt; dzielenia całkowitego&lt;br /&gt;
*gdy chcemy zakończyć &amp;quot;rozmowę&amp;quot; z interpreterem, piszemy &amp;lt;tt&amp;gt;exit()&amp;lt;/tt&amp;gt;; jeżeli pracujemy w Linuxie, zadziała również dwukrotne &amp;lt;tt&amp;gt;Ctrl-D&amp;lt;/tt&amp;gt; (tzn. trzymając naciśnięty klawisz &amp;lt;tt&amp;gt;Ctrl&amp;lt;/tt&amp;gt; stukamy dwukrotnie w klawisz &amp;lt;tt&amp;gt;D&amp;lt;/tt&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
==Jak uzyskać pomoc==&lt;br /&gt;
&lt;br /&gt;
W programie IPython mamy w każdej chwili dostęp do pomocy na temat poleceń, funkcji itd. Pythona:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
In [8]: print?&lt;br /&gt;
Type:        builtin_function_or_method&lt;br /&gt;
String form: &amp;lt;built-in function print&amp;gt;&lt;br /&gt;
Namespace:   Python builtin&lt;br /&gt;
Docstring:&lt;br /&gt;
print(value, ..., sep=' ', end='\n', file=sys.stdout, flush=False)&lt;br /&gt;
&lt;br /&gt;
Prints the values to a stream, or to sys.stdout by default.&lt;br /&gt;
Optional keyword arguments:&lt;br /&gt;
file:  a file-like object (stream); defaults to the current sys.stdout.&lt;br /&gt;
sep:   string inserted between values, default a space.&lt;br /&gt;
end:   string appended after the last value, default a newline.&lt;br /&gt;
flush: whether to forcibly flush the stream.&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
W tym przykładzie uzyskaliśmy szczegółowy opis zastosowania funkcji wbudowanej &amp;lt;tt&amp;gt;print&amp;lt;/tt&amp;gt;. Wprawdzie po angielsku, ale mam nadzieję, że nie jest to przeszkoda nie do przeskoczenia. Już niedługo będziemy dokładnie rozumieli to, co jest tu napisane.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&lt;br /&gt;
Jeżeli tekst pomocy jest dłuższy, to będzie wyświetlany w trybie pozwalającym m. in. na jego przewijanie z użyciem klawiszy strzałek czy &amp;lt;tt&amp;gt;PgUp&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;PgDn&amp;lt;/tt&amp;gt;. Aby wyjść z tego trybu i powrócić do interpretera, wystarczy nacisnąć &amp;lt;tt&amp;gt;q&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Najprostszy program==&lt;br /&gt;
&lt;br /&gt;
Za pomocą ulubionego edytora tekstowego stwórzmy plik o nazwie &amp;lt;tt&amp;gt;hello.py&amp;lt;/tt&amp;gt; i następującej treści:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
#! /usr/bin/python3&lt;br /&gt;
&lt;br /&gt;
print('Witaj świecie!')&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Zgodnie z tradycją, będzie to program wykonujący jedno banalne zadanie: wypisanie komunikatu o ustalonej treści. Zgodnie z zasadą, że programowanie w Pythonie ma być maksymalnie proste - jedynym niezbędnym elementem tego programu jest linijka wywołująca funkcję &amp;lt;tt&amp;gt;print&amp;lt;/tt&amp;gt;. W tym przykładzie, uzupełniłem treść programu o pierwszą linijkę, zaczynającą się od znaku kratki (&amp;lt;tt&amp;gt;#&amp;lt;/tt&amp;gt;) - istotne jest, aby była to dokładnie pierwsza linijka w pliku, i by zaczynała się od pierwszej pozycji w wierszu. Czyli, aby &amp;lt;tt&amp;gt;#!&amp;lt;/tt&amp;gt; były dokładnie dwoma pierwszymi znakami w treści pliku. Z punktu widzenia Pythona, linijka ta jest komentarzem, i przy uruchamianiu pliku jest ignorowana. Pozwala ona jednak, by plik ten był automatycznie rozpoznawany przez system operacyjny (Linux) jako zawierający program w języku Python. Jaki z tego pożytek, dowiemy się za chwilę.&lt;br /&gt;
&lt;br /&gt;
Aby ten program uruchomić, jest parę sposobów. Najprościej:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=bash&amp;gt;&lt;br /&gt;
$ python3 hello.py&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
powyższe polecenie wpisujemy w terminalu, w trybie powłoki systemowej (''nie w programie IPython!''). Tutaj musieliśmy jawnie wywołać interpreter Pythona i wskazać mu plik &amp;lt;tt&amp;gt;hello.py&amp;lt;/tt&amp;gt; jako zawierający kod do uruchomienia.&lt;br /&gt;
&lt;br /&gt;
Zamiast tego, możemy nadać plikowi &amp;lt;tt&amp;gt;hello.py&amp;lt;/tt&amp;gt; atrybut pliku wykonywalnego, czyli programu, i uruchomić go bezpośrednio:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=bash&amp;gt;&lt;br /&gt;
$ chmod +x hello.py&lt;br /&gt;
$ ./hello.py&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*Polecenie z pierwszej linijki wystarczy wykonać raz dla danego pliku&lt;br /&gt;
*Zamiast z linii poleceń, można w okienku ''Właściwości'' pliku znaleźć odpowiednie pole do kliknięcia&lt;br /&gt;
*Postać drugiej linijki tłumaczy się tym, że nasz program &amp;lt;tt&amp;gt;hello.py&amp;lt;/tt&amp;gt; nie jest zainstalowany w systemie i nie zostanie odnaleziony przez przeszukanie standardowych lokalizacji programów na dysku. Należy wyraźnie wskazać, że chodzi o plik znajdujący się w bieżącym folderze - i to tu robimy.&lt;br /&gt;
*Plik z kodem w Pythonie nie musi mieć nazwy kończącej się na &amp;lt;tt&amp;gt;.py&amp;lt;/tt&amp;gt; - jest to jednak wygodne, bo np. edytory tekstu traktują to jako sugestię co do zawartości pliku, i mogą dostosować do tego swoje działanie (np. &amp;lt;tt&amp;gt;gedit&amp;lt;/tt&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
==Ćwiczenia==&lt;br /&gt;
&lt;br /&gt;
===Rachunki w linii poleceń===&lt;br /&gt;
&lt;br /&gt;
#Ile wynosi reszta z dzielenia 2&amp;lt;sup&amp;gt;999&amp;lt;/sup&amp;gt; przez 7?&lt;br /&gt;
#Która z tych liczb mniej się różni od pierwiastka kwadratowego z 2: 721/510 czy 722/510?&lt;br /&gt;
#Oblicz pierwiastek kwadratowy z 2, a następnie - podnieś go do kwadratu; ile wynosi względny błąd wyniku?&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
''CDN''&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
[[PPy3/Wprowadzenie|poprzednia]] | [[&amp;quot;Programowanie z Pythonem3&amp;quot;|Strona główna]] | [[PPy3/StałeIZmienne|dalej]]&lt;br /&gt;
&lt;br /&gt;
--[[Użytkownik:RobertJB|RobertJB]] ([[Dyskusja użytkownika:RobertJB|dyskusja]]) 13:53, 15 cze 2016 (CEST)&lt;/div&gt;</summary>
		<author><name>RobertJB</name></author>
		
	</entry>
	<entry>
		<id>http://brain.fuw.edu.pl/edu/index.php?title=PPy3/InstrukcjaWarunkowa&amp;diff=8944</id>
		<title>PPy3/InstrukcjaWarunkowa</title>
		<link rel="alternate" type="text/html" href="http://brain.fuw.edu.pl/edu/index.php?title=PPy3/InstrukcjaWarunkowa&amp;diff=8944"/>
		<updated>2022-10-19T07:16:48Z</updated>

		<summary type="html">&lt;p&gt;RobertJB: /* Ćwiczenia */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=Instrukcja warunkowa=&lt;br /&gt;
&lt;br /&gt;
Zasadniczo każdy program w Pythonie składa się z ciągu instrukcji, które są wykonywane w kolejności, w jakiej zostały zapisane. W programowaniu potrzebna jest jednak możliwość podejmowania decyzji o przyjęciu różnych kursów postępowania, w zależności od danych z jakimi mamy do czynienia. Umożliwiają to instrukcje złożone, a szczególnie - instrukcja warunkowa.&lt;br /&gt;
&lt;br /&gt;
Instrukcja warunkowa to pierwszy przykład instrukcji złożonej. W najprostszej postaci składa się ona z ciągu (jednej lub więcej) instrukcji ujętych w blok, który jako całość będzie wykonany lub nie, w zależności od tego, czy spełniony jest pewien warunek - co zależy zazwyczaj od aktualnych wartości pewnych zmiennych. Warunek ten zapisuje się w postaci wyrażenia logicznego.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&amp;lt;small&amp;gt;&lt;br /&gt;
Wśród instrukcji tworzących blok warunkowy mogą oczywiście się pojawić również instrukcje złożone, nie tylko instrukcje proste. Na przykład, kolejne instrukcje warunkowe.&lt;br /&gt;
&amp;lt;/small&amp;gt;&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Przykład minimalny:==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
x1, x2 = None, None&lt;br /&gt;
if delta &amp;gt; 0 and not a == 0:&lt;br /&gt;
    x1 = (-b + delta) / 2 / a&lt;br /&gt;
    x2 = (-b - delta) / 2 / a&lt;br /&gt;
print(x1, x2)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Linijka z wywołaniem &amp;lt;tt&amp;gt;print&amp;lt;/tt&amp;gt; nie jest już częścią instrukcji warunkowej, tylko kolejną instrukcją.&lt;br /&gt;
&lt;br /&gt;
'''Do zapamiętania''':&lt;br /&gt;
*wiersz otwierający instrukcję złożoną (czyli tu: zaczynająca się od &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt;) zawsze kończy się dwukropkiem&lt;br /&gt;
*instrukcje tworzące blok w instrukcji złożonej są pisane z wcięciem, które musi być jednolite&lt;br /&gt;
*koniec bloku rozpoznaje się po powrocie do uprzedniego poziomu wcięcia&lt;br /&gt;
*blok instrukcji pod &amp;lt;tt&amp;gt;if ...&amp;lt;/tt&amp;gt; nie może być pusty. Instrukcja &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt; z pustym blokiem warunkowym jest nie tylko nieprzydatna, ale jest również błędem składniowym.&lt;br /&gt;
&lt;br /&gt;
==Przykład bardziej złożony:==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
if a == 0:&lt;br /&gt;
    print('Równanie nie jest kwadratowe.')&lt;br /&gt;
elif delta &amp;gt; 0 and not a == 0:&lt;br /&gt;
    x1 = (-b + delta) / 2 / a&lt;br /&gt;
    x2 = (-b - delta) / 2 / a&lt;br /&gt;
    print('Są dwa pierwiastki: x1 =', x1, 'x2 =', x2)&lt;br /&gt;
elif delta == 0:&lt;br /&gt;
    x = -b / 2 / a&lt;br /&gt;
    print('Jest tylko jeden pierwiastek: x =', x)&lt;br /&gt;
else: # delta &amp;lt; 0:&lt;br /&gt;
    print('Nie ma pierwiastków rzeczywistych.')&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Jak to działa?&lt;br /&gt;
&lt;br /&gt;
*Jeżeli spełniony jest warunek &amp;lt;tt&amp;gt;a == 0&amp;lt;/tt&amp;gt;, wykonany zostanie blok poniżej &amp;lt;tt&amp;gt;if ...&amp;lt;/tt&amp;gt;, a reszta instrukcji zostanie pominięta;&lt;br /&gt;
*Jeżeli warunek ten jest nieprawdziwy (i tylko wtedy), to sprawdzane są kolejno warunki umieszczone w wierszach zaczynających się od &amp;lt;tt&amp;gt;elif&amp;lt;/tt&amp;gt;. Jeśli któryś z nich okaże się prawdziwy, to blok poniżej tej linijki zostanie wykonany, a cała reszta - pominięta;&lt;br /&gt;
*Jeżeli żaden z warunków - tych po &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt;, i tych po wszystkich &amp;lt;tt&amp;gt;elif&amp;lt;/tt&amp;gt; - nie okazał się prawdziwy, wykonany zostanie blok związany z &amp;lt;tt&amp;gt;else&amp;lt;/tt&amp;gt;.&lt;br /&gt;
*Bloków &amp;lt;tt&amp;gt;elif&amp;lt;/tt&amp;gt; może być w instrukcji dowolnie wiele (w tym - wcale), &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt; jest obowiązkowy (inaczej nie byłoby instrukcji warunkowej) i tylko jeden, &amp;lt;tt&amp;gt;else&amp;lt;/tt&amp;gt; może wystąpić wyłącznie na końcu - jeden raz, lub wcale.&lt;br /&gt;
*Komentarz po &amp;lt;tt&amp;gt;else:&amp;lt;/tt&amp;gt; jest podpowiedzią dla czytającego, że skoro już zbadano warunki &amp;lt;tt&amp;gt;delta == 0&amp;lt;/tt&amp;gt; oraz &amp;lt;tt&amp;gt;delta &amp;gt; 0&amp;lt;/tt&amp;gt;, a wykonanie dotarło do tej linijki, to &amp;lt;tt&amp;gt;delta &amp;lt; 0&amp;lt;/tt&amp;gt; jest jedyną pozostałą możliwością (o ile możemy założyć, że &amp;lt;tt&amp;gt;delta&amp;lt;/tt&amp;gt; jest na pewno liczbą!). Jest on przeznaczony wyłącznie dla ludzkich oczu - interpreter go zignoruje, jak każdy komentarz.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&amp;lt;small&amp;gt;&lt;br /&gt;
Mam nadzieję, że czytający już zauważył, że &amp;lt;tt&amp;gt;and not a == 0&amp;lt;/tt&amp;gt; w trzeciej linijce jest niepotrzebne. Dlaczego?&lt;br /&gt;
&amp;lt;/small&amp;gt;&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Wyrażenie warunkowe==&lt;br /&gt;
&lt;br /&gt;
Innym sposobem uzależnienia wyniku działania od jakiegoś warunku jest tzw. ''wyrażenie warunkowe''. Jest ono szczególnie wygodne w prostych przypadkach, i pozwala zapisać pewne działania w bardziej zwięzły sposób. &lt;br /&gt;
&lt;br /&gt;
Przykład: chcemy, aby z nazwą &amp;lt;tt&amp;gt;wbx&amp;lt;/tt&amp;gt; wiązała się wartość bezwzględna (moduł) aktualnej wartości (liczby) &amp;lt;tt&amp;gt;x&amp;lt;/tt&amp;gt;. Za pomocą instrukcji warunkowej można to zrealizować tak:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
if x &amp;lt; 0:&lt;br /&gt;
    wbx = -x&lt;br /&gt;
else:&lt;br /&gt;
    wbx = x&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ten sam wynik można osiągnąć za pomocą wyrażenia warunkowego:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
wbx = -x if x &amp;lt; 0 else x&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
W wyrażeniu warunkowym nie ma opcji uwzględnienie dodatkowych możliwości za pomocą &amp;lt;tt&amp;gt;elif&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=Ćwiczenia=&lt;br /&gt;
&lt;br /&gt;
W programach ćwiczebnych nieraz przyda nam się funkcja &amp;lt;tt&amp;gt;input()&amp;lt;/tt&amp;gt;. Działa ona w sposób następujący: argumentem wywołania powinien być jakiś napis (np. w postaci stałej napisowej): &amp;lt;tt&amp;gt;input('podaj jakąś liczbę całkowitą: ')&amp;lt;/tt&amp;gt;. Gdy w programie przyjdzie kolej na wykonanie takiego wywołania, program wypisze ten napis do terminalu i będzie oczekiwał na reakcję użytkownika, czyli wpisanie czegoś z klawiatury (i zakończenie naciśnięciem klawisza ''Enter''). Gdy to nastąpi, wynikiem wywołania funkcji &amp;lt;tt&amp;gt;input&amp;lt;/tt&amp;gt; w programie będzie treść wpisana prze użytkownika (bez końcowego znaku nowej linii).&lt;br /&gt;
&lt;br /&gt;
''Uwaga:'' wartość zwracana przez &amp;lt;tt&amp;gt;input()&amp;lt;/tt&amp;gt; zawsze jest napisem, a nie liczbą - choćby się składał z samych cyfr.&lt;br /&gt;
&lt;br /&gt;
1. Napisz program, którego uruchomienie ma następujący skutek:&lt;br /&gt;
*program wita użytkownika (komunikatem w terminalu),&lt;br /&gt;
*prosi o wprowadzenie liczby całkowitej,&lt;br /&gt;
*sprawdza, czy liczba ta jest podzielna przez 7, i informuje o wyniku tego sprawdzenia&lt;br /&gt;
&lt;br /&gt;
2. Napisz program, którego uruchomienie ma następujący skutek:&lt;br /&gt;
* program prosi użytkownika o podanie swojego (lub czyjegoś) wieku w latach&lt;br /&gt;
* jeśli wiek jest ujemny, odpowiada ,,Nieprawidłowy wiek&amp;quot;&lt;br /&gt;
* jeśli wiek wynosi 0, odpowiada ,,niemowlę&amp;quot;&lt;br /&gt;
* jeśli wiek jest poniżej 18, odpowiada ,,dziecko&amp;quot;&lt;br /&gt;
* jeśli wiek jest pomiędzy 18 a 120 (włącznie), odpowiada ,,dorosły&amp;quot;&lt;br /&gt;
* jeśli wiek przekracza 120, odpowiada ,,ludzie tyle nie żyją&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
''CDN''&lt;br /&gt;
&lt;br /&gt;
---- &lt;br /&gt;
&lt;br /&gt;
[[PPy3/StałeIZmienne|poprzednia]] | [[&amp;quot;Programowanie z Pythonem3&amp;quot;|Strona główna]] | [[PPy3/SekwencjeIIteracja|dalej]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Użytkownik:RobertJB|RobertJB]] ([[Dyskusja użytkownika:RobertJB|dyskusja]]) 15:42, 28 cze 2016 (CEST)&lt;/div&gt;</summary>
		<author><name>RobertJB</name></author>
		
	</entry>
	<entry>
		<id>http://brain.fuw.edu.pl/edu/index.php?title=%22Programowanie_z_Pythonem3%22&amp;diff=8934</id>
		<title>&quot;Programowanie z Pythonem3&quot;</title>
		<link rel="alternate" type="text/html" href="http://brain.fuw.edu.pl/edu/index.php?title=%22Programowanie_z_Pythonem3%22&amp;diff=8934"/>
		<updated>2022-09-27T14:54:36Z</updated>

		<summary type="html">&lt;p&gt;RobertJB: /* Uwagi ogólne */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Grafika:Python-logo.png]]&lt;br /&gt;
&lt;br /&gt;
[[Category:Informatyka]]&lt;br /&gt;
== Semestr zimowy 2022/2023 ==&lt;br /&gt;
&lt;br /&gt;
'''''W trakcie opracowania'''''&lt;br /&gt;
&lt;br /&gt;
===Uwagi ogólne===&lt;br /&gt;
&lt;br /&gt;
Zasady zaliczenia ćwiczeń w roku 2022/2023:&lt;br /&gt;
&lt;br /&gt;
* maksymalnie można zdobyć 40 punktów&lt;br /&gt;
* w semestrze będą dwa kolokwia, w połowie i pod koniec; na każdym można zdobyć po 15 punktów&lt;br /&gt;
* w sesji będzie kolokwium dodatkowe, dla chętnych; wynik z niego (maks. 15 punktów) zastępuje gorszy z wyników kolokwiów z semestru, o ile jest on od niego lepszy&lt;br /&gt;
* maksymalnie 10 punktów uzyskuje się na podstawie zadań domowych i kartkówek na ćwiczeniach&lt;br /&gt;
* zaliczenie ćwiczeń na pozytywną ocenę wymaga co najmniej 50% punktów (20 p.)&lt;br /&gt;
* ocena rośnie o pół stopnia z osiągnięciem progu każdych kolejnych 10%, tj. 4 punktów&lt;br /&gt;
* prowadzący może przyznać dodatkowo do 3 punktów &amp;quot;premiowych&amp;quot; na podstawie aktywności na ćwiczeniach&lt;br /&gt;
&lt;br /&gt;
Obecność na ćwiczeniach jest obowiązkowa. Dopuszczalne są '''dwie''' nieobecności nieusprawiedliwione w semestrze. '''Za każdą kolejną nieobecność nieusprawiedliwioną powyżej dwóch odejmujemy od wyniku 5 punktów.'''&lt;br /&gt;
&lt;br /&gt;
Ocena końcowa z przedmiotu składa się z oceny z ćwiczeń, oraz z oceny z egzaminu testowego kończącego wykład, w proporcji 3:2 - z tym, że '''obie te oceny cząstkowe muszą być pozytywne''' aby ocena z całości była pozytywna.&lt;br /&gt;
&lt;br /&gt;
===Spis treści===&lt;br /&gt;
&lt;br /&gt;
#[[PPy3/Wprowadzenie|Wprowadzenie]]&lt;br /&gt;
#[[PPy3/PierwszeKroki|Pierwsze kroki]]&lt;br /&gt;
#[[PPy3/StałeIZmienne|Stałe i zmienne]]&lt;br /&gt;
#[[PPy3/InstrukcjaWarunkowa|Instrukcja warunkowa]]&lt;br /&gt;
#[[PPy3/SekwencjeIIteracja|Sekwencje i iteracja]]&lt;br /&gt;
#[[PPy3/Funkcje|Funkcje]]&lt;br /&gt;
#[[PPy3/Kolekcje|Kolekcje]]&lt;br /&gt;
#[[PPy3/Moduły|Moduły i biblioteki]]&lt;br /&gt;
#[[PPy3/WejścieWyjście|Obsługa wejścia i wyjścia]]&lt;br /&gt;
#[[PPy3/NumPy|NumPy]] - rachunki numeryczne na tablicach liczb&lt;br /&gt;
#[[PPy3/Matplotlib|Matplotlib]] - wizualizacja danych&lt;br /&gt;
#[[PPy3/TematyDodatkowe|Tematy dodatkowe]] - uzupełnienie&lt;br /&gt;
#[[PPy3/DobrePraktyki|Zasady dobrej praktyki]]&lt;br /&gt;
&lt;br /&gt;
===O skrypcie===&lt;br /&gt;
&lt;br /&gt;
Opracowane na nowo przez [[Użytkownik:RobertJB|RobertJB]], częściowo z wykorzystaniem [[&amp;quot;Programowanie z Pythonem&amp;quot;|poprzedniej wersji]].&lt;/div&gt;</summary>
		<author><name>RobertJB</name></author>
		
	</entry>
	<entry>
		<id>http://brain.fuw.edu.pl/edu/index.php?title=PPy3/Kolekcje&amp;diff=8926</id>
		<title>PPy3/Kolekcje</title>
		<link rel="alternate" type="text/html" href="http://brain.fuw.edu.pl/edu/index.php?title=PPy3/Kolekcje&amp;diff=8926"/>
		<updated>2022-08-01T12:11:12Z</updated>

		<summary type="html">&lt;p&gt;RobertJB: /* Napisy (jeszcze raz) */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=Kolekcje=&lt;br /&gt;
&lt;br /&gt;
'''Kolekcje''' to są takie typy danych, które składają się z elementów. Szczególnym przypadkiem, [[PPy3/SekwencjeIIteracja|omawianym już wcześniej]] przy okazji wprowadzenia pętli, są sekwencje - kolekcje uporządkowane. Rozmaite typy kolekcji różnią się sposobem dostępu do elementów, modyfikowalnością - lub przeciwnie, optymalizacją pod względem różnych zastosowań. &lt;br /&gt;
&lt;br /&gt;
*Szereg typów kolekcji jest ,,wbudowanych&amp;quot; w pythonie - to znaczy, że można z nich swobodnie korzystać bez żadnych dodatkowych zabiegów; &lt;br /&gt;
*niektóre inne są zaimplementowane w modułach biblioteki standardowej - a więc korzystanie z nich wymaga wcześniejszego polecenia &amp;lt;tt&amp;gt;import&amp;lt;/tt&amp;gt; (p. [[PPy3/Moduły|Moduły]]); &lt;br /&gt;
*ważne dla zastosowań do obliczeń naukowych typy tablicowe są zaimplementowane w bibliotece [[PPy3/NumPy|NumPy]], która '''nie''' jest częścią biblioteki standardowej, i na ogół np. nie znajdzie się w domyślnym zestawie pakietów typowej dystrybucji Linuxa. Na pewno będzie jednak dostępna jako opcjonalny element instalacji;&lt;br /&gt;
*na każdym typie kolekcji umie działać funkcja &amp;lt;tt&amp;gt;len&amp;lt;/tt&amp;gt;, zwracająca liczbę elementów kolekcji będącej jej argumentem.&lt;br /&gt;
&lt;br /&gt;
Omówimy tu kolejno w skrócie najważniejsze i najbardziej przydatne wg. nas typy kolekcji, z pominięciem tablic NumPy - którym będzie poświęcony [[PPy3/NumPy|osobny rozdział]].&lt;br /&gt;
&lt;br /&gt;
==Listy==&lt;br /&gt;
&lt;br /&gt;
O listach już nieco wiemy. Lista to kolekcja uporządkowana, i modyfikowalna. Elementem listy może być cokolwiek - również inna lista. A nawet ta sama lista - tak, lista może być elementem samej siebie, jednak sztuczka taka nie jest chyba przydatna, choć legalna.&lt;br /&gt;
&lt;br /&gt;
O adresowaniu elementów przez pozycję (lub ''indeks'') oraz o pobieraniu (i podstawianiu do) wycinków już było. Dodamy tu jeszcze parę użytecznych operacji na listach:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
L = [0, 1, 3]&lt;br /&gt;
L.append(5) # dołączamy element do końca, przedłużając listę&lt;br /&gt;
→ L == [0, 1, 3, 5]&lt;br /&gt;
L.extend(['a', 'b']) # przedłużamy od razu o całą listę dodatkowych elementów&lt;br /&gt;
→ L == [0, 1, 3, 5, 'a', 'b']&lt;br /&gt;
L.insert(2, 'dwa') # pierwszy argument to pozycja, drugi to element wstawiany; dalsze elementy przesuwają się&lt;br /&gt;
→ L == [0, 1, 'dwa', 3, 5, 'a', 'b']&lt;br /&gt;
x = L.pop() # usuwamy ostatni element i zwracamy go jako wynik&lt;br /&gt;
→ teraz x == 'b', a L == [0, 1, 'dwa', 3, 5, 'a']&lt;br /&gt;
y = L.pop(2) # możemy zrobić to samo, wskazując inną pozycję zamiast ostatniej&lt;br /&gt;
→ teraz y == 'dwa', a L == [0, 1, 3, 5, 'a']&lt;br /&gt;
L.reverse() # odwrócenie porządku elementów&lt;br /&gt;
→ teraz L == ['a', 5, 3, 1, 0]&lt;br /&gt;
L.sort() # uporządkowanie elementów listy&lt;br /&gt;
→ BŁĄD - nie zadziała, gdyż lista zawiera elementy nieporównywalne (liczby i napis)&lt;br /&gt;
L.pop(0) # usuwamy napis, stojący w pozycji 0&lt;br /&gt;
L.sort()&lt;br /&gt;
→ teraz L == [0, 1, 3, 5]&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Oprócz operacji &amp;lt;tt&amp;gt;L.sort()&amp;lt;/tt&amp;gt; istnieje jeszcze funkcja &amp;lt;tt&amp;gt;sorted(L)&amp;lt;/tt&amp;gt; - różniąca się tym, że pozostawia niezmienioną listę &amp;lt;tt&amp;gt;L&amp;lt;/tt&amp;gt;, zamiast tego tworząc '''nową''' listę uporządkowaną, zawierającą te same elementy, co &amp;lt;tt&amp;gt;L&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Notację postaci &amp;lt;tt&amp;gt;L.append(5)&amp;lt;/tt&amp;gt; można czytać tak: zastosuj ''metodę'' obiektu &amp;lt;tt&amp;gt;L&amp;lt;/tt&amp;gt;, o nazwie &amp;lt;tt&amp;gt;append&amp;lt;/tt&amp;gt;, do liczby 5. Metoda jest to operacja związana z pewnym obiektem (w tym przypadku - listą) - tym, do którego odnosi się nazwa stojąca przed kropką. Metodę można uważać za pewien rodzaj funkcji - takiej , która oprócz ewentualnych argumentów umieszczonych w nawiasach po jej nazwie, ,,wie&amp;quot; jeszcze o tym, z jakiego obiektu została wywołana.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&amp;lt;small&amp;gt;&lt;br /&gt;
W Pythonie każda dana jest obiektem jakiegoś rodzaju (''klasy''), nawet liczba; i każdy obiekt posiada właściwe sobie metody (na ogół wyznaczone przez klasę, do jakiej przynależy). Programista może zresztą sam tworzyć klasy obiektów na potrzeby swojego programu. Więcej na ten temat później.&lt;br /&gt;
&amp;lt;/small&amp;gt;&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Funkcja &amp;lt;tt&amp;gt;list&amp;lt;/tt&amp;gt; tworzy listę z dowolnej sekwencji (np. z napisu). Wywołanie bez argumentów &amp;lt;tt&amp;gt;list()&amp;lt;/tt&amp;gt; zwraca pustą listę; wywołanie &amp;lt;tt&amp;gt;list(s)&amp;lt;/tt&amp;gt;, gdzie &amp;lt;tt&amp;gt;s&amp;lt;/tt&amp;gt; jest napisem, zwraca listę znaków (napisów jednoelementowych), z których składa się napis &amp;lt;tt&amp;gt;s&amp;lt;/tt&amp;gt;. Wywołanie, gdzie argumentem jest lista, zwraca duplikat tej listy - tzn. listę o tych samych elementach (i w tym samym porządku), ale nie tożsamą.&lt;br /&gt;
&lt;br /&gt;
===Przykład: suma cyfr===&lt;br /&gt;
&lt;br /&gt;
Spróbujmy policzyć sumę cyfr, z jakich składa się zapis liczby naturalnej &amp;lt;tt&amp;gt;n&amp;lt;/tt&amp;gt; - a wyrażając się precyzyjniej, sumę liczb reprezentowanych przez cyfry zapisu dziesiętnego liczby &amp;lt;tt&amp;gt;n&amp;lt;/tt&amp;gt; (cyfra to znak, a więc w rozumieniu Pythona pewien napis jednoelementowy - a nie liczba; ponadto, ten sam problem można by postawić dla zapisu pozycyjnego o dowolnej podstawie, np. dwójkowego lub szesnastkowego).&lt;br /&gt;
&lt;br /&gt;
Pierwszym rozwiązaniem tego problemu jest takie, jakie można by nazwać arytmetycznym:&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;source lang=python&amp;gt;&lt;br /&gt;
  def sumacyfr(n):&lt;br /&gt;
      suma = 0&lt;br /&gt;
      while n:&lt;br /&gt;
          suma += n % 10&lt;br /&gt;
          n = n // 10&lt;br /&gt;
      return suma&lt;br /&gt;
  &amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Proste: ostatnią cyfrę zapisu liczby &amp;lt;tt&amp;gt;n&amp;lt;/tt&amp;gt; (a wyrażając się pedantycznie: odpowiadającą jej liczbę między 0 a 9) otrzymujemy jako resztę z dzielenia &amp;lt;tt&amp;gt;n&amp;lt;/tt&amp;gt; przez 10; następnie ,,skracamy&amp;quot; &amp;lt;tt&amp;gt;n&amp;lt;/tt&amp;gt; o tę ostatnią cyfrę, zastępując &amp;lt;tt&amp;gt;n&amp;lt;/tt&amp;gt; przez jej iloraz całkowitoliczbowy przez 10. I tak do skutku, aż zabraknie cyfr.&lt;br /&gt;
&lt;br /&gt;
Można jednak napisać znacznie krótszą wersję tej funkcji, korzystając z tego, że Python ,,sam&amp;quot; umie wyznaczyć cyfry zapisu dziesiętnego każdej liczby i nie musimy do tego pisać własnego kodu. Robi to funkcja &amp;lt;tt&amp;gt;str(n)&amp;lt;/tt&amp;gt; - zastosowana do liczby całkowitej, zwraca ona napis składający się z cyfr dziesiętnych, reprezentujący tę liczbę. Rozwiązanie uproszczone wygląda więc tak:&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;source lang=python&amp;gt;&lt;br /&gt;
  def sumacyfr(n):&lt;br /&gt;
      suma = 0&lt;br /&gt;
      for c in str(n):&lt;br /&gt;
          suma += int(c)&lt;br /&gt;
      return suma&lt;br /&gt;
  &amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dalsze uproszczenie otrzymujemy zastępując pętlę tzw. ''wyrażeniem generatorowym'', i korzystając z wbudowanej funkcji &amp;lt;tt&amp;gt;sum&amp;lt;/tt&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;source lang=python&amp;gt;&lt;br /&gt;
  def sumacyfr(n):&lt;br /&gt;
      return sum(int(c) for c in str(n))&lt;br /&gt;
  &amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wyrażenia generatorowe to jakby odwrotny zapis pętli &amp;lt;tt&amp;gt;for&amp;lt;/tt&amp;gt;. Notacja ta definiuje obiekt (''generator'') będący odpowiednikiem i uogólnieniem obiektu, jaki produkuje funkcja &amp;lt;tt&amp;gt;range&amp;lt;/tt&amp;gt;: jest to ''niby-sekwencja'', która może zastąpić sekwencję (np. listę) w pętli &amp;lt;tt&amp;gt;for&amp;lt;/tt&amp;gt;, a także w funkcjach (takich jak &amp;lt;tt&amp;gt;sum&amp;lt;/tt&amp;gt; lub &amp;lt;tt&amp;gt;sorted&amp;lt;/tt&amp;gt;), które jako argumentu oczekują sekwencji. W odróżnieniu od sekwencji, generator nie ma z góry ustalonego ciągu elementów, można powiedzieć, że produkuje kolejne elementy ,,na żądanie'', np. gdy są potrzebne dla kolejnego obiegu pętli &amp;lt;tt&amp;gt;for&amp;lt;/tt&amp;gt;. Wyrażenie generatorowe określa generator na podstawie elementów podawanych przez inny generator (lub sekwencję), poddając je jakiemuś przekształceniu i/lub selekcji:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;source lang=python&amp;gt;&lt;br /&gt;
 gen = (f(x) for x in elementy if w(x))&lt;br /&gt;
 &amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
tu: &amp;lt;tt&amp;gt;elementy&amp;lt;/tt&amp;gt; to sekwencja lub generator, &amp;lt;tt&amp;gt;w(x)&amp;lt;/tt&amp;gt; to warunek decydujący o uwzględnieniu lub pominięciu elementu &amp;lt;tt&amp;gt;x&amp;lt;/tt&amp;gt;, a &amp;lt;tt&amp;gt;f(x)&amp;lt;/tt&amp;gt; to w ogólności wyrażenie, którego wartość będzie kolejnym elementem podawanym przez generator &amp;lt;tt&amp;gt;gen&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
''Uwaga:'' nawiasy okrągłe otaczające wyrażenie generatorowe są obowiązkowe. Jeśli wyrażenie to wstawiamy bezpośrednio pod wywołanie funkcji jako jej jedyny argument, to wystarczają nawiasy zawarte w składni wywołania funkcji - nie potrzeba ich podwajać. Jeśli w miejsce nawiasów okrągłych napiszemy kwadratowe, otrzymamy nie generator - a listę o tych samych elementach.&lt;br /&gt;
&lt;br /&gt;
==Krotki==&lt;br /&gt;
&lt;br /&gt;
Krotki to prawie listy; zasadnicza różnica polega na tym, że krotki są '''niemodyfikowalne'''. Podobnie jak napisy - krotki raz stworzonej nie można zmienić, w sensie zmiany jej zawartości (elementów), a tym bardziej - jej długości. Można ją najwyżej zastąpić inną krotką. W związku z tym, krotki pozbawione są metod modyfikujących zawartość, jakie posiadają listy. Inne operacje, jak adresowanie elementów i wycinków, dodawanie (sklejanie) i mnożenie (powielanie) działają analogicznie jak dla list.&lt;br /&gt;
&lt;br /&gt;
Literalne krotki zapisuje się zwykle używając nawiasów okrągłych:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
T = (3, 5, 8)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
chociaż tak naprawdę, to nawiasy są opcjonalne, a krotkę tworzą ''przecinki'' stojące pomiędzy elementami. Pominięcie nawiasów powoduje jednak, że musimy pamiętać o tym jaka jest kolejność operacji, jeżeli literalny zapis krotki jest elementem większego wyrażenia. Zwykle prościej i czytelniej jest użyć nawiasów.&lt;br /&gt;
&lt;br /&gt;
Krotka może oczywiście składać się z jednego elementu, a nawet być pusta:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
T1 = 1, # krotka o jednym elemencie - liczbie 1&lt;br /&gt;
T0 = () # krotka pusta&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
w tym ostatnim przypadku nie można się obyć bez nawiasów. Oczywiście tworzenie takich krotek rzadko bywa przydatne; mogą się one jednak pojawiać jako wyniki rozmaitych operacji.&lt;br /&gt;
&lt;br /&gt;
Po co są w ogóle krotki, skoro to tylko jakby ,,słabsze&amp;quot; listy? &lt;br /&gt;
&lt;br /&gt;
*Czasami warto użyć typu niemodyfikowalnego, aby próba zmiany zawartości kolekcji (np. w wyniku błędu) nie mogła się udać;&lt;br /&gt;
*optymalizacja - krotki są ,,lżejsze&amp;quot; od list, co może mieć znaczenie jeśli potrzebujemy je tworzyć w dużej liczbie;&lt;br /&gt;
*w niektórych przypadkach użycie niemodyfikowalnego typu danych jest konieczne; o tym dalej.&lt;br /&gt;
&lt;br /&gt;
Warto jednak pamiętać, że choć sama krotka jest niemodyfikowalna - to jej elementem może być np. lista, której zawartość może być zmieniona niezależnie od tego, że jest elementem krotki.&lt;br /&gt;
&lt;br /&gt;
Każdą sekwencję (a i pewne inne obiekty &amp;amp;mdash; np. generatory) można ,,zrzutować&amp;quot; na krotkę, za pomocą funkcji &amp;lt;tt&amp;gt;tuple&amp;lt;/tt&amp;gt;. Wyrażając się precyzyjniej, wyrażenie &amp;lt;tt&amp;gt;tuple(s)&amp;lt;/tt&amp;gt; jest krotką o tej samej zawartości (i w tym samym porządku) co sekwencja (lub inny obiekt iterowalny) &amp;lt;tt&amp;gt;s&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==Słowniki==&lt;br /&gt;
&lt;br /&gt;
Słownik (''dictionary'') to taka kolekcja, której elementy - zamiast być uporządkowane - są powiązane z ''kluczami''. Kluczem może być liczba (całkowita lub ułamkowa), napis, ale również dana szeregu innych typów (chociaż nie każdego). Pobranie elementu słownika wiąże się z podaniem odpowiadającego mu klucza. Klucze w słowniku są niepowtarzalne - a więc każdy z nich jest związany z dokładnie jedną wartością. Wartości za to mogą się powtarzać, i nie podlegają żadnym ograniczeniom co do typu. Zapis literalny słowników posługuje się nawiasami klamrowymi:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
slownik = {'jeden' : 1, 'dwa' : 2, 'trzy' : 3}&lt;br /&gt;
slownik['dwa']&lt;br /&gt;
→ 2&lt;br /&gt;
slownik['cztery']&lt;br /&gt;
&lt;br /&gt;
KeyError                                  Traceback (most recent call last)&lt;br /&gt;
&amp;lt;ipython-input-2-22c7b016c2c6&amp;gt; in &amp;lt;module&amp;gt;()&lt;br /&gt;
----&amp;gt; 1 slownik['cztery']&lt;br /&gt;
&lt;br /&gt;
KeyError: 'cztery'&lt;br /&gt;
slownik['cztery'] = 4&lt;br /&gt;
slownik['cztery'] == 4&lt;br /&gt;
→ True&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
W notacji literalnej w nawiasach stoją, oddzielone przecinkami, pary klucz-wartość, a klucz od wartości oddziela dwukropek.&lt;br /&gt;
Nazwa ''słownik'' bierze się stąd, że jednym z możliwych zastosowań jest przekład kluczy (tu: słowa oznaczające liczby) na odpowiadające im wartości (tu: liczby). Widzimy też, że próba pobrania wartości odpowiadającej kluczowi, którego w słowniku nie ma, kończy się błędem. Z drugiej strony, w każdej chwili można do słownika dodać następną parę klucz-wartość; analogicznie, można wymienić wartość związaną z kluczem już istniejącym na inną.&lt;br /&gt;
&lt;br /&gt;
Warto podkreślić jeszcze raz, że pary klucz-wartość w słowniku nie charakteryzują się w zasadzie określonym porządkiem. Niemniej w nowszych wersjach Pythona obowiązuje zasada, że pozycje słownika zachowują porządek, w jakim były tworzone &amp;amp;mdash; i np. w iteracji będą się pojawiać zgodnie z tym porządkiem.&lt;br /&gt;
&lt;br /&gt;
Dalsze podstawowe operacje na słowniku to sprawdzenie występowania klucza, oraz iteracja:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
'cztery' in slownik # operator `in' sprawdza przynależność do zbioru kluczy&lt;br /&gt;
→ True&lt;br /&gt;
'zero' in slownik&lt;br /&gt;
→ False&lt;br /&gt;
for klucz in slownik:&lt;br /&gt;
    print(klucz, slownik[klucz])&lt;br /&gt;
→&lt;br /&gt;
jeden 1                                                                                                                              &lt;br /&gt;
dwa 2                                                                                                                                &lt;br /&gt;
trzy 3                                                                                                                               &lt;br /&gt;
cztery 4&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Jak widać, w iteracji klucze słownika pojawiają się w porządku, w którym je dodawano. Takie zachowanie jest przepisane w definicji języka Python od wersji 3.7. Mając do czynienia z wersjami wcześniejszymi należy się liczyć z tym, że ten porządek nie będzie zachowany. Natomiast gwarantuje się, że każdy klucz pojawi się w iteracji dokładnie jeden raz.&lt;br /&gt;
&lt;br /&gt;
W iteracjach (tzn. pętlach &amp;lt;tt&amp;gt;for&amp;lt;/tt&amp;gt;) bardzo przydatne są kolekcje zwracane przez metody słowników: &amp;lt;tt&amp;gt;items&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;values&amp;lt;/tt&amp;gt; i (rzadziej przydatna) &amp;lt;tt&amp;gt;keys&amp;lt;/tt&amp;gt;. Zwracają one obiekty ,,listo-podobne&amp;quot;; jeżeli potrzebne są nam one w postaci dosłownych list, to wystarczy zastosować do nich funkcję &amp;lt;tt&amp;gt;list&amp;lt;/tt&amp;gt;; jeżeli natomiast zamierzamy je wykorzystać w pętli &amp;lt;tt&amp;gt;for&amp;lt;/tt&amp;gt;, to nie jest to potrzebne. Zawartość to odpowiednio:&lt;br /&gt;
&lt;br /&gt;
*&amp;lt;tt&amp;gt;slownik.items()&amp;lt;/tt&amp;gt;: pary (dwuelementowe krotki) postaci ''(klucz, wartość)''&lt;br /&gt;
*&amp;lt;tt&amp;gt;slownik.values()&amp;lt;/tt&amp;gt;: same wartości występujące w słowniku&lt;br /&gt;
*&amp;lt;tt&amp;gt;slownik.keys()&amp;lt;/tt&amp;gt;: same klucze występujące w słowniku.&lt;br /&gt;
&lt;br /&gt;
Uwaga dotycząca porządku pozycji słownika stosuje się również do wyników zwracanych przez te metody.&lt;br /&gt;
&lt;br /&gt;
Funkcją - konstruktorem słownika jest funkcja &amp;lt;tt&amp;gt;dict&amp;lt;/tt&amp;gt;. Zamienia ona np. sekwencję par ''(klucz, wartość)'' w odpowiedni słownik. Jeżeli klucze w tej sekwencji się powtarzają, ,,wygrywa&amp;quot; ostatnie wystąpienie.&lt;br /&gt;
&lt;br /&gt;
Wspomnieliśmy wcześniej, że nie każdy typ wartości może być kluczem słownika. Dokładniej - kluczami w słowniku mogą być tylko wartości typów niemodyfikowalnych, a więc nie listy ani same słowniki. Mogą nimi natomiast być napisy, liczby i krotki. ''Nota bene'': ponieważ liczby ułamkowe należy traktować jako przybliżone, używanie ich jako kluczy słownika na ogół nie jest dobrym pomysłem. Nie ma ograniczeń co do mieszania różnych typów kluczy (ani wartości) w jednym słowniku.&lt;br /&gt;
&lt;br /&gt;
==Zbiory==&lt;br /&gt;
&lt;br /&gt;
Zbiory w Pythonie mają sens taki, jak zbiory w matematyce (teorii mnogości). Mówiąc po prostu, zbiór jest kolekcją nieuporządkowaną i nie dopuszczającą powtórzeń: dany element albo do zbioru należy, albo nie; nie może należeć ''dwukrotnie'' (ani więcej razy). Standardowe zbiory są obiektami modyfikowalnymi.&lt;br /&gt;
&lt;br /&gt;
Zbiór literalny zapisuje się za pomocą nawiasów klamrowych &amp;amp;mdash; łatwo odróżnić, że nie chodzi o słownik, gdyż zapis dla zbiorów nie zawiera dwukropków.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&amp;lt;small&amp;gt;&lt;br /&gt;
Wiąże się z tym jednak jeden problem: czy &amp;lt;tt&amp;gt;{}&amp;lt;/tt&amp;gt; oznacza zbiór pusty, czy pusty słownik? Dość arbitralnie przyjęto, że jednak pusty słownik (notację dla zbiorów wprowadzono później niż dla słowników).&amp;lt;/small&amp;gt;&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Przykłady:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
zbior = {'a', 'b', 'c'}&lt;br /&gt;
'a' in zbior&lt;br /&gt;
→ True&lt;br /&gt;
6 in zbior&lt;br /&gt;
→ False&lt;br /&gt;
zbior.add('d')&lt;br /&gt;
→ zbior == {'a', 'b', 'c', 'd'}&lt;br /&gt;
zbior.remove('a')&lt;br /&gt;
→ zbior == {'b', 'c', 'd'}&lt;br /&gt;
innyzb = {1, 2, 'b'}&lt;br /&gt;
zbior | innyzb  # suma zbiorów&lt;br /&gt;
→ {'a', 1, 2, 'c', 'd', 'b'}&lt;br /&gt;
zbior &amp;amp; innyzb  # iloczyn (część wspólna) zbiorów&lt;br /&gt;
→ {'b'}&lt;br /&gt;
zbior - innyzb  # różnica zbiorów&lt;br /&gt;
→ {'a', 'c', 'd'}&lt;br /&gt;
zbior ^ innyzb == (zbior | innyzb) - (zbior &amp;amp; innyzb)  # definicja różnicy symetrycznej zbiorów&lt;br /&gt;
→ True&lt;br /&gt;
innyzb &amp;lt;= zbior # pierwszy jest podzbiorem drugiego?&lt;br /&gt;
→ False&lt;br /&gt;
{'b', 'c'} &amp;lt;= zbior&lt;br /&gt;
→ True&lt;br /&gt;
{'b', 'c'} &amp;lt; zbior  # podzbiór właściwy?&lt;br /&gt;
→ True&lt;br /&gt;
# znaki nierówności mogą być skierowane odwrotnie, z odp. zamianą argumentów&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Elementy zbiorów podlegają analogicznemu ograniczeniu co do typów danych, co klucze słownika: nie mogą być to obiekty modyfikowalne.&lt;br /&gt;
&lt;br /&gt;
Konstruktorem zbioru jest funkcja &amp;lt;tt&amp;gt;set&amp;lt;/tt&amp;gt;: można jej podać jako argument dowolną kolekcję, a ona zwróci zbiór jej elementów (z dokładnością do ograniczeń co do typów danych tych elementów). Na przykład, typowy chwyt na usunięcie powtórzeń elementów: aby uzyskać uporządkowaną listę znaków, z jaki składa się napis &amp;lt;tt&amp;gt;s&amp;lt;/tt&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
znaki = sorted(set(napis))&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Podobnie jak lista ma swój odpowiednik niemodyfikowalny (krotkę), tak niemodyfikowalnym odpowiednikiem zbioru jest ''zbiór zamrożony'' (''frozenset''). Można taki wyprodukować za pomocą funkcji &amp;lt;tt&amp;gt;frozenset&amp;lt;/tt&amp;gt;, analogu funkcji &amp;lt;tt&amp;gt;set&amp;lt;/tt&amp;gt;. Zbiory zamrożone dopuszczają wszystkie te same operacje, co zwykłe zbiory - za wyjątkiem operacji zmieniających skład (jak &amp;lt;tt&amp;gt;add&amp;lt;/tt&amp;gt; i &amp;lt;tt&amp;gt;remove&amp;lt;/tt&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
==Napisy (jeszcze raz)==&lt;br /&gt;
&lt;br /&gt;
O napisach już nieco było wcześniej, ale dla kompletności przypomnijmy.&lt;br /&gt;
&lt;br /&gt;
*Napis to niemodyfikowalna sekwencja&lt;br /&gt;
*Jej elementami są znaki - napisy o długości 1&lt;br /&gt;
*Operatorem &amp;lt;tt&amp;gt;in&amp;lt;/tt&amp;gt; można badać nie tylko, czy dany znak występuje w napisie, ale również czy jeden napis jest fragmentem drugiego:&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
s = 'abc XYZ'&lt;br /&gt;
'abc' in s&lt;br /&gt;
→ True&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
*Napisy mają szereg użytecznych metod; ale ''żadna z tych metod nie zmienia napisu, którego dotyczy'' - może jedynie tworzyć (i zwracać) nowy napis, utworzony na podstawie istniejącego. Przykłady:&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
s.lower()&lt;br /&gt;
→ 'abc xyz'&lt;br /&gt;
s.upper()&lt;br /&gt;
→ 'ABC XYZ'&lt;br /&gt;
s.replace(' ', ';')&lt;br /&gt;
→ 'abc;XYZ'&lt;br /&gt;
s.find('XY') # znajduje pozycję, na jakiej występuje podany fragment w napisie s&lt;br /&gt;
→ 4&lt;br /&gt;
s.find('q')  # szukamy fragmentu, którego w s nie ma..&lt;br /&gt;
→ -1 &lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
*Metod tych jest więcej, poznamy je w przykładach&lt;br /&gt;
*Funkcją - konstruktorem napisu jest &amp;lt;tt&amp;gt;str&amp;lt;/tt&amp;gt;; np. liczbę - zamienia w napis będący jej zapisem (najbardziej ,,standardowym&amp;quot;), i podobnie z innymi typami danych - zwraca najbardziej ,,standardową&amp;quot; ich reprezentację za pomocą napisu&lt;br /&gt;
*Szczególnie ważną i przydatną operacją napisową jest metoda &amp;lt;tt&amp;gt;format&amp;lt;/tt&amp;gt;, o niej zaraz.&lt;br /&gt;
&lt;br /&gt;
===Formatowanie===&lt;br /&gt;
&lt;br /&gt;
Idea formatowania jest następująca: mamy pewien napis, który służy jako szablon do tworzenia napisów, w ten sposób, że określone miejsca w szablonie wypełniane są wartościami (a dokładniej - ich przedstawieniami napisowymi), które zazwyczaj nie są z góry znane i są wyliczane dopiero w wyniku działania programu. Najczęściej chodzi po prostu o przedstawienie uzyskanych wyników w postaci komunikatów lub zapisów w plikach, o określonej przez programistę postaci.&lt;br /&gt;
&lt;br /&gt;
Gdy korzystamy z metody &amp;lt;tt&amp;gt;format&amp;lt;/tt&amp;gt;, napis pełniący rolę szablonu (literalny lub przywołany poprzez nazwę) stoi przed kropką, tzn. wywołujemy metodę &amp;lt;tt&amp;gt;format&amp;lt;/tt&amp;gt; tegoż napisu - szablonu, natomiast argumentami tego wywołania są wartości, które mają być wstawione w przeznaczone na to pozycje w szablonie.&lt;br /&gt;
&lt;br /&gt;
Język opisu szablonów jest stosunkowo złożony i kryje w sobie szereg możliwości, na razie wprowadzimy najprostsze przypadki.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
# Najprostsze formatowanie: wartości wstawiane są kolejno w miejsca zaznaczone poprzez {}&lt;br /&gt;
'x = {}, y = {}'.format(1.2, 9) &lt;br /&gt;
→ 'x = 1.2, y = 9'&lt;br /&gt;
# Numerowanie pozycji (ten sam numerek może występować więcej niż raz w szablonie&lt;br /&gt;
'x1 = {1}, x0 = {0}'.format(3, 15)&lt;br /&gt;
→ 'x1 = 15, x0 = 3'&lt;br /&gt;
# Obcięcie przedstawienia liczby ułamkowej do określonej liczby cyfr po kropce&lt;br /&gt;
'{0:.4f}'.format(3.141592653589793) &lt;br /&gt;
→ '3.1416'&lt;br /&gt;
# Bardziej szczegółowa kontrola formatowania&lt;br /&gt;
'{:4s}{:4s}{:*&amp;gt;4s}'.format('a', 'b', 'c')&lt;br /&gt;
→ 'a   b   ***c'&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
W tym ostatnim przykładzie, liczby 4 specyfikują ''minimalną'' szerokość pól przeznaczonych na wypełnienie podanymi wartościami, natomiast &amp;lt;tt&amp;gt;*&amp;gt;&amp;lt;/tt&amp;gt; oznacza, że gwiazdka ma być ,,wypełniaczem&amp;quot; pustego miejsca, jeżeli takie pozostanie w zadanej wielkości pola po wstawieniu wartości, a znak &amp;lt;tt&amp;gt;&amp;gt;&amp;lt;/tt&amp;gt; oznacza wyrównanie (wewnątrz pola) do strony prawej. Więcej szczegółów - w [https://docs.python.org/3/library/string.html#formatstrings dokumentacji].&lt;br /&gt;
&lt;br /&gt;
Począwszy od wersji 3.6 języka Python wprowadzono uproszczoną składnię formatowania napisów. Poprzedzając w zapisie napisu literalnego otwierający cudzysłów (lub apostrof) literą &amp;lt;tt&amp;gt;f&amp;lt;/tt&amp;gt; (lub &amp;lt;tt&amp;gt;F&amp;lt;/tt&amp;gt;), możemy w tym napisie skorzystać z sekwencji w parach nawiasów klamrowych, gdzie wewnątrz nawiasów umieszczamy (zamiast jak wyżej &amp;amp;mdash; numeru pozycji w liście argumentów wywołania &amp;lt;tt&amp;gt;format()&amp;lt;/tt&amp;gt;) po prostu zapis wyrażenia w Pythonie, którego aktualna wartość znajdzie się w tym miejscu w wyniku ewaluacji, plus ewentualnie dwukropek a po nim dyrektywy formatowania, jak wyżej. Przykłady:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
x, y = 1.2, 9&lt;br /&gt;
f'x = {x}, y = {y}'&lt;br /&gt;
→ x = 1.2, y = 9&lt;br /&gt;
f'wynik działania arytmetycznego: {2 * x + y}'&lt;br /&gt;
→ wynik działania arytmetycznego: 11.4&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Jeżeli chcemy, aby w wyniku wystąpiły dosłowne nawiasy klamrowe, a nie zostały one zinterpretowane jako pole do wypełnienia wartością wyrażenia, to musimy je podwoić (&amp;lt;tt&amp;gt;f'{{'&amp;lt;/tt&amp;gt; → { itd.)&lt;br /&gt;
&lt;br /&gt;
=Ćwiczenia=&lt;br /&gt;
&lt;br /&gt;
1. Ile wynosi najmniejsza liczba &amp;lt;tt&amp;gt;N&amp;lt;/tt&amp;gt;, dla której &amp;lt;tt&amp;gt;S_N = 1 + 2**3 + 3**3 + ... + N**3&amp;lt;/tt&amp;gt;&lt;br /&gt;
jest liczbą której zapis dziesiętny ma więcej niż M cyfr? Napisać funkcję &amp;lt;tt&amp;gt;znajdzN(M)&amp;lt;/tt&amp;gt;, która wyznacza i zwraca tę liczbę.&lt;br /&gt;
&lt;br /&gt;
''CDN''&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
[[PPy3/Funkcje|poprzednie]] | [[&amp;quot;Programowanie z Pythonem3&amp;quot;|strona główna]] | [[PPy3/Moduły|dalej]]&lt;br /&gt;
&lt;br /&gt;
[[Użytkownik:RobertJB|RobertJB]] ([[Dyskusja użytkownika:RobertJB|dyskusja]]) 16:06, 5 lip 2016 (CEST)&lt;/div&gt;</summary>
		<author><name>RobertJB</name></author>
		
	</entry>
	<entry>
		<id>http://brain.fuw.edu.pl/edu/index.php?title=PPy3/Kolekcje&amp;diff=8925</id>
		<title>PPy3/Kolekcje</title>
		<link rel="alternate" type="text/html" href="http://brain.fuw.edu.pl/edu/index.php?title=PPy3/Kolekcje&amp;diff=8925"/>
		<updated>2022-08-01T12:10:00Z</updated>

		<summary type="html">&lt;p&gt;RobertJB: /* Kolekcje */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=Kolekcje=&lt;br /&gt;
&lt;br /&gt;
'''Kolekcje''' to są takie typy danych, które składają się z elementów. Szczególnym przypadkiem, [[PPy3/SekwencjeIIteracja|omawianym już wcześniej]] przy okazji wprowadzenia pętli, są sekwencje - kolekcje uporządkowane. Rozmaite typy kolekcji różnią się sposobem dostępu do elementów, modyfikowalnością - lub przeciwnie, optymalizacją pod względem różnych zastosowań. &lt;br /&gt;
&lt;br /&gt;
*Szereg typów kolekcji jest ,,wbudowanych&amp;quot; w pythonie - to znaczy, że można z nich swobodnie korzystać bez żadnych dodatkowych zabiegów; &lt;br /&gt;
*niektóre inne są zaimplementowane w modułach biblioteki standardowej - a więc korzystanie z nich wymaga wcześniejszego polecenia &amp;lt;tt&amp;gt;import&amp;lt;/tt&amp;gt; (p. [[PPy3/Moduły|Moduły]]); &lt;br /&gt;
*ważne dla zastosowań do obliczeń naukowych typy tablicowe są zaimplementowane w bibliotece [[PPy3/NumPy|NumPy]], która '''nie''' jest częścią biblioteki standardowej, i na ogół np. nie znajdzie się w domyślnym zestawie pakietów typowej dystrybucji Linuxa. Na pewno będzie jednak dostępna jako opcjonalny element instalacji;&lt;br /&gt;
*na każdym typie kolekcji umie działać funkcja &amp;lt;tt&amp;gt;len&amp;lt;/tt&amp;gt;, zwracająca liczbę elementów kolekcji będącej jej argumentem.&lt;br /&gt;
&lt;br /&gt;
Omówimy tu kolejno w skrócie najważniejsze i najbardziej przydatne wg. nas typy kolekcji, z pominięciem tablic NumPy - którym będzie poświęcony [[PPy3/NumPy|osobny rozdział]].&lt;br /&gt;
&lt;br /&gt;
==Listy==&lt;br /&gt;
&lt;br /&gt;
O listach już nieco wiemy. Lista to kolekcja uporządkowana, i modyfikowalna. Elementem listy może być cokolwiek - również inna lista. A nawet ta sama lista - tak, lista może być elementem samej siebie, jednak sztuczka taka nie jest chyba przydatna, choć legalna.&lt;br /&gt;
&lt;br /&gt;
O adresowaniu elementów przez pozycję (lub ''indeks'') oraz o pobieraniu (i podstawianiu do) wycinków już było. Dodamy tu jeszcze parę użytecznych operacji na listach:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
L = [0, 1, 3]&lt;br /&gt;
L.append(5) # dołączamy element do końca, przedłużając listę&lt;br /&gt;
→ L == [0, 1, 3, 5]&lt;br /&gt;
L.extend(['a', 'b']) # przedłużamy od razu o całą listę dodatkowych elementów&lt;br /&gt;
→ L == [0, 1, 3, 5, 'a', 'b']&lt;br /&gt;
L.insert(2, 'dwa') # pierwszy argument to pozycja, drugi to element wstawiany; dalsze elementy przesuwają się&lt;br /&gt;
→ L == [0, 1, 'dwa', 3, 5, 'a', 'b']&lt;br /&gt;
x = L.pop() # usuwamy ostatni element i zwracamy go jako wynik&lt;br /&gt;
→ teraz x == 'b', a L == [0, 1, 'dwa', 3, 5, 'a']&lt;br /&gt;
y = L.pop(2) # możemy zrobić to samo, wskazując inną pozycję zamiast ostatniej&lt;br /&gt;
→ teraz y == 'dwa', a L == [0, 1, 3, 5, 'a']&lt;br /&gt;
L.reverse() # odwrócenie porządku elementów&lt;br /&gt;
→ teraz L == ['a', 5, 3, 1, 0]&lt;br /&gt;
L.sort() # uporządkowanie elementów listy&lt;br /&gt;
→ BŁĄD - nie zadziała, gdyż lista zawiera elementy nieporównywalne (liczby i napis)&lt;br /&gt;
L.pop(0) # usuwamy napis, stojący w pozycji 0&lt;br /&gt;
L.sort()&lt;br /&gt;
→ teraz L == [0, 1, 3, 5]&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Oprócz operacji &amp;lt;tt&amp;gt;L.sort()&amp;lt;/tt&amp;gt; istnieje jeszcze funkcja &amp;lt;tt&amp;gt;sorted(L)&amp;lt;/tt&amp;gt; - różniąca się tym, że pozostawia niezmienioną listę &amp;lt;tt&amp;gt;L&amp;lt;/tt&amp;gt;, zamiast tego tworząc '''nową''' listę uporządkowaną, zawierającą te same elementy, co &amp;lt;tt&amp;gt;L&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Notację postaci &amp;lt;tt&amp;gt;L.append(5)&amp;lt;/tt&amp;gt; można czytać tak: zastosuj ''metodę'' obiektu &amp;lt;tt&amp;gt;L&amp;lt;/tt&amp;gt;, o nazwie &amp;lt;tt&amp;gt;append&amp;lt;/tt&amp;gt;, do liczby 5. Metoda jest to operacja związana z pewnym obiektem (w tym przypadku - listą) - tym, do którego odnosi się nazwa stojąca przed kropką. Metodę można uważać za pewien rodzaj funkcji - takiej , która oprócz ewentualnych argumentów umieszczonych w nawiasach po jej nazwie, ,,wie&amp;quot; jeszcze o tym, z jakiego obiektu została wywołana.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&amp;lt;small&amp;gt;&lt;br /&gt;
W Pythonie każda dana jest obiektem jakiegoś rodzaju (''klasy''), nawet liczba; i każdy obiekt posiada właściwe sobie metody (na ogół wyznaczone przez klasę, do jakiej przynależy). Programista może zresztą sam tworzyć klasy obiektów na potrzeby swojego programu. Więcej na ten temat później.&lt;br /&gt;
&amp;lt;/small&amp;gt;&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Funkcja &amp;lt;tt&amp;gt;list&amp;lt;/tt&amp;gt; tworzy listę z dowolnej sekwencji (np. z napisu). Wywołanie bez argumentów &amp;lt;tt&amp;gt;list()&amp;lt;/tt&amp;gt; zwraca pustą listę; wywołanie &amp;lt;tt&amp;gt;list(s)&amp;lt;/tt&amp;gt;, gdzie &amp;lt;tt&amp;gt;s&amp;lt;/tt&amp;gt; jest napisem, zwraca listę znaków (napisów jednoelementowych), z których składa się napis &amp;lt;tt&amp;gt;s&amp;lt;/tt&amp;gt;. Wywołanie, gdzie argumentem jest lista, zwraca duplikat tej listy - tzn. listę o tych samych elementach (i w tym samym porządku), ale nie tożsamą.&lt;br /&gt;
&lt;br /&gt;
===Przykład: suma cyfr===&lt;br /&gt;
&lt;br /&gt;
Spróbujmy policzyć sumę cyfr, z jakich składa się zapis liczby naturalnej &amp;lt;tt&amp;gt;n&amp;lt;/tt&amp;gt; - a wyrażając się precyzyjniej, sumę liczb reprezentowanych przez cyfry zapisu dziesiętnego liczby &amp;lt;tt&amp;gt;n&amp;lt;/tt&amp;gt; (cyfra to znak, a więc w rozumieniu Pythona pewien napis jednoelementowy - a nie liczba; ponadto, ten sam problem można by postawić dla zapisu pozycyjnego o dowolnej podstawie, np. dwójkowego lub szesnastkowego).&lt;br /&gt;
&lt;br /&gt;
Pierwszym rozwiązaniem tego problemu jest takie, jakie można by nazwać arytmetycznym:&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;source lang=python&amp;gt;&lt;br /&gt;
  def sumacyfr(n):&lt;br /&gt;
      suma = 0&lt;br /&gt;
      while n:&lt;br /&gt;
          suma += n % 10&lt;br /&gt;
          n = n // 10&lt;br /&gt;
      return suma&lt;br /&gt;
  &amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Proste: ostatnią cyfrę zapisu liczby &amp;lt;tt&amp;gt;n&amp;lt;/tt&amp;gt; (a wyrażając się pedantycznie: odpowiadającą jej liczbę między 0 a 9) otrzymujemy jako resztę z dzielenia &amp;lt;tt&amp;gt;n&amp;lt;/tt&amp;gt; przez 10; następnie ,,skracamy&amp;quot; &amp;lt;tt&amp;gt;n&amp;lt;/tt&amp;gt; o tę ostatnią cyfrę, zastępując &amp;lt;tt&amp;gt;n&amp;lt;/tt&amp;gt; przez jej iloraz całkowitoliczbowy przez 10. I tak do skutku, aż zabraknie cyfr.&lt;br /&gt;
&lt;br /&gt;
Można jednak napisać znacznie krótszą wersję tej funkcji, korzystając z tego, że Python ,,sam&amp;quot; umie wyznaczyć cyfry zapisu dziesiętnego każdej liczby i nie musimy do tego pisać własnego kodu. Robi to funkcja &amp;lt;tt&amp;gt;str(n)&amp;lt;/tt&amp;gt; - zastosowana do liczby całkowitej, zwraca ona napis składający się z cyfr dziesiętnych, reprezentujący tę liczbę. Rozwiązanie uproszczone wygląda więc tak:&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;source lang=python&amp;gt;&lt;br /&gt;
  def sumacyfr(n):&lt;br /&gt;
      suma = 0&lt;br /&gt;
      for c in str(n):&lt;br /&gt;
          suma += int(c)&lt;br /&gt;
      return suma&lt;br /&gt;
  &amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dalsze uproszczenie otrzymujemy zastępując pętlę tzw. ''wyrażeniem generatorowym'', i korzystając z wbudowanej funkcji &amp;lt;tt&amp;gt;sum&amp;lt;/tt&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;source lang=python&amp;gt;&lt;br /&gt;
  def sumacyfr(n):&lt;br /&gt;
      return sum(int(c) for c in str(n))&lt;br /&gt;
  &amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wyrażenia generatorowe to jakby odwrotny zapis pętli &amp;lt;tt&amp;gt;for&amp;lt;/tt&amp;gt;. Notacja ta definiuje obiekt (''generator'') będący odpowiednikiem i uogólnieniem obiektu, jaki produkuje funkcja &amp;lt;tt&amp;gt;range&amp;lt;/tt&amp;gt;: jest to ''niby-sekwencja'', która może zastąpić sekwencję (np. listę) w pętli &amp;lt;tt&amp;gt;for&amp;lt;/tt&amp;gt;, a także w funkcjach (takich jak &amp;lt;tt&amp;gt;sum&amp;lt;/tt&amp;gt; lub &amp;lt;tt&amp;gt;sorted&amp;lt;/tt&amp;gt;), które jako argumentu oczekują sekwencji. W odróżnieniu od sekwencji, generator nie ma z góry ustalonego ciągu elementów, można powiedzieć, że produkuje kolejne elementy ,,na żądanie'', np. gdy są potrzebne dla kolejnego obiegu pętli &amp;lt;tt&amp;gt;for&amp;lt;/tt&amp;gt;. Wyrażenie generatorowe określa generator na podstawie elementów podawanych przez inny generator (lub sekwencję), poddając je jakiemuś przekształceniu i/lub selekcji:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;source lang=python&amp;gt;&lt;br /&gt;
 gen = (f(x) for x in elementy if w(x))&lt;br /&gt;
 &amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
tu: &amp;lt;tt&amp;gt;elementy&amp;lt;/tt&amp;gt; to sekwencja lub generator, &amp;lt;tt&amp;gt;w(x)&amp;lt;/tt&amp;gt; to warunek decydujący o uwzględnieniu lub pominięciu elementu &amp;lt;tt&amp;gt;x&amp;lt;/tt&amp;gt;, a &amp;lt;tt&amp;gt;f(x)&amp;lt;/tt&amp;gt; to w ogólności wyrażenie, którego wartość będzie kolejnym elementem podawanym przez generator &amp;lt;tt&amp;gt;gen&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
''Uwaga:'' nawiasy okrągłe otaczające wyrażenie generatorowe są obowiązkowe. Jeśli wyrażenie to wstawiamy bezpośrednio pod wywołanie funkcji jako jej jedyny argument, to wystarczają nawiasy zawarte w składni wywołania funkcji - nie potrzeba ich podwajać. Jeśli w miejsce nawiasów okrągłych napiszemy kwadratowe, otrzymamy nie generator - a listę o tych samych elementach.&lt;br /&gt;
&lt;br /&gt;
==Krotki==&lt;br /&gt;
&lt;br /&gt;
Krotki to prawie listy; zasadnicza różnica polega na tym, że krotki są '''niemodyfikowalne'''. Podobnie jak napisy - krotki raz stworzonej nie można zmienić, w sensie zmiany jej zawartości (elementów), a tym bardziej - jej długości. Można ją najwyżej zastąpić inną krotką. W związku z tym, krotki pozbawione są metod modyfikujących zawartość, jakie posiadają listy. Inne operacje, jak adresowanie elementów i wycinków, dodawanie (sklejanie) i mnożenie (powielanie) działają analogicznie jak dla list.&lt;br /&gt;
&lt;br /&gt;
Literalne krotki zapisuje się zwykle używając nawiasów okrągłych:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
T = (3, 5, 8)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
chociaż tak naprawdę, to nawiasy są opcjonalne, a krotkę tworzą ''przecinki'' stojące pomiędzy elementami. Pominięcie nawiasów powoduje jednak, że musimy pamiętać o tym jaka jest kolejność operacji, jeżeli literalny zapis krotki jest elementem większego wyrażenia. Zwykle prościej i czytelniej jest użyć nawiasów.&lt;br /&gt;
&lt;br /&gt;
Krotka może oczywiście składać się z jednego elementu, a nawet być pusta:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
T1 = 1, # krotka o jednym elemencie - liczbie 1&lt;br /&gt;
T0 = () # krotka pusta&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
w tym ostatnim przypadku nie można się obyć bez nawiasów. Oczywiście tworzenie takich krotek rzadko bywa przydatne; mogą się one jednak pojawiać jako wyniki rozmaitych operacji.&lt;br /&gt;
&lt;br /&gt;
Po co są w ogóle krotki, skoro to tylko jakby ,,słabsze&amp;quot; listy? &lt;br /&gt;
&lt;br /&gt;
*Czasami warto użyć typu niemodyfikowalnego, aby próba zmiany zawartości kolekcji (np. w wyniku błędu) nie mogła się udać;&lt;br /&gt;
*optymalizacja - krotki są ,,lżejsze&amp;quot; od list, co może mieć znaczenie jeśli potrzebujemy je tworzyć w dużej liczbie;&lt;br /&gt;
*w niektórych przypadkach użycie niemodyfikowalnego typu danych jest konieczne; o tym dalej.&lt;br /&gt;
&lt;br /&gt;
Warto jednak pamiętać, że choć sama krotka jest niemodyfikowalna - to jej elementem może być np. lista, której zawartość może być zmieniona niezależnie od tego, że jest elementem krotki.&lt;br /&gt;
&lt;br /&gt;
Każdą sekwencję (a i pewne inne obiekty &amp;amp;mdash; np. generatory) można ,,zrzutować&amp;quot; na krotkę, za pomocą funkcji &amp;lt;tt&amp;gt;tuple&amp;lt;/tt&amp;gt;. Wyrażając się precyzyjniej, wyrażenie &amp;lt;tt&amp;gt;tuple(s)&amp;lt;/tt&amp;gt; jest krotką o tej samej zawartości (i w tym samym porządku) co sekwencja (lub inny obiekt iterowalny) &amp;lt;tt&amp;gt;s&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==Słowniki==&lt;br /&gt;
&lt;br /&gt;
Słownik (''dictionary'') to taka kolekcja, której elementy - zamiast być uporządkowane - są powiązane z ''kluczami''. Kluczem może być liczba (całkowita lub ułamkowa), napis, ale również dana szeregu innych typów (chociaż nie każdego). Pobranie elementu słownika wiąże się z podaniem odpowiadającego mu klucza. Klucze w słowniku są niepowtarzalne - a więc każdy z nich jest związany z dokładnie jedną wartością. Wartości za to mogą się powtarzać, i nie podlegają żadnym ograniczeniom co do typu. Zapis literalny słowników posługuje się nawiasami klamrowymi:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
slownik = {'jeden' : 1, 'dwa' : 2, 'trzy' : 3}&lt;br /&gt;
slownik['dwa']&lt;br /&gt;
→ 2&lt;br /&gt;
slownik['cztery']&lt;br /&gt;
&lt;br /&gt;
KeyError                                  Traceback (most recent call last)&lt;br /&gt;
&amp;lt;ipython-input-2-22c7b016c2c6&amp;gt; in &amp;lt;module&amp;gt;()&lt;br /&gt;
----&amp;gt; 1 slownik['cztery']&lt;br /&gt;
&lt;br /&gt;
KeyError: 'cztery'&lt;br /&gt;
slownik['cztery'] = 4&lt;br /&gt;
slownik['cztery'] == 4&lt;br /&gt;
→ True&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
W notacji literalnej w nawiasach stoją, oddzielone przecinkami, pary klucz-wartość, a klucz od wartości oddziela dwukropek.&lt;br /&gt;
Nazwa ''słownik'' bierze się stąd, że jednym z możliwych zastosowań jest przekład kluczy (tu: słowa oznaczające liczby) na odpowiadające im wartości (tu: liczby). Widzimy też, że próba pobrania wartości odpowiadającej kluczowi, którego w słowniku nie ma, kończy się błędem. Z drugiej strony, w każdej chwili można do słownika dodać następną parę klucz-wartość; analogicznie, można wymienić wartość związaną z kluczem już istniejącym na inną.&lt;br /&gt;
&lt;br /&gt;
Warto podkreślić jeszcze raz, że pary klucz-wartość w słowniku nie charakteryzują się w zasadzie określonym porządkiem. Niemniej w nowszych wersjach Pythona obowiązuje zasada, że pozycje słownika zachowują porządek, w jakim były tworzone &amp;amp;mdash; i np. w iteracji będą się pojawiać zgodnie z tym porządkiem.&lt;br /&gt;
&lt;br /&gt;
Dalsze podstawowe operacje na słowniku to sprawdzenie występowania klucza, oraz iteracja:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
'cztery' in slownik # operator `in' sprawdza przynależność do zbioru kluczy&lt;br /&gt;
→ True&lt;br /&gt;
'zero' in slownik&lt;br /&gt;
→ False&lt;br /&gt;
for klucz in slownik:&lt;br /&gt;
    print(klucz, slownik[klucz])&lt;br /&gt;
→&lt;br /&gt;
jeden 1                                                                                                                              &lt;br /&gt;
dwa 2                                                                                                                                &lt;br /&gt;
trzy 3                                                                                                                               &lt;br /&gt;
cztery 4&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Jak widać, w iteracji klucze słownika pojawiają się w porządku, w którym je dodawano. Takie zachowanie jest przepisane w definicji języka Python od wersji 3.7. Mając do czynienia z wersjami wcześniejszymi należy się liczyć z tym, że ten porządek nie będzie zachowany. Natomiast gwarantuje się, że każdy klucz pojawi się w iteracji dokładnie jeden raz.&lt;br /&gt;
&lt;br /&gt;
W iteracjach (tzn. pętlach &amp;lt;tt&amp;gt;for&amp;lt;/tt&amp;gt;) bardzo przydatne są kolekcje zwracane przez metody słowników: &amp;lt;tt&amp;gt;items&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;values&amp;lt;/tt&amp;gt; i (rzadziej przydatna) &amp;lt;tt&amp;gt;keys&amp;lt;/tt&amp;gt;. Zwracają one obiekty ,,listo-podobne&amp;quot;; jeżeli potrzebne są nam one w postaci dosłownych list, to wystarczy zastosować do nich funkcję &amp;lt;tt&amp;gt;list&amp;lt;/tt&amp;gt;; jeżeli natomiast zamierzamy je wykorzystać w pętli &amp;lt;tt&amp;gt;for&amp;lt;/tt&amp;gt;, to nie jest to potrzebne. Zawartość to odpowiednio:&lt;br /&gt;
&lt;br /&gt;
*&amp;lt;tt&amp;gt;slownik.items()&amp;lt;/tt&amp;gt;: pary (dwuelementowe krotki) postaci ''(klucz, wartość)''&lt;br /&gt;
*&amp;lt;tt&amp;gt;slownik.values()&amp;lt;/tt&amp;gt;: same wartości występujące w słowniku&lt;br /&gt;
*&amp;lt;tt&amp;gt;slownik.keys()&amp;lt;/tt&amp;gt;: same klucze występujące w słowniku.&lt;br /&gt;
&lt;br /&gt;
Uwaga dotycząca porządku pozycji słownika stosuje się również do wyników zwracanych przez te metody.&lt;br /&gt;
&lt;br /&gt;
Funkcją - konstruktorem słownika jest funkcja &amp;lt;tt&amp;gt;dict&amp;lt;/tt&amp;gt;. Zamienia ona np. sekwencję par ''(klucz, wartość)'' w odpowiedni słownik. Jeżeli klucze w tej sekwencji się powtarzają, ,,wygrywa&amp;quot; ostatnie wystąpienie.&lt;br /&gt;
&lt;br /&gt;
Wspomnieliśmy wcześniej, że nie każdy typ wartości może być kluczem słownika. Dokładniej - kluczami w słowniku mogą być tylko wartości typów niemodyfikowalnych, a więc nie listy ani same słowniki. Mogą nimi natomiast być napisy, liczby i krotki. ''Nota bene'': ponieważ liczby ułamkowe należy traktować jako przybliżone, używanie ich jako kluczy słownika na ogół nie jest dobrym pomysłem. Nie ma ograniczeń co do mieszania różnych typów kluczy (ani wartości) w jednym słowniku.&lt;br /&gt;
&lt;br /&gt;
==Zbiory==&lt;br /&gt;
&lt;br /&gt;
Zbiory w Pythonie mają sens taki, jak zbiory w matematyce (teorii mnogości). Mówiąc po prostu, zbiór jest kolekcją nieuporządkowaną i nie dopuszczającą powtórzeń: dany element albo do zbioru należy, albo nie; nie może należeć ''dwukrotnie'' (ani więcej razy). Standardowe zbiory są obiektami modyfikowalnymi.&lt;br /&gt;
&lt;br /&gt;
Zbiór literalny zapisuje się za pomocą nawiasów klamrowych &amp;amp;mdash; łatwo odróżnić, że nie chodzi o słownik, gdyż zapis dla zbiorów nie zawiera dwukropków.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&amp;lt;small&amp;gt;&lt;br /&gt;
Wiąże się z tym jednak jeden problem: czy &amp;lt;tt&amp;gt;{}&amp;lt;/tt&amp;gt; oznacza zbiór pusty, czy pusty słownik? Dość arbitralnie przyjęto, że jednak pusty słownik (notację dla zbiorów wprowadzono później niż dla słowników).&amp;lt;/small&amp;gt;&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Przykłady:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
zbior = {'a', 'b', 'c'}&lt;br /&gt;
'a' in zbior&lt;br /&gt;
→ True&lt;br /&gt;
6 in zbior&lt;br /&gt;
→ False&lt;br /&gt;
zbior.add('d')&lt;br /&gt;
→ zbior == {'a', 'b', 'c', 'd'}&lt;br /&gt;
zbior.remove('a')&lt;br /&gt;
→ zbior == {'b', 'c', 'd'}&lt;br /&gt;
innyzb = {1, 2, 'b'}&lt;br /&gt;
zbior | innyzb  # suma zbiorów&lt;br /&gt;
→ {'a', 1, 2, 'c', 'd', 'b'}&lt;br /&gt;
zbior &amp;amp; innyzb  # iloczyn (część wspólna) zbiorów&lt;br /&gt;
→ {'b'}&lt;br /&gt;
zbior - innyzb  # różnica zbiorów&lt;br /&gt;
→ {'a', 'c', 'd'}&lt;br /&gt;
zbior ^ innyzb == (zbior | innyzb) - (zbior &amp;amp; innyzb)  # definicja różnicy symetrycznej zbiorów&lt;br /&gt;
→ True&lt;br /&gt;
innyzb &amp;lt;= zbior # pierwszy jest podzbiorem drugiego?&lt;br /&gt;
→ False&lt;br /&gt;
{'b', 'c'} &amp;lt;= zbior&lt;br /&gt;
→ True&lt;br /&gt;
{'b', 'c'} &amp;lt; zbior  # podzbiór właściwy?&lt;br /&gt;
→ True&lt;br /&gt;
# znaki nierówności mogą być skierowane odwrotnie, z odp. zamianą argumentów&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Elementy zbiorów podlegają analogicznemu ograniczeniu co do typów danych, co klucze słownika: nie mogą być to obiekty modyfikowalne.&lt;br /&gt;
&lt;br /&gt;
Konstruktorem zbioru jest funkcja &amp;lt;tt&amp;gt;set&amp;lt;/tt&amp;gt;: można jej podać jako argument dowolną kolekcję, a ona zwróci zbiór jej elementów (z dokładnością do ograniczeń co do typów danych tych elementów). Na przykład, typowy chwyt na usunięcie powtórzeń elementów: aby uzyskać uporządkowaną listę znaków, z jaki składa się napis &amp;lt;tt&amp;gt;s&amp;lt;/tt&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
znaki = sorted(set(napis))&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Podobnie jak lista ma swój odpowiednik niemodyfikowalny (krotkę), tak niemodyfikowalnym odpowiednikiem zbioru jest ''zbiór zamrożony'' (''frozenset''). Można taki wyprodukować za pomocą funkcji &amp;lt;tt&amp;gt;frozenset&amp;lt;/tt&amp;gt;, analogu funkcji &amp;lt;tt&amp;gt;set&amp;lt;/tt&amp;gt;. Zbiory zamrożone dopuszczają wszystkie te same operacje, co zwykłe zbiory - za wyjątkiem operacji zmieniających skład (jak &amp;lt;tt&amp;gt;add&amp;lt;/tt&amp;gt; i &amp;lt;tt&amp;gt;remove&amp;lt;/tt&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
==Napisy (jeszcze raz)==&lt;br /&gt;
&lt;br /&gt;
O napisach już nieco było wcześniej, ale dla kompletności przypomnijmy.&lt;br /&gt;
&lt;br /&gt;
*Napis to niemodyfikowalna sekwencja&lt;br /&gt;
*Jej elementami są znaki - napisy o długości 1&lt;br /&gt;
*Operatorem &amp;lt;tt&amp;gt;in&amp;lt;/tt&amp;gt; można badać nie tylko, czy dany znak występuje w napisie, ale również czy jeden napis jest fragmentem drugiego:&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
s = 'abc XYZ'&lt;br /&gt;
'abc' in s&lt;br /&gt;
→ True&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
*Napisy mają szereg użytecznych metod; ale ''żadna z tych metod nie zmienia napisu, którego dotyczy'' - może jedynie tworzyć (i zwracać) nowy napis, utworzony na podstawie istniejącego. Przykłady:&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
s.lower()&lt;br /&gt;
→ 'abc xyz'&lt;br /&gt;
s.upper()&lt;br /&gt;
→ 'ABC XYZ'&lt;br /&gt;
s.replace(' ', ';')&lt;br /&gt;
→ 'abc;XYZ'&lt;br /&gt;
s.find('XY') # znajduje pozycję, na jakiej występuje podany fragment w napisie s&lt;br /&gt;
→ 4&lt;br /&gt;
s.find('q')  # szukamy fragmentu, którego w s nie ma..&lt;br /&gt;
→ -1 &lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
*Metod tych jest więcej, poznamy je w przykładach&lt;br /&gt;
*Funkcją - konstruktorem napisu jest &amp;lt;tt&amp;gt;str&amp;lt;/tt&amp;gt;; np. liczbę - zamienia w napis będący jej zapisem (najbardziej ,,standardowym&amp;quot;), i podobnie z innymi typami danych - zwraca najbardziej ,,standardową&amp;quot; ich reprezentację za pomocą napisu&lt;br /&gt;
*Szczególnie ważną i przydatną operacją napisową jest metoda &amp;lt;tt&amp;gt;format&amp;lt;/tt&amp;gt;, o niej zaraz.&lt;br /&gt;
&lt;br /&gt;
===Formatowanie===&lt;br /&gt;
&lt;br /&gt;
Idea formatowania jest następująca: mamy pewien napis, który służy jako szablon do tworzenia napisów, w ten sposób, że określone miejsca w szablonie wypełniane są wartościami (a dokładniej - ich przedstawieniami napisowymi), które zazwyczaj nie są z góry znane i są wyliczane dopiero w wyniku działania programu. Najczęściej chodzi po prostu o przedstawienie uzyskanych wyników w postaci komunikatów lub zapisów w plikach, o określonej przez programistę postaci.&lt;br /&gt;
&lt;br /&gt;
Gdy korzystamy z metody &amp;lt;tt&amp;gt;format&amp;lt;/tt&amp;gt;, napis pełniący rolę szablonu (literalny lub przywołany poprzez nazwę) stoi przed kropką, tzn. wywołujemy metodę &amp;lt;tt&amp;gt;format&amp;lt;/tt&amp;gt; tegoż napisu - szablonu, natomiast argumentami tego wywołania są wartości, które mają być wstawione w przeznaczone na to pozycje w szablonie.&lt;br /&gt;
&lt;br /&gt;
Język opisu szablonów jest stosunkowo złożony i kryje w sobie szereg możliwości, na razie wprowadzimy najprostsze przypadki.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
# Najprostsze formatowanie: wartości wstawiane są kolejno w miejsca zaznaczone poprzez {}&lt;br /&gt;
'x = {}, y = {}'.format(1.2, 9) &lt;br /&gt;
→ 'x = 1.2, y = 9'&lt;br /&gt;
# Numerowanie pozycji (ten sam numerek może występować więcej niż raz w szablonie&lt;br /&gt;
'x1 = {1}, x0 = {0}'.format(3, 15)&lt;br /&gt;
→ 'x1 = 15, x0 = 3'&lt;br /&gt;
# Obcięcie przedstawienia liczby ułamkowej do określonej liczby cyfr po kropce&lt;br /&gt;
'{0:.4f}'.format(3.141592653589793) &lt;br /&gt;
→ '3.1416'&lt;br /&gt;
# Bardziej szczegółowa kontrola formatowania&lt;br /&gt;
'{:4s}{:4s}{:*&amp;gt;4s}'.format('a', 'b', 'c')&lt;br /&gt;
→ 'a   b   ***c'&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
W tym ostatnim przykładzie, liczby 4 specyfikują ''minimalną'' szerokość pól przeznaczonych na wypełnienie podanymi wartościami, natomiast &amp;lt;tt&amp;gt;*&amp;gt;&amp;lt;/tt&amp;gt; oznacza, że gwiazdka ma być ,,wypełniaczem&amp;quot; pustego miejsca, jeżeli takie pozostanie w zadanej wielkości pola po wstawieniu wartości, a znak &amp;lt;tt&amp;gt;&amp;gt;&amp;lt;/tt&amp;gt; oznacza wyrównanie (wewnątrz pola) do strony prawej. Więcej szczegółów - w [https://docs.python.org/3/library/string.html#formatstrings dokumentacji].&lt;br /&gt;
&lt;br /&gt;
Począwszy od wersji 3.6 języka Python wprowadzono uproszczoną składnię formatowania napisów. Poprzedzając w zapisie napisu literalnego otwierający cudzysłów (lub apostrof) literą &amp;lt;tt&amp;gt;f&amp;lt;/tt&amp;gt; (lub &amp;lt;tt&amp;gt;F&amp;lt;/tt&amp;gt;), możemy w tym napisie skorzystać z sekwencji w parach nawiasów klamrowych, gdzie wewnątrz nawiasów umieszczamy (zamiast jak wyżej &amp;amp;mdash; numeru pozycji w liście argumentów wywołania &amp;lt;tt&amp;gt;format()&amp;lt;/tt&amp;gt;) po prostu zapis wyrażenia w Pythonie, którego aktualna wartość znajdzie się w tym miejscu w wyniku ewaluacji, plus ewentualnie dwukropek a po nim dyrektywy formatowania, jak wyżej. Przykłady:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
x, y = 1.2, 9&lt;br /&gt;
f'x = {x}, y = {y}'&lt;br /&gt;
→ x = 1.2, y = 9&lt;br /&gt;
f'wynik działania arytmetycznego: {2 * x + y}'&lt;br /&gt;
→ wynik działania arytmetycznego: 11.4&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Jeżeli chcemy, aby w wyniku wystąpiły dosłowne nawiasy klamrowe, a nie zostały one zinterpretowane jako pole do wypełnienia wartością wyrażenia, to musimy je podwoić (&amp;lt;tt&amp;gt;f'{{'&amp;lt;/t&amp;gt; → { itd.)&lt;br /&gt;
&lt;br /&gt;
=Ćwiczenia=&lt;br /&gt;
&lt;br /&gt;
1. Ile wynosi najmniejsza liczba &amp;lt;tt&amp;gt;N&amp;lt;/tt&amp;gt;, dla której &amp;lt;tt&amp;gt;S_N = 1 + 2**3 + 3**3 + ... + N**3&amp;lt;/tt&amp;gt;&lt;br /&gt;
jest liczbą której zapis dziesiętny ma więcej niż M cyfr? Napisać funkcję &amp;lt;tt&amp;gt;znajdzN(M)&amp;lt;/tt&amp;gt;, która wyznacza i zwraca tę liczbę.&lt;br /&gt;
&lt;br /&gt;
''CDN''&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
[[PPy3/Funkcje|poprzednie]] | [[&amp;quot;Programowanie z Pythonem3&amp;quot;|strona główna]] | [[PPy3/Moduły|dalej]]&lt;br /&gt;
&lt;br /&gt;
[[Użytkownik:RobertJB|RobertJB]] ([[Dyskusja użytkownika:RobertJB|dyskusja]]) 16:06, 5 lip 2016 (CEST)&lt;/div&gt;</summary>
		<author><name>RobertJB</name></author>
		
	</entry>
	<entry>
		<id>http://brain.fuw.edu.pl/edu/index.php?title=PPy3/Funkcje&amp;diff=8924</id>
		<title>PPy3/Funkcje</title>
		<link rel="alternate" type="text/html" href="http://brain.fuw.edu.pl/edu/index.php?title=PPy3/Funkcje&amp;diff=8924"/>
		<updated>2022-07-29T13:05:47Z</updated>

		<summary type="html">&lt;p&gt;RobertJB: /* Definiowanie funkcji */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=Funkcje=&lt;br /&gt;
&lt;br /&gt;
Gdy raz wymyślimy jakiś sprytny algorytm, to nie ma co go za każdym razem odkrywać na nowo. Żeby było łatwiej pisać raz, a korzystać wielokrotnie - wymyślono funkcje.&lt;br /&gt;
&lt;br /&gt;
==Definiowanie funkcji==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
def funkcja(x, y):&lt;br /&gt;
    BLOK INSTRUKCJI&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*Definicja funkcji to instrukcja złożona, podobna w strukturze do tych, które już znamy - instrukcji warunkowej i pętli.&lt;br /&gt;
*Wykonanie definicji funkcji ''nie wiąże się z natychmiastowym wykonaniem zawartego w niej bloku''.&lt;br /&gt;
*W definicji funkcji (przykładowej) &amp;lt;tt&amp;gt;x&amp;lt;/tt&amp;gt; i &amp;lt;tt&amp;gt;y&amp;lt;/tt&amp;gt; to ''parametry formalne''; nie mają one w tym momencie określonych wartości, są miejscami do wypełnienia konkretnymi wartościami, gdy funkcję postanowimy użyć. Może ich być (niemal) dowolnie wiele, w tym &amp;amp;mdash; zero. W tym ostatnim przypadku piszemy pustą parę nawiasów.&lt;br /&gt;
*Wykonanie definicji funkcji polega na nadaniu znaczenia jej nazwie, która odtąd będzie oznaczała ciąg instrukcji stanowiących wewnętrzny blok.&lt;br /&gt;
*Użycie czyli ''wywołanie'' funkcji to wyrażenie postaci&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
funkcja(x, y)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
gdzie &amp;lt;tt&amp;gt;x&amp;lt;/tt&amp;gt; i &amp;lt;tt&amp;gt;y&amp;lt;/tt&amp;gt; mają już konkretne wartości (w tym miejscu mogą stać również wyrażenia złożone), które będą użyte w instrukcjach stanowiących definicję.&lt;br /&gt;
&lt;br /&gt;
*W definicji na ogół występuje (raz lub więcej razy) słowo (instrukcja) &amp;lt;tt&amp;gt;return&amp;lt;/tt&amp;gt;. Oznacza ono, że w tym miejscu wykonanie funkcji się kończy - funkcja powraca. Wartość wyrażenia po słowie &amp;lt;tt&amp;gt;return&amp;lt;/tt&amp;gt; stanowi wynik zwracany przez funkcję - czyli wartość wyrażenia, będącego wywołaniem funkcji.&lt;br /&gt;
*Jeśli &amp;lt;tt&amp;gt;return&amp;lt;/tt&amp;gt; nie ma, albo nie ma po nim wartości zwracanej, albo wykonanie funkcji kończy się ,,wypadnięciem&amp;quot; przez koniec bloku, wartością zwracaną jest &amp;lt;tt&amp;gt;None&amp;lt;/tt&amp;gt; &amp;amp;mdash; która w zasadzie do niczego się specjalnie nie nadaje, poza sprawdzeniem, czy mamy do czynienia z właśnie tą wartością.&lt;br /&gt;
*''funkcja'' w Pythonie (i większości języków programowania) to coś nieco podobnego do funkcji (odwzorowania) w matematyce, ale '''to nie jest to samo pojęcie''':&lt;br /&gt;
**w Pythonie wywołanie funkcji może mieć skutki uboczne;&lt;br /&gt;
**wynik funkcji, w tym skutki uboczne, może zależeć nie tylko od argumentów wywołania.&lt;br /&gt;
Skutkami ubocznymi wywołania nazywamy jakiekolwiek efekty tej instrukcji, które nie sprowadzają się do wartości zwracanej. A więc, zmianę wartości innych zmiennych, czy np. wysłanie jakichś danych siecią, lub wypisanie czegoś na ekran.&lt;br /&gt;
*Funkcja może być wartością zmiennej; inaczej mówiąc, funkcja może być znana pod dodatkowymi nazwami (aliasami), może być włożona do listy na którąś z jej pozycji itp.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
ff = funkcja&lt;br /&gt;
...&lt;br /&gt;
wynik = ff(x)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*,,Oryginalna&amp;quot; nazwa funkcji, czyli występująca w jej definicji, jest jednak w pewnym sensie uprzywilejowana.&lt;br /&gt;
*Zmienne (nazwy) '''powołane do życia''' wewnątrz funkcji są lokalne; ich wartości ,,żyją&amp;quot; tylko póki wykonuje się funkcja.&lt;br /&gt;
*Zmienne lokalne powielające nazwy ,,zewnętrzne&amp;quot; względem funkcji przesłaniają te zewnętrzne. Chyba, że użyjemy deklaracji &amp;lt;tt&amp;gt;global&amp;lt;/tt&amp;gt;:&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
x = 1&lt;br /&gt;
def podwojx():  # to nie zadziała:&lt;br /&gt;
    x = x * 2&lt;br /&gt;
podwojx()&lt;br /&gt;
UnboundLocalError                         Traceback (most recent call last)&lt;br /&gt;
&amp;lt;ipython-input-3-6edd575e5cda&amp;gt; in &amp;lt;module&amp;gt;()&lt;br /&gt;
----&amp;gt; 1 podwojx()&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ipython-input-1-1da635f42ffa&amp;gt; in podwojx()&lt;br /&gt;
      1 def podwojx():&lt;br /&gt;
----&amp;gt; 2     x *= 2&lt;br /&gt;
      3 &lt;br /&gt;
&lt;br /&gt;
UnboundLocalError: local variable 'x' referenced before assignment&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Jak widzimy, komunikat o błędzie pojawił się dopiero w wyniku wywołania błędnej funkcji.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
x = 1&lt;br /&gt;
def podwojx():  # to zadziała - co nie znaczy, że jest mądre...&lt;br /&gt;
    global x&lt;br /&gt;
    x = x * 2&lt;br /&gt;
podwojx()&lt;br /&gt;
print x&lt;br /&gt;
→ 2&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Należy unikać takich sztuczek, jak powyżej; jeśli już, to:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
def podwoj(x):&lt;br /&gt;
    return 2 * x&lt;br /&gt;
liczba = 1&lt;br /&gt;
print podwoj(liczba)&lt;br /&gt;
→ 2&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
''Wskazówka:'' każde użycie deklaracji &amp;lt;tt&amp;gt;global&amp;lt;/tt&amp;gt; w programie powinno być dobrze uzasadnione. Jeżeli używamy jej więcej niż sporadycznie, to coś jest nie tak.&lt;br /&gt;
&lt;br /&gt;
Funkcja może być &lt;br /&gt;
&lt;br /&gt;
*jednoargumentowa (jak powyższa &amp;lt;tt&amp;gt;podwoj&amp;lt;/tt&amp;gt;), &lt;br /&gt;
*dwuargumentowa (jak przykładowa),&lt;br /&gt;
*trzy-, cztero-, ... itd.&lt;br /&gt;
*o zmiennej liczbie argumentów, z wartościami domyślnymi dla brakujących:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
def dodaj(x, y=1):&lt;br /&gt;
    return x + y&lt;br /&gt;
dodaj(2, 3)&lt;br /&gt;
→ 5&lt;br /&gt;
dodaj(2)&lt;br /&gt;
→ 3&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Parametry z wartościami domyślnymi muszą występować na końcu listy parametrów.&lt;br /&gt;
&lt;br /&gt;
=Ćwiczenia=&lt;br /&gt;
&lt;br /&gt;
1. Napisz funkcję &amp;lt;tt&amp;gt;pierwiastki(a, b, c)&amp;lt;/tt&amp;gt;, która wypisuje na ekran (za pomocą wywołania &amp;lt;tt&amp;gt;print&amp;lt;/tt&amp;gt;) pierwiastki równania kwadratowego o wspołczynnikach ''a'', ''b'' i ''c'': &amp;lt;tt&amp;gt;a * x**2 + b * x + c == 0&amp;lt;/tt&amp;gt;. W przypadku, gdy pierwiastków nie ma, wypisuje komunikat ''Równanie nie ma pierwiastków.'' W przypadku, gdy ''a=0'', wypisuje komunikat ''Błędne dane: a==0'' i kończy działanie.&lt;br /&gt;
&lt;br /&gt;
2. Napisz analogiczną funkcję, która zamiast bezpośrednio wypisywać rozwiązania, zwraca je jako wynik swojego działania. Wypisaniem ich na ekran zajmuje się odrębna instrukcja. W przypadku, gdy pierwiastków nie ma, zwraca wartość &amp;lt;tt&amp;gt;None&amp;lt;/tt&amp;gt;. Nie sprawdzaj warunku ''a!=0'' - co się dzieje, gdy nie jest spełniony przez argumenty wywołania funkcji?&lt;br /&gt;
&lt;br /&gt;
3. Napisz funkcję &amp;lt;tt&amp;gt;silnia(n)&amp;lt;/tt&amp;gt;, która oblicza i zwraca wartość silni: &amp;lt;tt&amp;gt;n! := 1 * 2 * 3 * ... (n - 1) * n&amp;lt;/tt&amp;gt;. Uwzględnij, że przyjmuje się że &amp;lt;tt&amp;gt;0! = 1&amp;lt;/tt&amp;gt;, natomiast dla liczb ujemnych silnia nie jest określona - co można zasygnalizować zwracając jako wynik &amp;lt;tt&amp;gt;None&amp;lt;/tt&amp;gt;. Użyj pętli &amp;lt;tt&amp;gt;for&amp;lt;/tt&amp;gt; i funkcji &amp;lt;tt&amp;gt;range&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
4. Funkcję silnia można zdefiniować w sposób rekurencyjny - za pomocą następujących warunków:&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;n! == None&amp;lt;/tt&amp;gt; dla &amp;lt;tt&amp;gt;n &amp;lt; 0&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;0! == 1&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;n! == n * (n - 1)!&amp;lt;/tt&amp;gt;&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
Napisz kod funkcji &amp;lt;tt&amp;gt;silnia(n)&amp;lt;/tt&amp;gt; realizujący powyższą definicję. Porównaj działanie tego kodu z realizacją tej funkcji z poprzedniego przykładu dla dużych wartości &amp;lt;tt&amp;gt;n&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
[[PPy3/SekwencjeIIteracja|poprzednie]] | [[&amp;quot;Programowanie z Pythonem3&amp;quot;|strona główna]] | [[PPy3/Kolekcje|dalej]]&lt;br /&gt;
&lt;br /&gt;
[[Użytkownik:RobertJB|RobertJB]] ([[Dyskusja użytkownika:RobertJB|dyskusja]]) 16:10, 30 cze 2016 (CEST)&lt;/div&gt;</summary>
		<author><name>RobertJB</name></author>
		
	</entry>
	<entry>
		<id>http://brain.fuw.edu.pl/edu/index.php?title=PPy3/SekwencjeIIteracja&amp;diff=8923</id>
		<title>PPy3/SekwencjeIIteracja</title>
		<link rel="alternate" type="text/html" href="http://brain.fuw.edu.pl/edu/index.php?title=PPy3/SekwencjeIIteracja&amp;diff=8923"/>
		<updated>2022-07-29T12:58:23Z</updated>

		<summary type="html">&lt;p&gt;RobertJB: /* Sekwencje i iteracja */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=Sekwencje i iteracja=&lt;br /&gt;
&lt;br /&gt;
'''Sekwencje''' to typ danych charakteryzujący się tym, że składają się z ''elementów'' zgromadzonych w pewnej ''kolejności''. Elementem sekwencji może być cokolwiek (w tym - inna sekwencja), ale w najprostszym przypadku elementami tymi są liczby.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&amp;lt;small&amp;gt;&lt;br /&gt;
Sekwencje to szczególny przypadek ''kolekcji'' - takich typów danych, które składają się z elementów, ale niekoniecznie są one uporządkowane. Innym przykładem kolekcji jest zbiór (''set'').&lt;br /&gt;
&amp;lt;/small&amp;gt;&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Najczęściej używanym typem sekwencji jest ''lista'' (''list''). Listę można stworzyć (i zapamiętać) np. nadając jej pewien początkowy skład:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
numerki = [0, 1, 2, 3, 5, 8]&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To co stoi po prawej stronie znaku równości to literalny zapis listy - ciąg elementów, oddzielonych przecinkami, wewnątrz pary nawiasów kwadratowych. Oczywiście jako elementy mogą występować zarówno stałe literalne - jak w tym przykładzie, jak i nazwy (zmienne) &amp;amp;mdash; oczywiście takie, którym uprzednio nadano wartości.&lt;br /&gt;
&lt;br /&gt;
Z listy - podobnie jak z każdej sekwencji - można pobrać element stojący w dowolnej pozycji, podając jej numer:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
print(numerki[4])&lt;br /&gt;
→ 5&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Uwaga:''' pozycje numerowane są kolejnymi liczbami naturalnymi, począwszy od zera - podobnie, jak w większości języków programowania.&lt;br /&gt;
&lt;br /&gt;
Sięgnięcie po element nie występujący w liście, to znaczy podanie numeru pozycji poza zakresem rozmiaru danej listy, będzie błędem i domyślnie spowoduje przerwanie wykonywania programu.&lt;br /&gt;
&lt;br /&gt;
Można też podmienić istniejący element na inny:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
numerki[0] = -1&lt;br /&gt;
print(numerki)&lt;br /&gt;
→ [-1, 1, 2, 3, 5, 8]&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
a nawet przedłużyć ją o kolejny element:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
numerki.append(13)&lt;br /&gt;
print(numerki)&lt;br /&gt;
→ [-1, 1, 2, 3, 5, 8, 13]&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
oraz usunąć element (skracając listę):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
del numerki[0]&lt;br /&gt;
print numerki&lt;br /&gt;
→ [1, 2, 3, 5, 8, 13]&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Łatwo też ustalić, jaka jest ,,długość&amp;quot; listy, czyli liczba jej elementów:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
print(len(numerki))&lt;br /&gt;
→ 6&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Jest jeszcze sporo innych ,,gotowych do użytku&amp;quot; operacji na listach. Ale najważniejsza cecha listy jest taka: '''można zmieniać jej skład, a nawet długość, a pozostaje ona tą samą listą'''. Nawet jeśli występuje w programie pod więcej niż jedną nazwą.&lt;br /&gt;
&lt;br /&gt;
==Pętla &amp;lt;tt&amp;gt;for&amp;lt;/tt&amp;gt;==&lt;br /&gt;
&lt;br /&gt;
Naczelne zastosowanie listy (czy ogólniej -sekwencji), to iteracja - czyli wykonanie jakiejś operacji dla każdego elementu. I tak wygląda najprostszy rodzaj iteracji - Pętla &amp;lt;tt&amp;gt;for&amp;lt;/tt&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
for x in numerki:&lt;br /&gt;
    print(x)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Zamiast &amp;lt;tt&amp;gt;print(x)&amp;lt;/tt&amp;gt; pętlę &amp;lt;tt&amp;gt;for&amp;lt;/tt&amp;gt; może tworzyć dowolny blok instrukcji, zgodnie z zasadami jakie już poznaliśmy przy omawianiu instrukcji warunkowej. Cały blok tworzący wnętrze pętli będzie wykonany wielokrotnie, tyle razy, ile elementów ma lista, a za każdym razem pod nazwę stojącą bezpośrednio po słowie &amp;lt;tt&amp;gt;for&amp;lt;/tt&amp;gt; podstawiony będzie kolejny element listy (przywołanej po słowie &amp;lt;tt&amp;gt;in&amp;lt;/tt&amp;gt;) - kolejny, tzn. zgodnie z kolejnością, w jakiej umieszczone są one w liście.&lt;br /&gt;
&lt;br /&gt;
Inny, znany nam już rodzaj sekwencji to napis (''string''), zwany czasami ''łańcuchem znakowym''. Napis składa się ze znaków, i jest w szczególności sekwencją, której elementami są znaki. Analogicznie jak w przypadku listy, można pobierać znaki stojące na poszczególnych pozycjach w napisie. '''Nie można''' natomiast podmieniać znaków w napisie, ani ich usuwać bądź dopisywać:  w odróżnieniu od listy, napis raz utworzony jest ''niezmienny''. Można go zastąpić innym napisem, i ewentualnie opatrzyć ten nowy napis tą samą nazwą, ale nie da się go zmodyfikować. I nie jest to dzielenie włosa na czworo, własność ta ma namacalne konsekwencje:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
napis1 = 'abc'&lt;br /&gt;
napis2 = napis1&lt;br /&gt;
napis1 = 'ABC'&lt;br /&gt;
print(napis1, napis2)&lt;br /&gt;
→ ABC abc&lt;br /&gt;
# dla porównania, listy:&lt;br /&gt;
lista1 = ['a', 'b', 'c']&lt;br /&gt;
lista2 = lista1&lt;br /&gt;
lista1[0] = 'A'&lt;br /&gt;
print(lista1, lista2)&lt;br /&gt;
→ ['A', 'b', 'c'] ['A', 'b', 'c']&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&amp;lt;small&amp;gt;&lt;br /&gt;
Powraca jeszcze raz pytanie: czym są poszczególne znaki? Tzn. jaki typ danych reprezentują? Otóż w Pythonie pojedyncze znaki też są po prostu napisami, tyle że o długości jeden. Poza długością nic ich szczególnie nie wyróżnia. Ta uwaga jest na użytek tych z Was, którzy znają jakiś inny język programowania, gdyż w wielu z nich znak jest oddzielnym, innym niż napis typem danych.&lt;br /&gt;
&amp;lt;/small&amp;gt;&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Pętlę &amp;lt;tt&amp;gt;for&amp;lt;/tt&amp;gt; można zatem zastosować do napisu - zamiast do listy, wówczas w kolejnych iteracjach będą uwzględniane kolejne znaki, a których składa się napis.&lt;br /&gt;
&lt;br /&gt;
===Ogólna postać pętli &amp;lt;tt&amp;gt;for&amp;lt;/tt&amp;gt;===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
for element in sekwencja:&lt;br /&gt;
    &amp;lt;blok instrukcji&amp;gt;&lt;br /&gt;
else:&lt;br /&gt;
    &amp;lt;blok instrukcji&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*Pierwszy blok instrukcji będzie wykonany ''w zasadzie'' tyle razy, ile elementów ma sekwencja&lt;br /&gt;
*Za każdym razem nazwa ''element'' oznaczać będzie kolejny element sekwencji, zgodnie z ich porządkiem&lt;br /&gt;
*''sekwencja'' może być pusta; nie jest to błąd, ale wtedy pierwszy blok nie będzie wykonany ani razu&lt;br /&gt;
*Gdy elementy sekwencji się wyczerpią, wykonany zostanie blok po &amp;lt;tt&amp;gt;else&amp;lt;/tt&amp;gt;&lt;br /&gt;
*Blok &amp;lt;tt&amp;gt;else&amp;lt;/tt&amp;gt; (wraz z linijką go otwierającą) jest opcjonalny (niekonieczny)&lt;br /&gt;
*W pierwszym bloku mogą wystąpić specjalne polecenia: &amp;lt;tt&amp;gt;break&amp;lt;/tt&amp;gt; i &amp;lt;tt&amp;gt;continue&amp;lt;/tt&amp;gt;&lt;br /&gt;
**&amp;lt;tt&amp;gt;break&amp;lt;/tt&amp;gt; znaczy: przerwij pętlę natychmiast, pomiń wszystkie pozostałe elementy sekwekcji, '''pomiń również ewentualny blok &amp;lt;tt&amp;gt;else&amp;lt;/tt&amp;gt;'''&lt;br /&gt;
**&amp;lt;tt&amp;gt;continue&amp;lt;/tt&amp;gt; oznacza: przerwij działania na aktualnym elemencie, i wróć do początku bloku biorąc kolejny element. Jeśli już zabrakło elementów, przejdź do bloku &amp;lt;tt&amp;gt;else&amp;lt;/tt&amp;gt;, albo (gdy go nie ma) do polecenia następnego po pętli&lt;br /&gt;
*W miejscu gdzie stoi ''sekwencja'' może tak naprawdę stać dowolny obiekt ''iterowalny'' - np. kolekcja. Ale innych typów kolekcji jeszcze nie poznaliśmy...&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&amp;lt;small&amp;gt;&lt;br /&gt;
Blok &amp;lt;tt&amp;gt;else&amp;lt;/tt&amp;gt; w pętli &amp;lt;tt&amp;gt;for&amp;lt;/tt&amp;gt; jest stosunkowo rzadko widywany. Nawet wielu programistów dość biegłych w Pythonie nie wie (lub zapomniało) o istnieniu tej opcji.&lt;br /&gt;
&amp;lt;/small&amp;gt;&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A co, jeśli chcielibyśmy za pomocą pętli &amp;lt;tt&amp;gt;for&amp;lt;/tt&amp;gt; (lub inaczej) zmienić w jakiś sposób skład samej sekwencji? Na przykład:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
for x in lista:&lt;br /&gt;
    x = x + 1&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''TO NIE ZADZIAŁA''' - w tym sensie, że ''lista'' będzie dalej miała te same elementy co poprzednio, a nie - powiększone o 1. W istocie operacja taka nic nie osiąga - oprócz tego, że po jej zakończeniu nazwa ''x'' ma wartość ostatniego elementu listy, powiększonego o 1. To samo można dostać bez pisania pętli. &lt;br /&gt;
&lt;br /&gt;
Jak więc osiągnąć zmianę - przeliczenie - wszystkich elementów sekwencji wg. jakiejś reguły (np. powiększ każdy z nich o 1)?&lt;br /&gt;
&lt;br /&gt;
Pożytecznym sposobem tworzenia sekwencji jest funkcja &amp;lt;tt&amp;gt;range&amp;lt;/tt&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
for x in range(3):&lt;br /&gt;
    print(x)&lt;br /&gt;
→ 0&lt;br /&gt;
→ 1&lt;br /&gt;
→ 2&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Argument (tu: 3) oznacza liczbę elementów w wyprodukowanej sekwencji. Domyślnie zaczyna się ona od zera, tak jak numeracja pozycji w sekwencjach - ale można użyć wywołania &amp;lt;tt&amp;gt;range(a, b)&amp;lt;/tt&amp;gt; aby uzyskać elementy dowolnego ciągu arytmetycznego - o elemencie początkowym ''a'' i przyroście ''b''.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&amp;lt;small&amp;gt;&lt;br /&gt;
Tu jest pewne oszustwo: wynikiem wywołania &amp;lt;tt&amp;gt;range&amp;lt;/tt&amp;gt; nie jest tak naprawdę lista, ale pewnego innego rodzaju typ sekwencji, a więc mogący służyć za źródło elementów w iteracji. Na razie to jest jednak drobny szczegół. Jeżeli potrzebujemy dosłownej listy o takich elementach, wystarczy wykonać tzw. rzutowanie, czyli przyłożyć funkcję &amp;lt;tt&amp;gt;list&amp;lt;/tt&amp;gt;: &amp;lt;tt&amp;gt;lista = list(range(3))&amp;lt;/tt&amp;gt;&lt;br /&gt;
&amp;lt;/small&amp;gt;&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wracając do problemu przeliczenia wszystkich elementów listy:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
lista = [3, 5, 8]&lt;br /&gt;
for k in range(3):&lt;br /&gt;
    lista[k] += 1&lt;br /&gt;
print lista&lt;br /&gt;
→ [4, 6, 9]&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
I to działa. Nie jest to jednak optymalne rozwiązanie.&lt;br /&gt;
&lt;br /&gt;
*Pisząc to co powyżej wiedzieliśmy, że mamy do czynienia z listą o długości 3. W ogólności musielibyśmy użyć funkcji &amp;lt;tt&amp;gt;len&amp;lt;/tt&amp;gt;;&lt;br /&gt;
*Można to jednak zrobić bardziej elegancko:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
for k, x in enumerate(lista):&lt;br /&gt;
    lista[k] = x + 1&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Funkcja &amp;lt;tt&amp;gt;enumerate&amp;lt;/tt&amp;gt; produkuje sekwencję par: ''nr pozycji'', ''element'' - i jest bardzo przydatna w takich sytuacjach. &lt;br /&gt;
&lt;br /&gt;
Z dokonywaniem wewnątrz pętli zmian na sekwencji, po której iterujemy, należy jednak uważać. To, co robimy w tym przykładzie jest akurat niegroźne, natomiast umieszczenie wewnątrz pętli operacji zmieniających '''długość''' sekwencji, po której iterujemy mogłoby dać nieoczekiwane wyniki. Spróbuj np.:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
L = [0, 1, 2, 3, 4]&lt;br /&gt;
for i in range(5):&lt;br /&gt;
    del L[i]&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Co tu się stanie, i dlaczego?&lt;br /&gt;
&lt;br /&gt;
==Więcej o listach==&lt;br /&gt;
&lt;br /&gt;
Elementy listy (innych rodzajów sekwencji również) można numerować od końca, używając ujemnych wartości wskaźników pozycji:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
numerki = [0, 1, 2, 3, 5, 8]&lt;br /&gt;
numerki[-1]&lt;br /&gt;
→ 8&lt;br /&gt;
numerki[-3]&lt;br /&gt;
→ 3&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Z list (i innych sekwencji) można wyjmować nie tylko poszczególne elementy, ale również podsekwencje, zwane też wycinkami:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
numerki = [0, 1, 2, 3, 5, 8]&lt;br /&gt;
nn = numerki[1:4]&lt;br /&gt;
→ [1, 2, 3]&lt;br /&gt;
nn = numerki[2:]&lt;br /&gt;
→ [2, 3, 5, 8]&lt;br /&gt;
nn = numerki[:3]&lt;br /&gt;
→ [0, 1, 2]&lt;br /&gt;
nn = numerki[1:4:2]&lt;br /&gt;
→ [1, 3]&lt;br /&gt;
nn = numerki[4:1:-1]&lt;br /&gt;
→ [5, 3, 2]&lt;br /&gt;
nn = numerki[:]&lt;br /&gt;
→ [0, 1, 2, 3, 5, 8]&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Jak widać, pominięcie pozycji początkowej lub końcowej oznacza: ,,do oporu&amp;quot;. Trzecia liczba charakteryzująca wycinek, o ile występuje - to ,,skok&amp;quot; wskaźnika. Przykładowo, &amp;lt;tt&amp;gt;a[::2]&amp;lt;/tt&amp;gt; oznaczałoby listę zawierającą co drugi element listy &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt;, natomiast &amp;lt;tt&amp;gt;a[::-1]&amp;lt;/tt&amp;gt;: listę składającą się z tych samych elementów, co &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; - lecz w odwrotnej kolejności.&lt;br /&gt;
&lt;br /&gt;
Wyrażenie &amp;lt;tt&amp;gt;numerki[:]&amp;lt;/tt&amp;gt;, tzw. pełny wycinek, tworzy pełną ''kopię'' listy &amp;lt;tt&amp;gt;numerki&amp;lt;/tt&amp;gt;; tzn. '''nie''' jest to ''ta sama'' lista, chociaż składa się z tych samych elementów. Jest to tzw. ''kopia płytka'' - oznacza to tyle, że jeżeli wśród elementów kopiowanej listy były obiekty złożone (np. inne listy), to elementami kopii będą '''te same''' listy, a nie - ich kopie.&lt;br /&gt;
&lt;br /&gt;
Wycinek jest zawsze nową listą, również w ostatnim przypadku - gdy jej skład jest taki sam, jak oryginalnej. Wtedy stanowi kopię pierwotnej listy. Można jednak też podstawiać do wycinka:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
numerki[4:5] = [4]&lt;br /&gt;
→ [0, 1, 2, 3, 4, 8]&lt;br /&gt;
numerki[5:5] = [5, 6, 7]&lt;br /&gt;
→ [0, 1, 2, 3, 4, 5, 6, 7, 8]&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
i jest to jeszcze jeden sposób, by zmienić zawartość listy - w tym być może jej długość - zachowując jej tożsamość.&lt;br /&gt;
&lt;br /&gt;
Listy można do siebie dodawać:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
l = ['a', 'b', 'c'] + ['y', 'z']&lt;br /&gt;
→ ['a', 'b', 'c', 'y', 'z']&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
w ten sposób powstaje nowa lista, która ze składników bierze elementy, ale poza tym nie ma z nimi nic wspólnego; późniejsze zmiany w listach-składnikach nie mają wpływu na sumę.&lt;br /&gt;
&lt;br /&gt;
Listy można też zwielokrotnić; np. aby uzyskać listę siedmiu dwójek:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
l = [2] * 7&lt;br /&gt;
→ [2, 2, 2, 2, 2, 2, 2]&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
ta sama co poprzednio uwaga stosuje się i tu.&lt;br /&gt;
&lt;br /&gt;
Elementy listy można posumować:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
x = sum(range(101))&lt;br /&gt;
→ 5050&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
(wprawdzie &amp;lt;tt&amp;gt;range(101)&amp;lt;/tt&amp;gt; nie jest dosłownie listą, ale z ,,prawdziwą&amp;quot; listą można zrobić to samo).&lt;br /&gt;
&lt;br /&gt;
Podobnie jak inne ''obiekty'', listy posiadają szereg ''metod'', za pomocą których można na nich wykonywać różne działania. Przykładowo:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
numerki.append(9)&lt;br /&gt;
→ [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]&lt;br /&gt;
numerki.extend([10, 11])&lt;br /&gt;
→ [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Zwróćcie uwagę na notację: kropka sygnalizuje ,,wyciągnięcie&amp;quot; metody z danego obiektu (tu: listy), w nawiasach wpisujemy dane dla tej metody (argumenty - tu pojedyncze, ale może być więcej).&lt;br /&gt;
&lt;br /&gt;
==Więcej o napisach==&lt;br /&gt;
&lt;br /&gt;
Napisy dopuszczają tylko część operacji dostępnych dla list, ze względu na własność niemodyfikowalności. Posiadają za to szereg swoistych metod. Trzeba pamiętać, że żadna z tych metod ''nie zmienia'' napisu, którego dotyczy - wynikiem może być jedynie '''nowy''' napis, stworzony na podstawie oryginalnego.&lt;br /&gt;
&lt;br /&gt;
Niemniej napis ''również'' jest sekwencją, i może być np. zastosowany w pętli &amp;lt;tt&amp;gt;for&amp;lt;/tt&amp;gt;. Ale sekwencją czego? Oczywiście znaków &amp;amp;mdash; z tym, że w Pythonie nie ma oddzielnego typu danych ,,znak&amp;quot;. Znaki to po prostu napisy jednoelementowe. &lt;br /&gt;
&lt;br /&gt;
Przykład: metoda &amp;lt;tt&amp;gt;upper&amp;lt;/tt&amp;gt; (zamienia małe litery na wielkie):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
'abcde'.upper()&lt;br /&gt;
→ 'ABCDE'&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Napis zawsze można łatwo zamienić na listę znaków:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
l = list('abcde')&lt;br /&gt;
→ ['a', 'b', 'c', 'd', 'e']&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
(choć rzadko zachodzi taka potrzeba).&lt;br /&gt;
&lt;br /&gt;
Do operacji odwrotnej można użyć metody &amp;lt;tt&amp;gt;join&amp;lt;/tt&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
''.join(l)&lt;br /&gt;
→ 'abcde'&lt;br /&gt;
', '.join(l)&lt;br /&gt;
→ 'a, b, c, d, e'&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Pętla &amp;lt;tt&amp;gt;while&amp;lt;/tt&amp;gt;==&lt;br /&gt;
&lt;br /&gt;
To jeszcze jeden sposób iteracji, tak naprawdę prostszy od pętli &amp;lt;tt&amp;gt;for&amp;lt;/tt&amp;gt; &amp;amp;mdash; gdyż nie oparty na sekwencjach; zwykle mniej wygodny w użyciu, ale w niektórych przypadkach nieodzowny.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
# postać najprostsza&lt;br /&gt;
&lt;br /&gt;
while WARUNEK:&lt;br /&gt;
    BLOK INSTRUKCJI&lt;br /&gt;
&lt;br /&gt;
# ogólna postać:&lt;br /&gt;
&lt;br /&gt;
while WARUNEK:&lt;br /&gt;
    BLOK1&lt;br /&gt;
else:&lt;br /&gt;
    BLOK2&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Polega na powtarzaniu bloku instrukcji nieokreśloną liczbę razy; przed każdym kolejnym wykonaniem na nowo sprawdzany jest warunek, i jeśli okaże się fałszywy - powtarzanie się kończy.&lt;br /&gt;
&lt;br /&gt;
Innym sposobem przerwania pętli &amp;lt;tt&amp;gt;while&amp;lt;/tt&amp;gt; jest umieszczenie gdzieś w bloku instrukcji &amp;lt;tt&amp;gt;break&amp;lt;/tt&amp;gt; - zwykle pod pewnym warunkiem (tzn. wewnątrz instrukcji warunkowej &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt;). Wykonanie break polega na ,,wyskoczeniu&amp;quot; z pętli - i przejściu do dalszego ciągu programu, po bloku wewnętrznym pętli.&lt;br /&gt;
&lt;br /&gt;
Oczywiście aby &amp;lt;tt&amp;gt;WARUNEK&amp;lt;/tt&amp;gt; mógł okazać się za którymś razem fałszywy, i spowodować przerwanie pętli, musi on być zbudowany z wykorzystaniem zmiennych, których wartości ulegają zmianom wewnątrz pętli. Zdarza się jednak widzieć pętlę zaczynającą się od &amp;lt;tt&amp;gt;while True:&amp;lt;/tt&amp;gt; - formalnie jest to pętla nieskończona, którą może zakończyć jedynie wywołanie instrukcji &amp;lt;tt&amp;gt;break&amp;lt;/tt&amp;gt; występującej gdzieś w wewnętrznym bloku.&lt;br /&gt;
&lt;br /&gt;
Wewnątrz bloku może wystąpić również instrukcja &amp;lt;tt&amp;gt;continue&amp;lt;/tt&amp;gt; - działa ona analogicznie, jak w pętli &amp;lt;tt&amp;gt;for&amp;lt;/tt&amp;gt;, a więc powoduje przerwanie wykonywania aktualnej iteracji i przeskok do początku pętli, czyli sprawdzenia warunku jej kontynuowania.&lt;br /&gt;
&lt;br /&gt;
W ogólnej postaci, blok występujący po linijce &amp;lt;tt&amp;gt;else:&amp;lt;/tt&amp;gt; jest wykonywany po zakończeniu pętli wskutek niespełnienia warunku początkowego, natomiast jest pomijany, jeśli przerwanie pętli było spowodowane instrukcją &amp;lt;tt&amp;gt;break&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Zasadniczo każdą pętlę &amp;lt;tt&amp;gt;for&amp;lt;/tt&amp;gt; dałoby się przepisać jako równoważną pętlę &amp;lt;tt&amp;gt;while&amp;lt;/tt&amp;gt; - przykładowo:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
for x in lista:&lt;br /&gt;
    działaj_na(x)&lt;br /&gt;
&lt;br /&gt;
# równoważnie:&lt;br /&gt;
&lt;br /&gt;
k = 0&lt;br /&gt;
while k &amp;lt; len(lista):&lt;br /&gt;
    działaj_na(lista[k])&lt;br /&gt;
    k += 1&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
nie należy jednak zazwyczaj tego robić, ponieważ (najczęściej) pętla &amp;lt;tt&amp;gt;for&amp;lt;/tt&amp;gt; jest bardziej czytelna.&lt;br /&gt;
&lt;br /&gt;
=Ćwiczenia=&lt;br /&gt;
&lt;br /&gt;
1. Napisać program, który sumuje liczby naturalne od 1 do 100:&lt;br /&gt;
&lt;br /&gt;
*z wykorzystaniem pętli &amp;lt;tt&amp;gt;for&amp;lt;/tt&amp;gt;&lt;br /&gt;
*z wykorzystaniem pętli &amp;lt;tt&amp;gt;while&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
2. Wykorzystując pętlę &amp;lt;tt&amp;gt;while&amp;lt;/tt&amp;gt; napisać program, który sprawdza czy zadana liczba naturalna jest liczbą pierwszą.&lt;br /&gt;
&lt;br /&gt;
3. Napisać program, który sprawdza jaka jest najmniejsza liczba wyrazów szeregu harmonicznego, jaką należy posumować, aby wynik przekroczył daną liczbę dodatnią (,,próg&amp;quot;).&lt;br /&gt;
&lt;br /&gt;
4. Napisać program, który gra z użytkownikiem w zgadywanie liczby (,,sekretna&amp;quot; liczba do odgadnięcia jest wpisana w kod programu). Użytkownik jest proszony o próbę zgadnięcia, w odpowiedzi otrzymuje informację, czy sekretna liczba jest większa czy mniejsza od podanej przez niego; w przypadku trafnego zgadnięcia, program składa gratulacje i podaje, po ilu próbach udało się zgadnąć.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
[[PPy3/InstrukcjaWarunkowa|poprzednie]] | [[&amp;quot;Programowanie z Pythonem3&amp;quot;|strona główna]] | [[PPy3/Funkcje|dalej]]&lt;br /&gt;
&lt;br /&gt;
[[Użytkownik:RobertJB|RobertJB]] ([[Dyskusja użytkownika:RobertJB|dyskusja]]) 12:22, 29 cze 2016 (CEST)&lt;/div&gt;</summary>
		<author><name>RobertJB</name></author>
		
	</entry>
	<entry>
		<id>http://brain.fuw.edu.pl/edu/index.php?title=PPy3/SekwencjeIIteracja&amp;diff=8922</id>
		<title>PPy3/SekwencjeIIteracja</title>
		<link rel="alternate" type="text/html" href="http://brain.fuw.edu.pl/edu/index.php?title=PPy3/SekwencjeIIteracja&amp;diff=8922"/>
		<updated>2022-07-29T12:54:56Z</updated>

		<summary type="html">&lt;p&gt;RobertJB: /* Sekwencje i iteracja */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=Sekwencje i iteracja=&lt;br /&gt;
&lt;br /&gt;
'''Sekwencje''' to typ danych charakteryzujący się tym, że składają się z ''elementów'' zgromadzonych w pewnej ''kolejności''. Elementem sekwencji może być cokolwiek (w tym - inna sekwencja), ale w najprostszym przypadku elementami tymi są liczby.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&amp;lt;small&amp;gt;&lt;br /&gt;
Sekwencje to szczególny przypadek ''kolekcji'' - takich typów danych, które składają się z elementów, ale niekoniecznie są one uporządkowane. Innym przykładem kolekcji jest zbiór (''set'').&lt;br /&gt;
&amp;lt;/small&amp;gt;&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Najczęściej używanym typem sekwencji jest ''lista'' (''list''). Listę można stworzyć (i zapamiętać) np. nadając jej pewien początkowy skład:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
numerki = [0, 1, 2, 3, 5, 8]&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To co stoi po prawej stronie znaku równości to literalny zapis listy - ciąg elementów, oddzielonych przecinkami, wewnątrz pary nawiasów kwadratowych. Oczywiście jako elementy mogą występować zarówno stałe literalne - jak w tym przykładzie, jak i nazwy (zmienne) &amp;amp;mdash; oczywiście takie, którym uprzednio nadano wartości.&lt;br /&gt;
&lt;br /&gt;
Z listy - podobnie jak z każdej sekwencji - można pobrać element stojący w dowolnej pozycji, podając jej numer:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
print(numerki[4])&lt;br /&gt;
→ 5&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Uwaga:''' pozycje numerowane są kolejnymi liczbami naturalnymi, począwszy od zera - podobnie, jak w większości języków programowania.&lt;br /&gt;
&lt;br /&gt;
Można też podmienić istniejący element na inny:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
numerki[0] = -1&lt;br /&gt;
print(numerki)&lt;br /&gt;
→ [-1, 1, 2, 3, 5, 8]&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
a nawet przedłużyć ją o kolejny element:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
numerki.append(13)&lt;br /&gt;
print(numerki)&lt;br /&gt;
→ [-1, 1, 2, 3, 5, 8, 13]&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
oraz usunąć element (skracając listę):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
del numerki[0]&lt;br /&gt;
print numerki&lt;br /&gt;
→ [1, 2, 3, 5, 8, 13]&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Łatwo też ustalić, jaka jest ,,długość&amp;quot; listy, czyli liczba jej elementów:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
print(len(numerki))&lt;br /&gt;
→ 6&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Jest jeszcze sporo innych ,,gotowych do użytku&amp;quot; operacji na listach. Ale najważniejsza cecha listy jest taka: '''można zmieniać jej skład, a nawet długość, a pozostaje ona tą samą listą'''. Nawet jeśli występuje w programie pod więcej niż jedną nazwą.&lt;br /&gt;
&lt;br /&gt;
==Pętla &amp;lt;tt&amp;gt;for&amp;lt;/tt&amp;gt;==&lt;br /&gt;
&lt;br /&gt;
Naczelne zastosowanie listy (czy ogólniej -sekwencji), to iteracja - czyli wykonanie jakiejś operacji dla każdego elementu. I tak wygląda najprostszy rodzaj iteracji - Pętla &amp;lt;tt&amp;gt;for&amp;lt;/tt&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
for x in numerki:&lt;br /&gt;
    print(x)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Zamiast &amp;lt;tt&amp;gt;print(x)&amp;lt;/tt&amp;gt; pętlę &amp;lt;tt&amp;gt;for&amp;lt;/tt&amp;gt; może tworzyć dowolny blok instrukcji, zgodnie z zasadami jakie już poznaliśmy przy omawianiu instrukcji warunkowej. Cały blok tworzący wnętrze pętli będzie wykonany wielokrotnie, tyle razy, ile elementów ma lista, a za każdym razem pod nazwę stojącą bezpośrednio po słowie &amp;lt;tt&amp;gt;for&amp;lt;/tt&amp;gt; podstawiony będzie kolejny element listy (przywołanej po słowie &amp;lt;tt&amp;gt;in&amp;lt;/tt&amp;gt;) - kolejny, tzn. zgodnie z kolejnością, w jakiej umieszczone są one w liście.&lt;br /&gt;
&lt;br /&gt;
Inny, znany nam już rodzaj sekwencji to napis (''string''), zwany czasami ''łańcuchem znakowym''. Napis składa się ze znaków, i jest w szczególności sekwencją, której elementami są znaki. Analogicznie jak w przypadku listy, można pobierać znaki stojące na poszczególnych pozycjach w napisie. '''Nie można''' natomiast podmieniać znaków w napisie, ani ich usuwać bądź dopisywać:  w odróżnieniu od listy, napis raz utworzony jest ''niezmienny''. Można go zastąpić innym napisem, i ewentualnie opatrzyć ten nowy napis tą samą nazwą, ale nie da się go zmodyfikować. I nie jest to dzielenie włosa na czworo, własność ta ma namacalne konsekwencje:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
napis1 = 'abc'&lt;br /&gt;
napis2 = napis1&lt;br /&gt;
napis1 = 'ABC'&lt;br /&gt;
print(napis1, napis2)&lt;br /&gt;
→ ABC abc&lt;br /&gt;
# dla porównania, listy:&lt;br /&gt;
lista1 = ['a', 'b', 'c']&lt;br /&gt;
lista2 = lista1&lt;br /&gt;
lista1[0] = 'A'&lt;br /&gt;
print(lista1, lista2)&lt;br /&gt;
→ ['A', 'b', 'c'] ['A', 'b', 'c']&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&amp;lt;small&amp;gt;&lt;br /&gt;
Powraca jeszcze raz pytanie: czym są poszczególne znaki? Tzn. jaki typ danych reprezentują? Otóż w Pythonie pojedyncze znaki też są po prostu napisami, tyle że o długości jeden. Poza długością nic ich szczególnie nie wyróżnia. Ta uwaga jest na użytek tych z Was, którzy znają jakiś inny język programowania, gdyż w wielu z nich znak jest oddzielnym, innym niż napis typem danych.&lt;br /&gt;
&amp;lt;/small&amp;gt;&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Pętlę &amp;lt;tt&amp;gt;for&amp;lt;/tt&amp;gt; można zatem zastosować do napisu - zamiast do listy, wówczas w kolejnych iteracjach będą uwzględniane kolejne znaki, a których składa się napis.&lt;br /&gt;
&lt;br /&gt;
===Ogólna postać pętli &amp;lt;tt&amp;gt;for&amp;lt;/tt&amp;gt;===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
for element in sekwencja:&lt;br /&gt;
    &amp;lt;blok instrukcji&amp;gt;&lt;br /&gt;
else:&lt;br /&gt;
    &amp;lt;blok instrukcji&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*Pierwszy blok instrukcji będzie wykonany ''w zasadzie'' tyle razy, ile elementów ma sekwencja&lt;br /&gt;
*Za każdym razem nazwa ''element'' oznaczać będzie kolejny element sekwencji, zgodnie z ich porządkiem&lt;br /&gt;
*''sekwencja'' może być pusta; nie jest to błąd, ale wtedy pierwszy blok nie będzie wykonany ani razu&lt;br /&gt;
*Gdy elementy sekwencji się wyczerpią, wykonany zostanie blok po &amp;lt;tt&amp;gt;else&amp;lt;/tt&amp;gt;&lt;br /&gt;
*Blok &amp;lt;tt&amp;gt;else&amp;lt;/tt&amp;gt; (wraz z linijką go otwierającą) jest opcjonalny (niekonieczny)&lt;br /&gt;
*W pierwszym bloku mogą wystąpić specjalne polecenia: &amp;lt;tt&amp;gt;break&amp;lt;/tt&amp;gt; i &amp;lt;tt&amp;gt;continue&amp;lt;/tt&amp;gt;&lt;br /&gt;
**&amp;lt;tt&amp;gt;break&amp;lt;/tt&amp;gt; znaczy: przerwij pętlę natychmiast, pomiń wszystkie pozostałe elementy sekwekcji, '''pomiń również ewentualny blok &amp;lt;tt&amp;gt;else&amp;lt;/tt&amp;gt;'''&lt;br /&gt;
**&amp;lt;tt&amp;gt;continue&amp;lt;/tt&amp;gt; oznacza: przerwij działania na aktualnym elemencie, i wróć do początku bloku biorąc kolejny element. Jeśli już zabrakło elementów, przejdź do bloku &amp;lt;tt&amp;gt;else&amp;lt;/tt&amp;gt;, albo (gdy go nie ma) do polecenia następnego po pętli&lt;br /&gt;
*W miejscu gdzie stoi ''sekwencja'' może tak naprawdę stać dowolny obiekt ''iterowalny'' - np. kolekcja. Ale innych typów kolekcji jeszcze nie poznaliśmy...&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&amp;lt;small&amp;gt;&lt;br /&gt;
Blok &amp;lt;tt&amp;gt;else&amp;lt;/tt&amp;gt; w pętli &amp;lt;tt&amp;gt;for&amp;lt;/tt&amp;gt; jest stosunkowo rzadko widywany. Nawet wielu programistów dość biegłych w Pythonie nie wie (lub zapomniało) o istnieniu tej opcji.&lt;br /&gt;
&amp;lt;/small&amp;gt;&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A co, jeśli chcielibyśmy za pomocą pętli &amp;lt;tt&amp;gt;for&amp;lt;/tt&amp;gt; (lub inaczej) zmienić w jakiś sposób skład samej sekwencji? Na przykład:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
for x in lista:&lt;br /&gt;
    x = x + 1&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''TO NIE ZADZIAŁA''' - w tym sensie, że ''lista'' będzie dalej miała te same elementy co poprzednio, a nie - powiększone o 1. W istocie operacja taka nic nie osiąga - oprócz tego, że po jej zakończeniu nazwa ''x'' ma wartość ostatniego elementu listy, powiększonego o 1. To samo można dostać bez pisania pętli. &lt;br /&gt;
&lt;br /&gt;
Jak więc osiągnąć zmianę - przeliczenie - wszystkich elementów sekwencji wg. jakiejś reguły (np. powiększ każdy z nich o 1)?&lt;br /&gt;
&lt;br /&gt;
Pożytecznym sposobem tworzenia sekwencji jest funkcja &amp;lt;tt&amp;gt;range&amp;lt;/tt&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
for x in range(3):&lt;br /&gt;
    print(x)&lt;br /&gt;
→ 0&lt;br /&gt;
→ 1&lt;br /&gt;
→ 2&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Argument (tu: 3) oznacza liczbę elementów w wyprodukowanej sekwencji. Domyślnie zaczyna się ona od zera, tak jak numeracja pozycji w sekwencjach - ale można użyć wywołania &amp;lt;tt&amp;gt;range(a, b)&amp;lt;/tt&amp;gt; aby uzyskać elementy dowolnego ciągu arytmetycznego - o elemencie początkowym ''a'' i przyroście ''b''.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&amp;lt;small&amp;gt;&lt;br /&gt;
Tu jest pewne oszustwo: wynikiem wywołania &amp;lt;tt&amp;gt;range&amp;lt;/tt&amp;gt; nie jest tak naprawdę lista, ale pewnego innego rodzaju typ sekwencji, a więc mogący służyć za źródło elementów w iteracji. Na razie to jest jednak drobny szczegół. Jeżeli potrzebujemy dosłownej listy o takich elementach, wystarczy wykonać tzw. rzutowanie, czyli przyłożyć funkcję &amp;lt;tt&amp;gt;list&amp;lt;/tt&amp;gt;: &amp;lt;tt&amp;gt;lista = list(range(3))&amp;lt;/tt&amp;gt;&lt;br /&gt;
&amp;lt;/small&amp;gt;&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wracając do problemu przeliczenia wszystkich elementów listy:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
lista = [3, 5, 8]&lt;br /&gt;
for k in range(3):&lt;br /&gt;
    lista[k] += 1&lt;br /&gt;
print lista&lt;br /&gt;
→ [4, 6, 9]&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
I to działa. Nie jest to jednak optymalne rozwiązanie.&lt;br /&gt;
&lt;br /&gt;
*Pisząc to co powyżej wiedzieliśmy, że mamy do czynienia z listą o długości 3. W ogólności musielibyśmy użyć funkcji &amp;lt;tt&amp;gt;len&amp;lt;/tt&amp;gt;;&lt;br /&gt;
*Można to jednak zrobić bardziej elegancko:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
for k, x in enumerate(lista):&lt;br /&gt;
    lista[k] = x + 1&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Funkcja &amp;lt;tt&amp;gt;enumerate&amp;lt;/tt&amp;gt; produkuje sekwencję par: ''nr pozycji'', ''element'' - i jest bardzo przydatna w takich sytuacjach. &lt;br /&gt;
&lt;br /&gt;
Z dokonywaniem wewnątrz pętli zmian na sekwencji, po której iterujemy, należy jednak uważać. To, co robimy w tym przykładzie jest akurat niegroźne, natomiast umieszczenie wewnątrz pętli operacji zmieniających '''długość''' sekwencji, po której iterujemy mogłoby dać nieoczekiwane wyniki. Spróbuj np.:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
L = [0, 1, 2, 3, 4]&lt;br /&gt;
for i in range(5):&lt;br /&gt;
    del L[i]&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Co tu się stanie, i dlaczego?&lt;br /&gt;
&lt;br /&gt;
==Więcej o listach==&lt;br /&gt;
&lt;br /&gt;
Elementy listy (innych rodzajów sekwencji również) można numerować od końca, używając ujemnych wartości wskaźników pozycji:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
numerki = [0, 1, 2, 3, 5, 8]&lt;br /&gt;
numerki[-1]&lt;br /&gt;
→ 8&lt;br /&gt;
numerki[-3]&lt;br /&gt;
→ 3&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Z list (i innych sekwencji) można wyjmować nie tylko poszczególne elementy, ale również podsekwencje, zwane też wycinkami:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
numerki = [0, 1, 2, 3, 5, 8]&lt;br /&gt;
nn = numerki[1:4]&lt;br /&gt;
→ [1, 2, 3]&lt;br /&gt;
nn = numerki[2:]&lt;br /&gt;
→ [2, 3, 5, 8]&lt;br /&gt;
nn = numerki[:3]&lt;br /&gt;
→ [0, 1, 2]&lt;br /&gt;
nn = numerki[1:4:2]&lt;br /&gt;
→ [1, 3]&lt;br /&gt;
nn = numerki[4:1:-1]&lt;br /&gt;
→ [5, 3, 2]&lt;br /&gt;
nn = numerki[:]&lt;br /&gt;
→ [0, 1, 2, 3, 5, 8]&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Jak widać, pominięcie pozycji początkowej lub końcowej oznacza: ,,do oporu&amp;quot;. Trzecia liczba charakteryzująca wycinek, o ile występuje - to ,,skok&amp;quot; wskaźnika. Przykładowo, &amp;lt;tt&amp;gt;a[::2]&amp;lt;/tt&amp;gt; oznaczałoby listę zawierającą co drugi element listy &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt;, natomiast &amp;lt;tt&amp;gt;a[::-1]&amp;lt;/tt&amp;gt;: listę składającą się z tych samych elementów, co &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; - lecz w odwrotnej kolejności.&lt;br /&gt;
&lt;br /&gt;
Wyrażenie &amp;lt;tt&amp;gt;numerki[:]&amp;lt;/tt&amp;gt;, tzw. pełny wycinek, tworzy pełną ''kopię'' listy &amp;lt;tt&amp;gt;numerki&amp;lt;/tt&amp;gt;; tzn. '''nie''' jest to ''ta sama'' lista, chociaż składa się z tych samych elementów. Jest to tzw. ''kopia płytka'' - oznacza to tyle, że jeżeli wśród elementów kopiowanej listy były obiekty złożone (np. inne listy), to elementami kopii będą '''te same''' listy, a nie - ich kopie.&lt;br /&gt;
&lt;br /&gt;
Wycinek jest zawsze nową listą, również w ostatnim przypadku - gdy jej skład jest taki sam, jak oryginalnej. Wtedy stanowi kopię pierwotnej listy. Można jednak też podstawiać do wycinka:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
numerki[4:5] = [4]&lt;br /&gt;
→ [0, 1, 2, 3, 4, 8]&lt;br /&gt;
numerki[5:5] = [5, 6, 7]&lt;br /&gt;
→ [0, 1, 2, 3, 4, 5, 6, 7, 8]&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
i jest to jeszcze jeden sposób, by zmienić zawartość listy - w tym być może jej długość - zachowując jej tożsamość.&lt;br /&gt;
&lt;br /&gt;
Listy można do siebie dodawać:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
l = ['a', 'b', 'c'] + ['y', 'z']&lt;br /&gt;
→ ['a', 'b', 'c', 'y', 'z']&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
w ten sposób powstaje nowa lista, która ze składników bierze elementy, ale poza tym nie ma z nimi nic wspólnego; późniejsze zmiany w listach-składnikach nie mają wpływu na sumę.&lt;br /&gt;
&lt;br /&gt;
Listy można też zwielokrotnić; np. aby uzyskać listę siedmiu dwójek:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
l = [2] * 7&lt;br /&gt;
→ [2, 2, 2, 2, 2, 2, 2]&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
ta sama co poprzednio uwaga stosuje się i tu.&lt;br /&gt;
&lt;br /&gt;
Elementy listy można posumować:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
x = sum(range(101))&lt;br /&gt;
→ 5050&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
(wprawdzie &amp;lt;tt&amp;gt;range(101)&amp;lt;/tt&amp;gt; nie jest dosłownie listą, ale z ,,prawdziwą&amp;quot; listą można zrobić to samo).&lt;br /&gt;
&lt;br /&gt;
Podobnie jak inne ''obiekty'', listy posiadają szereg ''metod'', za pomocą których można na nich wykonywać różne działania. Przykładowo:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
numerki.append(9)&lt;br /&gt;
→ [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]&lt;br /&gt;
numerki.extend([10, 11])&lt;br /&gt;
→ [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Zwróćcie uwagę na notację: kropka sygnalizuje ,,wyciągnięcie&amp;quot; metody z danego obiektu (tu: listy), w nawiasach wpisujemy dane dla tej metody (argumenty - tu pojedyncze, ale może być więcej).&lt;br /&gt;
&lt;br /&gt;
==Więcej o napisach==&lt;br /&gt;
&lt;br /&gt;
Napisy dopuszczają tylko część operacji dostępnych dla list, ze względu na własność niemodyfikowalności. Posiadają za to szereg swoistych metod. Trzeba pamiętać, że żadna z tych metod ''nie zmienia'' napisu, którego dotyczy - wynikiem może być jedynie '''nowy''' napis, stworzony na podstawie oryginalnego.&lt;br /&gt;
&lt;br /&gt;
Niemniej napis ''również'' jest sekwencją, i może być np. zastosowany w pętli &amp;lt;tt&amp;gt;for&amp;lt;/tt&amp;gt;. Ale sekwencją czego? Oczywiście znaków &amp;amp;mdash; z tym, że w Pythonie nie ma oddzielnego typu danych ,,znak&amp;quot;. Znaki to po prostu napisy jednoelementowe. &lt;br /&gt;
&lt;br /&gt;
Przykład: metoda &amp;lt;tt&amp;gt;upper&amp;lt;/tt&amp;gt; (zamienia małe litery na wielkie):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
'abcde'.upper()&lt;br /&gt;
→ 'ABCDE'&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Napis zawsze można łatwo zamienić na listę znaków:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
l = list('abcde')&lt;br /&gt;
→ ['a', 'b', 'c', 'd', 'e']&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
(choć rzadko zachodzi taka potrzeba).&lt;br /&gt;
&lt;br /&gt;
Do operacji odwrotnej można użyć metody &amp;lt;tt&amp;gt;join&amp;lt;/tt&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
''.join(l)&lt;br /&gt;
→ 'abcde'&lt;br /&gt;
', '.join(l)&lt;br /&gt;
→ 'a, b, c, d, e'&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Pętla &amp;lt;tt&amp;gt;while&amp;lt;/tt&amp;gt;==&lt;br /&gt;
&lt;br /&gt;
To jeszcze jeden sposób iteracji, tak naprawdę prostszy od pętli &amp;lt;tt&amp;gt;for&amp;lt;/tt&amp;gt; &amp;amp;mdash; gdyż nie oparty na sekwencjach; zwykle mniej wygodny w użyciu, ale w niektórych przypadkach nieodzowny.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
# postać najprostsza&lt;br /&gt;
&lt;br /&gt;
while WARUNEK:&lt;br /&gt;
    BLOK INSTRUKCJI&lt;br /&gt;
&lt;br /&gt;
# ogólna postać:&lt;br /&gt;
&lt;br /&gt;
while WARUNEK:&lt;br /&gt;
    BLOK1&lt;br /&gt;
else:&lt;br /&gt;
    BLOK2&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Polega na powtarzaniu bloku instrukcji nieokreśloną liczbę razy; przed każdym kolejnym wykonaniem na nowo sprawdzany jest warunek, i jeśli okaże się fałszywy - powtarzanie się kończy.&lt;br /&gt;
&lt;br /&gt;
Innym sposobem przerwania pętli &amp;lt;tt&amp;gt;while&amp;lt;/tt&amp;gt; jest umieszczenie gdzieś w bloku instrukcji &amp;lt;tt&amp;gt;break&amp;lt;/tt&amp;gt; - zwykle pod pewnym warunkiem (tzn. wewnątrz instrukcji warunkowej &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt;). Wykonanie break polega na ,,wyskoczeniu&amp;quot; z pętli - i przejściu do dalszego ciągu programu, po bloku wewnętrznym pętli.&lt;br /&gt;
&lt;br /&gt;
Oczywiście aby &amp;lt;tt&amp;gt;WARUNEK&amp;lt;/tt&amp;gt; mógł okazać się za którymś razem fałszywy, i spowodować przerwanie pętli, musi on być zbudowany z wykorzystaniem zmiennych, których wartości ulegają zmianom wewnątrz pętli. Zdarza się jednak widzieć pętlę zaczynającą się od &amp;lt;tt&amp;gt;while True:&amp;lt;/tt&amp;gt; - formalnie jest to pętla nieskończona, którą może zakończyć jedynie wywołanie instrukcji &amp;lt;tt&amp;gt;break&amp;lt;/tt&amp;gt; występującej gdzieś w wewnętrznym bloku.&lt;br /&gt;
&lt;br /&gt;
Wewnątrz bloku może wystąpić również instrukcja &amp;lt;tt&amp;gt;continue&amp;lt;/tt&amp;gt; - działa ona analogicznie, jak w pętli &amp;lt;tt&amp;gt;for&amp;lt;/tt&amp;gt;, a więc powoduje przerwanie wykonywania aktualnej iteracji i przeskok do początku pętli, czyli sprawdzenia warunku jej kontynuowania.&lt;br /&gt;
&lt;br /&gt;
W ogólnej postaci, blok występujący po linijce &amp;lt;tt&amp;gt;else:&amp;lt;/tt&amp;gt; jest wykonywany po zakończeniu pętli wskutek niespełnienia warunku początkowego, natomiast jest pomijany, jeśli przerwanie pętli było spowodowane instrukcją &amp;lt;tt&amp;gt;break&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Zasadniczo każdą pętlę &amp;lt;tt&amp;gt;for&amp;lt;/tt&amp;gt; dałoby się przepisać jako równoważną pętlę &amp;lt;tt&amp;gt;while&amp;lt;/tt&amp;gt; - przykładowo:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
for x in lista:&lt;br /&gt;
    działaj_na(x)&lt;br /&gt;
&lt;br /&gt;
# równoważnie:&lt;br /&gt;
&lt;br /&gt;
k = 0&lt;br /&gt;
while k &amp;lt; len(lista):&lt;br /&gt;
    działaj_na(lista[k])&lt;br /&gt;
    k += 1&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
nie należy jednak zazwyczaj tego robić, ponieważ (najczęściej) pętla &amp;lt;tt&amp;gt;for&amp;lt;/tt&amp;gt; jest bardziej czytelna.&lt;br /&gt;
&lt;br /&gt;
=Ćwiczenia=&lt;br /&gt;
&lt;br /&gt;
1. Napisać program, który sumuje liczby naturalne od 1 do 100:&lt;br /&gt;
&lt;br /&gt;
*z wykorzystaniem pętli &amp;lt;tt&amp;gt;for&amp;lt;/tt&amp;gt;&lt;br /&gt;
*z wykorzystaniem pętli &amp;lt;tt&amp;gt;while&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
2. Wykorzystując pętlę &amp;lt;tt&amp;gt;while&amp;lt;/tt&amp;gt; napisać program, który sprawdza czy zadana liczba naturalna jest liczbą pierwszą.&lt;br /&gt;
&lt;br /&gt;
3. Napisać program, który sprawdza jaka jest najmniejsza liczba wyrazów szeregu harmonicznego, jaką należy posumować, aby wynik przekroczył daną liczbę dodatnią (,,próg&amp;quot;).&lt;br /&gt;
&lt;br /&gt;
4. Napisać program, który gra z użytkownikiem w zgadywanie liczby (,,sekretna&amp;quot; liczba do odgadnięcia jest wpisana w kod programu). Użytkownik jest proszony o próbę zgadnięcia, w odpowiedzi otrzymuje informację, czy sekretna liczba jest większa czy mniejsza od podanej przez niego; w przypadku trafnego zgadnięcia, program składa gratulacje i podaje, po ilu próbach udało się zgadnąć.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
[[PPy3/InstrukcjaWarunkowa|poprzednie]] | [[&amp;quot;Programowanie z Pythonem3&amp;quot;|strona główna]] | [[PPy3/Funkcje|dalej]]&lt;br /&gt;
&lt;br /&gt;
[[Użytkownik:RobertJB|RobertJB]] ([[Dyskusja użytkownika:RobertJB|dyskusja]]) 12:22, 29 cze 2016 (CEST)&lt;/div&gt;</summary>
		<author><name>RobertJB</name></author>
		
	</entry>
	<entry>
		<id>http://brain.fuw.edu.pl/edu/index.php?title=PPy3/InstrukcjaWarunkowa&amp;diff=8921</id>
		<title>PPy3/InstrukcjaWarunkowa</title>
		<link rel="alternate" type="text/html" href="http://brain.fuw.edu.pl/edu/index.php?title=PPy3/InstrukcjaWarunkowa&amp;diff=8921"/>
		<updated>2022-07-29T12:24:41Z</updated>

		<summary type="html">&lt;p&gt;RobertJB: /* Ćwiczenia */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=Instrukcja warunkowa=&lt;br /&gt;
&lt;br /&gt;
Zasadniczo każdy program w Pythonie składa się z ciągu instrukcji, które są wykonywane w kolejności, w jakiej zostały zapisane. W programowaniu potrzebna jest jednak możliwość podejmowania decyzji o przyjęciu różnych kursów postępowania, w zależności od danych z jakimi mamy do czynienia. Umożliwiają to instrukcje złożone, a szczególnie - instrukcja warunkowa.&lt;br /&gt;
&lt;br /&gt;
Instrukcja warunkowa to pierwszy przykład instrukcji złożonej. W najprostszej postaci składa się ona z ciągu (jednej lub więcej) instrukcji ujętych w blok, który jako całość będzie wykonany lub nie, w zależności od tego, czy spełniony jest pewien warunek - co zależy zazwyczaj od aktualnych wartości pewnych zmiennych. Warunek ten zapisuje się w postaci wyrażenia logicznego.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&amp;lt;small&amp;gt;&lt;br /&gt;
Wśród instrukcji tworzących blok warunkowy mogą oczywiście się pojawić również instrukcje złożone, nie tylko instrukcje proste. Na przykład, kolejne instrukcje warunkowe.&lt;br /&gt;
&amp;lt;/small&amp;gt;&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Przykład minimalny:==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
x1, x2 = None, None&lt;br /&gt;
if delta &amp;gt; 0 and not a == 0:&lt;br /&gt;
    x1 = (-b + delta) / 2 / a&lt;br /&gt;
    x2 = (-b - delta) / 2 / a&lt;br /&gt;
print(x1, x2)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Linijka z wywołaniem &amp;lt;tt&amp;gt;print&amp;lt;/tt&amp;gt; nie jest już częścią instrukcji warunkowej, tylko kolejną instrukcją.&lt;br /&gt;
&lt;br /&gt;
'''Do zapamiętania''':&lt;br /&gt;
*wiersz otwierający instrukcję złożoną (czyli tu: zaczynająca się od &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt;) zawsze kończy się dwukropkiem&lt;br /&gt;
*instrukcje tworzące blok w instrukcji złożonej są pisane z wcięciem, które musi być jednolite&lt;br /&gt;
*koniec bloku rozpoznaje się po powrocie do uprzedniego poziomu wcięcia&lt;br /&gt;
*blok instrukcji pod &amp;lt;tt&amp;gt;if ...&amp;lt;/tt&amp;gt; nie może być pusty. Instrukcja &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt; z pustym blokiem warunkowym jest nie tylko nieprzydatna, ale jest również błędem składniowym.&lt;br /&gt;
&lt;br /&gt;
==Przykład bardziej złożony:==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
if a == 0:&lt;br /&gt;
    print('Równanie nie jest kwadratowe.')&lt;br /&gt;
elif delta &amp;gt; 0 and not a == 0:&lt;br /&gt;
    x1 = (-b + delta) / 2 / a&lt;br /&gt;
    x2 = (-b - delta) / 2 / a&lt;br /&gt;
    print('Są dwa pierwiastki: x1 =', x1, 'x2 =', x2)&lt;br /&gt;
elif delta == 0:&lt;br /&gt;
    x = -b / 2 / a&lt;br /&gt;
    print('Jest tylko jeden pierwiastek: x =', x)&lt;br /&gt;
else: # delta &amp;lt; 0:&lt;br /&gt;
    print('Nie ma pierwiastków rzeczywistych.')&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Jak to działa?&lt;br /&gt;
&lt;br /&gt;
*Jeżeli spełniony jest warunek &amp;lt;tt&amp;gt;a == 0&amp;lt;/tt&amp;gt;, wykonany zostanie blok poniżej &amp;lt;tt&amp;gt;if ...&amp;lt;/tt&amp;gt;, a reszta instrukcji zostanie pominięta;&lt;br /&gt;
*Jeżeli warunek ten jest nieprawdziwy (i tylko wtedy), to sprawdzane są kolejno warunki umieszczone w wierszach zaczynających się od &amp;lt;tt&amp;gt;elif&amp;lt;/tt&amp;gt;. Jeśli któryś z nich okaże się prawdziwy, to blok poniżej tej linijki zostanie wykonany, a cała reszta - pominięta;&lt;br /&gt;
*Jeżeli żaden z warunków - tych po &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt;, i tych po wszystkich &amp;lt;tt&amp;gt;elif&amp;lt;/tt&amp;gt; - nie okazał się prawdziwy, wykonany zostanie blok związany z &amp;lt;tt&amp;gt;else&amp;lt;/tt&amp;gt;.&lt;br /&gt;
*Bloków &amp;lt;tt&amp;gt;elif&amp;lt;/tt&amp;gt; może być w instrukcji dowolnie wiele (w tym - wcale), &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt; jest obowiązkowy (inaczej nie byłoby instrukcji warunkowej) i tylko jeden, &amp;lt;tt&amp;gt;else&amp;lt;/tt&amp;gt; może wystąpić wyłącznie na końcu - jeden raz, lub wcale.&lt;br /&gt;
*Komentarz po &amp;lt;tt&amp;gt;else:&amp;lt;/tt&amp;gt; jest podpowiedzią dla czytającego, że skoro już zbadano warunki &amp;lt;tt&amp;gt;delta == 0&amp;lt;/tt&amp;gt; oraz &amp;lt;tt&amp;gt;delta &amp;gt; 0&amp;lt;/tt&amp;gt;, a wykonanie dotarło do tej linijki, to &amp;lt;tt&amp;gt;delta &amp;lt; 0&amp;lt;/tt&amp;gt; jest jedyną pozostałą możliwością (o ile możemy założyć, że &amp;lt;tt&amp;gt;delta&amp;lt;/tt&amp;gt; jest na pewno liczbą!). Jest on przeznaczony wyłącznie dla ludzkich oczu - interpreter go zignoruje, jak każdy komentarz.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&amp;lt;small&amp;gt;&lt;br /&gt;
Mam nadzieję, że czytający już zauważył, że &amp;lt;tt&amp;gt;and not a == 0&amp;lt;/tt&amp;gt; w trzeciej linijce jest niepotrzebne. Dlaczego?&lt;br /&gt;
&amp;lt;/small&amp;gt;&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Wyrażenie warunkowe==&lt;br /&gt;
&lt;br /&gt;
Innym sposobem uzależnienia wyniku działania od jakiegoś warunku jest tzw. ''wyrażenie warunkowe''. Jest ono szczególnie wygodne w prostych przypadkach, i pozwala zapisać pewne działania w bardziej zwięzły sposób. &lt;br /&gt;
&lt;br /&gt;
Przykład: chcemy, aby z nazwą &amp;lt;tt&amp;gt;wbx&amp;lt;/tt&amp;gt; wiązała się wartość bezwzględna (moduł) aktualnej wartości (liczby) &amp;lt;tt&amp;gt;x&amp;lt;/tt&amp;gt;. Za pomocą instrukcji warunkowej można to zrealizować tak:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
if x &amp;lt; 0:&lt;br /&gt;
    wbx = -x&lt;br /&gt;
else:&lt;br /&gt;
    wbx = x&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ten sam wynik można osiągnąć za pomocą wyrażenia warunkowego:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
wbx = -x if x &amp;lt; 0 else x&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
W wyrażeniu warunkowym nie ma opcji uwzględnienie dodatkowych możliwości za pomocą &amp;lt;tt&amp;gt;elif&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=Ćwiczenia=&lt;br /&gt;
&lt;br /&gt;
W programach ćwiczebnych nieraz przyda nam się funkcja &amp;lt;tt&amp;gt;input()&amp;lt;/tt&amp;gt;. Działa ona w sposób następujący: argumentem wywołania powinien być jakiś napis (np. w postaci stałej napisowej): &amp;lt;tt&amp;gt;input('podaj jakąś liczbę całkowitą: ')&amp;lt;/tt&amp;gt;. Gdy w programie przyjdzie kolej na wykonanie takiego wywołania, program wypisze ten napis do terminalu i będzie oczekiwał na reakcję użytkownika, czyli wpisanie czegoś z klawiatury (i zakończenie naciśnięciem klawisza ''Enter''). Gdy to nastąpi, wynikiem wywołania funkcji &amp;lt;tt&amp;gt;input&amp;lt;/tt&amp;gt; w programie będzie treść wpisana prze użytkownika (bez końcowego znaku nowej linii).&lt;br /&gt;
&lt;br /&gt;
''Uwaga:'' wartość zwracana przez &amp;lt;tt&amp;gt;input()&amp;lt;/tt&amp;gt; zawsze jest napisem, a nie liczbą - choćby się składał z samych cyfr.&lt;br /&gt;
&lt;br /&gt;
1. Napisz program, którego uruchomienie ma następujący skutek:&lt;br /&gt;
*program wita użytkownika (komunikatem w terminalu),&lt;br /&gt;
*prosi o wprowadzenie liczby całkowitej,&lt;br /&gt;
*sprawdza, czy liczba ta jest podzielna przez 7, i informuje o wyniku tego sprawdzenia&lt;br /&gt;
&lt;br /&gt;
2. Napisz program, którego uruchomienie ma następujący skutek:&lt;br /&gt;
* program prosi użytkownika o podanie swojego (lub czyjegoś) wieku w latach&lt;br /&gt;
* jeśli wiek jest ujemny lub przekracza 120, odpowiada ,,Nieprawidłowy wiek&amp;quot;&lt;br /&gt;
* jeśli wiek wynosi 0, odpowiada ,,niemowlę&amp;quot;&lt;br /&gt;
* jeśli wiek jest poniżej 18, odpowiada ,,dziecko&amp;quot;&lt;br /&gt;
* jeśli wiek jest pomiędzy 18 a 120 (włącznie), odpowiada ,,dorosły&amp;quot;&lt;br /&gt;
* jeśli wiek przekracza 120, odpowiada ,,ludzie tyle nie żyją&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
''CDN''&lt;br /&gt;
&lt;br /&gt;
---- &lt;br /&gt;
&lt;br /&gt;
[[PPy3/StałeIZmienne|poprzednia]] | [[&amp;quot;Programowanie z Pythonem3&amp;quot;|Strona główna]] | [[PPy3/SekwencjeIIteracja|dalej]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Użytkownik:RobertJB|RobertJB]] ([[Dyskusja użytkownika:RobertJB|dyskusja]]) 15:42, 28 cze 2016 (CEST)&lt;/div&gt;</summary>
		<author><name>RobertJB</name></author>
		
	</entry>
	<entry>
		<id>http://brain.fuw.edu.pl/edu/index.php?title=PPy3/InstrukcjaWarunkowa&amp;diff=8920</id>
		<title>PPy3/InstrukcjaWarunkowa</title>
		<link rel="alternate" type="text/html" href="http://brain.fuw.edu.pl/edu/index.php?title=PPy3/InstrukcjaWarunkowa&amp;diff=8920"/>
		<updated>2022-07-29T12:19:36Z</updated>

		<summary type="html">&lt;p&gt;RobertJB: /* Przykład minimalny: */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=Instrukcja warunkowa=&lt;br /&gt;
&lt;br /&gt;
Zasadniczo każdy program w Pythonie składa się z ciągu instrukcji, które są wykonywane w kolejności, w jakiej zostały zapisane. W programowaniu potrzebna jest jednak możliwość podejmowania decyzji o przyjęciu różnych kursów postępowania, w zależności od danych z jakimi mamy do czynienia. Umożliwiają to instrukcje złożone, a szczególnie - instrukcja warunkowa.&lt;br /&gt;
&lt;br /&gt;
Instrukcja warunkowa to pierwszy przykład instrukcji złożonej. W najprostszej postaci składa się ona z ciągu (jednej lub więcej) instrukcji ujętych w blok, który jako całość będzie wykonany lub nie, w zależności od tego, czy spełniony jest pewien warunek - co zależy zazwyczaj od aktualnych wartości pewnych zmiennych. Warunek ten zapisuje się w postaci wyrażenia logicznego.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&amp;lt;small&amp;gt;&lt;br /&gt;
Wśród instrukcji tworzących blok warunkowy mogą oczywiście się pojawić również instrukcje złożone, nie tylko instrukcje proste. Na przykład, kolejne instrukcje warunkowe.&lt;br /&gt;
&amp;lt;/small&amp;gt;&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Przykład minimalny:==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
x1, x2 = None, None&lt;br /&gt;
if delta &amp;gt; 0 and not a == 0:&lt;br /&gt;
    x1 = (-b + delta) / 2 / a&lt;br /&gt;
    x2 = (-b - delta) / 2 / a&lt;br /&gt;
print(x1, x2)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Linijka z wywołaniem &amp;lt;tt&amp;gt;print&amp;lt;/tt&amp;gt; nie jest już częścią instrukcji warunkowej, tylko kolejną instrukcją.&lt;br /&gt;
&lt;br /&gt;
'''Do zapamiętania''':&lt;br /&gt;
*wiersz otwierający instrukcję złożoną (czyli tu: zaczynająca się od &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt;) zawsze kończy się dwukropkiem&lt;br /&gt;
*instrukcje tworzące blok w instrukcji złożonej są pisane z wcięciem, które musi być jednolite&lt;br /&gt;
*koniec bloku rozpoznaje się po powrocie do uprzedniego poziomu wcięcia&lt;br /&gt;
*blok instrukcji pod &amp;lt;tt&amp;gt;if ...&amp;lt;/tt&amp;gt; nie może być pusty. Instrukcja &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt; z pustym blokiem warunkowym jest nie tylko nieprzydatna, ale jest również błędem składniowym.&lt;br /&gt;
&lt;br /&gt;
==Przykład bardziej złożony:==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
if a == 0:&lt;br /&gt;
    print('Równanie nie jest kwadratowe.')&lt;br /&gt;
elif delta &amp;gt; 0 and not a == 0:&lt;br /&gt;
    x1 = (-b + delta) / 2 / a&lt;br /&gt;
    x2 = (-b - delta) / 2 / a&lt;br /&gt;
    print('Są dwa pierwiastki: x1 =', x1, 'x2 =', x2)&lt;br /&gt;
elif delta == 0:&lt;br /&gt;
    x = -b / 2 / a&lt;br /&gt;
    print('Jest tylko jeden pierwiastek: x =', x)&lt;br /&gt;
else: # delta &amp;lt; 0:&lt;br /&gt;
    print('Nie ma pierwiastków rzeczywistych.')&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Jak to działa?&lt;br /&gt;
&lt;br /&gt;
*Jeżeli spełniony jest warunek &amp;lt;tt&amp;gt;a == 0&amp;lt;/tt&amp;gt;, wykonany zostanie blok poniżej &amp;lt;tt&amp;gt;if ...&amp;lt;/tt&amp;gt;, a reszta instrukcji zostanie pominięta;&lt;br /&gt;
*Jeżeli warunek ten jest nieprawdziwy (i tylko wtedy), to sprawdzane są kolejno warunki umieszczone w wierszach zaczynających się od &amp;lt;tt&amp;gt;elif&amp;lt;/tt&amp;gt;. Jeśli któryś z nich okaże się prawdziwy, to blok poniżej tej linijki zostanie wykonany, a cała reszta - pominięta;&lt;br /&gt;
*Jeżeli żaden z warunków - tych po &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt;, i tych po wszystkich &amp;lt;tt&amp;gt;elif&amp;lt;/tt&amp;gt; - nie okazał się prawdziwy, wykonany zostanie blok związany z &amp;lt;tt&amp;gt;else&amp;lt;/tt&amp;gt;.&lt;br /&gt;
*Bloków &amp;lt;tt&amp;gt;elif&amp;lt;/tt&amp;gt; może być w instrukcji dowolnie wiele (w tym - wcale), &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt; jest obowiązkowy (inaczej nie byłoby instrukcji warunkowej) i tylko jeden, &amp;lt;tt&amp;gt;else&amp;lt;/tt&amp;gt; może wystąpić wyłącznie na końcu - jeden raz, lub wcale.&lt;br /&gt;
*Komentarz po &amp;lt;tt&amp;gt;else:&amp;lt;/tt&amp;gt; jest podpowiedzią dla czytającego, że skoro już zbadano warunki &amp;lt;tt&amp;gt;delta == 0&amp;lt;/tt&amp;gt; oraz &amp;lt;tt&amp;gt;delta &amp;gt; 0&amp;lt;/tt&amp;gt;, a wykonanie dotarło do tej linijki, to &amp;lt;tt&amp;gt;delta &amp;lt; 0&amp;lt;/tt&amp;gt; jest jedyną pozostałą możliwością (o ile możemy założyć, że &amp;lt;tt&amp;gt;delta&amp;lt;/tt&amp;gt; jest na pewno liczbą!). Jest on przeznaczony wyłącznie dla ludzkich oczu - interpreter go zignoruje, jak każdy komentarz.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&amp;lt;small&amp;gt;&lt;br /&gt;
Mam nadzieję, że czytający już zauważył, że &amp;lt;tt&amp;gt;and not a == 0&amp;lt;/tt&amp;gt; w trzeciej linijce jest niepotrzebne. Dlaczego?&lt;br /&gt;
&amp;lt;/small&amp;gt;&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Wyrażenie warunkowe==&lt;br /&gt;
&lt;br /&gt;
Innym sposobem uzależnienia wyniku działania od jakiegoś warunku jest tzw. ''wyrażenie warunkowe''. Jest ono szczególnie wygodne w prostych przypadkach, i pozwala zapisać pewne działania w bardziej zwięzły sposób. &lt;br /&gt;
&lt;br /&gt;
Przykład: chcemy, aby z nazwą &amp;lt;tt&amp;gt;wbx&amp;lt;/tt&amp;gt; wiązała się wartość bezwzględna (moduł) aktualnej wartości (liczby) &amp;lt;tt&amp;gt;x&amp;lt;/tt&amp;gt;. Za pomocą instrukcji warunkowej można to zrealizować tak:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
if x &amp;lt; 0:&lt;br /&gt;
    wbx = -x&lt;br /&gt;
else:&lt;br /&gt;
    wbx = x&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ten sam wynik można osiągnąć za pomocą wyrażenia warunkowego:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
wbx = -x if x &amp;lt; 0 else x&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
W wyrażeniu warunkowym nie ma opcji uwzględnienie dodatkowych możliwości za pomocą &amp;lt;tt&amp;gt;elif&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=Ćwiczenia=&lt;br /&gt;
&lt;br /&gt;
W programach ćwiczebnych nieraz przyda nam się funkcja &amp;lt;tt&amp;gt;input()&amp;lt;/tt&amp;gt;. Działa ona w sposób następujący: argumentem wywołania powinien być jakiś napis (np. w postaci stałej napisowej): &amp;lt;tt&amp;gt;input('podaj jakąś liczbę całkowitą: ')&amp;lt;/tt&amp;gt;. Gdy w programie przyjdzie kolej na wykonanie takiego wywołania, program wypisze ten napis do terminalu i będzie oczekiwał na reakcję użytkownika, czyli wpisanie czegoś z klawiatury (i zakończenie naciśnięciem klawisza ''Enter''). Gdy to nastąpi, wynikiem wywołania funkcji &amp;lt;tt&amp;gt;input&amp;lt;/tt&amp;gt; w programie będzie treść wpisana prze użytkownika (bez końcowego znaku nowej linii).&lt;br /&gt;
&lt;br /&gt;
''Uwaga:'' wartość zwracana przez &amp;lt;tt&amp;gt;input()&amp;lt;/tt&amp;gt; zawsze jest napisem, a nie liczbą - choćby się składał z samych cyfr.&lt;br /&gt;
&lt;br /&gt;
1. Napisz program, którego uruchomienie ma następujący skutek:&lt;br /&gt;
*program wita użytkownika (komunikatem w terminalu),&lt;br /&gt;
*prosi o wprowadzenie liczby całkowitej,&lt;br /&gt;
*sprawdza, czy liczba ta jest podzielna przez 7, i informuje o wyniku tego sprawdzenia&lt;br /&gt;
&lt;br /&gt;
2. Napisz program, którego uruchomienie ma następujący skutek:&lt;br /&gt;
* program prosi użytkownika o podanie swojego (lub czyjegoś) wieku w latach&lt;br /&gt;
* jeśli wiek jest ujemny lub przekracza 120, odpowiada ,,Nieprawidłowy wiek&amp;quot;&lt;br /&gt;
* jeśli wiek wynosi 0, odpowiada ,,niemowlę&amp;quot;&lt;br /&gt;
* jeśli wiek jest poniżej 18, odpowiada ,,dziecko&amp;quot;&lt;br /&gt;
* jeśli wiek jest pomiędzy 18 a 120 (włącznie), odpowiada ,,dorosły&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
''CDN''&lt;br /&gt;
&lt;br /&gt;
---- &lt;br /&gt;
&lt;br /&gt;
[[PPy3/StałeIZmienne|poprzednia]] | [[&amp;quot;Programowanie z Pythonem3&amp;quot;|Strona główna]] | [[PPy3/SekwencjeIIteracja|dalej]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Użytkownik:RobertJB|RobertJB]] ([[Dyskusja użytkownika:RobertJB|dyskusja]]) 15:42, 28 cze 2016 (CEST)&lt;/div&gt;</summary>
		<author><name>RobertJB</name></author>
		
	</entry>
	<entry>
		<id>http://brain.fuw.edu.pl/edu/index.php?title=PPy3/Sta%C5%82eIZmienne&amp;diff=8919</id>
		<title>PPy3/StałeIZmienne</title>
		<link rel="alternate" type="text/html" href="http://brain.fuw.edu.pl/edu/index.php?title=PPy3/Sta%C5%82eIZmienne&amp;diff=8919"/>
		<updated>2022-07-29T12:16:56Z</updated>

		<summary type="html">&lt;p&gt;RobertJB: /* Inne wyrażenia */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=Stałe i zmienne=&lt;br /&gt;
&lt;br /&gt;
==Stałe dosłowne (literalne)==&lt;br /&gt;
&lt;br /&gt;
Stałe dosłowne to takie, których wartości wprost wpisano do pliku z kodem (lub w linii poleceń interpretera). Mogą to być liczby (paru rodzajów) lub napisy, ale również różne złożone rodzaje (typy) danych, z którymi zapoznamy się nieco później.&lt;br /&gt;
&lt;br /&gt;
'''Zapamiętajmy''' od razu: ''liczba'' dla komputera to zupełnie co innego, niż ''napis'' składający się z cyfr. Na napisie nie wykonamy operacji arytmetycznych - a na liczbie, operacji właściwych dla napisów (takich jak np. wyjęcie z niego znaku stojącego na określonej pozycji). Istnieją jednak operacje przekształcające każdy z tych typów danych w drugi.&lt;br /&gt;
&lt;br /&gt;
===Liczby===&lt;br /&gt;
&lt;br /&gt;
Dobrze jest pamiętać, że nieco odmiennie traktowane są liczby całkowite, a inaczej - liczby ułamkowe, zwykle zwane ''zmiennoprzecinkowymi'' (po angielsku ''floating point'', jako że Amerykanie piszą kropkę dziesiętną a nie - jak my - przecinek, przez co i w Pythonie używa się w tym celu kropki).&lt;br /&gt;
&lt;br /&gt;
*Liczby całkowite w zapisie dziesiętnym: &amp;lt;tt&amp;gt;1024&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;-666&amp;lt;/tt&amp;gt;, ...&lt;br /&gt;
*Liczby ułamkowe: &amp;lt;tt&amp;gt;1.0&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;.99&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;98.6&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;-37.43&amp;lt;/tt&amp;gt;, ...&lt;br /&gt;
*Liczby ułamkowe w zapisie wykładniczym: &amp;lt;tt&amp;gt;1.024e3&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;96.9E-12&amp;lt;/tt&amp;gt;, ...&lt;br /&gt;
&lt;br /&gt;
Notacja &amp;lt;tt&amp;gt;e3&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;E-12&amp;lt;/tt&amp;gt; itp. (wielka i mała litera &amp;lt;tt&amp;gt;e&amp;lt;/tt&amp;gt; są tu równoważne) oznacza pomnożenie poprzedzającej liczby przez odpowiednio 10&amp;lt;sup&amp;gt;3&amp;lt;/sup&amp;gt;, 10&amp;lt;sup&amp;gt;-12&amp;lt;/sup&amp;gt;, ... i służy ułatwieniu zapisu liczb bardzo dużych lub bardzo małych. Nie można tam wtrącać dodatkowych odstępów, podobnie jak pomiędzy cyframi.&lt;br /&gt;
&lt;br /&gt;
Jeśli część całkowita (lub ułamkowa) liczby zmiennoprzecinkowej wynosi zero, to można to zero pominąć. Oczywiście nie można pominąć obu, zapisując liczbę zero! (można napisać: &amp;lt;tt&amp;gt;0.&amp;lt;/tt&amp;gt; albo &amp;lt;tt&amp;gt;.0&amp;lt;/tt&amp;gt;, ale nie samotną kropkę).&lt;br /&gt;
&lt;br /&gt;
Podstawowa różnica pomiędzy sposobem traktowania liczb całkowitych i zmiennoprzecinkowych polega na tym, że:&lt;br /&gt;
&lt;br /&gt;
*liczby całkowite mogą być dowolnie duże, a rachunki całkowitoliczbowe wykonywane są dokładnie,&lt;br /&gt;
*liczby ułamkowe oraz wyniki rachunków na liczbach ułamkowych należy zawsze traktować jako przybliżone (oczywiście dla szczególnych wartości zdarza się, że są one dokładne); zakres wielkości liczb ułamkowych jest ograniczony.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&amp;lt;small&amp;gt;&lt;br /&gt;
Python zna też liczby ''zespolone'' oraz operacje na nich, ale tego zdaje się nie było w szkole...&lt;br /&gt;
&amp;lt;/small&amp;gt;&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Liczby całkowite można pisać również w podstawach innych niż 10:&lt;br /&gt;
&lt;br /&gt;
*dwójkowe: &amp;lt;tt&amp;gt;0b101 == 5&amp;lt;/tt&amp;gt;&lt;br /&gt;
*ósemkowe: &amp;lt;tt&amp;gt;0o123 == 83&amp;lt;/tt&amp;gt;&lt;br /&gt;
*szesnastkowe: &amp;lt;tt&amp;gt;0x1f == 31&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
(podwojony znak równości oznacza: lewa strona jest równa prawej; litery b, o, x mogą być zarówno małe jak i wielkie).&lt;br /&gt;
&lt;br /&gt;
W zapisie szesnastkowym, wymagającym 16 różnych cyfr, w roli &amp;quot;brakujących&amp;quot; cyfr oznaczających liczby od 10 do 15 przyjmuje się początkowe litery alfabetu (a-f), można równoważnie używać liter małych lub wielkich.&lt;br /&gt;
&lt;br /&gt;
===Napisy===&lt;br /&gt;
&lt;br /&gt;
Napis (ang. ''string'') to po prostu ciąg znaków.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&amp;lt;small&amp;gt;&lt;br /&gt;
OK, nic nie jest tak proste, jak się wydaje. Pytanie: co to jest znak? Odpowiedzi dostarcza standard ''Unicode'', w skład którego chodzi m. in. katalog wszystkich znaków, używanych przez systemy pisma wszystkich w zasadzie języków świata (języków żywych, i co ważniejszych spośród martwych). Nie będziemy się w tej chwili zastanawiać nad tym, jak dokładnie znaki te są reprezentowane w komputerze. Warto jednak pamiętać, że napisy nie muszą ograniczać się do znaków znanych z zapisu języków europejskich.&lt;br /&gt;
&amp;lt;/small&amp;gt;&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Literalne stałe napisowe, czyli napisy &amp;quot;na twardo&amp;quot; wpisane do kodu, mogą być podane w paru różnych postaciach:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
napis1 = 'jedna z postaci napisu'&lt;br /&gt;
napis2 = &amp;quot;nieco inna postać napisu&amp;quot;&lt;br /&gt;
napis3 = '''tak też może wyglądać napis,&lt;br /&gt;
i w tej postaci może zawierać przejścia do nowego wiersza&lt;br /&gt;
(w poprzednich nie może)'''&lt;br /&gt;
napis4 = &amp;quot;&amp;quot;&amp;quot;zamiast apostrofów, mogą być cudzysłowy - wychodzi na to samo,&lt;br /&gt;
również w postaci takiej, jak napis1 i napis2 są one równoważne&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
napis5 = &amp;quot;korzyść z tego pojawia się np. gdy w treści napisu potrzebujemy umieścić znak taki jak ' &amp;quot;&lt;br /&gt;
napis6 = 'w treści napisów można użyć kilku specjalnych sekwencji:\nTo powoduje przejście do nowego wiersza..'&lt;br /&gt;
napis7 = 'jeśli dwa napisy (lub więcej) postawimy ' 'jeden obok drugiego ' 'to zostaną połączone w jeden'&lt;br /&gt;
napis8 = 'lecz uwaga: pomiędzy sklejone napisy nie zostanie wstawiona żadna spacja ani w ogóle nic.'&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Sekwencje specjalne w napisach'''&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;\\&amp;lt;/tt&amp;gt;||dosłowny znak &amp;lt;tt&amp;gt;\&amp;lt;/tt&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;\'&amp;lt;/tt&amp;gt;||apostrof: &amp;lt;tt&amp;gt;'&amp;lt;/tt&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;\&amp;quot;&amp;lt;/tt&amp;gt;||cudzysłów: &amp;lt;tt&amp;gt;&amp;quot;&amp;lt;/tt&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;\a&amp;lt;/tt&amp;gt;||kod BEL&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;\b&amp;lt;/tt&amp;gt;||kod BS ('backspace')&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;\f&amp;lt;/tt&amp;gt;||kod FF ('formfeed')&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;\n&amp;lt;/tt&amp;gt;||kod LF ('linefeed')&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;\r&amp;lt;/tt&amp;gt;||kod CR ('carriage return')&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;\t&amp;lt;/tt&amp;gt;||kod HT ('horizontal tab')&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;\v&amp;lt;/tt&amp;gt;||kod VT ('vertical tab')&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;\nnn&amp;lt;/tt&amp;gt;||znak o kodzie 'nnn' w zapisie ósemkowym&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;\xnn&amp;lt;/tt&amp;gt;||znak o kodzie 'nn' w zapisie szesnastkowym&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;\N{nazwa}&amp;lt;/tt&amp;gt;||znak o danej nazwie symbolicznej w tabeli Unicode&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;\unnnn&amp;lt;/tt&amp;gt;||znak o pozycji '0xnnnn' w 16-bitowej tabeli Unicode&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;\Unnnnnnnn&amp;lt;/tt&amp;gt;||znak o pozycji '0xnnnnnnnn' w 32-bitowej tabeli Unicode&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
To co określam tutaj nazwą ''kod'' to są szczególne ,,znaki&amp;quot;, które nie posiadają reprezentacji graficznej, ale mogą wystąpić w strumieniu tekstowym pełniąc jakiegoś rodzaju rolę sterującą (p. poniżej). Czasami stosuje się określenie ''znaki niedrukowalne''. Jest ich więcej, niż występuje w powyższej tabeli &amp;amp;mdash; pozostałym nie nadano specjalnego zapisu i dostępne są np. przez notację &amp;lt;tt&amp;gt;\nnn&amp;lt;/tt&amp;gt; albo &amp;lt;tt&amp;gt;\xnn&amp;lt;/tt&amp;gt;, ale niezwykle rzadko bywają potrzebne.&lt;br /&gt;
&lt;br /&gt;
* Wypisanie kodu BEL na terminal najczęściej skutkuje sygnałem akustycznym (''BIP!'') lub wizualnym (błysk), zależy to od ustawień emulatora terminala&lt;br /&gt;
* Kod BS cofa kursor o jedną pozycję, umożliwiając nadpisanie ostatniego wypisanego znaku&lt;br /&gt;
* Kod FF stosowano w tekście przeznaczonym do wydrukowania na drukarce wierszowej, powodował przejście do następnej strony. Obecnie ze względu na wymarcie drukarek wierszowych w zasadzie nie ma zastosowania&lt;br /&gt;
* Kod LF to przejście do nowej linii, inaczej - znacznik końca linii w strumieniu tekstowym&lt;br /&gt;
* Kod CR czyli powrót karetki cofa kursor do początku aktualnej linii&lt;br /&gt;
* Kod HT to ten, który zwykle nazywa się po prostu kodem tabulacji. Jego interpretacja zależy od ustawień terminala lub innego programu renderującego tekst, zwykle oznacza przeskok do pozycji będącej kolejną całkowitą wielokrotnością 4 lub 8 w bieżącej linii&lt;br /&gt;
* Kod VT z założenia działa analogicznie jak HT, ale w kierunku pionowym. Obecnie rzadko stosowany&lt;br /&gt;
* W zapisie &amp;lt;tt&amp;gt;\nnn&amp;lt;/tt&amp;gt; może wystąpić jedna, dwie lub trzy cyfry ósemkowe ''n''&lt;br /&gt;
* W zapisie &amp;lt;tt&amp;gt;\xnn&amp;lt;/tt&amp;gt; należy użyć dokładnie dwóch cyfr szesnatkowych ''n''&lt;br /&gt;
* W zapisie &amp;lt;tt&amp;gt;\unnnn&amp;lt;/tt&amp;gt; należy użyć dokładnie czterech cyfr szesnastkowych ''n''&lt;br /&gt;
* W zapisie &amp;lt;tt&amp;gt;\Unnnnnnnn&amp;lt;/tt&amp;gt; należy użyć dokładnie ośmiu cyfr szesnastkowych ''n''&lt;br /&gt;
&lt;br /&gt;
Jeżeli chcemy zapisać napis obfitujący w znaki &amp;lt;tt&amp;gt;\&amp;lt;/tt&amp;gt;, możemy użyć notacji takiej:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
napis1 = r'oto\napis\z\bakslaszami'&lt;br /&gt;
napis2 = R'tu\znak&amp;quot;\&amp;quot;nie\będzie\nigdy\oznaczał\początku\specjalnej\sekwencji'&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wielkość użytej na początku litery &amp;lt;tt&amp;gt;R&amp;lt;/tt&amp;gt; nie ma znaczenia.&lt;br /&gt;
&lt;br /&gt;
==Zmienne, czyli nazwy==&lt;br /&gt;
&lt;br /&gt;
Programy oczywiście nie operują jedynie na stałych. Potrzebny jest w nich sposób odnoszenia się do wartości, które nie są znane z góry (w chwili pisania programu) - albo dlatego, że zostaną dostarczone dopiero przy uruchomieniu lub w trakcie pracy programu, jako dane wejściowe (później zobaczymy, na jakie sposoby można tego dokonać), albo dlatego, że będą wynikiem obliczeń lub przekształceń danych wykonywanych przez program.&lt;br /&gt;
&lt;br /&gt;
Do tego w Pythonie służą ''zmienne'' - można je uważać za nazwy, z jakimi wiążemy pewne wartości (liczby, napisy, itd.), poprzez ''instrukcję podstawienia''. Do zapisu instrukcji podstawienia służy znak równości (&amp;lt;tt&amp;gt;=&amp;lt;/tt&amp;gt;), po jego lewej stronie stawiamy nazwę (zmiennej), po drugiej - ''wyrażenie'', np. literalną stałą, ale również może być to wyrażenie zbudowane ze stałych, operatorów (np. arytmetycznych), nazw zmiennych (reprezentujących w wyrażeniu związane z nimi aktualnie wartości), i szereg innych elementów które dopiero poznamy.&lt;br /&gt;
&lt;br /&gt;
'''Do zapamiętania''': pojedynczy znak równości &amp;lt;tt&amp;gt;=&amp;lt;/tt&amp;gt; w Pythonie (i wielu innych językach programowania) nie tworzy ''równania'', czyli stwierdzenia, że lewa strona jest równa prawej; tylko ''podstawienie'', a więc operację powodującą, że z nazwą stojącą po stronie lewej zostaje związana obliczona wartość wyrażenie stojącego po prawej. Zauważmy, że jest to operacja niesymetryczna (stron nie można bezkarne zamienić miejscami):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
i = 0 # pierwsze użycie nazwy, w tym przypadku 'i', tworzy zmienną i wiąże z nią wartość&lt;br /&gt;
i = i + 2 # to jest legalne, i oznacza, że wartość związana z 'i' rośnie o 2&lt;br /&gt;
i + 2 = i # to jest błędne, po lewej stronie nie może stać wyrażenie złożone&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Pojawienie się w wyrażeniu stojącym po prawej stronie podstawienia tej samej nazwy, która stoi po lewej stronie, nie tworzy jakiejkolwiek niejednoznaczności: zasadą jest, że ''wpierw'' obliczana jest wartość wyrażenia z prawej strony, z wykorzystaniem aktualnych wartości zmiennych, a ''potem'' następuje związanie nazwy zmiennej stojącej po lewej z wynikiem.&lt;br /&gt;
&lt;br /&gt;
Zauważmy, że błędem byłoby użycie nazwy po raz pierwszy ''bez'' uprzedniego nadania jej wartości, np. w wyrażeniu arytmetycznym.&lt;br /&gt;
&lt;br /&gt;
===Reguły tworzenia nazw===&lt;br /&gt;
&lt;br /&gt;
Aktualnie reguły określające, co jest poprawną nazwą w Pythonie, dopuszczają użycie całkiem szerokiego podzbioru znaków Unicode i są dość trudne do opisania w zrozumiały sposób. Pomijając jednak taką możliwość, że ktoś zechce użyć w nazwie zmiennej znaków pisma Kanji lub perskiego, można w dużym uproszczeniu powiedzieć tak:&lt;br /&gt;
&lt;br /&gt;
*nazwy można budować z liter (wielkich i małych), cyfr, i znaku podkreślenia (&amp;lt;tt&amp;gt;_&amp;lt;/tt&amp;gt;)&lt;br /&gt;
*z zastrzeżeniem, że pierwszym znakiem nazwy nie może być cyfra&lt;br /&gt;
*litery wielkie i małe są rozróżniane, tak więc nazwy różniące się jedynie wielkością liter ''są różne''&lt;br /&gt;
*długość nazwy nie podlega ograniczeniu&lt;br /&gt;
*zabronione jest użycie jako nazwy któregokolwiek z tzw. słów zastrzeżonych, które mają specjalne znaczenie w składni języka Python.[https://docs.python.org/3/reference/lexical_analysis.html#keywords Tutaj można znaleźć ich wykaz].&lt;br /&gt;
&lt;br /&gt;
W szczególności, nazwy (zmiennych i innych obiektów) mogą jak najbardziej zawierać litery właściwe dla języka polskiego (oraz dla innych języków). Z rozmaitych względów nie jest to jednak szczególnie rekomendowane, lepiej (przynajmniej na razie) ograniczyć się do liter podstawowego alfabetu łacińskiego. &lt;br /&gt;
&lt;br /&gt;
Oprócz twardych reguł zawartych w definicji języka, w tworzeniu nazw programiści trzymają się na ogół pewnych konwencji - które nie są w żaden sposób egzekwowane przez interpreter, ale ułatwiają czytanie kodu &amp;amp;mdash; zwłaszcza, gdy się nim dzielimy z innymi:&lt;br /&gt;
&lt;br /&gt;
*w nazwach zmiennych używamy małych liter (a nie wielkich)&lt;br /&gt;
*wielkie litery rezerwujemy dla nazw oznaczających wartości stałe, które nie mają prawa się zmienić w trakcie pracy programu&lt;br /&gt;
*staramy się, by nazwy coś znaczyły i ułatwiały zrozumienie kodu programu&lt;br /&gt;
*nie unikamy nazw składających się z dwóch lub nawet kilku słów; ponieważ spacja jako składnik nazwy nie jest dozwolona, zastępujemy ją znakiem podkreślenia&lt;br /&gt;
*unikamy jednak nazw przesadnie długich, a nazwy zmiennych, które są potrzebne jedynie &amp;quot;chwilowo&amp;quot; mogą wręcz być jednoliterowe&lt;br /&gt;
*nazwy zaczynające się od podkreślenia (&amp;lt;tt&amp;gt;_&amp;lt;/tt&amp;gt;) mają pewne specjalne znaczenia i nie tworzymy takich nazw, chyba że całkiem świadomie.&lt;br /&gt;
&lt;br /&gt;
=Wyrażenia=&lt;br /&gt;
&lt;br /&gt;
==Arytmetyczne==&lt;br /&gt;
&lt;br /&gt;
Wyrażenia arytmetyczne tworzymy z udziałem znanych już operatorów arytmetycznych &amp;lt;tt&amp;gt;+, -, /, *, **, //, %, ...&amp;lt;/tt&amp;gt;, ale również wywołań funkcji zwracających wartości liczbowe (więcej o tym dalej), z wykorzystaniem literalnych liczb i nazw oznaczających zmienne, których aktualne wartości powinny być liczbami. Możemy również używać nawiasów (wyłącznie okrągłych!) do grupowania podwyrażeń, aby wymusić określoną kolejność operacji. Każdy na ogół pamięta, że dzielenie i mnożenie mają pierwszeństwo przed dodawaniem i odejmowaniem; potęgowanie ma jeszcze wyższy priorytet. Gdy mamy do czynienia z operatorami o równym priorytecie, to operacje wykonywane są zgodnie z kolejnością czytania, od lewej do prawej. Jeżeli mamy wątpliwości, to użycie nawiasów nie będzie błędem. Przykłady:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
a + b * c == a + (b * c)&lt;br /&gt;
a / b / c == (a / b) / c&lt;br /&gt;
a * b ** c == a * (b ** c)&lt;br /&gt;
a ** b ** c == a ** (b ** c)&lt;br /&gt;
a ** - b == a ** (-b)&lt;br /&gt;
a ** b / c == (a ** b) / c&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Zachowanie operatora potęgowania jest tu nieco szczególne, i zgadza się z umową przyjętą w matematyce.&lt;br /&gt;
&lt;br /&gt;
Operatory arytmetyczne znajdują również czasem zastosowanie do obiektów nie będących liczbami, mają wtedy oczywiście nieco inne znaczenie. Np. suma dwóch napisów jest ich sklejeniem (mówi się też: ''konkatenacją''). &lt;br /&gt;
&lt;br /&gt;
W przypadku, gdy będziemy mieszać w jednym wyrażeniu liczby całkowite i zmiennoprzecinkowe, to wynik będzie liczbą zmiennoprzecinkową. Wyjątkiem jest dzielenie: &amp;lt;tt&amp;gt;a / b&amp;lt;/tt&amp;gt; zawsze da w wyniku liczbę zmiennoprzecinkową, natomiast &amp;lt;tt&amp;gt;a // b&amp;lt;/tt&amp;gt; - całkowitą, jeśli oba argumenty są całkowite; w przeciwnym razie, zmiennoprzecinkową (ale o zerowej części ułamkowej).&lt;br /&gt;
&lt;br /&gt;
===Rozszerzone operatory przypisania===&lt;br /&gt;
&lt;br /&gt;
Z dwuargumentowymi operatorami arytmetycznymi związane są tzw. ''rozszerzone operatory przypisania'', stanowiące drobne udogodnienie pozwalające w sposób bardziej zwięzły zapisać dość często występujące operacje - takie, jak powiększenie aktualnej wartości &amp;lt;tt&amp;gt;x&amp;lt;/tt&amp;gt; o 1 i zapamiętanie tej nowej, powiększonej wartości pod nazwą &amp;lt;tt&amp;gt;x&amp;lt;/tt&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
# poniższe instrukcje są parami równoważne&lt;br /&gt;
x = x + a &lt;br /&gt;
x += a &lt;br /&gt;
#&lt;br /&gt;
x = x * a&lt;br /&gt;
x *= a&lt;br /&gt;
#&lt;br /&gt;
x = x - a&lt;br /&gt;
x -= a&lt;br /&gt;
#&lt;br /&gt;
x = x / a&lt;br /&gt;
x /= a&lt;br /&gt;
#&lt;br /&gt;
x **= a&lt;br /&gt;
x = x**a&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wersja np. z potęgowaniem może jest niezbyt często przydatna, ale wprowadzono ją choćby po to, by było konsekwentnie.&lt;br /&gt;
&lt;br /&gt;
==Logiczne==&lt;br /&gt;
&lt;br /&gt;
Wyrażenia logiczne mogą mieć jedną z dwu wartości: Prawda (&amp;lt;tt&amp;gt;True&amp;lt;/tt&amp;gt;) lub Fałsz (&amp;lt;tt&amp;gt;False&amp;lt;/tt&amp;gt;). Literalne wartości &amp;lt;tt&amp;gt;True&amp;lt;/tt&amp;gt; i &amp;lt;tt&amp;gt;False&amp;lt;/tt&amp;gt; są też przykładami wyrażeń logicznych, choć dość mało przydatnymi. Prawdziwe lub fałszywe mogą być np. porównania dwóch wartości, tworzone za pomocą operatorów &amp;lt;tt&amp;gt;&amp;amp;gt;&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;&amp;amp;lt;&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;&amp;amp;gt;=&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;&amp;amp;lt;=&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;==&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;!=&amp;lt;/tt&amp;gt; (to ostatnie, to sposób w jaki w Pythonie pisze się znak nierówności). Jak już wspomniano, podwojony znak równości jest operatorem porównania (w odróżnieniu od pojedynczego - przypisania). Porównywać można przede wszystkim liczby (a więc - dowolne wyrażenia o wartościach liczbowych), ale również np. napisy - wówczas większy oznacza tyle, co dalszy w porządku leksykograficznym. Porównania mają priorytet niższy, niż operatory arytmetyczne.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&amp;lt;small&amp;gt;&lt;br /&gt;
Przy bliższym poznaniu okazuje się, że wartości &amp;lt;tt&amp;gt;True&amp;lt;/tt&amp;gt; i &amp;lt;tt&amp;gt;False&amp;lt;/tt&amp;gt; są tak naprawdę w pewnym sensie liczbami: odpowiednio 1 i 0. Dozwolone jest więc np. stosowanie do nich operacji arytmetycznych.&lt;br /&gt;
&amp;lt;/small&amp;gt;&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Z elementarnych wyrażeń logicznych (porównań) można tworzyć złożone wyrażenia logiczne za pomocą operatorów (spójników) logicznych, pisanych &amp;lt;tt&amp;gt;and&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;or&amp;lt;/tt&amp;gt; i &amp;lt;tt&amp;gt;not&amp;lt;/tt&amp;gt;. Mają one następujące właśności:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
(a and b) == (b and a)&lt;br /&gt;
(False and False) == False&lt;br /&gt;
(False and True) == False&lt;br /&gt;
(True and True) == True&lt;br /&gt;
(a or b) == (b or a)&lt;br /&gt;
(False or False) == False&lt;br /&gt;
(False or True) == True&lt;br /&gt;
(True or True) == True&lt;br /&gt;
(not True) == False&lt;br /&gt;
(not False) == True &lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Spójniki logiczne mają priorytet jeszcze niższy, niż porównania - stąd nawiasy w powyższym. Wśród nich najwyższy priorytet ma &amp;lt;tt&amp;gt;not&amp;lt;/tt&amp;gt;, następnie &amp;lt;tt&amp;gt;and&amp;lt;/tt&amp;gt;, na końcu &amp;lt;tt&amp;gt;or&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Wyrażenia logiczne mają tę szczególną własność, że wartość wyrażenia można często określić obliczając jedynie część jego elementów. Np. &amp;lt;tt&amp;gt;a and b&amp;lt;/tt&amp;gt;, jeżeli wartością &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; jest &amp;lt;tt&amp;gt;False&amp;lt;/tt&amp;gt;, jest na pewno &amp;lt;tt&amp;gt;False&amp;lt;/tt&amp;gt; - niezależnie od wartości &amp;lt;tt&amp;gt;b&amp;lt;/tt&amp;gt;. W takich przypadkach Python przerywa obliczanie (od lewej do prawej, z uwzględnieniem nawiasów) gdy tylko wartość jest określona. Fakt ten czasami może mieć znaczenie - jeżeli np. obliczenie któregoś z członów wyrażenia logicznego jest szczególnie czasochłonne, lub ma tzw. skutki uboczne.&lt;br /&gt;
&lt;br /&gt;
Wyrażenia logiczne znajdują zastosowanie przede wszystkim w instrukcji warunkowej - pozwalają określić warunki, pod jakimi pewne operacje będą wykonane, lub nie - o tym dalej.&lt;br /&gt;
&lt;br /&gt;
Warto wiedzieć, że w Pythonie '''każde wyrażenie może służyć jako wyrażenie logiczne'''. Inaczej mówiąc, każda wartość (napis, liczba, lista, itd.) może być wykorzystana w charakterze wartości logicznej. Obowiązują tu proste reguły:&lt;br /&gt;
&lt;br /&gt;
* liczba &amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt; jest fałszywa (równoważna &amp;lt;tt&amp;gt;False&amp;lt;/tt&amp;gt;); obojętne, czy całkowita czy zmiennoprzecinkowa;&lt;br /&gt;
* każda liczba różna od zera jest prawdziwa (równoważna &amp;lt;tt&amp;gt;True&amp;lt;/tt&amp;gt;);&lt;br /&gt;
* napis pusty (o długości 0) jest fałszywy, każdy inny napis jest prawdziwy (również np. zawierający wyłącznie spacje);&lt;br /&gt;
* ogólniej &amp;amp;mdash; dowolnego typu kolekcja (lista, słownik, zbiór, ...) jest prawdziwa, o ile jest niepusta; każda kolekcja pusta (0-elementowa) jest fałszywa;&lt;br /&gt;
* wartość pusta czyli &amp;lt;tt&amp;gt;None&amp;lt;/tt&amp;gt; jest, jak nietrudno zgadnąć, fałszywa.&lt;br /&gt;
&lt;br /&gt;
W przypadku ogólniejszych typów danych (obiektów klas złożonych) sytuacja może już nie być taka prosta, ponieważ twórca klasy ma moc określenia reguły decydującej o prawdziwości / nieprawdziwości obiektów danej klasy. Ten temat jest na razie poza zakresem naszego kursu.&lt;br /&gt;
&lt;br /&gt;
Jeżeli chcemy wymusić, aby dana wartość stała się dosłownie wartością logiczną, tzn. jedną z (&amp;lt;tt&amp;gt;True&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;False&amp;lt;/tt&amp;gt;) w sposób zgodny z powyższymi regułami, można to osiągnąć przykładając funkcję &amp;lt;tt&amp;gt;bool&amp;lt;/tt&amp;gt;: a więc &amp;lt;tt&amp;gt;bool(wyrażenie)&amp;lt;/tt&amp;gt;. Rzadko jednak bywa to potrzebne.&lt;br /&gt;
&lt;br /&gt;
Reguła „skrótowej&amp;quot; ewaluacji wyrażeń logicznych, w połączeniu z regułami prawdziwości innych typów danych, pozwala na dość popularne idiomy, jak np.:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
# jeśli `wynik' jest niepustą listą to wypisze jej zawartość&lt;br /&gt;
# jeśli natomiast pustą, pojawi się komunikat&lt;br /&gt;
print(wynik or &amp;quot;wynik jest pusty!&amp;quot;)&lt;br /&gt;
&amp;lt;/source&amp;gt; &lt;br /&gt;
&lt;br /&gt;
które pozwalają uniknąć używania instrukcji złożonych w wielu prostych przypadkach. Działa to dzięki temu, że spójniki &amp;lt;tt&amp;gt;and&amp;lt;/tt&amp;gt; i &amp;lt;tt&amp;gt;or&amp;lt;/tt&amp;gt; nie wymuszają aby wynik był wartością logiczną:&lt;br /&gt;
&lt;br /&gt;
* jeżeli &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; jest prawdziwe, to &amp;lt;tt&amp;gt;a or b == a&amp;lt;/tt&amp;gt;, i &amp;lt;tt&amp;gt;a and b == b&amp;lt;/tt&amp;gt; dla każdego &amp;lt;tt&amp;gt;b&amp;lt;/tt&amp;gt;;&lt;br /&gt;
* jeżeli &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; jest fałszywe, to &amp;lt;tt&amp;gt;a and b == a&amp;lt;/tt&amp;gt;, i &amp;lt;tt&amp;gt;a or b == b&amp;lt;/tt&amp;gt; dla każdego &amp;lt;tt&amp;gt;b&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Inaczej w przypadku operatora &amp;lt;tt&amp;gt;not&amp;lt;/tt&amp;gt;: wynikiem jego działania jest zawsze jedna z wartości logicznych, podobnie jak w przypadku funkcji &amp;lt;tt&amp;gt;bool()&amp;lt;/tt&amp;gt; &amp;amp;mdash; tyle, że przeciwna.&lt;br /&gt;
&lt;br /&gt;
==Napisowe==&lt;br /&gt;
&lt;br /&gt;
Wartością wyrażenia może być również napis. Na przykład, &amp;lt;tt&amp;gt;a + b&amp;lt;/tt&amp;gt;, jeżeli &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; i &amp;lt;tt&amp;gt;b&amp;lt;/tt&amp;gt; są napisami, jest napisem utworzonym przez ich sklejenie (zauważmy, że w odróżnieniu od dodawania liczb nie jest to operacja przemienna). &lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&amp;lt;small&amp;gt;&lt;br /&gt;
Wcześniej wspomniano, że dwa napisy literalne postawione obok siebie zostaną automatycznie sklejone w jeden: np. &amp;lt;tt&amp;gt;'abc' &amp;quot;123&amp;quot;&amp;lt;/tt&amp;gt; jest równoważne &amp;lt;tt&amp;gt;'abc123'&amp;lt;/tt&amp;gt;. Nie stosuje się to jednak np. do zmiennych o wartościach napisowych: napisanie dwóch nazw obok siebie bez operatora pomiędzy nimi jest błędem składniowym. Jest tak, ponieważ wspomniane sklejenie napisów literalnych ma miejsce na etapie ''kompilacji'' kodu - tzn. wtedy, gdy interpreter analizuje zapis programu i przekłada go na instrukcje, jakie zostaną wykonane w etapie uruchomienia - a wartości stojące za nazwami zmiennych nie są na tym etapie jednoznacznie określone. &lt;br /&gt;
&amp;lt;/small&amp;gt;&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Bogatszy repertuar operacji tworzących wyrażenia o wartościach będących napisami poznamy dalej.&lt;br /&gt;
&lt;br /&gt;
==Inne wyrażenia==&lt;br /&gt;
&lt;br /&gt;
Oprócz liczb, napisów i wartości logicznych, Python posiada szereg dalszych, złożonych typów danych, które również mogą być wartościami wyrażeń. Wspomniano już przelotnie o kolekcjach (listy, słowniki, zbiory, ...) &amp;amp;mdash; służą one jako ,,pojemniki&amp;quot; do gromadzenia obiektów w zasadzie dowolnych typów, i zostaną omówione w dalszym ciągu. Istnieje też specjalny typ ''obiektu pustego'', mający dokładnie jednego reprezentanta: wartość specjalną &amp;lt;tt&amp;gt;None&amp;lt;/tt&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Każdy typ obiektu w Pythonie może być wartością odpowiednio zbudowanego wyrażenia. Gdy poznamy kolejne typy danych, wprowadzimy również operacje tworzące takie wyrażenia.&lt;br /&gt;
&lt;br /&gt;
=Ćwiczenia=&lt;br /&gt;
&lt;br /&gt;
1. Które z następujących są poprawnymi nazwami według reguł Pythona:&lt;br /&gt;
   nazwa1&lt;br /&gt;
   9sił&lt;br /&gt;
   dluga-nazwa&lt;br /&gt;
   wykonaj_rachunki&lt;br /&gt;
   _&lt;br /&gt;
   to&amp;amp;owo&lt;br /&gt;
   if &lt;br /&gt;
&lt;br /&gt;
2. Wykazać, że poniższe równości są równoważnościami -- tzn. że zachodzą dla dowolnej kombinacji wartości &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; i &amp;lt;tt&amp;gt;b&amp;lt;/tt&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
   not (a or b) == not a and not b&lt;br /&gt;
   not (a and b) == not a or not b&lt;br /&gt;
   a or not a == True&lt;br /&gt;
&lt;br /&gt;
''Wskazówka:'' stworzyć tabelki wartości wyrażeń po lewej i prawej stronie operatora porównania &amp;lt;tt&amp;gt;==&amp;lt;/tt&amp;gt; dla wszystkich możliwych kombinacji wartości &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; i &amp;lt;tt&amp;gt;b&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
3. Które z poniższych równości są tożsamościami, w wyniku działania reguł pierwszeństwa operatorów?&lt;br /&gt;
&lt;br /&gt;
   a / b / c == a / (b / c)&lt;br /&gt;
   a ** b / c == (a ** b) / c&lt;br /&gt;
   -a ** b == (-a) ** b&lt;br /&gt;
&lt;br /&gt;
''CDN...''&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
[[PPy3/PierwszeKroki|poprzednia]] | [[&amp;quot;Programowanie z Pythonem3&amp;quot;|Strona główna]] | [[PPy3/InstrukcjaWarunkowa|dalej]]&lt;br /&gt;
&lt;br /&gt;
--[[Użytkownik:RobertJB|RobertJB]] ([[Dyskusja użytkownika:RobertJB|dyskusja]]) 14:22, 21 cze 2016 (CEST)&lt;/div&gt;</summary>
		<author><name>RobertJB</name></author>
		
	</entry>
	<entry>
		<id>http://brain.fuw.edu.pl/edu/index.php?title=PPy3/Sta%C5%82eIZmienne&amp;diff=8918</id>
		<title>PPy3/StałeIZmienne</title>
		<link rel="alternate" type="text/html" href="http://brain.fuw.edu.pl/edu/index.php?title=PPy3/Sta%C5%82eIZmienne&amp;diff=8918"/>
		<updated>2022-07-29T12:11:13Z</updated>

		<summary type="html">&lt;p&gt;RobertJB: /* Logiczne */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=Stałe i zmienne=&lt;br /&gt;
&lt;br /&gt;
==Stałe dosłowne (literalne)==&lt;br /&gt;
&lt;br /&gt;
Stałe dosłowne to takie, których wartości wprost wpisano do pliku z kodem (lub w linii poleceń interpretera). Mogą to być liczby (paru rodzajów) lub napisy, ale również różne złożone rodzaje (typy) danych, z którymi zapoznamy się nieco później.&lt;br /&gt;
&lt;br /&gt;
'''Zapamiętajmy''' od razu: ''liczba'' dla komputera to zupełnie co innego, niż ''napis'' składający się z cyfr. Na napisie nie wykonamy operacji arytmetycznych - a na liczbie, operacji właściwych dla napisów (takich jak np. wyjęcie z niego znaku stojącego na określonej pozycji). Istnieją jednak operacje przekształcające każdy z tych typów danych w drugi.&lt;br /&gt;
&lt;br /&gt;
===Liczby===&lt;br /&gt;
&lt;br /&gt;
Dobrze jest pamiętać, że nieco odmiennie traktowane są liczby całkowite, a inaczej - liczby ułamkowe, zwykle zwane ''zmiennoprzecinkowymi'' (po angielsku ''floating point'', jako że Amerykanie piszą kropkę dziesiętną a nie - jak my - przecinek, przez co i w Pythonie używa się w tym celu kropki).&lt;br /&gt;
&lt;br /&gt;
*Liczby całkowite w zapisie dziesiętnym: &amp;lt;tt&amp;gt;1024&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;-666&amp;lt;/tt&amp;gt;, ...&lt;br /&gt;
*Liczby ułamkowe: &amp;lt;tt&amp;gt;1.0&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;.99&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;98.6&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;-37.43&amp;lt;/tt&amp;gt;, ...&lt;br /&gt;
*Liczby ułamkowe w zapisie wykładniczym: &amp;lt;tt&amp;gt;1.024e3&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;96.9E-12&amp;lt;/tt&amp;gt;, ...&lt;br /&gt;
&lt;br /&gt;
Notacja &amp;lt;tt&amp;gt;e3&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;E-12&amp;lt;/tt&amp;gt; itp. (wielka i mała litera &amp;lt;tt&amp;gt;e&amp;lt;/tt&amp;gt; są tu równoważne) oznacza pomnożenie poprzedzającej liczby przez odpowiednio 10&amp;lt;sup&amp;gt;3&amp;lt;/sup&amp;gt;, 10&amp;lt;sup&amp;gt;-12&amp;lt;/sup&amp;gt;, ... i służy ułatwieniu zapisu liczb bardzo dużych lub bardzo małych. Nie można tam wtrącać dodatkowych odstępów, podobnie jak pomiędzy cyframi.&lt;br /&gt;
&lt;br /&gt;
Jeśli część całkowita (lub ułamkowa) liczby zmiennoprzecinkowej wynosi zero, to można to zero pominąć. Oczywiście nie można pominąć obu, zapisując liczbę zero! (można napisać: &amp;lt;tt&amp;gt;0.&amp;lt;/tt&amp;gt; albo &amp;lt;tt&amp;gt;.0&amp;lt;/tt&amp;gt;, ale nie samotną kropkę).&lt;br /&gt;
&lt;br /&gt;
Podstawowa różnica pomiędzy sposobem traktowania liczb całkowitych i zmiennoprzecinkowych polega na tym, że:&lt;br /&gt;
&lt;br /&gt;
*liczby całkowite mogą być dowolnie duże, a rachunki całkowitoliczbowe wykonywane są dokładnie,&lt;br /&gt;
*liczby ułamkowe oraz wyniki rachunków na liczbach ułamkowych należy zawsze traktować jako przybliżone (oczywiście dla szczególnych wartości zdarza się, że są one dokładne); zakres wielkości liczb ułamkowych jest ograniczony.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&amp;lt;small&amp;gt;&lt;br /&gt;
Python zna też liczby ''zespolone'' oraz operacje na nich, ale tego zdaje się nie było w szkole...&lt;br /&gt;
&amp;lt;/small&amp;gt;&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Liczby całkowite można pisać również w podstawach innych niż 10:&lt;br /&gt;
&lt;br /&gt;
*dwójkowe: &amp;lt;tt&amp;gt;0b101 == 5&amp;lt;/tt&amp;gt;&lt;br /&gt;
*ósemkowe: &amp;lt;tt&amp;gt;0o123 == 83&amp;lt;/tt&amp;gt;&lt;br /&gt;
*szesnastkowe: &amp;lt;tt&amp;gt;0x1f == 31&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
(podwojony znak równości oznacza: lewa strona jest równa prawej; litery b, o, x mogą być zarówno małe jak i wielkie).&lt;br /&gt;
&lt;br /&gt;
W zapisie szesnastkowym, wymagającym 16 różnych cyfr, w roli &amp;quot;brakujących&amp;quot; cyfr oznaczających liczby od 10 do 15 przyjmuje się początkowe litery alfabetu (a-f), można równoważnie używać liter małych lub wielkich.&lt;br /&gt;
&lt;br /&gt;
===Napisy===&lt;br /&gt;
&lt;br /&gt;
Napis (ang. ''string'') to po prostu ciąg znaków.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&amp;lt;small&amp;gt;&lt;br /&gt;
OK, nic nie jest tak proste, jak się wydaje. Pytanie: co to jest znak? Odpowiedzi dostarcza standard ''Unicode'', w skład którego chodzi m. in. katalog wszystkich znaków, używanych przez systemy pisma wszystkich w zasadzie języków świata (języków żywych, i co ważniejszych spośród martwych). Nie będziemy się w tej chwili zastanawiać nad tym, jak dokładnie znaki te są reprezentowane w komputerze. Warto jednak pamiętać, że napisy nie muszą ograniczać się do znaków znanych z zapisu języków europejskich.&lt;br /&gt;
&amp;lt;/small&amp;gt;&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Literalne stałe napisowe, czyli napisy &amp;quot;na twardo&amp;quot; wpisane do kodu, mogą być podane w paru różnych postaciach:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
napis1 = 'jedna z postaci napisu'&lt;br /&gt;
napis2 = &amp;quot;nieco inna postać napisu&amp;quot;&lt;br /&gt;
napis3 = '''tak też może wyglądać napis,&lt;br /&gt;
i w tej postaci może zawierać przejścia do nowego wiersza&lt;br /&gt;
(w poprzednich nie może)'''&lt;br /&gt;
napis4 = &amp;quot;&amp;quot;&amp;quot;zamiast apostrofów, mogą być cudzysłowy - wychodzi na to samo,&lt;br /&gt;
również w postaci takiej, jak napis1 i napis2 są one równoważne&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
napis5 = &amp;quot;korzyść z tego pojawia się np. gdy w treści napisu potrzebujemy umieścić znak taki jak ' &amp;quot;&lt;br /&gt;
napis6 = 'w treści napisów można użyć kilku specjalnych sekwencji:\nTo powoduje przejście do nowego wiersza..'&lt;br /&gt;
napis7 = 'jeśli dwa napisy (lub więcej) postawimy ' 'jeden obok drugiego ' 'to zostaną połączone w jeden'&lt;br /&gt;
napis8 = 'lecz uwaga: pomiędzy sklejone napisy nie zostanie wstawiona żadna spacja ani w ogóle nic.'&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Sekwencje specjalne w napisach'''&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;\\&amp;lt;/tt&amp;gt;||dosłowny znak &amp;lt;tt&amp;gt;\&amp;lt;/tt&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;\'&amp;lt;/tt&amp;gt;||apostrof: &amp;lt;tt&amp;gt;'&amp;lt;/tt&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;\&amp;quot;&amp;lt;/tt&amp;gt;||cudzysłów: &amp;lt;tt&amp;gt;&amp;quot;&amp;lt;/tt&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;\a&amp;lt;/tt&amp;gt;||kod BEL&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;\b&amp;lt;/tt&amp;gt;||kod BS ('backspace')&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;\f&amp;lt;/tt&amp;gt;||kod FF ('formfeed')&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;\n&amp;lt;/tt&amp;gt;||kod LF ('linefeed')&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;\r&amp;lt;/tt&amp;gt;||kod CR ('carriage return')&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;\t&amp;lt;/tt&amp;gt;||kod HT ('horizontal tab')&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;\v&amp;lt;/tt&amp;gt;||kod VT ('vertical tab')&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;\nnn&amp;lt;/tt&amp;gt;||znak o kodzie 'nnn' w zapisie ósemkowym&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;\xnn&amp;lt;/tt&amp;gt;||znak o kodzie 'nn' w zapisie szesnastkowym&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;\N{nazwa}&amp;lt;/tt&amp;gt;||znak o danej nazwie symbolicznej w tabeli Unicode&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;\unnnn&amp;lt;/tt&amp;gt;||znak o pozycji '0xnnnn' w 16-bitowej tabeli Unicode&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;\Unnnnnnnn&amp;lt;/tt&amp;gt;||znak o pozycji '0xnnnnnnnn' w 32-bitowej tabeli Unicode&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
To co określam tutaj nazwą ''kod'' to są szczególne ,,znaki&amp;quot;, które nie posiadają reprezentacji graficznej, ale mogą wystąpić w strumieniu tekstowym pełniąc jakiegoś rodzaju rolę sterującą (p. poniżej). Czasami stosuje się określenie ''znaki niedrukowalne''. Jest ich więcej, niż występuje w powyższej tabeli &amp;amp;mdash; pozostałym nie nadano specjalnego zapisu i dostępne są np. przez notację &amp;lt;tt&amp;gt;\nnn&amp;lt;/tt&amp;gt; albo &amp;lt;tt&amp;gt;\xnn&amp;lt;/tt&amp;gt;, ale niezwykle rzadko bywają potrzebne.&lt;br /&gt;
&lt;br /&gt;
* Wypisanie kodu BEL na terminal najczęściej skutkuje sygnałem akustycznym (''BIP!'') lub wizualnym (błysk), zależy to od ustawień emulatora terminala&lt;br /&gt;
* Kod BS cofa kursor o jedną pozycję, umożliwiając nadpisanie ostatniego wypisanego znaku&lt;br /&gt;
* Kod FF stosowano w tekście przeznaczonym do wydrukowania na drukarce wierszowej, powodował przejście do następnej strony. Obecnie ze względu na wymarcie drukarek wierszowych w zasadzie nie ma zastosowania&lt;br /&gt;
* Kod LF to przejście do nowej linii, inaczej - znacznik końca linii w strumieniu tekstowym&lt;br /&gt;
* Kod CR czyli powrót karetki cofa kursor do początku aktualnej linii&lt;br /&gt;
* Kod HT to ten, który zwykle nazywa się po prostu kodem tabulacji. Jego interpretacja zależy od ustawień terminala lub innego programu renderującego tekst, zwykle oznacza przeskok do pozycji będącej kolejną całkowitą wielokrotnością 4 lub 8 w bieżącej linii&lt;br /&gt;
* Kod VT z założenia działa analogicznie jak HT, ale w kierunku pionowym. Obecnie rzadko stosowany&lt;br /&gt;
* W zapisie &amp;lt;tt&amp;gt;\nnn&amp;lt;/tt&amp;gt; może wystąpić jedna, dwie lub trzy cyfry ósemkowe ''n''&lt;br /&gt;
* W zapisie &amp;lt;tt&amp;gt;\xnn&amp;lt;/tt&amp;gt; należy użyć dokładnie dwóch cyfr szesnatkowych ''n''&lt;br /&gt;
* W zapisie &amp;lt;tt&amp;gt;\unnnn&amp;lt;/tt&amp;gt; należy użyć dokładnie czterech cyfr szesnastkowych ''n''&lt;br /&gt;
* W zapisie &amp;lt;tt&amp;gt;\Unnnnnnnn&amp;lt;/tt&amp;gt; należy użyć dokładnie ośmiu cyfr szesnastkowych ''n''&lt;br /&gt;
&lt;br /&gt;
Jeżeli chcemy zapisać napis obfitujący w znaki &amp;lt;tt&amp;gt;\&amp;lt;/tt&amp;gt;, możemy użyć notacji takiej:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
napis1 = r'oto\napis\z\bakslaszami'&lt;br /&gt;
napis2 = R'tu\znak&amp;quot;\&amp;quot;nie\będzie\nigdy\oznaczał\początku\specjalnej\sekwencji'&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wielkość użytej na początku litery &amp;lt;tt&amp;gt;R&amp;lt;/tt&amp;gt; nie ma znaczenia.&lt;br /&gt;
&lt;br /&gt;
==Zmienne, czyli nazwy==&lt;br /&gt;
&lt;br /&gt;
Programy oczywiście nie operują jedynie na stałych. Potrzebny jest w nich sposób odnoszenia się do wartości, które nie są znane z góry (w chwili pisania programu) - albo dlatego, że zostaną dostarczone dopiero przy uruchomieniu lub w trakcie pracy programu, jako dane wejściowe (później zobaczymy, na jakie sposoby można tego dokonać), albo dlatego, że będą wynikiem obliczeń lub przekształceń danych wykonywanych przez program.&lt;br /&gt;
&lt;br /&gt;
Do tego w Pythonie służą ''zmienne'' - można je uważać za nazwy, z jakimi wiążemy pewne wartości (liczby, napisy, itd.), poprzez ''instrukcję podstawienia''. Do zapisu instrukcji podstawienia służy znak równości (&amp;lt;tt&amp;gt;=&amp;lt;/tt&amp;gt;), po jego lewej stronie stawiamy nazwę (zmiennej), po drugiej - ''wyrażenie'', np. literalną stałą, ale również może być to wyrażenie zbudowane ze stałych, operatorów (np. arytmetycznych), nazw zmiennych (reprezentujących w wyrażeniu związane z nimi aktualnie wartości), i szereg innych elementów które dopiero poznamy.&lt;br /&gt;
&lt;br /&gt;
'''Do zapamiętania''': pojedynczy znak równości &amp;lt;tt&amp;gt;=&amp;lt;/tt&amp;gt; w Pythonie (i wielu innych językach programowania) nie tworzy ''równania'', czyli stwierdzenia, że lewa strona jest równa prawej; tylko ''podstawienie'', a więc operację powodującą, że z nazwą stojącą po stronie lewej zostaje związana obliczona wartość wyrażenie stojącego po prawej. Zauważmy, że jest to operacja niesymetryczna (stron nie można bezkarne zamienić miejscami):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
i = 0 # pierwsze użycie nazwy, w tym przypadku 'i', tworzy zmienną i wiąże z nią wartość&lt;br /&gt;
i = i + 2 # to jest legalne, i oznacza, że wartość związana z 'i' rośnie o 2&lt;br /&gt;
i + 2 = i # to jest błędne, po lewej stronie nie może stać wyrażenie złożone&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Pojawienie się w wyrażeniu stojącym po prawej stronie podstawienia tej samej nazwy, która stoi po lewej stronie, nie tworzy jakiejkolwiek niejednoznaczności: zasadą jest, że ''wpierw'' obliczana jest wartość wyrażenia z prawej strony, z wykorzystaniem aktualnych wartości zmiennych, a ''potem'' następuje związanie nazwy zmiennej stojącej po lewej z wynikiem.&lt;br /&gt;
&lt;br /&gt;
Zauważmy, że błędem byłoby użycie nazwy po raz pierwszy ''bez'' uprzedniego nadania jej wartości, np. w wyrażeniu arytmetycznym.&lt;br /&gt;
&lt;br /&gt;
===Reguły tworzenia nazw===&lt;br /&gt;
&lt;br /&gt;
Aktualnie reguły określające, co jest poprawną nazwą w Pythonie, dopuszczają użycie całkiem szerokiego podzbioru znaków Unicode i są dość trudne do opisania w zrozumiały sposób. Pomijając jednak taką możliwość, że ktoś zechce użyć w nazwie zmiennej znaków pisma Kanji lub perskiego, można w dużym uproszczeniu powiedzieć tak:&lt;br /&gt;
&lt;br /&gt;
*nazwy można budować z liter (wielkich i małych), cyfr, i znaku podkreślenia (&amp;lt;tt&amp;gt;_&amp;lt;/tt&amp;gt;)&lt;br /&gt;
*z zastrzeżeniem, że pierwszym znakiem nazwy nie może być cyfra&lt;br /&gt;
*litery wielkie i małe są rozróżniane, tak więc nazwy różniące się jedynie wielkością liter ''są różne''&lt;br /&gt;
*długość nazwy nie podlega ograniczeniu&lt;br /&gt;
*zabronione jest użycie jako nazwy któregokolwiek z tzw. słów zastrzeżonych, które mają specjalne znaczenie w składni języka Python.[https://docs.python.org/3/reference/lexical_analysis.html#keywords Tutaj można znaleźć ich wykaz].&lt;br /&gt;
&lt;br /&gt;
W szczególności, nazwy (zmiennych i innych obiektów) mogą jak najbardziej zawierać litery właściwe dla języka polskiego (oraz dla innych języków). Z rozmaitych względów nie jest to jednak szczególnie rekomendowane, lepiej (przynajmniej na razie) ograniczyć się do liter podstawowego alfabetu łacińskiego. &lt;br /&gt;
&lt;br /&gt;
Oprócz twardych reguł zawartych w definicji języka, w tworzeniu nazw programiści trzymają się na ogół pewnych konwencji - które nie są w żaden sposób egzekwowane przez interpreter, ale ułatwiają czytanie kodu &amp;amp;mdash; zwłaszcza, gdy się nim dzielimy z innymi:&lt;br /&gt;
&lt;br /&gt;
*w nazwach zmiennych używamy małych liter (a nie wielkich)&lt;br /&gt;
*wielkie litery rezerwujemy dla nazw oznaczających wartości stałe, które nie mają prawa się zmienić w trakcie pracy programu&lt;br /&gt;
*staramy się, by nazwy coś znaczyły i ułatwiały zrozumienie kodu programu&lt;br /&gt;
*nie unikamy nazw składających się z dwóch lub nawet kilku słów; ponieważ spacja jako składnik nazwy nie jest dozwolona, zastępujemy ją znakiem podkreślenia&lt;br /&gt;
*unikamy jednak nazw przesadnie długich, a nazwy zmiennych, które są potrzebne jedynie &amp;quot;chwilowo&amp;quot; mogą wręcz być jednoliterowe&lt;br /&gt;
*nazwy zaczynające się od podkreślenia (&amp;lt;tt&amp;gt;_&amp;lt;/tt&amp;gt;) mają pewne specjalne znaczenia i nie tworzymy takich nazw, chyba że całkiem świadomie.&lt;br /&gt;
&lt;br /&gt;
=Wyrażenia=&lt;br /&gt;
&lt;br /&gt;
==Arytmetyczne==&lt;br /&gt;
&lt;br /&gt;
Wyrażenia arytmetyczne tworzymy z udziałem znanych już operatorów arytmetycznych &amp;lt;tt&amp;gt;+, -, /, *, **, //, %, ...&amp;lt;/tt&amp;gt;, ale również wywołań funkcji zwracających wartości liczbowe (więcej o tym dalej), z wykorzystaniem literalnych liczb i nazw oznaczających zmienne, których aktualne wartości powinny być liczbami. Możemy również używać nawiasów (wyłącznie okrągłych!) do grupowania podwyrażeń, aby wymusić określoną kolejność operacji. Każdy na ogół pamięta, że dzielenie i mnożenie mają pierwszeństwo przed dodawaniem i odejmowaniem; potęgowanie ma jeszcze wyższy priorytet. Gdy mamy do czynienia z operatorami o równym priorytecie, to operacje wykonywane są zgodnie z kolejnością czytania, od lewej do prawej. Jeżeli mamy wątpliwości, to użycie nawiasów nie będzie błędem. Przykłady:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
a + b * c == a + (b * c)&lt;br /&gt;
a / b / c == (a / b) / c&lt;br /&gt;
a * b ** c == a * (b ** c)&lt;br /&gt;
a ** b ** c == a ** (b ** c)&lt;br /&gt;
a ** - b == a ** (-b)&lt;br /&gt;
a ** b / c == (a ** b) / c&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Zachowanie operatora potęgowania jest tu nieco szczególne, i zgadza się z umową przyjętą w matematyce.&lt;br /&gt;
&lt;br /&gt;
Operatory arytmetyczne znajdują również czasem zastosowanie do obiektów nie będących liczbami, mają wtedy oczywiście nieco inne znaczenie. Np. suma dwóch napisów jest ich sklejeniem (mówi się też: ''konkatenacją''). &lt;br /&gt;
&lt;br /&gt;
W przypadku, gdy będziemy mieszać w jednym wyrażeniu liczby całkowite i zmiennoprzecinkowe, to wynik będzie liczbą zmiennoprzecinkową. Wyjątkiem jest dzielenie: &amp;lt;tt&amp;gt;a / b&amp;lt;/tt&amp;gt; zawsze da w wyniku liczbę zmiennoprzecinkową, natomiast &amp;lt;tt&amp;gt;a // b&amp;lt;/tt&amp;gt; - całkowitą, jeśli oba argumenty są całkowite; w przeciwnym razie, zmiennoprzecinkową (ale o zerowej części ułamkowej).&lt;br /&gt;
&lt;br /&gt;
===Rozszerzone operatory przypisania===&lt;br /&gt;
&lt;br /&gt;
Z dwuargumentowymi operatorami arytmetycznymi związane są tzw. ''rozszerzone operatory przypisania'', stanowiące drobne udogodnienie pozwalające w sposób bardziej zwięzły zapisać dość często występujące operacje - takie, jak powiększenie aktualnej wartości &amp;lt;tt&amp;gt;x&amp;lt;/tt&amp;gt; o 1 i zapamiętanie tej nowej, powiększonej wartości pod nazwą &amp;lt;tt&amp;gt;x&amp;lt;/tt&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
# poniższe instrukcje są parami równoważne&lt;br /&gt;
x = x + a &lt;br /&gt;
x += a &lt;br /&gt;
#&lt;br /&gt;
x = x * a&lt;br /&gt;
x *= a&lt;br /&gt;
#&lt;br /&gt;
x = x - a&lt;br /&gt;
x -= a&lt;br /&gt;
#&lt;br /&gt;
x = x / a&lt;br /&gt;
x /= a&lt;br /&gt;
#&lt;br /&gt;
x **= a&lt;br /&gt;
x = x**a&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wersja np. z potęgowaniem może jest niezbyt często przydatna, ale wprowadzono ją choćby po to, by było konsekwentnie.&lt;br /&gt;
&lt;br /&gt;
==Logiczne==&lt;br /&gt;
&lt;br /&gt;
Wyrażenia logiczne mogą mieć jedną z dwu wartości: Prawda (&amp;lt;tt&amp;gt;True&amp;lt;/tt&amp;gt;) lub Fałsz (&amp;lt;tt&amp;gt;False&amp;lt;/tt&amp;gt;). Literalne wartości &amp;lt;tt&amp;gt;True&amp;lt;/tt&amp;gt; i &amp;lt;tt&amp;gt;False&amp;lt;/tt&amp;gt; są też przykładami wyrażeń logicznych, choć dość mało przydatnymi. Prawdziwe lub fałszywe mogą być np. porównania dwóch wartości, tworzone za pomocą operatorów &amp;lt;tt&amp;gt;&amp;amp;gt;&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;&amp;amp;lt;&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;&amp;amp;gt;=&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;&amp;amp;lt;=&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;==&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;!=&amp;lt;/tt&amp;gt; (to ostatnie, to sposób w jaki w Pythonie pisze się znak nierówności). Jak już wspomniano, podwojony znak równości jest operatorem porównania (w odróżnieniu od pojedynczego - przypisania). Porównywać można przede wszystkim liczby (a więc - dowolne wyrażenia o wartościach liczbowych), ale również np. napisy - wówczas większy oznacza tyle, co dalszy w porządku leksykograficznym. Porównania mają priorytet niższy, niż operatory arytmetyczne.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&amp;lt;small&amp;gt;&lt;br /&gt;
Przy bliższym poznaniu okazuje się, że wartości &amp;lt;tt&amp;gt;True&amp;lt;/tt&amp;gt; i &amp;lt;tt&amp;gt;False&amp;lt;/tt&amp;gt; są tak naprawdę w pewnym sensie liczbami: odpowiednio 1 i 0. Dozwolone jest więc np. stosowanie do nich operacji arytmetycznych.&lt;br /&gt;
&amp;lt;/small&amp;gt;&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Z elementarnych wyrażeń logicznych (porównań) można tworzyć złożone wyrażenia logiczne za pomocą operatorów (spójników) logicznych, pisanych &amp;lt;tt&amp;gt;and&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;or&amp;lt;/tt&amp;gt; i &amp;lt;tt&amp;gt;not&amp;lt;/tt&amp;gt;. Mają one następujące właśności:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
(a and b) == (b and a)&lt;br /&gt;
(False and False) == False&lt;br /&gt;
(False and True) == False&lt;br /&gt;
(True and True) == True&lt;br /&gt;
(a or b) == (b or a)&lt;br /&gt;
(False or False) == False&lt;br /&gt;
(False or True) == True&lt;br /&gt;
(True or True) == True&lt;br /&gt;
(not True) == False&lt;br /&gt;
(not False) == True &lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Spójniki logiczne mają priorytet jeszcze niższy, niż porównania - stąd nawiasy w powyższym. Wśród nich najwyższy priorytet ma &amp;lt;tt&amp;gt;not&amp;lt;/tt&amp;gt;, następnie &amp;lt;tt&amp;gt;and&amp;lt;/tt&amp;gt;, na końcu &amp;lt;tt&amp;gt;or&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Wyrażenia logiczne mają tę szczególną własność, że wartość wyrażenia można często określić obliczając jedynie część jego elementów. Np. &amp;lt;tt&amp;gt;a and b&amp;lt;/tt&amp;gt;, jeżeli wartością &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; jest &amp;lt;tt&amp;gt;False&amp;lt;/tt&amp;gt;, jest na pewno &amp;lt;tt&amp;gt;False&amp;lt;/tt&amp;gt; - niezależnie od wartości &amp;lt;tt&amp;gt;b&amp;lt;/tt&amp;gt;. W takich przypadkach Python przerywa obliczanie (od lewej do prawej, z uwzględnieniem nawiasów) gdy tylko wartość jest określona. Fakt ten czasami może mieć znaczenie - jeżeli np. obliczenie któregoś z członów wyrażenia logicznego jest szczególnie czasochłonne, lub ma tzw. skutki uboczne.&lt;br /&gt;
&lt;br /&gt;
Wyrażenia logiczne znajdują zastosowanie przede wszystkim w instrukcji warunkowej - pozwalają określić warunki, pod jakimi pewne operacje będą wykonane, lub nie - o tym dalej.&lt;br /&gt;
&lt;br /&gt;
Warto wiedzieć, że w Pythonie '''każde wyrażenie może służyć jako wyrażenie logiczne'''. Inaczej mówiąc, każda wartość (napis, liczba, lista, itd.) może być wykorzystana w charakterze wartości logicznej. Obowiązują tu proste reguły:&lt;br /&gt;
&lt;br /&gt;
* liczba &amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt; jest fałszywa (równoważna &amp;lt;tt&amp;gt;False&amp;lt;/tt&amp;gt;); obojętne, czy całkowita czy zmiennoprzecinkowa;&lt;br /&gt;
* każda liczba różna od zera jest prawdziwa (równoważna &amp;lt;tt&amp;gt;True&amp;lt;/tt&amp;gt;);&lt;br /&gt;
* napis pusty (o długości 0) jest fałszywy, każdy inny napis jest prawdziwy (również np. zawierający wyłącznie spacje);&lt;br /&gt;
* ogólniej &amp;amp;mdash; dowolnego typu kolekcja (lista, słownik, zbiór, ...) jest prawdziwa, o ile jest niepusta; każda kolekcja pusta (0-elementowa) jest fałszywa;&lt;br /&gt;
* wartość pusta czyli &amp;lt;tt&amp;gt;None&amp;lt;/tt&amp;gt; jest, jak nietrudno zgadnąć, fałszywa.&lt;br /&gt;
&lt;br /&gt;
W przypadku ogólniejszych typów danych (obiektów klas złożonych) sytuacja może już nie być taka prosta, ponieważ twórca klasy ma moc określenia reguły decydującej o prawdziwości / nieprawdziwości obiektów danej klasy. Ten temat jest na razie poza zakresem naszego kursu.&lt;br /&gt;
&lt;br /&gt;
Jeżeli chcemy wymusić, aby dana wartość stała się dosłownie wartością logiczną, tzn. jedną z (&amp;lt;tt&amp;gt;True&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;False&amp;lt;/tt&amp;gt;) w sposób zgodny z powyższymi regułami, można to osiągnąć przykładając funkcję &amp;lt;tt&amp;gt;bool&amp;lt;/tt&amp;gt;: a więc &amp;lt;tt&amp;gt;bool(wyrażenie)&amp;lt;/tt&amp;gt;. Rzadko jednak bywa to potrzebne.&lt;br /&gt;
&lt;br /&gt;
Reguła „skrótowej&amp;quot; ewaluacji wyrażeń logicznych, w połączeniu z regułami prawdziwości innych typów danych, pozwala na dość popularne idiomy, jak np.:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
# jeśli `wynik' jest niepustą listą to wypisze jej zawartość&lt;br /&gt;
# jeśli natomiast pustą, pojawi się komunikat&lt;br /&gt;
print(wynik or &amp;quot;wynik jest pusty!&amp;quot;)&lt;br /&gt;
&amp;lt;/source&amp;gt; &lt;br /&gt;
&lt;br /&gt;
które pozwalają uniknąć używania instrukcji złożonych w wielu prostych przypadkach. Działa to dzięki temu, że spójniki &amp;lt;tt&amp;gt;and&amp;lt;/tt&amp;gt; i &amp;lt;tt&amp;gt;or&amp;lt;/tt&amp;gt; nie wymuszają aby wynik był wartością logiczną:&lt;br /&gt;
&lt;br /&gt;
* jeżeli &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; jest prawdziwe, to &amp;lt;tt&amp;gt;a or b == a&amp;lt;/tt&amp;gt;, i &amp;lt;tt&amp;gt;a and b == b&amp;lt;/tt&amp;gt; dla każdego &amp;lt;tt&amp;gt;b&amp;lt;/tt&amp;gt;;&lt;br /&gt;
* jeżeli &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; jest fałszywe, to &amp;lt;tt&amp;gt;a and b == a&amp;lt;/tt&amp;gt;, i &amp;lt;tt&amp;gt;a or b == b&amp;lt;/tt&amp;gt; dla każdego &amp;lt;tt&amp;gt;b&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Inaczej w przypadku operatora &amp;lt;tt&amp;gt;not&amp;lt;/tt&amp;gt;: wynikiem jego działania jest zawsze jedna z wartości logicznych, podobnie jak w przypadku funkcji &amp;lt;tt&amp;gt;bool()&amp;lt;/tt&amp;gt; &amp;amp;mdash; tyle, że przeciwna.&lt;br /&gt;
&lt;br /&gt;
==Napisowe==&lt;br /&gt;
&lt;br /&gt;
Wartością wyrażenia może być również napis. Na przykład, &amp;lt;tt&amp;gt;a + b&amp;lt;/tt&amp;gt;, jeżeli &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; i &amp;lt;tt&amp;gt;b&amp;lt;/tt&amp;gt; są napisami, jest napisem utworzonym przez ich sklejenie (zauważmy, że w odróżnieniu od dodawania liczb nie jest to operacja przemienna). &lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&amp;lt;small&amp;gt;&lt;br /&gt;
Wcześniej wspomniano, że dwa napisy literalne postawione obok siebie zostaną automatycznie sklejone w jeden: np. &amp;lt;tt&amp;gt;'abc' &amp;quot;123&amp;quot;&amp;lt;/tt&amp;gt; jest równoważne &amp;lt;tt&amp;gt;'abc123'&amp;lt;/tt&amp;gt;. Nie stosuje się to jednak np. do zmiennych o wartościach napisowych: napisanie dwóch nazw obok siebie bez operatora pomiędzy nimi jest błędem składniowym. Jest tak, ponieważ wspomniane sklejenie napisów literalnych ma miejsce na etapie ''kompilacji'' kodu - tzn. wtedy, gdy interpreter analizuje zapis programu i przekłada go na instrukcje, jakie zostaną wykonane w etapie uruchomienia - a wartości stojące za nazwami zmiennych nie są na tym etapie jednoznacznie określone. &lt;br /&gt;
&amp;lt;/small&amp;gt;&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Bogatszy repertuar operacji tworzących wyrażenia o wartościach będących napisami poznamy dalej.&lt;br /&gt;
&lt;br /&gt;
==Inne wyrażenia==&lt;br /&gt;
&lt;br /&gt;
Oprócz liczb, napisów i wartości logicznych, Python posiada szereg dalszych, złożonych typów danych, które również mogą być wartościami wyrażeń. Każdy typ obiektu w Pythonie może być wartością odpowiednio zbudowanego wyrażenia. Gdy poznamy kolejne typy danych, wprowadzimy również operacje tworzące takie wyrażenia.&lt;br /&gt;
&lt;br /&gt;
=Ćwiczenia=&lt;br /&gt;
&lt;br /&gt;
1. Które z następujących są poprawnymi nazwami według reguł Pythona:&lt;br /&gt;
   nazwa1&lt;br /&gt;
   9sił&lt;br /&gt;
   dluga-nazwa&lt;br /&gt;
   wykonaj_rachunki&lt;br /&gt;
   _&lt;br /&gt;
   to&amp;amp;owo&lt;br /&gt;
   if &lt;br /&gt;
&lt;br /&gt;
2. Wykazać, że poniższe równości są równoważnościami -- tzn. że zachodzą dla dowolnej kombinacji wartości &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; i &amp;lt;tt&amp;gt;b&amp;lt;/tt&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
   not (a or b) == not a and not b&lt;br /&gt;
   not (a and b) == not a or not b&lt;br /&gt;
   a or not a == True&lt;br /&gt;
&lt;br /&gt;
''Wskazówka:'' stworzyć tabelki wartości wyrażeń po lewej i prawej stronie operatora porównania &amp;lt;tt&amp;gt;==&amp;lt;/tt&amp;gt; dla wszystkich możliwych kombinacji wartości &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; i &amp;lt;tt&amp;gt;b&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
3. Które z poniższych równości są tożsamościami, w wyniku działania reguł pierwszeństwa operatorów?&lt;br /&gt;
&lt;br /&gt;
   a / b / c == a / (b / c)&lt;br /&gt;
   a ** b / c == (a ** b) / c&lt;br /&gt;
   -a ** b == (-a) ** b&lt;br /&gt;
&lt;br /&gt;
''CDN...''&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
[[PPy3/PierwszeKroki|poprzednia]] | [[&amp;quot;Programowanie z Pythonem3&amp;quot;|Strona główna]] | [[PPy3/InstrukcjaWarunkowa|dalej]]&lt;br /&gt;
&lt;br /&gt;
--[[Użytkownik:RobertJB|RobertJB]] ([[Dyskusja użytkownika:RobertJB|dyskusja]]) 14:22, 21 cze 2016 (CEST)&lt;/div&gt;</summary>
		<author><name>RobertJB</name></author>
		
	</entry>
	<entry>
		<id>http://brain.fuw.edu.pl/edu/index.php?title=PPy3/Sta%C5%82eIZmienne&amp;diff=8917</id>
		<title>PPy3/StałeIZmienne</title>
		<link rel="alternate" type="text/html" href="http://brain.fuw.edu.pl/edu/index.php?title=PPy3/Sta%C5%82eIZmienne&amp;diff=8917"/>
		<updated>2022-07-29T11:32:53Z</updated>

		<summary type="html">&lt;p&gt;RobertJB: /* Stałe dosłowne (literalne) */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=Stałe i zmienne=&lt;br /&gt;
&lt;br /&gt;
==Stałe dosłowne (literalne)==&lt;br /&gt;
&lt;br /&gt;
Stałe dosłowne to takie, których wartości wprost wpisano do pliku z kodem (lub w linii poleceń interpretera). Mogą to być liczby (paru rodzajów) lub napisy, ale również różne złożone rodzaje (typy) danych, z którymi zapoznamy się nieco później.&lt;br /&gt;
&lt;br /&gt;
'''Zapamiętajmy''' od razu: ''liczba'' dla komputera to zupełnie co innego, niż ''napis'' składający się z cyfr. Na napisie nie wykonamy operacji arytmetycznych - a na liczbie, operacji właściwych dla napisów (takich jak np. wyjęcie z niego znaku stojącego na określonej pozycji). Istnieją jednak operacje przekształcające każdy z tych typów danych w drugi.&lt;br /&gt;
&lt;br /&gt;
===Liczby===&lt;br /&gt;
&lt;br /&gt;
Dobrze jest pamiętać, że nieco odmiennie traktowane są liczby całkowite, a inaczej - liczby ułamkowe, zwykle zwane ''zmiennoprzecinkowymi'' (po angielsku ''floating point'', jako że Amerykanie piszą kropkę dziesiętną a nie - jak my - przecinek, przez co i w Pythonie używa się w tym celu kropki).&lt;br /&gt;
&lt;br /&gt;
*Liczby całkowite w zapisie dziesiętnym: &amp;lt;tt&amp;gt;1024&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;-666&amp;lt;/tt&amp;gt;, ...&lt;br /&gt;
*Liczby ułamkowe: &amp;lt;tt&amp;gt;1.0&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;.99&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;98.6&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;-37.43&amp;lt;/tt&amp;gt;, ...&lt;br /&gt;
*Liczby ułamkowe w zapisie wykładniczym: &amp;lt;tt&amp;gt;1.024e3&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;96.9E-12&amp;lt;/tt&amp;gt;, ...&lt;br /&gt;
&lt;br /&gt;
Notacja &amp;lt;tt&amp;gt;e3&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;E-12&amp;lt;/tt&amp;gt; itp. (wielka i mała litera &amp;lt;tt&amp;gt;e&amp;lt;/tt&amp;gt; są tu równoważne) oznacza pomnożenie poprzedzającej liczby przez odpowiednio 10&amp;lt;sup&amp;gt;3&amp;lt;/sup&amp;gt;, 10&amp;lt;sup&amp;gt;-12&amp;lt;/sup&amp;gt;, ... i służy ułatwieniu zapisu liczb bardzo dużych lub bardzo małych. Nie można tam wtrącać dodatkowych odstępów, podobnie jak pomiędzy cyframi.&lt;br /&gt;
&lt;br /&gt;
Jeśli część całkowita (lub ułamkowa) liczby zmiennoprzecinkowej wynosi zero, to można to zero pominąć. Oczywiście nie można pominąć obu, zapisując liczbę zero! (można napisać: &amp;lt;tt&amp;gt;0.&amp;lt;/tt&amp;gt; albo &amp;lt;tt&amp;gt;.0&amp;lt;/tt&amp;gt;, ale nie samotną kropkę).&lt;br /&gt;
&lt;br /&gt;
Podstawowa różnica pomiędzy sposobem traktowania liczb całkowitych i zmiennoprzecinkowych polega na tym, że:&lt;br /&gt;
&lt;br /&gt;
*liczby całkowite mogą być dowolnie duże, a rachunki całkowitoliczbowe wykonywane są dokładnie,&lt;br /&gt;
*liczby ułamkowe oraz wyniki rachunków na liczbach ułamkowych należy zawsze traktować jako przybliżone (oczywiście dla szczególnych wartości zdarza się, że są one dokładne); zakres wielkości liczb ułamkowych jest ograniczony.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&amp;lt;small&amp;gt;&lt;br /&gt;
Python zna też liczby ''zespolone'' oraz operacje na nich, ale tego zdaje się nie było w szkole...&lt;br /&gt;
&amp;lt;/small&amp;gt;&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Liczby całkowite można pisać również w podstawach innych niż 10:&lt;br /&gt;
&lt;br /&gt;
*dwójkowe: &amp;lt;tt&amp;gt;0b101 == 5&amp;lt;/tt&amp;gt;&lt;br /&gt;
*ósemkowe: &amp;lt;tt&amp;gt;0o123 == 83&amp;lt;/tt&amp;gt;&lt;br /&gt;
*szesnastkowe: &amp;lt;tt&amp;gt;0x1f == 31&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
(podwojony znak równości oznacza: lewa strona jest równa prawej; litery b, o, x mogą być zarówno małe jak i wielkie).&lt;br /&gt;
&lt;br /&gt;
W zapisie szesnastkowym, wymagającym 16 różnych cyfr, w roli &amp;quot;brakujących&amp;quot; cyfr oznaczających liczby od 10 do 15 przyjmuje się początkowe litery alfabetu (a-f), można równoważnie używać liter małych lub wielkich.&lt;br /&gt;
&lt;br /&gt;
===Napisy===&lt;br /&gt;
&lt;br /&gt;
Napis (ang. ''string'') to po prostu ciąg znaków.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&amp;lt;small&amp;gt;&lt;br /&gt;
OK, nic nie jest tak proste, jak się wydaje. Pytanie: co to jest znak? Odpowiedzi dostarcza standard ''Unicode'', w skład którego chodzi m. in. katalog wszystkich znaków, używanych przez systemy pisma wszystkich w zasadzie języków świata (języków żywych, i co ważniejszych spośród martwych). Nie będziemy się w tej chwili zastanawiać nad tym, jak dokładnie znaki te są reprezentowane w komputerze. Warto jednak pamiętać, że napisy nie muszą ograniczać się do znaków znanych z zapisu języków europejskich.&lt;br /&gt;
&amp;lt;/small&amp;gt;&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Literalne stałe napisowe, czyli napisy &amp;quot;na twardo&amp;quot; wpisane do kodu, mogą być podane w paru różnych postaciach:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
napis1 = 'jedna z postaci napisu'&lt;br /&gt;
napis2 = &amp;quot;nieco inna postać napisu&amp;quot;&lt;br /&gt;
napis3 = '''tak też może wyglądać napis,&lt;br /&gt;
i w tej postaci może zawierać przejścia do nowego wiersza&lt;br /&gt;
(w poprzednich nie może)'''&lt;br /&gt;
napis4 = &amp;quot;&amp;quot;&amp;quot;zamiast apostrofów, mogą być cudzysłowy - wychodzi na to samo,&lt;br /&gt;
również w postaci takiej, jak napis1 i napis2 są one równoważne&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
napis5 = &amp;quot;korzyść z tego pojawia się np. gdy w treści napisu potrzebujemy umieścić znak taki jak ' &amp;quot;&lt;br /&gt;
napis6 = 'w treści napisów można użyć kilku specjalnych sekwencji:\nTo powoduje przejście do nowego wiersza..'&lt;br /&gt;
napis7 = 'jeśli dwa napisy (lub więcej) postawimy ' 'jeden obok drugiego ' 'to zostaną połączone w jeden'&lt;br /&gt;
napis8 = 'lecz uwaga: pomiędzy sklejone napisy nie zostanie wstawiona żadna spacja ani w ogóle nic.'&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Sekwencje specjalne w napisach'''&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;\\&amp;lt;/tt&amp;gt;||dosłowny znak &amp;lt;tt&amp;gt;\&amp;lt;/tt&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;\'&amp;lt;/tt&amp;gt;||apostrof: &amp;lt;tt&amp;gt;'&amp;lt;/tt&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;\&amp;quot;&amp;lt;/tt&amp;gt;||cudzysłów: &amp;lt;tt&amp;gt;&amp;quot;&amp;lt;/tt&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;\a&amp;lt;/tt&amp;gt;||kod BEL&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;\b&amp;lt;/tt&amp;gt;||kod BS ('backspace')&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;\f&amp;lt;/tt&amp;gt;||kod FF ('formfeed')&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;\n&amp;lt;/tt&amp;gt;||kod LF ('linefeed')&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;\r&amp;lt;/tt&amp;gt;||kod CR ('carriage return')&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;\t&amp;lt;/tt&amp;gt;||kod HT ('horizontal tab')&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;\v&amp;lt;/tt&amp;gt;||kod VT ('vertical tab')&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;\nnn&amp;lt;/tt&amp;gt;||znak o kodzie 'nnn' w zapisie ósemkowym&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;\xnn&amp;lt;/tt&amp;gt;||znak o kodzie 'nn' w zapisie szesnastkowym&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;\N{nazwa}&amp;lt;/tt&amp;gt;||znak o danej nazwie symbolicznej w tabeli Unicode&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;\unnnn&amp;lt;/tt&amp;gt;||znak o pozycji '0xnnnn' w 16-bitowej tabeli Unicode&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;\Unnnnnnnn&amp;lt;/tt&amp;gt;||znak o pozycji '0xnnnnnnnn' w 32-bitowej tabeli Unicode&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
To co określam tutaj nazwą ''kod'' to są szczególne ,,znaki&amp;quot;, które nie posiadają reprezentacji graficznej, ale mogą wystąpić w strumieniu tekstowym pełniąc jakiegoś rodzaju rolę sterującą (p. poniżej). Czasami stosuje się określenie ''znaki niedrukowalne''. Jest ich więcej, niż występuje w powyższej tabeli &amp;amp;mdash; pozostałym nie nadano specjalnego zapisu i dostępne są np. przez notację &amp;lt;tt&amp;gt;\nnn&amp;lt;/tt&amp;gt; albo &amp;lt;tt&amp;gt;\xnn&amp;lt;/tt&amp;gt;, ale niezwykle rzadko bywają potrzebne.&lt;br /&gt;
&lt;br /&gt;
* Wypisanie kodu BEL na terminal najczęściej skutkuje sygnałem akustycznym (''BIP!'') lub wizualnym (błysk), zależy to od ustawień emulatora terminala&lt;br /&gt;
* Kod BS cofa kursor o jedną pozycję, umożliwiając nadpisanie ostatniego wypisanego znaku&lt;br /&gt;
* Kod FF stosowano w tekście przeznaczonym do wydrukowania na drukarce wierszowej, powodował przejście do następnej strony. Obecnie ze względu na wymarcie drukarek wierszowych w zasadzie nie ma zastosowania&lt;br /&gt;
* Kod LF to przejście do nowej linii, inaczej - znacznik końca linii w strumieniu tekstowym&lt;br /&gt;
* Kod CR czyli powrót karetki cofa kursor do początku aktualnej linii&lt;br /&gt;
* Kod HT to ten, który zwykle nazywa się po prostu kodem tabulacji. Jego interpretacja zależy od ustawień terminala lub innego programu renderującego tekst, zwykle oznacza przeskok do pozycji będącej kolejną całkowitą wielokrotnością 4 lub 8 w bieżącej linii&lt;br /&gt;
* Kod VT z założenia działa analogicznie jak HT, ale w kierunku pionowym. Obecnie rzadko stosowany&lt;br /&gt;
* W zapisie &amp;lt;tt&amp;gt;\nnn&amp;lt;/tt&amp;gt; może wystąpić jedna, dwie lub trzy cyfry ósemkowe ''n''&lt;br /&gt;
* W zapisie &amp;lt;tt&amp;gt;\xnn&amp;lt;/tt&amp;gt; należy użyć dokładnie dwóch cyfr szesnatkowych ''n''&lt;br /&gt;
* W zapisie &amp;lt;tt&amp;gt;\unnnn&amp;lt;/tt&amp;gt; należy użyć dokładnie czterech cyfr szesnastkowych ''n''&lt;br /&gt;
* W zapisie &amp;lt;tt&amp;gt;\Unnnnnnnn&amp;lt;/tt&amp;gt; należy użyć dokładnie ośmiu cyfr szesnastkowych ''n''&lt;br /&gt;
&lt;br /&gt;
Jeżeli chcemy zapisać napis obfitujący w znaki &amp;lt;tt&amp;gt;\&amp;lt;/tt&amp;gt;, możemy użyć notacji takiej:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
napis1 = r'oto\napis\z\bakslaszami'&lt;br /&gt;
napis2 = R'tu\znak&amp;quot;\&amp;quot;nie\będzie\nigdy\oznaczał\początku\specjalnej\sekwencji'&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wielkość użytej na początku litery &amp;lt;tt&amp;gt;R&amp;lt;/tt&amp;gt; nie ma znaczenia.&lt;br /&gt;
&lt;br /&gt;
==Zmienne, czyli nazwy==&lt;br /&gt;
&lt;br /&gt;
Programy oczywiście nie operują jedynie na stałych. Potrzebny jest w nich sposób odnoszenia się do wartości, które nie są znane z góry (w chwili pisania programu) - albo dlatego, że zostaną dostarczone dopiero przy uruchomieniu lub w trakcie pracy programu, jako dane wejściowe (później zobaczymy, na jakie sposoby można tego dokonać), albo dlatego, że będą wynikiem obliczeń lub przekształceń danych wykonywanych przez program.&lt;br /&gt;
&lt;br /&gt;
Do tego w Pythonie służą ''zmienne'' - można je uważać za nazwy, z jakimi wiążemy pewne wartości (liczby, napisy, itd.), poprzez ''instrukcję podstawienia''. Do zapisu instrukcji podstawienia służy znak równości (&amp;lt;tt&amp;gt;=&amp;lt;/tt&amp;gt;), po jego lewej stronie stawiamy nazwę (zmiennej), po drugiej - ''wyrażenie'', np. literalną stałą, ale również może być to wyrażenie zbudowane ze stałych, operatorów (np. arytmetycznych), nazw zmiennych (reprezentujących w wyrażeniu związane z nimi aktualnie wartości), i szereg innych elementów które dopiero poznamy.&lt;br /&gt;
&lt;br /&gt;
'''Do zapamiętania''': pojedynczy znak równości &amp;lt;tt&amp;gt;=&amp;lt;/tt&amp;gt; w Pythonie (i wielu innych językach programowania) nie tworzy ''równania'', czyli stwierdzenia, że lewa strona jest równa prawej; tylko ''podstawienie'', a więc operację powodującą, że z nazwą stojącą po stronie lewej zostaje związana obliczona wartość wyrażenie stojącego po prawej. Zauważmy, że jest to operacja niesymetryczna (stron nie można bezkarne zamienić miejscami):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
i = 0 # pierwsze użycie nazwy, w tym przypadku 'i', tworzy zmienną i wiąże z nią wartość&lt;br /&gt;
i = i + 2 # to jest legalne, i oznacza, że wartość związana z 'i' rośnie o 2&lt;br /&gt;
i + 2 = i # to jest błędne, po lewej stronie nie może stać wyrażenie złożone&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Pojawienie się w wyrażeniu stojącym po prawej stronie podstawienia tej samej nazwy, która stoi po lewej stronie, nie tworzy jakiejkolwiek niejednoznaczności: zasadą jest, że ''wpierw'' obliczana jest wartość wyrażenia z prawej strony, z wykorzystaniem aktualnych wartości zmiennych, a ''potem'' następuje związanie nazwy zmiennej stojącej po lewej z wynikiem.&lt;br /&gt;
&lt;br /&gt;
Zauważmy, że błędem byłoby użycie nazwy po raz pierwszy ''bez'' uprzedniego nadania jej wartości, np. w wyrażeniu arytmetycznym.&lt;br /&gt;
&lt;br /&gt;
===Reguły tworzenia nazw===&lt;br /&gt;
&lt;br /&gt;
Aktualnie reguły określające, co jest poprawną nazwą w Pythonie, dopuszczają użycie całkiem szerokiego podzbioru znaków Unicode i są dość trudne do opisania w zrozumiały sposób. Pomijając jednak taką możliwość, że ktoś zechce użyć w nazwie zmiennej znaków pisma Kanji lub perskiego, można w dużym uproszczeniu powiedzieć tak:&lt;br /&gt;
&lt;br /&gt;
*nazwy można budować z liter (wielkich i małych), cyfr, i znaku podkreślenia (&amp;lt;tt&amp;gt;_&amp;lt;/tt&amp;gt;)&lt;br /&gt;
*z zastrzeżeniem, że pierwszym znakiem nazwy nie może być cyfra&lt;br /&gt;
*litery wielkie i małe są rozróżniane, tak więc nazwy różniące się jedynie wielkością liter ''są różne''&lt;br /&gt;
*długość nazwy nie podlega ograniczeniu&lt;br /&gt;
*zabronione jest użycie jako nazwy któregokolwiek z tzw. słów zastrzeżonych, które mają specjalne znaczenie w składni języka Python.[https://docs.python.org/3/reference/lexical_analysis.html#keywords Tutaj można znaleźć ich wykaz].&lt;br /&gt;
&lt;br /&gt;
W szczególności, nazwy (zmiennych i innych obiektów) mogą jak najbardziej zawierać litery właściwe dla języka polskiego (oraz dla innych języków). Z rozmaitych względów nie jest to jednak szczególnie rekomendowane, lepiej (przynajmniej na razie) ograniczyć się do liter podstawowego alfabetu łacińskiego. &lt;br /&gt;
&lt;br /&gt;
Oprócz twardych reguł zawartych w definicji języka, w tworzeniu nazw programiści trzymają się na ogół pewnych konwencji - które nie są w żaden sposób egzekwowane przez interpreter, ale ułatwiają czytanie kodu &amp;amp;mdash; zwłaszcza, gdy się nim dzielimy z innymi:&lt;br /&gt;
&lt;br /&gt;
*w nazwach zmiennych używamy małych liter (a nie wielkich)&lt;br /&gt;
*wielkie litery rezerwujemy dla nazw oznaczających wartości stałe, które nie mają prawa się zmienić w trakcie pracy programu&lt;br /&gt;
*staramy się, by nazwy coś znaczyły i ułatwiały zrozumienie kodu programu&lt;br /&gt;
*nie unikamy nazw składających się z dwóch lub nawet kilku słów; ponieważ spacja jako składnik nazwy nie jest dozwolona, zastępujemy ją znakiem podkreślenia&lt;br /&gt;
*unikamy jednak nazw przesadnie długich, a nazwy zmiennych, które są potrzebne jedynie &amp;quot;chwilowo&amp;quot; mogą wręcz być jednoliterowe&lt;br /&gt;
*nazwy zaczynające się od podkreślenia (&amp;lt;tt&amp;gt;_&amp;lt;/tt&amp;gt;) mają pewne specjalne znaczenia i nie tworzymy takich nazw, chyba że całkiem świadomie.&lt;br /&gt;
&lt;br /&gt;
=Wyrażenia=&lt;br /&gt;
&lt;br /&gt;
==Arytmetyczne==&lt;br /&gt;
&lt;br /&gt;
Wyrażenia arytmetyczne tworzymy z udziałem znanych już operatorów arytmetycznych &amp;lt;tt&amp;gt;+, -, /, *, **, //, %, ...&amp;lt;/tt&amp;gt;, ale również wywołań funkcji zwracających wartości liczbowe (więcej o tym dalej), z wykorzystaniem literalnych liczb i nazw oznaczających zmienne, których aktualne wartości powinny być liczbami. Możemy również używać nawiasów (wyłącznie okrągłych!) do grupowania podwyrażeń, aby wymusić określoną kolejność operacji. Każdy na ogół pamięta, że dzielenie i mnożenie mają pierwszeństwo przed dodawaniem i odejmowaniem; potęgowanie ma jeszcze wyższy priorytet. Gdy mamy do czynienia z operatorami o równym priorytecie, to operacje wykonywane są zgodnie z kolejnością czytania, od lewej do prawej. Jeżeli mamy wątpliwości, to użycie nawiasów nie będzie błędem. Przykłady:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
a + b * c == a + (b * c)&lt;br /&gt;
a / b / c == (a / b) / c&lt;br /&gt;
a * b ** c == a * (b ** c)&lt;br /&gt;
a ** b ** c == a ** (b ** c)&lt;br /&gt;
a ** - b == a ** (-b)&lt;br /&gt;
a ** b / c == (a ** b) / c&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Zachowanie operatora potęgowania jest tu nieco szczególne, i zgadza się z umową przyjętą w matematyce.&lt;br /&gt;
&lt;br /&gt;
Operatory arytmetyczne znajdują również czasem zastosowanie do obiektów nie będących liczbami, mają wtedy oczywiście nieco inne znaczenie. Np. suma dwóch napisów jest ich sklejeniem (mówi się też: ''konkatenacją''). &lt;br /&gt;
&lt;br /&gt;
W przypadku, gdy będziemy mieszać w jednym wyrażeniu liczby całkowite i zmiennoprzecinkowe, to wynik będzie liczbą zmiennoprzecinkową. Wyjątkiem jest dzielenie: &amp;lt;tt&amp;gt;a / b&amp;lt;/tt&amp;gt; zawsze da w wyniku liczbę zmiennoprzecinkową, natomiast &amp;lt;tt&amp;gt;a // b&amp;lt;/tt&amp;gt; - całkowitą, jeśli oba argumenty są całkowite; w przeciwnym razie, zmiennoprzecinkową (ale o zerowej części ułamkowej).&lt;br /&gt;
&lt;br /&gt;
===Rozszerzone operatory przypisania===&lt;br /&gt;
&lt;br /&gt;
Z dwuargumentowymi operatorami arytmetycznymi związane są tzw. ''rozszerzone operatory przypisania'', stanowiące drobne udogodnienie pozwalające w sposób bardziej zwięzły zapisać dość często występujące operacje - takie, jak powiększenie aktualnej wartości &amp;lt;tt&amp;gt;x&amp;lt;/tt&amp;gt; o 1 i zapamiętanie tej nowej, powiększonej wartości pod nazwą &amp;lt;tt&amp;gt;x&amp;lt;/tt&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
# poniższe instrukcje są parami równoważne&lt;br /&gt;
x = x + a &lt;br /&gt;
x += a &lt;br /&gt;
#&lt;br /&gt;
x = x * a&lt;br /&gt;
x *= a&lt;br /&gt;
#&lt;br /&gt;
x = x - a&lt;br /&gt;
x -= a&lt;br /&gt;
#&lt;br /&gt;
x = x / a&lt;br /&gt;
x /= a&lt;br /&gt;
#&lt;br /&gt;
x **= a&lt;br /&gt;
x = x**a&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wersja np. z potęgowaniem może jest niezbyt często przydatna, ale wprowadzono ją choćby po to, by było konsekwentnie.&lt;br /&gt;
&lt;br /&gt;
==Logiczne==&lt;br /&gt;
&lt;br /&gt;
Wyrażenia logiczne mogą mieć jedną z dwu wartości: Prawda (&amp;lt;tt&amp;gt;True&amp;lt;/tt&amp;gt;) lub Fałsz (&amp;lt;tt&amp;gt;False&amp;lt;/tt&amp;gt;). Literalne wartości &amp;lt;tt&amp;gt;True&amp;lt;/tt&amp;gt; i &amp;lt;tt&amp;gt;False&amp;lt;/tt&amp;gt; są też przykładami wyrażeń logicznych, choć dość mało przydatnymi. Prawdziwe lub fałszywe mogą być np. porównania dwóch wartości, tworzone za pomocą operatorów &amp;lt;tt&amp;gt;&amp;amp;gt;&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;&amp;amp;lt;&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;&amp;amp;gt;=&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;&amp;amp;lt;=&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;==&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;!=&amp;lt;/tt&amp;gt; (to ostatnie, to sposób w jaki w Pythonie pisze się znak nierówności). Jak już wspomniano, podwojony znak równości jest operatorem porównania (w odróżnieniu od pojedynczego - przypisania). Porównywać można przede wszystkim liczby (a więc - dowolne wyrażenia o wartościach liczbowych), ale również np. napisy - wówczas większy oznacza tyle, co dalszy w porządku leksykograficznym. Porównania mają priorytet niższy, niż operatory arytmetyczne.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&amp;lt;small&amp;gt;&lt;br /&gt;
Przy bliższym poznaniu okazuje się, że wartości &amp;lt;tt&amp;gt;True&amp;lt;/tt&amp;gt; i &amp;lt;tt&amp;gt;False&amp;lt;/tt&amp;gt; są tak naprawdę w pewnym sensie liczbami: odpowiednio 1 i 0. Dozwolone jest więc np. stosowanie do nich operacji arytmetycznych.&lt;br /&gt;
&amp;lt;/small&amp;gt;&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Z elementarnych wyrażeń logicznych (porównań) można tworzyć złożone wyrażenia logiczne za pomocą operatorów (spójników) logicznych, pisanych &amp;lt;tt&amp;gt;and&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;or&amp;lt;/tt&amp;gt; i &amp;lt;tt&amp;gt;not&amp;lt;/tt&amp;gt;. Mają one następujące właśności:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
(a and b) == (b and a)&lt;br /&gt;
(False and False) == False&lt;br /&gt;
(False and True) == False&lt;br /&gt;
(True and True) == True&lt;br /&gt;
(a or b) == (b or a)&lt;br /&gt;
(False or False) == False&lt;br /&gt;
(False or True) == True&lt;br /&gt;
(True or True) == True&lt;br /&gt;
(not True) == False&lt;br /&gt;
(not False) == True &lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Spójniki logiczne mają priorytet jeszcze niższy, niż porównania - stąd nawiasy w powyższym. Wśród nich najwyższy priorytet ma &amp;lt;tt&amp;gt;not&amp;lt;/tt&amp;gt;, następnie &amp;lt;tt&amp;gt;and&amp;lt;/tt&amp;gt;, na końcu &amp;lt;tt&amp;gt;or&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Wyrażenia logiczne mają tę szczególną własność, że wartość wyrażenia można często określić obliczając jedynie część jego elementów. Np. &amp;lt;tt&amp;gt;a and b&amp;lt;/tt&amp;gt;, jeżeli wartością &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; jest &amp;lt;tt&amp;gt;False&amp;lt;/tt&amp;gt;, jest na pewno &amp;lt;tt&amp;gt;False&amp;lt;/tt&amp;gt; - niezależnie od wartości &amp;lt;tt&amp;gt;b&amp;lt;/tt&amp;gt;. W takich przypadkach Python przerywa obliczanie (od prawej do lewej, z uwzględnieniem nawiasów) gdy tylko wartość jest określona. Fakt ten czasami może mieć znaczenie - jeżeli np. obliczenie któregoś z członów wyrażenia logicznego jest szczególnie czasochłonne, lub ma tzw. skutki uboczne.&lt;br /&gt;
&lt;br /&gt;
Wyrażenia logiczne znajdują zastosowanie przede wszystkim w instrukcji warunkowej - pozwalają określić warunki, pod jakimi pewne operacje będą wykonane, lub nie - o tym dalej.&lt;br /&gt;
&lt;br /&gt;
Warto wiedzieć, że w Pythonie '''każde wyrażenie może służyć jako wyrażenie logiczne'''. Inaczej mówiąc, każda wartość (napis, liczba, lista, itd.) może być wykorzystana w charakterze wartości logicznej. Obowiązują tu proste reguły:&lt;br /&gt;
&lt;br /&gt;
* liczba &amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt; jest fałszywa (równoważna &amp;lt;tt&amp;gt;False&amp;lt;/tt&amp;gt;); obojętne, czy całkowita czy zmiennoprzecinkowa;&lt;br /&gt;
* każda liczba różna od zera jest prawdziwa (równoważna &amp;lt;tt&amp;gt;True&amp;lt;/tt&amp;gt;);&lt;br /&gt;
* napis pusty (o długości 0) jest fałszywy, każdy inny napis jest prawdziwy (również np. zawierający wyłącznie spacje);&lt;br /&gt;
* ogólniej &amp;amp;mdash; dowolnego typu kolekcja (lista, słownik, zbiór, ...) jest prawdziwa, o ile jest niepusta; każda kolekcja pusta (0-elementowa) jest fałszywa;&lt;br /&gt;
* wartość pusta czyli &amp;lt;tt&amp;gt;None&amp;lt;/tt&amp;gt; jest, jak nietrudno zgadnąć, fałszywa.&lt;br /&gt;
&lt;br /&gt;
W przypadku ogólniejszych typów danych (obiektów klas złożonych) sytuacja może już nie być taka prosta, ponieważ twórca klasy ma moc określenia reguły decydującej o prawdziwości / nieprawdziwości obiektów danej klasy. Ten temat jest na razie poza zakresem naszego kursu.&lt;br /&gt;
&lt;br /&gt;
Jeżeli chcemy wymusić, aby dana wartość stała się dosłownie wartością logiczną, tzn. jedną z (&amp;lt;tt&amp;gt;True&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;False&amp;lt;/tt&amp;gt;) w sposób zgodny z powyższymi regułami, można to osiągnąć przykładając funkcję &amp;lt;tt&amp;gt;bool&amp;lt;/tt&amp;gt;: a więc &amp;lt;tt&amp;gt;bool(wyrażenie)&amp;lt;/tt&amp;gt;. Rzadko jednak bywa to potrzebne.&lt;br /&gt;
&lt;br /&gt;
Reguła „skrótowej&amp;quot; ewaluacji wyrażeń logicznych, w połączeniu z regułami prawdziwości innych typów danych, pozwala na dość popularne idiomy, jak np.:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
# jeśli `wynik' jest niepustą listą to wypisze jej zawartość&lt;br /&gt;
# jeśli natomiast pustą, pojawi się komunikat&lt;br /&gt;
print(wynik or &amp;quot;wynik jest pusty!&amp;quot;)&lt;br /&gt;
&amp;lt;/source&amp;gt; &lt;br /&gt;
&lt;br /&gt;
które pozwalają uniknąć używania instrukcji złożonych w wielu prostych przypadkach. Działa to dzięki temu, że spójniki &amp;lt;tt&amp;gt;and&amp;lt;/tt&amp;gt; i &amp;lt;tt&amp;gt;or&amp;lt;/tt&amp;gt; nie wymuszają aby wynik był wartością logiczną:&lt;br /&gt;
&lt;br /&gt;
* jeżeli &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; jest prawdziwe, to &amp;lt;tt&amp;gt;a or b == a&amp;lt;/tt&amp;gt;, i &amp;lt;tt&amp;gt;a and b == b&amp;lt;/tt&amp;gt; dla każdego &amp;lt;tt&amp;gt;b&amp;lt;/tt&amp;gt;;&lt;br /&gt;
* jeżeli &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; jest fałszywe, to &amp;lt;tt&amp;gt;a and b == a&amp;lt;/tt&amp;gt;, i &amp;lt;tt&amp;gt;a or b == b&amp;lt;/tt&amp;gt; dla każdego &amp;lt;tt&amp;gt;b&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Inaczej w przypadku operatora &amp;lt;tt&amp;gt;not&amp;lt;/tt&amp;gt;: wynikiem jego działania jest zawsze jedna z wartości logicznych, podobnie jak w przypadku funkcji &amp;lt;tt&amp;gt;bool()&amp;lt;/tt&amp;gt; &amp;amp;mdash; tyle, że przeciwna.&lt;br /&gt;
&lt;br /&gt;
==Napisowe==&lt;br /&gt;
&lt;br /&gt;
Wartością wyrażenia może być również napis. Na przykład, &amp;lt;tt&amp;gt;a + b&amp;lt;/tt&amp;gt;, jeżeli &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; i &amp;lt;tt&amp;gt;b&amp;lt;/tt&amp;gt; są napisami, jest napisem utworzonym przez ich sklejenie (zauważmy, że w odróżnieniu od dodawania liczb nie jest to operacja przemienna). &lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&amp;lt;small&amp;gt;&lt;br /&gt;
Wcześniej wspomniano, że dwa napisy literalne postawione obok siebie zostaną automatycznie sklejone w jeden: np. &amp;lt;tt&amp;gt;'abc' &amp;quot;123&amp;quot;&amp;lt;/tt&amp;gt; jest równoważne &amp;lt;tt&amp;gt;'abc123'&amp;lt;/tt&amp;gt;. Nie stosuje się to jednak np. do zmiennych o wartościach napisowych: napisanie dwóch nazw obok siebie bez operatora pomiędzy nimi jest błędem składniowym. Jest tak, ponieważ wspomniane sklejenie napisów literalnych ma miejsce na etapie ''kompilacji'' kodu - tzn. wtedy, gdy interpreter analizuje zapis programu i przekłada go na instrukcje, jakie zostaną wykonane w etapie uruchomienia - a wartości stojące za nazwami zmiennych nie są na tym etapie jednoznacznie określone. &lt;br /&gt;
&amp;lt;/small&amp;gt;&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Bogatszy repertuar operacji tworzących wyrażenia o wartościach będących napisami poznamy dalej.&lt;br /&gt;
&lt;br /&gt;
==Inne wyrażenia==&lt;br /&gt;
&lt;br /&gt;
Oprócz liczb, napisów i wartości logicznych, Python posiada szereg dalszych, złożonych typów danych, które również mogą być wartościami wyrażeń. Każdy typ obiektu w Pythonie może być wartością odpowiednio zbudowanego wyrażenia. Gdy poznamy kolejne typy danych, wprowadzimy również operacje tworzące takie wyrażenia.&lt;br /&gt;
&lt;br /&gt;
=Ćwiczenia=&lt;br /&gt;
&lt;br /&gt;
1. Które z następujących są poprawnymi nazwami według reguł Pythona:&lt;br /&gt;
   nazwa1&lt;br /&gt;
   9sił&lt;br /&gt;
   dluga-nazwa&lt;br /&gt;
   wykonaj_rachunki&lt;br /&gt;
   _&lt;br /&gt;
   to&amp;amp;owo&lt;br /&gt;
   if &lt;br /&gt;
&lt;br /&gt;
2. Wykazać, że poniższe równości są równoważnościami -- tzn. że zachodzą dla dowolnej kombinacji wartości &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; i &amp;lt;tt&amp;gt;b&amp;lt;/tt&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
   not (a or b) == not a and not b&lt;br /&gt;
   not (a and b) == not a or not b&lt;br /&gt;
   a or not a == True&lt;br /&gt;
&lt;br /&gt;
''Wskazówka:'' stworzyć tabelki wartości wyrażeń po lewej i prawej stronie operatora porównania &amp;lt;tt&amp;gt;==&amp;lt;/tt&amp;gt; dla wszystkich możliwych kombinacji wartości &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; i &amp;lt;tt&amp;gt;b&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
3. Które z poniższych równości są tożsamościami, w wyniku działania reguł pierwszeństwa operatorów?&lt;br /&gt;
&lt;br /&gt;
   a / b / c == a / (b / c)&lt;br /&gt;
   a ** b / c == (a ** b) / c&lt;br /&gt;
   -a ** b == (-a) ** b&lt;br /&gt;
&lt;br /&gt;
''CDN...''&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
[[PPy3/PierwszeKroki|poprzednia]] | [[&amp;quot;Programowanie z Pythonem3&amp;quot;|Strona główna]] | [[PPy3/InstrukcjaWarunkowa|dalej]]&lt;br /&gt;
&lt;br /&gt;
--[[Użytkownik:RobertJB|RobertJB]] ([[Dyskusja użytkownika:RobertJB|dyskusja]]) 14:22, 21 cze 2016 (CEST)&lt;/div&gt;</summary>
		<author><name>RobertJB</name></author>
		
	</entry>
	<entry>
		<id>http://brain.fuw.edu.pl/edu/index.php?title=PPy3/PierwszeKroki&amp;diff=8916</id>
		<title>PPy3/PierwszeKroki</title>
		<link rel="alternate" type="text/html" href="http://brain.fuw.edu.pl/edu/index.php?title=PPy3/PierwszeKroki&amp;diff=8916"/>
		<updated>2022-07-29T11:18:43Z</updated>

		<summary type="html">&lt;p&gt;RobertJB: /* Podstawowe cegiełki */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
= Pierwsze kroki =&lt;br /&gt;
&lt;br /&gt;
==Podstawowe cegiełki==&lt;br /&gt;
&lt;br /&gt;
*Program w Pythonie to tekst, stanowiący ciąg instrukcji; są one wykonywane przez ''interpreter'' (zasadniczo) kolejno jedna po drugiej.&lt;br /&gt;
*''Prosta'' instrukcja to (zasadniczo) jedna linijka, kończy się wraz z przejściem do kolejnej linii.&lt;br /&gt;
*Instrukcja złożona, to linijka otwierająca '''zawsze zakończona dwukropkiem''', a po niej - '''blok wcięty''', tj. ciąg instrukcji (prostych i/lub złożonych) pisanych z dodatkowym ''wcięciem'' w stosunku do linijki otwierającej; mogą to być dodatkowe (np. dwie lub cztery) spacje, lub kod tabulacji, na początku każdej linijki. Koniec instrukcji złożonej następuje wraz z powrotem do poprzedniego ''poziomu wcięcia''.&lt;br /&gt;
*W tekście programu można umieszczać komentarze; komentarz zaczyna się od znaku &amp;lt;tt&amp;gt;#&amp;lt;/tt&amp;gt;, a kończy się wraz z końcem bieżącej linii. Komentarze nie są częścią programu, tzn. są ignorowane przy jego wykonaniu.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&lt;br /&gt;
*Wyjątki od podanych reguł, istnienie których sygnalizuje słowo ''zasadniczo'', będą przedstawione później.&lt;br /&gt;
*Należy się raz zdecydować, jak dokładnie będziemy tworzyć poziomy wcięcia, i konsekwentnie się tego trzymać. Najlepiej po dwie lub cztery spacje (wg. upodobań), i ustawić w opcjach edytora kodu, żeby wciśnięcie klawisza ''Tab'' skutkowało odpowiednią liczbą spacji. Mieszanie w tekście kodu spacji i tabulacji zawsze prowadzi do kłopotów.&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Przykłady instrukcji prostych:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
x = 1 + 2&lt;br /&gt;
y = 2 * x&lt;br /&gt;
x = x + 1&lt;br /&gt;
print(x, y)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Przykłady instrukcji złożonych:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
if x &amp;gt; 0:&lt;br /&gt;
    print(x)&lt;br /&gt;
&lt;br /&gt;
def dodaj1(x):&lt;br /&gt;
    return x + 1&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ważnym elementem są komentarze:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
# a teraz, powiększę x o 1&lt;br /&gt;
x = x + 1&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*Instrukcje budowane są z wyrażeń, a wyrażenia - z nazw, stałych i operatorów.&lt;br /&gt;
*'''Nazwa''' może składać się z liter, cyfr i znaku podkreślenia (_). Nie może zaczynać się od cyfry. Litery małe i wielkie są rozróżniane.&lt;br /&gt;
*Przykładem stałych są liczby - całkowite i ułamki dziesiętne. Zamiast przecinkiem, część ułamkową oddziela się kropką.&lt;br /&gt;
*Inny rodzaj stałych to napisy. Można je budować na kilka sposobów:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
'to jest napis'&lt;br /&gt;
&amp;quot;to jest drugi napis&amp;quot;&lt;br /&gt;
'''a to jest...&lt;br /&gt;
jeszcze jeden napis'''&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*Ostatni przypadek to wyjątek od zasady że koniec linii kończy instrukcję. Napis podany w pierwszych dwóch postaciach nie może zawierać przejścia do nowej linii.&lt;br /&gt;
*Nazwy są po to, aby oznaczać nimi wartości. Wartościami mogą być np. liczby i napisy:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
pi = 3.14159&lt;br /&gt;
komunikat = 'Uwaga!!!'&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''UWAGA:''' znak równości to nie porównanie, a ''operator przypisania''. Powoduje on, że nazwa po jego lewej stronie będzie odtąd oznaczać wartość zapisaną po prawej. W szczególności, po lewej stronie znaku równości nie może występować np. stała liczba.&lt;br /&gt;
&lt;br /&gt;
*Więcej o stałych i nazwach na następnej stronie, na razie tyle nam wystarczy.&lt;br /&gt;
*Inne operatory, to w szczególności arytmetyka:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
+ - * /  // % **&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'*' to mnożenie, '//' to dzielenie całkowitoliczbowe, '%' to reszta z dzielenia (liczb całkowitych), '**' to potęgowanie.&lt;br /&gt;
&lt;br /&gt;
*Napisy też można &amp;quot;dodawać&amp;quot;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
imie = 'Jacek'&lt;br /&gt;
powitanie = 'witaj ' + imie&lt;br /&gt;
print(powitanie)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;small&amp;gt;Czemu właściwie operację ,,sklejania&amp;quot; napisów oznaczono plusem? W matematyce zazwyczaj plus stosuje się na oznaczenie operacji przemiennych, tzn. takich, których wynik nie zależy od kolejności składników &amp;amp;mdash; a sklejanie napisów ewidentnie taką operacją nie jest. Ale cóż, tak się przyjęło.&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Używanie linii poleceń interpretera==&lt;br /&gt;
&lt;br /&gt;
''Interpreter'' to aplikacja, która potrafi czytać tekst kodu w języku Python i wykonać zapisane w nim polecenia. Może on być używany jako samodzielne polecenie, wywoływane w oknie terminala, lub zintegrowany z środowiskiem programistycznym w rodzaju ''Spyder''. &lt;br /&gt;
&lt;br /&gt;
Zanim zaczniemy pisać &amp;quot;poważne&amp;quot; programy, nauczymy się korzystać z ''trybu interaktywnego'' interpretera, który pozwala na wpisywanie po jednym poleceniu i natychmiastowe uzyskanie wyniku jego wykonania. Można go używać do podręcznych rachunków - zamiast kalkulatora -- i do eksperymentowania z kodem w Pythonie. Do pracy interaktywnej warto używać &amp;quot;wzbogaconej&amp;quot; wersji interpretera, wywoływanej poleceniem&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=bash&amp;gt;&lt;br /&gt;
$ ipython3&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
w najprostszych zastosowaniach niewiele się on różni od &amp;quot;zwykłego&amp;quot; interpretera, wywoływanego przez &amp;lt;tt&amp;gt;python3&amp;lt;/tt&amp;gt;, ale posiada pewne dodatkowe możliwości, które niedługo się nam przydadzą.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&lt;br /&gt;
'''UWAGA:''' polecenie &amp;lt;tt&amp;gt;ipython&amp;lt;/tt&amp;gt; (bez 3) wywoła starszą wersję Pythona. I odpowiednio - &amp;lt;tt&amp;gt;python&amp;lt;/tt&amp;gt; wywołuje starszą wersję &amp;quot;zwykłego&amp;quot; interpretera, a &amp;lt;tt&amp;gt;python3&amp;lt;/tt&amp;gt; - wersję aktualną. &lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Wykonywanie rachunków===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
$ ipython3&lt;br /&gt;
Python 3.5.1+ (default, Mar 30 2016, 22:46:26) &lt;br /&gt;
Type &amp;quot;copyright&amp;quot;, &amp;quot;credits&amp;quot; or &amp;quot;license&amp;quot; for more information.&lt;br /&gt;
&lt;br /&gt;
IPython 2.4.1 -- An enhanced Interactive Python.&lt;br /&gt;
?         -&amp;gt; Introduction and overview of IPython's features.&lt;br /&gt;
%quickref -&amp;gt; Quick reference.&lt;br /&gt;
help      -&amp;gt; Python's own help system.&lt;br /&gt;
object?   -&amp;gt; Details about 'object', use 'object??' for extra details.&lt;br /&gt;
&lt;br /&gt;
In [1]: 7 * (3 + 5)&lt;br /&gt;
Out[1]: 56&lt;br /&gt;
&lt;br /&gt;
In [2]: 2.81 / (1.25 - .33)&lt;br /&gt;
Out[2]: 3.054347826086957&lt;br /&gt;
&lt;br /&gt;
In [3]: 2**128&lt;br /&gt;
Out[3]: 340282366920938463463374607431768211456&lt;br /&gt;
&lt;br /&gt;
In [4]: 1/9&lt;br /&gt;
Out[4]: 0.1111111111111111&lt;br /&gt;
&lt;br /&gt;
In [5]: 11//9, 11%9&lt;br /&gt;
Out[5]: (1, 2)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Zapis wyrażeń arytmetycznych raczej nie zaskakuje. Drobne uwagi:&lt;br /&gt;
&lt;br /&gt;
*spacje w zapisie wyrażenia, pomiędzy liczbami a operatorami (lub ich brak), nie mają znaczenia&lt;br /&gt;
*reguły pierwszeństwa operatorów (najpierw potęgowanie, potem mnożenie i dzielenie, potem odejmowanie i dodawanie,...) są w zasadzie takie, jak należy się spodziewać; kolejność operacji możemy narzucić nawiasami - ale tylko okrągłymi, które można wielokrotnie zagnieżdżać&lt;br /&gt;
*pisząc ułamek dziesiętny (liczbę z kropką), można pominąć część całkowitą lub ułamkową, o ile ma ona być zero (nie można jednak pominąć obu);&lt;br /&gt;
*liczby całkowite mogą być dowolnie duże (w ramach fizycznych ograniczeń komputera)&lt;br /&gt;
*operacje na ułamkach należy zawsze traktować jako przybliżone - komputer może ogarnąć tylko skończoną liczbę cyfr&lt;br /&gt;
*zwykłe dzielenie da zawsze wynik ułamkowy; istnieje jednak operator &amp;lt;tt&amp;gt;//&amp;lt;/tt&amp;gt; dzielenia całkowitego&lt;br /&gt;
*gdy chcemy zakończyć &amp;quot;rozmowę&amp;quot; z interpreterem, piszemy &amp;lt;tt&amp;gt;exit()&amp;lt;/tt&amp;gt;; jeżeli pracujemy w Linuxie, zadziała również dwukrotne &amp;lt;tt&amp;gt;Ctrl-D&amp;lt;/tt&amp;gt; (tzn. trzymając naciśnięty klawisz &amp;lt;tt&amp;gt;Ctrl&amp;lt;/tt&amp;gt; stukamy dwukrotnie w klawisz &amp;lt;tt&amp;gt;D&amp;lt;/tt&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
==Jak uzyskać pomoc==&lt;br /&gt;
&lt;br /&gt;
W programie IPython mamy w każdej chwili dostęp do pomocy na temat poleceń, funkcji itd. Pythona:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
In [8]: print?&lt;br /&gt;
Type:        builtin_function_or_method&lt;br /&gt;
String form: &amp;lt;built-in function print&amp;gt;&lt;br /&gt;
Namespace:   Python builtin&lt;br /&gt;
Docstring:&lt;br /&gt;
print(value, ..., sep=' ', end='\n', file=sys.stdout, flush=False)&lt;br /&gt;
&lt;br /&gt;
Prints the values to a stream, or to sys.stdout by default.&lt;br /&gt;
Optional keyword arguments:&lt;br /&gt;
file:  a file-like object (stream); defaults to the current sys.stdout.&lt;br /&gt;
sep:   string inserted between values, default a space.&lt;br /&gt;
end:   string appended after the last value, default a newline.&lt;br /&gt;
flush: whether to forcibly flush the stream.&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
W tym przykładzie uzyskaliśmy szczegółowy opis zastosowania funkcji wbudowanej &amp;lt;tt&amp;gt;print&amp;lt;/tt&amp;gt;. Wprawdzie po angielsku, ale mam nadzieję, że nie jest to przeszkoda nie do przeskoczenia. Już niedługo będziemy dokładnie rozumieli to, co jest tu napisane.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&lt;br /&gt;
Jeżeli tekst pomocy jest dłuższy, to będzie wyświetlany w trybie pozwalającym m. in. na jego przewijanie z użyciem klawiszy strzałek czy &amp;lt;tt&amp;gt;PgUp&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;PgDn&amp;lt;/tt&amp;gt;. Aby wyjść z tego trybu i powrócić do interpretera, wystarczy nacisnąć &amp;lt;tt&amp;gt;q&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Najprostszy program==&lt;br /&gt;
&lt;br /&gt;
Za pomocą ulubionego edytora tekstowego stwórzmy plik o nazwie &amp;lt;tt&amp;gt;hello.py&amp;lt;/tt&amp;gt; i następującej treści:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
#! /usr/bin/python3&lt;br /&gt;
&lt;br /&gt;
print('Witaj świecie!')&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Zgodnie z tradycją, będzie to program wykonujący jedno banalne zadanie: wypisanie komunikatu o ustalonej treści. Zgodnie z zasadą, że programowanie w Pythonie ma być maksymalnie proste - jedynym niezbędnym elementem tego programu jest linijka wywołująca funkcję &amp;lt;tt&amp;gt;print&amp;lt;/tt&amp;gt;. W tym przykładzie, uzupełniłem treść programu o pierwszą linijkę, zaczynającą się od znaku kratki (&amp;lt;tt&amp;gt;#&amp;lt;/tt&amp;gt;) - istotne jest, aby była to dokładnie pierwsza linijka w pliku, i by zaczynała się od pierwszej pozycji w wierszu. Czyli, aby &amp;lt;tt&amp;gt;#!&amp;lt;/tt&amp;gt; były dokładnie dwoma pierwszymi znakami w treści pliku. Z punktu widzenia Pythona, linijka ta jest komentarzem, i przy uruchamianiu pliku jest ignorowana. Pozwala ona jednak, by plik ten był automatycznie rozpoznawany przez system operacyjny (Linux) jako zawierający program w języku Python. Jaki z tego pożytek, dowiemy się za chwilę.&lt;br /&gt;
&lt;br /&gt;
Aby ten program uruchomić, jest parę sposobów. Najprościej:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=bash&amp;gt;&lt;br /&gt;
$ python3 hello.py&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
powyższe polecenie wpisujemy w terminalu, w trybie powłoki systemowej (''nie w programie IPython!''). Tutaj musieliśmy jawnie wywołać interpreter Pythona i wskazać mu plik &amp;lt;tt&amp;gt;hello.py&amp;lt;/tt&amp;gt; jako zawierający kod do uruchomienia.&lt;br /&gt;
&lt;br /&gt;
Zamiast tego, możemy nadać plikowi &amp;lt;tt&amp;gt;hello.py&amp;lt;/tt&amp;gt; atrybut pliku wykonywalnego, czyli programu, i uruchomić go bezpośrednio:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=bash&amp;gt;&lt;br /&gt;
$ chmod +x hello.py&lt;br /&gt;
$ ./hello.py&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*Polecenie z pierwszej linijki wystarczy wykonać raz dla danego pliku&lt;br /&gt;
*Zamiast z linii poleceń, można w okienku ''Właściwości'' pliku znaleźć odpowiednie pole do kliknięcia&lt;br /&gt;
*Postać drugiej linijki tłumaczy się tym, że nasz program &amp;lt;tt&amp;gt;hello.py&amp;lt;/tt&amp;gt; nie jest zainstalowany w systemie i nie zostanie odnaleziony przez przeszukanie standardowych lokalizacji programów na dysku. Należy wyraźnie wskazać, że chodzi o plik znajdujący się w bieżącym folderze - i to tu robimy.&lt;br /&gt;
*Plik z kodem w Pythonie nie musi mieć nazwy kończącej się na &amp;lt;tt&amp;gt;.py&amp;lt;/tt&amp;gt; - jest to jednak wygodne, bo np. edytory tekstu traktują to jako sugestię co do zawartości pliku, i mogą dostosować do tego swoje działanie (np. &amp;lt;tt&amp;gt;gedit&amp;lt;/tt&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
==Ćwiczenia==&lt;br /&gt;
&lt;br /&gt;
===Rachunki w linii poleceń===&lt;br /&gt;
&lt;br /&gt;
#Ile wynosi reszta z dzielenia 2&amp;lt;sup&amp;gt;999&amp;lt;/sup&amp;gt; przez 7?&lt;br /&gt;
#Która z tych liczb mniej się różni od pierwiastka kwadratowego z 2: 721/510 czy 722/510?&lt;br /&gt;
#Oblicz pierwiastek kwadratowy z 2, a następnie - podnieś go do kwadratu; ile wynosi względny błąd wyniku?&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
''CDN''&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
[[PPy3/Wprowadzenie|poprzednia]] | [[&amp;quot;Programowanie z Pythonem3&amp;quot;|Strona główna]] | [[PPy3/StałeIZmienne|dalej]]&lt;br /&gt;
&lt;br /&gt;
--[[Użytkownik:RobertJB|RobertJB]] ([[Dyskusja użytkownika:RobertJB|dyskusja]]) 13:53, 15 cze 2016 (CEST)&lt;/div&gt;</summary>
		<author><name>RobertJB</name></author>
		
	</entry>
	<entry>
		<id>http://brain.fuw.edu.pl/edu/index.php?title=%22Programowanie_z_Pythonem3%22&amp;diff=8915</id>
		<title>&quot;Programowanie z Pythonem3&quot;</title>
		<link rel="alternate" type="text/html" href="http://brain.fuw.edu.pl/edu/index.php?title=%22Programowanie_z_Pythonem3%22&amp;diff=8915"/>
		<updated>2022-07-27T13:12:22Z</updated>

		<summary type="html">&lt;p&gt;RobertJB: /* Semestr zimowy 2021/2022 */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Grafika:Python-logo.png]]&lt;br /&gt;
&lt;br /&gt;
[[Category:Informatyka]]&lt;br /&gt;
== Semestr zimowy 2022/2023 ==&lt;br /&gt;
&lt;br /&gt;
'''''W trakcie opracowania'''''&lt;br /&gt;
&lt;br /&gt;
===Uwagi ogólne===&lt;br /&gt;
&lt;br /&gt;
W pracowniach OKWF zainstalowane są zarówno stara wersja Pythona (2.7), jak i aktualna (3.x). Aktualnie polecenie &amp;lt;tt&amp;gt;python&amp;lt;/tt&amp;gt; uruchamia wersję 2.7; w celu uruchomienia wersji 3 należy pisać &amp;lt;tt&amp;gt;python3&amp;lt;/tt&amp;gt;. Analogicznie, istnieją wywołania &amp;lt;tt&amp;gt;ipython3&amp;lt;/tt&amp;gt; oraz &amp;lt;tt&amp;gt;spyder3&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Zasady zaliczenia ćwiczeń w roku 2022/2023:&lt;br /&gt;
&lt;br /&gt;
* maksymalnie można zdobyć 40 punktów&lt;br /&gt;
* w semestrze będą dwa kolokwia, w połowie i pod koniec; na każdym można zdobyć po 15 punktów&lt;br /&gt;
* w sesji będzie kolokwium dodatkowe, dla chętnych; wynik z niego (maks. 15 punktów) zastępuje gorszy z wyników kolokwiów z semestru, o ile jest on od niego lepszy&lt;br /&gt;
* maksymalnie 10 punktów przydziela prowadzący na podstawie zadań domowych i aktywności na ćwiczeniach&lt;br /&gt;
* zaliczenie ćwiczeń na pozytywną ocenę wymaga co najmniej 50% punktów (20 p.)&lt;br /&gt;
* ocena rośnie o pół stopnia z osiągnięciem progu każdych kolejnych 10%, tj. 4 punktów.&lt;br /&gt;
&lt;br /&gt;
Obecność na ćwiczeniach jest obowiązkowa. Dopuszczalne są '''dwie''' nieobecności nieusprawiedliwione w semestrze. '''Za każdą kolejną nieobecność nieusprawiedliwioną powyżej dwóch odejmujemy od wyniku 5 punktów.'''&lt;br /&gt;
&lt;br /&gt;
Ocena końcowa z przedmiotu składa się z oceny z ćwiczeń, oraz z oceny z egzaminu testowego kończącego wykład, w proporcji 3:2 - z tym, że '''obie te oceny cząstkowe muszą być pozytywne''' aby ocena z całości była pozytywna.&lt;br /&gt;
&lt;br /&gt;
===Spis treści===&lt;br /&gt;
&lt;br /&gt;
#[[PPy3/Wprowadzenie|Wprowadzenie]]&lt;br /&gt;
#[[PPy3/PierwszeKroki|Pierwsze kroki]]&lt;br /&gt;
#[[PPy3/StałeIZmienne|Stałe i zmienne]]&lt;br /&gt;
#[[PPy3/InstrukcjaWarunkowa|Instrukcja warunkowa]]&lt;br /&gt;
#[[PPy3/SekwencjeIIteracja|Sekwencje i iteracja]]&lt;br /&gt;
#[[PPy3/Funkcje|Funkcje]]&lt;br /&gt;
#[[PPy3/Kolekcje|Kolekcje]]&lt;br /&gt;
#[[PPy3/Moduły|Moduły i biblioteki]]&lt;br /&gt;
#[[PPy3/WejścieWyjście|Obsługa wejścia i wyjścia]]&lt;br /&gt;
#[[PPy3/NumPy|NumPy]] - rachunki numeryczne na tablicach liczb&lt;br /&gt;
#[[PPy3/Matplotlib|Matplotlib]] - wizualizacja danych&lt;br /&gt;
#[[PPy3/TematyDodatkowe|Tematy dodatkowe]] - uzupełnienie&lt;br /&gt;
#[[PPy3/DobrePraktyki|Zasady dobrej praktyki]]&lt;br /&gt;
&lt;br /&gt;
===O skrypcie===&lt;br /&gt;
&lt;br /&gt;
Opracowane na nowo przez [[Użytkownik:RobertJB|RobertJB]], częściowo z wykorzystaniem [[&amp;quot;Programowanie z Pythonem&amp;quot;|poprzedniej wersji]].&lt;/div&gt;</summary>
		<author><name>RobertJB</name></author>
		
	</entry>
	<entry>
		<id>http://brain.fuw.edu.pl/edu/index.php?title=PPy3/Wprowadzenie&amp;diff=8702</id>
		<title>PPy3/Wprowadzenie</title>
		<link rel="alternate" type="text/html" href="http://brain.fuw.edu.pl/edu/index.php?title=PPy3/Wprowadzenie&amp;diff=8702"/>
		<updated>2021-10-05T18:42:57Z</updated>

		<summary type="html">&lt;p&gt;RobertJB: /* Instalacja */  WSL&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Wprowadzenie==&lt;br /&gt;
&lt;br /&gt;
Aby komputer wykonał za nas jakąś pracę, musimy mu przekazać dość precyzyjne instrukcje, mówiące co ma zrobić. Taki zestaw instrukcji nazywa się ''programem'', a proces tworzenia programów - to ''programowanie''. Stworzenie programu wymaga wykonania dwóch zasadniczych zadań:&lt;br /&gt;
&lt;br /&gt;
#wymyślenia algorytmu&lt;br /&gt;
#zapisania tegoż algorytmu w sposób możliwy do zinterpretowania przez komputer - a więc w jakimś języku programowania.&lt;br /&gt;
&lt;br /&gt;
Podczas opracowywania algorytmu musimy zastanowić się, jak dojdziemy do poszukiwanego rozwiązania. W jaki sposób z posiadanych danych wejściowych uzyskać możemy oczekiwany wynik? Jakie operacje po drodze muszę wykonać? Ile razy? Co po drodze muszę wiedzieć, a co dodatkowo sprawdzić? Jeśli wiemy już, jakie niezbędne etapy obliczeń musimy wykonać możemy przejść do fazy drugiej, czyli pisania właściwego programu.&lt;br /&gt;
&lt;br /&gt;
Programy piszemy używając specjalnych języków stworzonych do komunikacji z komputerami. Zawierają one pewien zestaw słów — poleceń, które komputer może wykonać. Wybór konkretnego języka może zależeć od rozwiązywanego problemu, ale w wielu wypadkach jest sprawą drugorzędną. Ponieważ, tak jak w przypadku języków obcych, aby porozumieć się z cudzoziemcem musimy nauczyć się obcego języka, tak i tu musimy nauczyć się wybranego języka (języków) programowania.&lt;br /&gt;
&lt;br /&gt;
Dlaczego uczymy się programować akurat w języku Python?&lt;br /&gt;
&lt;br /&gt;
*Jest jednym z najłatwiejszych do opanowania języków programowania, i najbardziej czytelnych dla człowieka.&lt;br /&gt;
*Jest narzędziem dojrzałym, rozwijanym od wielu lat i dobrze sprawdzonym.&lt;br /&gt;
*Zawiera jako standardowe wyposażenie wiele gotowych rozwiązań, które można wykorzystać jako elementy własnych programów.&lt;br /&gt;
*Jest coraz szerzej wykorzystywany do zadań naukowych.&lt;br /&gt;
*Jest dostępny bezpłatnie i bez uciążliwych ograniczeń licencyjnych na wiele różnych platform - systemów operacyjnych.&lt;br /&gt;
&lt;br /&gt;
Na początku nauczymy się podstaw języka, aby móc zacząć pisać i uruchamiać pierwsze, na razie proste programy. Następnie przećwiczymy rozwiązywanie rozmaitych zagadnień, wymyślając do tego odpowiednie algorytmy i zapisując je w postaci programów w Pythonie. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&lt;br /&gt;
Pracując z komputerem tak jak sekretarz czy księgowy, nie potrzeba w zasadzie nic wiedzieć o programowaniu i wewnętrznym działaniu komputera. Tak jak kurs nauki jazdy nie uczy, jak projektować konstrukcje samochodów, ani nawet jak je naprawiać. Założeniem studiów na fizyce jest jednak przygotowanie absolwenta, który będzie umiał sobie radzić z nowymi zadaniami i rozwiązywać problemy, a nie jedynie wykonywać pewne procedury. Elementarna umiejętność programowania jest jednym z narzędzi do tego celu.&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Instalacja===&lt;br /&gt;
&lt;br /&gt;
W systemach z rodziny '''Linux''' Python należy do wyposażenie standardowego. Niewykluczone, że dla celów drugiej części kursu będzie potrzeba doinstalowania opcjonalnych składników środowiska Python, m. in. narzędzi do obliczeń numerycznych i wizualizacji danych (tj. wykresów, itp.). Oczywiście na pracowniach dydaktycznych zostało to już za nas wykonane. &lt;br /&gt;
&lt;br /&gt;
Dla systemów z rodziny '''Windows''' możemy np. skorzystać z [https://docs.microsoft.com/en-us/windows/python/beginners dystrybucji] dostępnej ze &amp;quot;sklepu&amp;quot; Microsoft, lub z [https://www.python.org/downloads/windows/ pakietów] dostępnych z oficjalnych stron projektu Python. Dla bardziej zaawansowanych użytkowników, którzy jednak nie chcą opuszczać środowiska Windows, ciekawym rozwiązaniem może być [https://docs.microsoft.com/en-us/windows/wsl/install WSL] &amp;amp;mdash; emulacja środowiska Linux wewnątrz Windows.&lt;br /&gt;
&lt;br /&gt;
W systemie '''MacOS''' Python dostępny jest domyślnie, preinstalowana wersja może być jednak niepełna i/lub przestarzała. Pakiety instalacyjne Pythona dostępne są np. [https://www.python.org/downloads/macos/ tu].&lt;br /&gt;
&lt;br /&gt;
===Ogólnie o pracy z komputerem===&lt;br /&gt;
&lt;br /&gt;
Tu jest właściwy moment, aby zapoznać się (o ile jest to komuś obce) z kilkoma podstawowymi faktami dotyczącymi&lt;br /&gt;
,,zaawansowanej&amp;quot; pracy z komputerem, a nie dotyczącymi samego Pythona &amp;amp;mdash; w tym:&lt;br /&gt;
&lt;br /&gt;
*logiczna organizacja danych na dysku; foldery (katalogi), podfoldery&lt;br /&gt;
*prawa dostępu do plików i folderów&lt;br /&gt;
*pliki tekstowe i jak je edytować&lt;br /&gt;
*co to jest terminal i powłoka systemowa (''shell'')&lt;br /&gt;
*co to jest katalog bieżący; podstawowe operacje na plikach w linii poleceń (''ls'', ''pwd'', ''cd'', ''cp'', ''mv'', ''rm'', ...)&lt;br /&gt;
*jak uruchomić program w linii poleceń; ścieżka wyszukiwania&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
[[&amp;quot;Programowanie_z_Pythonem3&amp;quot;|Strona główna]] | [[PPy3/PierwszeKroki|dalej]]&lt;br /&gt;
&lt;br /&gt;
--[[Użytkownik:RobertJB|RobertJB]] ([[Dyskusja użytkownika:RobertJB|dyskusja]]) 13:16, 29 wrz 2017 (CEST)&lt;/div&gt;</summary>
		<author><name>RobertJB</name></author>
		
	</entry>
	<entry>
		<id>http://brain.fuw.edu.pl/edu/index.php?title=PPy3/Wprowadzenie&amp;diff=8701</id>
		<title>PPy3/Wprowadzenie</title>
		<link rel="alternate" type="text/html" href="http://brain.fuw.edu.pl/edu/index.php?title=PPy3/Wprowadzenie&amp;diff=8701"/>
		<updated>2021-10-05T18:39:43Z</updated>

		<summary type="html">&lt;p&gt;RobertJB: /* Instalacja */ wywaliłem nieaktualne linki. Początkującym lepiej jednak nie polecać Anacondy.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Wprowadzenie==&lt;br /&gt;
&lt;br /&gt;
Aby komputer wykonał za nas jakąś pracę, musimy mu przekazać dość precyzyjne instrukcje, mówiące co ma zrobić. Taki zestaw instrukcji nazywa się ''programem'', a proces tworzenia programów - to ''programowanie''. Stworzenie programu wymaga wykonania dwóch zasadniczych zadań:&lt;br /&gt;
&lt;br /&gt;
#wymyślenia algorytmu&lt;br /&gt;
#zapisania tegoż algorytmu w sposób możliwy do zinterpretowania przez komputer - a więc w jakimś języku programowania.&lt;br /&gt;
&lt;br /&gt;
Podczas opracowywania algorytmu musimy zastanowić się, jak dojdziemy do poszukiwanego rozwiązania. W jaki sposób z posiadanych danych wejściowych uzyskać możemy oczekiwany wynik? Jakie operacje po drodze muszę wykonać? Ile razy? Co po drodze muszę wiedzieć, a co dodatkowo sprawdzić? Jeśli wiemy już, jakie niezbędne etapy obliczeń musimy wykonać możemy przejść do fazy drugiej, czyli pisania właściwego programu.&lt;br /&gt;
&lt;br /&gt;
Programy piszemy używając specjalnych języków stworzonych do komunikacji z komputerami. Zawierają one pewien zestaw słów — poleceń, które komputer może wykonać. Wybór konkretnego języka może zależeć od rozwiązywanego problemu, ale w wielu wypadkach jest sprawą drugorzędną. Ponieważ, tak jak w przypadku języków obcych, aby porozumieć się z cudzoziemcem musimy nauczyć się obcego języka, tak i tu musimy nauczyć się wybranego języka (języków) programowania.&lt;br /&gt;
&lt;br /&gt;
Dlaczego uczymy się programować akurat w języku Python?&lt;br /&gt;
&lt;br /&gt;
*Jest jednym z najłatwiejszych do opanowania języków programowania, i najbardziej czytelnych dla człowieka.&lt;br /&gt;
*Jest narzędziem dojrzałym, rozwijanym od wielu lat i dobrze sprawdzonym.&lt;br /&gt;
*Zawiera jako standardowe wyposażenie wiele gotowych rozwiązań, które można wykorzystać jako elementy własnych programów.&lt;br /&gt;
*Jest coraz szerzej wykorzystywany do zadań naukowych.&lt;br /&gt;
*Jest dostępny bezpłatnie i bez uciążliwych ograniczeń licencyjnych na wiele różnych platform - systemów operacyjnych.&lt;br /&gt;
&lt;br /&gt;
Na początku nauczymy się podstaw języka, aby móc zacząć pisać i uruchamiać pierwsze, na razie proste programy. Następnie przećwiczymy rozwiązywanie rozmaitych zagadnień, wymyślając do tego odpowiednie algorytmy i zapisując je w postaci programów w Pythonie. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&lt;br /&gt;
Pracując z komputerem tak jak sekretarz czy księgowy, nie potrzeba w zasadzie nic wiedzieć o programowaniu i wewnętrznym działaniu komputera. Tak jak kurs nauki jazdy nie uczy, jak projektować konstrukcje samochodów, ani nawet jak je naprawiać. Założeniem studiów na fizyce jest jednak przygotowanie absolwenta, który będzie umiał sobie radzić z nowymi zadaniami i rozwiązywać problemy, a nie jedynie wykonywać pewne procedury. Elementarna umiejętność programowania jest jednym z narzędzi do tego celu.&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Instalacja===&lt;br /&gt;
&lt;br /&gt;
W systemach z rodziny '''Linux''' Python należy do wyposażenie standardowego. Niewykluczone, że dla celów drugiej części kursu będzie potrzeba doinstalowania opcjonalnych składników środowiska Python, m. in. narzędzi do obliczeń numerycznych i wizualizacji danych (tj. wykresów, itp.). Oczywiście na pracowniach dydaktycznych zostało to już za nas wykonane. &lt;br /&gt;
&lt;br /&gt;
Dla systemów z rodziny '''Windows''' możemy np. skorzystać z [https://docs.microsoft.com/en-us/windows/python/beginners dystrybucji] dostępnej ze &amp;quot;sklepu&amp;quot; Microsoft, lub z [https://www.python.org/downloads/windows/ pakietów] dostępnych z oficjalnych stron projektu Python.&lt;br /&gt;
&lt;br /&gt;
W systemie '''MacOS''' Python dostępny jest domyślnie, preinstalowana wersja może być jednak niepełna i/lub przestarzała. Pakiety instalacyjne Pythona dostępne są np. [https://www.python.org/downloads/macos/ tu].&lt;br /&gt;
&lt;br /&gt;
===Ogólnie o pracy z komputerem===&lt;br /&gt;
&lt;br /&gt;
Tu jest właściwy moment, aby zapoznać się (o ile jest to komuś obce) z kilkoma podstawowymi faktami dotyczącymi&lt;br /&gt;
,,zaawansowanej&amp;quot; pracy z komputerem, a nie dotyczącymi samego Pythona &amp;amp;mdash; w tym:&lt;br /&gt;
&lt;br /&gt;
*logiczna organizacja danych na dysku; foldery (katalogi), podfoldery&lt;br /&gt;
*prawa dostępu do plików i folderów&lt;br /&gt;
*pliki tekstowe i jak je edytować&lt;br /&gt;
*co to jest terminal i powłoka systemowa (''shell'')&lt;br /&gt;
*co to jest katalog bieżący; podstawowe operacje na plikach w linii poleceń (''ls'', ''pwd'', ''cd'', ''cp'', ''mv'', ''rm'', ...)&lt;br /&gt;
*jak uruchomić program w linii poleceń; ścieżka wyszukiwania&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
[[&amp;quot;Programowanie_z_Pythonem3&amp;quot;|Strona główna]] | [[PPy3/PierwszeKroki|dalej]]&lt;br /&gt;
&lt;br /&gt;
--[[Użytkownik:RobertJB|RobertJB]] ([[Dyskusja użytkownika:RobertJB|dyskusja]]) 13:16, 29 wrz 2017 (CEST)&lt;/div&gt;</summary>
		<author><name>RobertJB</name></author>
		
	</entry>
	<entry>
		<id>http://brain.fuw.edu.pl/edu/index.php?title=%22Programowanie_z_Pythonem3%22&amp;diff=8697</id>
		<title>&quot;Programowanie z Pythonem3&quot;</title>
		<link rel="alternate" type="text/html" href="http://brain.fuw.edu.pl/edu/index.php?title=%22Programowanie_z_Pythonem3%22&amp;diff=8697"/>
		<updated>2021-10-04T13:52:01Z</updated>

		<summary type="html">&lt;p&gt;RobertJB: /* Uwagi ogólne */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Grafika:Python-logo.png]]&lt;br /&gt;
&lt;br /&gt;
[[Category:Informatyka]]&lt;br /&gt;
== Semestr zimowy 2021/2022 ==&lt;br /&gt;
&lt;br /&gt;
'''''W trakcie opracowania'''''&lt;br /&gt;
&lt;br /&gt;
===Uwagi ogólne===&lt;br /&gt;
&lt;br /&gt;
W pracowniach OKWF zainstalowane są zarówno stara wersja Pythona (2.7), jak i aktualna (3.x). Aktualnie polecenie &amp;lt;tt&amp;gt;python&amp;lt;/tt&amp;gt; uruchamia wersję 2.7; w celu uruchomienia wersji 3 należy pisać &amp;lt;tt&amp;gt;python3&amp;lt;/tt&amp;gt;. Analogicznie, istnieją wywołania &amp;lt;tt&amp;gt;ipython3&amp;lt;/tt&amp;gt; oraz &amp;lt;tt&amp;gt;spyder3&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Zasady zaliczenia ćwiczeń w roku 2021/2022:&lt;br /&gt;
&lt;br /&gt;
* maksymalnie można zdobyć 40 punktów&lt;br /&gt;
* w semestrze będą dwa kolokwia, w połowie i pod koniec; na każdym można zdobyć po 15 punktów&lt;br /&gt;
* w sesji będzie kolokwium dodatkowe, dla chętnych; wynik z niego (maks. 15 punktów) zastępuje gorszy z wyników kolokwiów z semestru, o ile jest on od niego lepszy&lt;br /&gt;
* maksymalnie 10 punktów przydziela prowadzący na podstawie zadań domowych i aktywności na ćwiczeniach&lt;br /&gt;
* zaliczenie ćwiczeń na pozytywną ocenę wymaga co najmniej 50% punktów (20 p.)&lt;br /&gt;
* ocena rośnie o pół stopnia z osiągnięciem progu każdych kolejnych 10%, tj. 4 punktów.&lt;br /&gt;
&lt;br /&gt;
Obecność na ćwiczeniach jest obowiązkowa. Dopuszczalne są '''dwie''' nieobecności nieusprawiedliwione w semestrze. '''Za każdą kolejną nieobecność nieusprawiedliwioną powyżej dwóch odejmujemy od wyniku 5 punktów.'''&lt;br /&gt;
&lt;br /&gt;
Ocena końcowa z przedmiotu składa się z oceny z ćwiczeń, oraz z oceny z egzaminu testowego kończącego wykład, w proporcji 3:2 - z tym, że '''obie te oceny cząstkowe muszą być pozytywne''' aby ocena z całości była pozytywna.&lt;br /&gt;
&lt;br /&gt;
===Spis treści===&lt;br /&gt;
&lt;br /&gt;
#[[PPy3/Wprowadzenie|Wprowadzenie]]&lt;br /&gt;
#[[PPy3/PierwszeKroki|Pierwsze kroki]]&lt;br /&gt;
#[[PPy3/StałeIZmienne|Stałe i zmienne]]&lt;br /&gt;
#[[PPy3/InstrukcjaWarunkowa|Instrukcja warunkowa]]&lt;br /&gt;
#[[PPy3/SekwencjeIIteracja|Sekwencje i iteracja]]&lt;br /&gt;
#[[PPy3/Funkcje|Funkcje]]&lt;br /&gt;
#[[PPy3/Kolekcje|Kolekcje]]&lt;br /&gt;
#[[PPy3/Moduły|Moduły i biblioteki]]&lt;br /&gt;
#[[PPy3/WejścieWyjście|Obsługa wejścia i wyjścia]]&lt;br /&gt;
#[[PPy3/NumPy|NumPy]] - rachunki numeryczne na tablicach liczb&lt;br /&gt;
#[[PPy3/Matplotlib|Matplotlib]] - wizualizacja danych&lt;br /&gt;
#[[PPy3/TematyDodatkowe|Tematy dodatkowe]] - uzupełnienie&lt;br /&gt;
#[[PPy3/DobrePraktyki|Zasady dobrej praktyki]]&lt;br /&gt;
&lt;br /&gt;
===O skrypcie===&lt;br /&gt;
&lt;br /&gt;
Opracowane na nowo przez [[Użytkownik:RobertJB|RobertJB]], częściowo z wykorzystaniem [[&amp;quot;Programowanie z Pythonem&amp;quot;|poprzedniej wersji]].&lt;/div&gt;</summary>
		<author><name>RobertJB</name></author>
		
	</entry>
	<entry>
		<id>http://brain.fuw.edu.pl/edu/index.php?title=Strona_g%C5%82%C3%B3wna&amp;diff=8692</id>
		<title>Strona główna</title>
		<link rel="alternate" type="text/html" href="http://brain.fuw.edu.pl/edu/index.php?title=Strona_g%C5%82%C3%B3wna&amp;diff=8692"/>
		<updated>2021-09-14T10:13:51Z</updated>

		<summary type="html">&lt;p&gt;RobertJB: /* Informatyka: */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=Materiały dydaktycznie dla studentów kierunku [http://fizykaxxi.fuw.edu.pl/zastosowania-fizyki-w-biologii-i-medycynie/ Zastosowania Fizyki w Biologii i Medycynie]=&lt;br /&gt;
&lt;br /&gt;
==Informatyka:==&lt;br /&gt;
 [[Plik:Pętla_while.svg|175px|right]]&lt;br /&gt;
* Technologia Informacyjna:&lt;br /&gt;
** Wykład    [[&amp;quot;Technologia informacyjna&amp;quot;]] &lt;br /&gt;
** Wykład [[Slajdy z wykładów dla optyki okularowej z roku 2015|&amp;quot;Technologie cyfrowe&amp;quot;]] (dla specjalności Optyka Okularowa)&lt;br /&gt;
** Ćwiczenia [[&amp;quot;Programowanie z Pythonem&amp;quot;]] (dla studentów Wydziału Fizyki) '''STARE'''&lt;br /&gt;
** Ćwiczenia [[&amp;quot;Programowanie z Pythonem3&amp;quot;]] (dla studentów Wydziału Fizyki) '''od 2020/21'''&lt;br /&gt;
** Ćwiczenia [[dla studentów Wydziału Biologii|&amp;quot;Technologia informacyjna&amp;quot;]] (dla studentów Wydziału Biologii)&lt;br /&gt;
* Programowanie dla Neuroinformatyków:&lt;br /&gt;
** Ćwiczenia [[&amp;quot;Programowanie dla Neuroinformatyków&amp;quot;]]&lt;br /&gt;
* Programowanie dla Fizyków Medycznych:&lt;br /&gt;
** Ćwiczenia [[&amp;quot;Programowanie dla Fizyków Medycznych&amp;quot;]]&lt;br /&gt;
* Bazy danych:&lt;br /&gt;
** Wykład    [[TI:WTBD|&amp;quot;Wstęp do technologii baz danych&amp;quot;]]&lt;br /&gt;
** Ćwiczenia [[TI:WTBD|&amp;quot;Wstęp do technologii baz danych&amp;quot;]]&lt;br /&gt;
* [[TI/Pracownia wykorzystania zasobów internetowych|Pracownia wykorzystania zasobów internetowych]]&lt;br /&gt;
&lt;br /&gt;
==Matematyka:==&lt;br /&gt;
* Wykład    [[Matematyka I - FMiN lecture|Matematyka I]] (dla specjalności Fizyka Medyczna i Neuroinformatyka)&lt;br /&gt;
** Ćwiczenia [[Matematyka I - FMiN exercises|Matematyka I]] (dla specjalności Fizyka Medyczna i Neuroinformatyka)&lt;br /&gt;
** Ćwiczenia [[Matematyka I - OO exercises|Matematyka I]] (dla specjalności Optyka Okularowa)&lt;br /&gt;
 [[Plik:main_math.png|175px|right]]&lt;br /&gt;
* Wykład    [[Matematyka II - FMiN lecture|Matematyka II]] (dla specjalności Fizyka Medyczna i Neuroinformatyka)&lt;br /&gt;
** Ćwiczenia [[Matematyka II - FMiN exercises|Matematyka II]] (dla specjalności Fizyka Medyczna i Neuroinformatyka)&lt;br /&gt;
&lt;br /&gt;
==Fizyka:==&lt;br /&gt;
* Fizyka I:&lt;br /&gt;
** Wykład [[Fizyka I - FMiN lecture|Fizyka I]] - Mechanika (dla specjalności Fizyka Medyczna i Neuroinformatyka)&lt;br /&gt;
** Wykład [[Fizyka I - OO lecture|Fizyka I]] - Mechanika (dla specjalności Optyka Okularowa)&lt;br /&gt;
** Ćwiczenia [[Fizyka I - FMiN exercises|Fizyka I]] - Mechanika (dla specjalności Fizyka Medyczna i Neuroinformatyka)&lt;br /&gt;
* Fizyka II: [[Plik:main_phys.png|220px|right]]&lt;br /&gt;
** Wykład [[Fizyka II - OO lecture|Fizyka II]] - Elektrostatyka (dla specjalności Optyka Okularowa)&lt;br /&gt;
** Wykład [[Fizyka II - NI lecture|Fizyka II]] - Elektrostatyka (dla specjalności Fizyka Medyczna i Neuroinformatyka)&lt;br /&gt;
** Ćwiczenia [[Fizyka II - FMiN exercises|Fizyka II]] - Elektrostatyka (dla specjalności Fizyka Medyczna i Neuroinformatyka)&lt;br /&gt;
** Ćwiczenia [[Fizyka II - OO exercises|Fizyka II]] - Elektrostatyka (dla specjalności Optyka Okularowa)&lt;br /&gt;
* Fizyka III:&lt;br /&gt;
** Wykład [[Fizyka III - FMiN lecture|Fizyka III]] - Drgania i Fale (dla specjalności Fizyka Medyczna i Neuroinformatyka)&lt;br /&gt;
** Ćwiczenia [[Fizyka III - FMiN exercises|Fizyka III]] - Drgania i Fale (dla specjalności Fizyka Medyczna i Neuroinformatyka)&lt;br /&gt;
* Elektrodynamika:&lt;br /&gt;
** Ćwiczenia [[Ćwiczenia z elektrodynamiki dla neuroinformatyków|Elektrodynamika]] (dla specjalności Neuroinformatyka)&lt;br /&gt;
* Ćwiczenia [[Fizyka Promieniowania Jądrowego]]&lt;br /&gt;
* Ćwiczenia [[Fizyka atomów oraz cząstek i makrocząstek biologicznych]]&lt;br /&gt;
&lt;br /&gt;
==Chemia:==&lt;br /&gt;
* Wykład [[Podstawy chemii z elementami biochemii]]&lt;br /&gt;
* Wykład [[Chemia ogólna - lecture|Chemia ogólna]] &lt;br /&gt;
* Pracownia [[Chemia ogólna - workshop|Chemia ogólna]]&lt;br /&gt;
* Wykład [[Chemia organiczna]]&lt;br /&gt;
&lt;br /&gt;
==Biologia:==&lt;br /&gt;
 [[Plik:main_biol.jpg|220px|right]]&lt;br /&gt;
* Wykład [[Biologia komórki]] &lt;br /&gt;
* Wykład [[Histologia]]&lt;br /&gt;
* Pracownia [[Biologia molekularna]]&lt;br /&gt;
&lt;br /&gt;
==Biofizyka molekularna:==&lt;br /&gt;
* Wykład [[Metody Biofizyki Molekularnej - lecture|Metody Biofizyki Molekularnej]]&lt;br /&gt;
** Ćwiczenia [[Metody Biofizyki Molekularnej - exercises|Metody Biofizyki Molekularnej]]&lt;br /&gt;
*[[Pracownia podstaw biofizyki]] (dla specjalności Biofizyka molekularna)&lt;br /&gt;
* Pracownia [[Podstawy Biofizyki]]&lt;br /&gt;
* Pracownia [[Pracownia Biofizyki dla Zaawansowanych]]&lt;br /&gt;
*[[Pracownia biofizyki dla zaawansowanych]] (dla specjalności Biofizyka Molekularna)&lt;br /&gt;
&lt;br /&gt;
== Przedmioty specjalizacyjne: ==&lt;br /&gt;
* Wykład [[Obrazowanie Medyczne]]&lt;br /&gt;
&amp;lt;!--* Wykład [[Metody fizyczne w biologii i medycynie]]--&amp;gt;&lt;br /&gt;
* Wykład [[Ochrona radiologiczna]]&lt;br /&gt;
* Wykład [[Ochrona radilogiczna 2]]&lt;br /&gt;
&amp;lt;!--* Wykład [[Sygnały Bioelektryczne]]--&amp;gt;&lt;br /&gt;
* Wykład [[Elektroencefalografia]]&lt;br /&gt;
* Wykład [[Wnioskowanie Statystyczne - lecture|Wnioskowanie Statystyczne]] [[Plik:main_eeg2.png|125px|right]]&lt;br /&gt;
** Ćwiczenia [[Wnioskowanie Statystyczne - exercises|Wnioskowanie Statystyczne]]&lt;br /&gt;
* Wykład [[Analiza sygnałów - lecture|Analiza sygnałów]] [[Plik:Logo_pelne_KNI.png|220px|right|link=https://pl-pl.facebook.com/KNNeuroinformatyki/]]&lt;br /&gt;
** Ćwiczenia [[Analiza sygnałów - exercises|Analiza sygnałów]]&lt;br /&gt;
* [[Uczenie maszynowe i sztuczne sieci neuronowe]]&lt;br /&gt;
&amp;lt;!-- ** Ćwiczenia [[Uczenie maszynowe i sztuczne sieci neuronowe_cw|Uczenie maszynowe i sztuczne sieci neuronowe]]--&amp;gt;&lt;br /&gt;
* Warsztaty [[Metody diagnostyczne]]&lt;br /&gt;
* Warsztaty [[Warsztaty_z_Metod_Terapeutycznych|z Metod Terapeutycznych]] (dla specjalności Fizyka Medyczna)&lt;br /&gt;
* Warsztaty [[Modelowanie molekularne 2]]&lt;br /&gt;
&lt;br /&gt;
== Pracownie specjalistyczne: ==&lt;br /&gt;
 [[Plik:main_eeg1.jpg|220px|right]]&lt;br /&gt;
*[[INFORMACJE O OPROGRAMOWANIU DO PRACOWNI EEG i SYGNAŁÓW BIOELEKTRYCZNYCH]]&lt;br /&gt;
*[[Pracownia Sygnałów Bioelektrycznych]] (dla specjalności Neuroinformatyka)&lt;br /&gt;
*[[Pracownia EEG|Pracownia EEG]] (dla specjalności Neuroinformatyka)&lt;br /&gt;
*[[Laboratorium EEG|Laboratorium EEG]] (dla specjalności Neuroinformatyka)&lt;br /&gt;
*[[Nowe technologie w fizyce biomedycznej]] (dla specjalności Fizyka Medyczna i Neuroinformatyka)&lt;br /&gt;
*[[USG|Warsztaty z metod obrazowania ultradźwiękowego]]&lt;br /&gt;
&lt;br /&gt;
== Inne: == &lt;br /&gt;
[[Plik:Bookstack.svg|130px|right]]&lt;br /&gt;
&amp;lt;!--* Wykład [[&amp;quot;Własność intelektualna i ochrona danych osobowych&amp;quot;]]--&amp;gt;&lt;br /&gt;
* Pracownia [[&amp;quot;Wykorzystanie zasobów internetowych&amp;quot;]]&lt;br /&gt;
* Proseminarium [[Proseminarium licencjackie|licencjackie]]&lt;br /&gt;
&lt;br /&gt;
==Strony dodatkowe==&lt;br /&gt;
* [[Podręcznik użytkownika systemu do badań dostępnego w laboratorium EEG Wydziału Fizyki Uniwersytetu Warszawskiego]]: http://laboratorium-eeg.braintech.pl/ w tym:&lt;br /&gt;
** dokumentacja SVAROG: http://laboratorium-eeg.braintech.pl/svarog/index.html&lt;br /&gt;
** dokumentacja PSYCHOPY: http://laboratorium-eeg.braintech.pl/psychopy/index.html&lt;br /&gt;
** dokumentacja techniczna BCI framework: http://laboratorium-eeg.braintech.pl/openbci/&lt;br /&gt;
** dokumentacja i tutorial biblioteki ReadManager (Python, Matlab): http://moduly-analizy-danych.braintech.pl/&lt;br /&gt;
&lt;br /&gt;
* [[Instalacja i konfiguracja Kinect, Wiimote i Eyetrackera]]&lt;br /&gt;
* Strona [http://www.fuw.edu.pl/biblioteki.html Biblioteki Wydziału Fizyki]&lt;br /&gt;
* Podręcznik dotyczący stosowania Jupyter notebook do prowadzenia zajęć dydaktycznych: https://jupyter4edu.github.io/jupyter-edu-book/notebooks-in-teaching-and-learning.html&lt;br /&gt;
&lt;br /&gt;
* Podręcznik [https://wuw.pl/data/include/cms/Neurocybernetyka_teoretyczna_Tadeusiewicz_Ryszard_red_nauk_2009.pdf Neurocybernetyka Teoretyczna]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
* Pracownia [[Pracownia Pokazów Wykładowych|Pokazów Wykładowych]]&lt;br /&gt;
* [[Tematy prac licencjackich]]&lt;br /&gt;
* AI, czyli [http://shanghailectures.org/lectures Sztuczna Inteligencja]&lt;br /&gt;
*[[dokumentacja SVAROG]]&lt;br /&gt;
*[[dokumentacja OBCI]]&lt;br /&gt;
--&amp;gt;&lt;/div&gt;</summary>
		<author><name>RobertJB</name></author>
		
	</entry>
	<entry>
		<id>http://brain.fuw.edu.pl/edu/index.php?title=%22Programowanie_z_Pythonem3%22&amp;diff=8691</id>
		<title>&quot;Programowanie z Pythonem3&quot;</title>
		<link rel="alternate" type="text/html" href="http://brain.fuw.edu.pl/edu/index.php?title=%22Programowanie_z_Pythonem3%22&amp;diff=8691"/>
		<updated>2021-09-14T10:13:27Z</updated>

		<summary type="html">&lt;p&gt;RobertJB: /* Uwagi ogólne */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Grafika:Python-logo.png]]&lt;br /&gt;
&lt;br /&gt;
[[Category:Informatyka]]&lt;br /&gt;
== Semestr zimowy 2021/2022 ==&lt;br /&gt;
&lt;br /&gt;
'''''W trakcie opracowania'''''&lt;br /&gt;
&lt;br /&gt;
===Uwagi ogólne===&lt;br /&gt;
&lt;br /&gt;
W pracowniach OKWF zainstalowane są zarówno stara wersja Pythona (2.7), jak i aktualna (3.x). Aktualnie polecenie &amp;lt;tt&amp;gt;python&amp;lt;/tt&amp;gt; uruchamia wersję 2.7; w celu uruchomienia wersji 3 należy pisać &amp;lt;tt&amp;gt;python3&amp;lt;/tt&amp;gt;. Analogicznie, istnieją wywołania &amp;lt;tt&amp;gt;ipython3&amp;lt;/tt&amp;gt; oraz &amp;lt;tt&amp;gt;spyder3&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Zasady zaliczenia ćwiczeń w roku 2021/2022:&lt;br /&gt;
&lt;br /&gt;
* maksymalnie można zdobyć 40 punktów&lt;br /&gt;
* w semestrze będą dwa kolokwia, w połowie i pod koniec; na każdym można zdobyć po 15 punktów&lt;br /&gt;
* w sesji będzie kolokwium dodatkowe, dla chętnych; wynik z niego (maks. 15 punktów) zastępuje gorszy z wyników kolokwiów z semestru, o ile jest on niego lepszy&lt;br /&gt;
* maksymalnie 10 punktów przydziela prowadzący na podstawie zadań domowych i aktywności na ćwiczeniach&lt;br /&gt;
* zaliczenie ćwiczeń na pozytywną ocenę wymaga co najmniej 50% punktów (20 p.)&lt;br /&gt;
* ocena rośnie o pół stopnia z osiągnięciem progu każdych kolejnych 10%, tj. 4 punktów.&lt;br /&gt;
&lt;br /&gt;
Obecność na ćwiczeniach jest obowiązkowa. Dopuszczalne są '''dwie''' nieobecności nieusprawiedliwione w semestrze. '''Za każdą kolejną nieobecność nieusprawiedliwioną powyżej dwóch odejmujemy od wyniku 5 punktów.'''&lt;br /&gt;
&lt;br /&gt;
Ocena końcowa z przedmiotu składa się z oceny z ćwiczeń, oraz z oceny z egzaminu testowego kończącego wykład, w proporcji 3:2 - z tym, że '''obie te oceny cząstkowe muszą być pozytywne''' aby ocena z całości była pozytywna.&lt;br /&gt;
&lt;br /&gt;
===Spis treści===&lt;br /&gt;
&lt;br /&gt;
#[[PPy3/Wprowadzenie|Wprowadzenie]]&lt;br /&gt;
#[[PPy3/PierwszeKroki|Pierwsze kroki]]&lt;br /&gt;
#[[PPy3/StałeIZmienne|Stałe i zmienne]]&lt;br /&gt;
#[[PPy3/InstrukcjaWarunkowa|Instrukcja warunkowa]]&lt;br /&gt;
#[[PPy3/SekwencjeIIteracja|Sekwencje i iteracja]]&lt;br /&gt;
#[[PPy3/Funkcje|Funkcje]]&lt;br /&gt;
#[[PPy3/Kolekcje|Kolekcje]]&lt;br /&gt;
#[[PPy3/Moduły|Moduły i biblioteki]]&lt;br /&gt;
#[[PPy3/WejścieWyjście|Obsługa wejścia i wyjścia]]&lt;br /&gt;
#[[PPy3/NumPy|NumPy]] - rachunki numeryczne na tablicach liczb&lt;br /&gt;
#[[PPy3/Matplotlib|Matplotlib]] - wizualizacja danych&lt;br /&gt;
#[[PPy3/TematyDodatkowe|Tematy dodatkowe]] - uzupełnienie&lt;br /&gt;
#[[PPy3/DobrePraktyki|Zasady dobrej praktyki]]&lt;br /&gt;
&lt;br /&gt;
===O skrypcie===&lt;br /&gt;
&lt;br /&gt;
Opracowane na nowo przez [[Użytkownik:RobertJB|RobertJB]], częściowo z wykorzystaniem [[&amp;quot;Programowanie z Pythonem&amp;quot;|poprzedniej wersji]].&lt;/div&gt;</summary>
		<author><name>RobertJB</name></author>
		
	</entry>
	<entry>
		<id>http://brain.fuw.edu.pl/edu/index.php?title=%22Programowanie_z_Pythonem3%22&amp;diff=8690</id>
		<title>&quot;Programowanie z Pythonem3&quot;</title>
		<link rel="alternate" type="text/html" href="http://brain.fuw.edu.pl/edu/index.php?title=%22Programowanie_z_Pythonem3%22&amp;diff=8690"/>
		<updated>2021-09-14T10:13:03Z</updated>

		<summary type="html">&lt;p&gt;RobertJB: /* Semestr zimowy 2020/2021 */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Grafika:Python-logo.png]]&lt;br /&gt;
&lt;br /&gt;
[[Category:Informatyka]]&lt;br /&gt;
== Semestr zimowy 2021/2022 ==&lt;br /&gt;
&lt;br /&gt;
'''''W trakcie opracowania'''''&lt;br /&gt;
&lt;br /&gt;
===Uwagi ogólne===&lt;br /&gt;
&lt;br /&gt;
W pracowniach OKWF zainstalowane są zarówno stara wersja Pythona (2.7), jak i aktualna (3.x). Aktualnie polecenie &amp;lt;tt&amp;gt;python&amp;lt;/tt&amp;gt; uruchamia wersję 2.7; w celu uruchomienia wersji 3 należy pisać &amp;lt;tt&amp;gt;python3&amp;lt;/tt&amp;gt;. Analogicznie, istnieją wywołania &amp;lt;tt&amp;gt;ipython3&amp;lt;/tt&amp;gt; oraz &amp;lt;tt&amp;gt;spyder3&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Zasady zaliczenia ćwiczeń w roku 2020/2021:&lt;br /&gt;
&lt;br /&gt;
* maksymalnie można zdobyć 40 punktów&lt;br /&gt;
* w semestrze będą dwa kolokwia, w połowie i pod koniec; na każdym można zdobyć po 15 punktów&lt;br /&gt;
* w sesji będzie kolokwium dodatkowe, dla chętnych; wynik z niego (maks. 15 punktów) zastępuje gorszy z wyników kolokwiów z semestru, o ile jest on niego lepszy&lt;br /&gt;
* maksymalnie 10 punktów przydziela prowadzący na podstawie zadań domowych i aktywności na ćwiczeniach&lt;br /&gt;
* zaliczenie ćwiczeń na pozytywną ocenę wymaga co najmniej 50% punktów (20 p.)&lt;br /&gt;
* ocena rośnie o pół stopnia z osiągnięciem progu każdych kolejnych 10%, tj. 4 punktów.&lt;br /&gt;
&lt;br /&gt;
Obecność na ćwiczeniach jest obowiązkowa. Dopuszczalne są '''dwie''' nieobecności nieusprawiedliwione w semestrze. '''Za każdą kolejną nieobecność nieusprawiedliwioną powyżej dwóch odejmujemy od wyniku 5 punktów.'''&lt;br /&gt;
&lt;br /&gt;
Ocena końcowa z przedmiotu składa się z oceny z ćwiczeń, oraz z oceny z egzaminu testowego kończącego wykład, w proporcji 3:2 - z tym, że '''obie te oceny cząstkowe muszą być pozytywne''' aby ocena z całości była pozytywna.&lt;br /&gt;
&lt;br /&gt;
===Spis treści===&lt;br /&gt;
&lt;br /&gt;
#[[PPy3/Wprowadzenie|Wprowadzenie]]&lt;br /&gt;
#[[PPy3/PierwszeKroki|Pierwsze kroki]]&lt;br /&gt;
#[[PPy3/StałeIZmienne|Stałe i zmienne]]&lt;br /&gt;
#[[PPy3/InstrukcjaWarunkowa|Instrukcja warunkowa]]&lt;br /&gt;
#[[PPy3/SekwencjeIIteracja|Sekwencje i iteracja]]&lt;br /&gt;
#[[PPy3/Funkcje|Funkcje]]&lt;br /&gt;
#[[PPy3/Kolekcje|Kolekcje]]&lt;br /&gt;
#[[PPy3/Moduły|Moduły i biblioteki]]&lt;br /&gt;
#[[PPy3/WejścieWyjście|Obsługa wejścia i wyjścia]]&lt;br /&gt;
#[[PPy3/NumPy|NumPy]] - rachunki numeryczne na tablicach liczb&lt;br /&gt;
#[[PPy3/Matplotlib|Matplotlib]] - wizualizacja danych&lt;br /&gt;
#[[PPy3/TematyDodatkowe|Tematy dodatkowe]] - uzupełnienie&lt;br /&gt;
#[[PPy3/DobrePraktyki|Zasady dobrej praktyki]]&lt;br /&gt;
&lt;br /&gt;
===O skrypcie===&lt;br /&gt;
&lt;br /&gt;
Opracowane na nowo przez [[Użytkownik:RobertJB|RobertJB]], częściowo z wykorzystaniem [[&amp;quot;Programowanie z Pythonem&amp;quot;|poprzedniej wersji]].&lt;/div&gt;</summary>
		<author><name>RobertJB</name></author>
		
	</entry>
	<entry>
		<id>http://brain.fuw.edu.pl/edu/index.php?title=%22Programowanie_z_Pythonem3%22&amp;diff=8652</id>
		<title>&quot;Programowanie z Pythonem3&quot;</title>
		<link rel="alternate" type="text/html" href="http://brain.fuw.edu.pl/edu/index.php?title=%22Programowanie_z_Pythonem3%22&amp;diff=8652"/>
		<updated>2021-05-13T09:58:27Z</updated>

		<summary type="html">&lt;p&gt;RobertJB: python logo&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Grafika:Python-logo.png]]&lt;br /&gt;
&lt;br /&gt;
[[Category:Informatyka]]&lt;br /&gt;
== Semestr zimowy 2020/2021 ==&lt;br /&gt;
&lt;br /&gt;
'''''W trakcie opracowania'''''&lt;br /&gt;
&lt;br /&gt;
===Uwagi ogólne===&lt;br /&gt;
&lt;br /&gt;
W pracowniach OKWF zainstalowane są zarówno stara wersja Pythona (2.7), jak i aktualna (3.x). Aktualnie polecenie &amp;lt;tt&amp;gt;python&amp;lt;/tt&amp;gt; uruchamia wersję 2.7; w celu uruchomienia wersji 3 należy pisać &amp;lt;tt&amp;gt;python3&amp;lt;/tt&amp;gt;. Analogicznie, istnieją wywołania &amp;lt;tt&amp;gt;ipython3&amp;lt;/tt&amp;gt; oraz &amp;lt;tt&amp;gt;spyder3&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Zasady zaliczenia ćwiczeń w roku 2020/2021:&lt;br /&gt;
&lt;br /&gt;
* maksymalnie można zdobyć 40 punktów&lt;br /&gt;
* w semestrze będą dwa kolokwia, w połowie i pod koniec; na każdym można zdobyć po 15 punktów&lt;br /&gt;
* w sesji będzie kolokwium dodatkowe, dla chętnych; wynik z niego (maks. 15 punktów) zastępuje gorszy z wyników kolokwiów z semestru, o ile jest on niego lepszy&lt;br /&gt;
* maksymalnie 10 punktów przydziela prowadzący na podstawie zadań domowych i aktywności na ćwiczeniach&lt;br /&gt;
* zaliczenie ćwiczeń na pozytywną ocenę wymaga co najmniej 50% punktów (20 p.)&lt;br /&gt;
* ocena rośnie o pół stopnia z osiągnięciem progu każdych kolejnych 10%, tj. 4 punktów.&lt;br /&gt;
&lt;br /&gt;
Obecność na ćwiczeniach jest obowiązkowa. Dopuszczalne są '''dwie''' nieobecności nieusprawiedliwione w semestrze. '''Za każdą kolejną nieobecność nieusprawiedliwioną powyżej dwóch odejmujemy od wyniku 5 punktów.'''&lt;br /&gt;
&lt;br /&gt;
Ocena końcowa z przedmiotu składa się z oceny z ćwiczeń, oraz z oceny z egzaminu testowego kończącego wykład, w proporcji 3:2 - z tym, że '''obie te oceny cząstkowe muszą być pozytywne''' aby ocena z całości była pozytywna.&lt;br /&gt;
&lt;br /&gt;
===Spis treści===&lt;br /&gt;
&lt;br /&gt;
#[[PPy3/Wprowadzenie|Wprowadzenie]]&lt;br /&gt;
#[[PPy3/PierwszeKroki|Pierwsze kroki]]&lt;br /&gt;
#[[PPy3/StałeIZmienne|Stałe i zmienne]]&lt;br /&gt;
#[[PPy3/InstrukcjaWarunkowa|Instrukcja warunkowa]]&lt;br /&gt;
#[[PPy3/SekwencjeIIteracja|Sekwencje i iteracja]]&lt;br /&gt;
#[[PPy3/Funkcje|Funkcje]]&lt;br /&gt;
#[[PPy3/Kolekcje|Kolekcje]]&lt;br /&gt;
#[[PPy3/Moduły|Moduły i biblioteki]]&lt;br /&gt;
#[[PPy3/WejścieWyjście|Obsługa wejścia i wyjścia]]&lt;br /&gt;
#[[PPy3/NumPy|NumPy]] - rachunki numeryczne na tablicach liczb&lt;br /&gt;
#[[PPy3/Matplotlib|Matplotlib]] - wizualizacja danych&lt;br /&gt;
#[[PPy3/TematyDodatkowe|Tematy dodatkowe]] - uzupełnienie&lt;br /&gt;
#[[PPy3/DobrePraktyki|Zasady dobrej praktyki]]&lt;br /&gt;
&lt;br /&gt;
===O skrypcie===&lt;br /&gt;
&lt;br /&gt;
Opracowane na nowo przez [[Użytkownik:RobertJB|RobertJB]], częściowo z wykorzystaniem [[&amp;quot;Programowanie z Pythonem&amp;quot;|poprzedniej wersji]].&lt;/div&gt;</summary>
		<author><name>RobertJB</name></author>
		
	</entry>
	<entry>
		<id>http://brain.fuw.edu.pl/edu/index.php?title=Plik:Python-logo.png&amp;diff=8651</id>
		<title>Plik:Python-logo.png</title>
		<link rel="alternate" type="text/html" href="http://brain.fuw.edu.pl/edu/index.php?title=Plik:Python-logo.png&amp;diff=8651"/>
		<updated>2021-05-13T09:55:07Z</updated>

		<summary type="html">&lt;p&gt;RobertJB: Python Logo&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Opis ==&lt;br /&gt;
Python Logo&lt;/div&gt;</summary>
		<author><name>RobertJB</name></author>
		
	</entry>
	<entry>
		<id>http://brain.fuw.edu.pl/edu/index.php?title=PPy3/Matplotlib&amp;diff=8500</id>
		<title>PPy3/Matplotlib</title>
		<link rel="alternate" type="text/html" href="http://brain.fuw.edu.pl/edu/index.php?title=PPy3/Matplotlib&amp;diff=8500"/>
		<updated>2021-01-08T09:45:01Z</updated>

		<summary type="html">&lt;p&gt;RobertJB: /* Przykład bardziej zaawansowany */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Matplotlib - wizualizacja danych = &lt;br /&gt;
&lt;br /&gt;
== Wprowadzenie do pakietu Matplotlib na przykładach ==&lt;br /&gt;
&lt;br /&gt;
Pakiet Matplotlib bazuje na pakiecie numerycznym Numpy i korzysta z obiektów w nim zawartych. Pokażemy, jak z jego pomocą rysować różnorodne wykresy prezentujące graficznie przetwarzane dane i wyniki obliczeń. Zamiast wyliczać zawartość pakietu  pokażemy ich użyteczność na przykładach. Zaczniemy od prostych i będziemy po drodze omawiać zastosowane w nich konstrukcje.&lt;br /&gt;
&lt;br /&gt;
== Wykresy funkcji ==&lt;br /&gt;
&lt;br /&gt;
===''y'' = ''f''(''x'')===&lt;br /&gt;
&lt;br /&gt;
Prześledźmy działanie poniższego programu:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang = python&amp;gt;&lt;br /&gt;
import matplotlib.pyplot as plt&lt;br /&gt;
x = [1,2,3]&lt;br /&gt;
y = [4,6,5]&lt;br /&gt;
plt.plot(x,y)&lt;br /&gt;
plt.show()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
; Rezultat&lt;br /&gt;
[[Grafika:Wykres1.gif]]&lt;br /&gt;
&lt;br /&gt;
; Jak to działa?&lt;br /&gt;
&lt;br /&gt;
Aby skorzystać z pakietu graficznego Matplotlib importujemy go do naszego programu poleceniem &amp;lt;tt&amp;gt;import&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&lt;br /&gt;
Pod-pakiet pyplot jest jednym z paru nieco różnych ''interfejsów'' do Matplotlib - tj. sposobów wykorzystania&lt;br /&gt;
jego funkcjonalności. Inny, też często wykorzystywany, nazywa się &amp;lt;tt&amp;gt;pylab&amp;lt;/tt&amp;gt; i można go importować wprost&lt;br /&gt;
(&amp;lt;tt&amp;gt;import pylab&amp;lt;/tt&amp;gt;). Pyplot zapewnie nieco większą elastyczność, chociaż dla najprostszych przykładów - &lt;br /&gt;
takich, jakie tu omówimy - nie ma istotnej różnicy.&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wytwarzamy dwie listy &amp;lt;tt&amp;gt;x&amp;lt;/tt&amp;gt; i &amp;lt;tt&amp;gt;y&amp;lt;/tt&amp;gt; zawierające ciągi liczb 1, 2, 3 oraz 4, 6, 5. &lt;br /&gt;
&lt;br /&gt;
Funkcja &amp;lt;tt&amp;gt;plot&amp;lt;/tt&amp;gt; rysuje wykres i umieszcza na nim punkty o współrzędnych zawartych w listach przekazanych jej jako argumenty. Pierwszy argument zawiera współrzędne ''x''-owe kolejnych punktów, a drugi argument współrzędne ''y''-owe kolejnych punktów wykresu. Ponieważ listy mają po trzy elementy, tak więc wykres zawierać będzie trzy punkty o współrzędnych (1, 4), (2, 6) oraz (3, 5). Domyślnie punkty na wykresie łączone są ze sobą niebieską linią ciągłą. To &lt;br /&gt;
oczywiście można zmienić - dodając opcjonalne parametry do wywołania &amp;lt;tt&amp;gt;plot&amp;lt;/tt&amp;gt; można uzyskać linię o innym kolorze, &lt;br /&gt;
linię przerywaną, z kropek, albo w ogóle brak linii - a za to np. duże kropki (trójkąty, gwiazdki, ...) w miejscach&lt;br /&gt;
odpowiadających punktom danych.&lt;br /&gt;
&lt;br /&gt;
Po wywołaniu funkcji &amp;lt;tt&amp;gt;plot&amp;lt;/tt&amp;gt; wykres nie pokazuje się jeszcze na ekranie. Aby go pokazać, używamy funkcji &amp;lt;tt&amp;gt;show&amp;lt;/tt&amp;gt;. Wykres pojawia się na ekranie w osobnym oknie, a Python czeka z wykonywaniem kolejnych instrukcji do momentu zamknięcia okna z wykresem.&lt;br /&gt;
&lt;br /&gt;
W okienku wykresu mamy kilka guzików (po lewej stronie na dole). Służą one do manipulowania wyglądem rysunku. Guzikiem z krzyżykiem możemy zmniejszać/zwiększać skalę na osiach (wciskając prawy guzik myszy i przesuwając kursor po obrazku) oraz przesuwać cały wykres (wciskając lewy guzik myszy i przesuwając kursor po obrazku). Guzik z okienkiem i strzałkami pozwala także zmieniać rozmiar i położenie osi wykresu wewnątrz okna wybierając właściwe wartości. Guzik z domkiem przywraca wyjściowe ustawienia rysunku. Guzik z obrazkiem dyskietki (czy ktoś jeszcze wie, co to takiego?) pozwala&lt;br /&gt;
zachować wykres (jego aktualny stan, czyli z uwzględnieniem dokonanych interaktywnie modyfikacji) jako plik graficzny&lt;br /&gt;
jednego z kilku formatów.&lt;br /&gt;
&lt;br /&gt;
=== Rysujemy wykres funkcji sinus ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang = python&amp;gt;&lt;br /&gt;
import numpy as np&lt;br /&gt;
import matplotlib.pyplot as plt&lt;br /&gt;
x = np.arange(0.0, 2.0, 0.01)&lt;br /&gt;
y = np.sin(2.0*np.pi*x)&lt;br /&gt;
plt.plot(x,y)&lt;br /&gt;
plt.show()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
; Rezultat&lt;br /&gt;
[[Grafika:Wykres2.gif]]&lt;br /&gt;
&lt;br /&gt;
; Jak to działa?&lt;br /&gt;
&lt;br /&gt;
Oprócz funkcji z Matplotlib będziemu tu odwoływać się również wprost do elementów z pakietu NumPy.&lt;br /&gt;
&lt;br /&gt;
Funkcja &amp;lt;tt&amp;gt;arange&amp;lt;/tt&amp;gt; jest podobna do standardowej funkcji &amp;lt;tt&amp;gt;range&amp;lt;/tt&amp;gt; wytwarzającej określone sekwencje liczb w postaci listy. Funkcja &amp;lt;tt&amp;gt;arange&amp;lt;/tt&amp;gt; zamiast listy wytwarza tablicę zawierającą ciąg liczb zmiennoprzecinkowych zaczynający się od pierwszego podanego argumentu funkcji &amp;lt;tt&amp;gt;arange&amp;lt;/tt&amp;gt; (u nas &amp;lt;tt&amp;gt;0.0&amp;lt;/tt&amp;gt;), a kończący się przed drugim argumentem (tradycyjnie, ciąg wynikowy nie zawiera wartości podanej jako drugi argument, u nas &amp;lt;tt&amp;gt;2.0&amp;lt;/tt&amp;gt;). Różnica między elementami wytworzonego ciągu domyślnie wynosi 1, ale jeśli podamy funkcji &amp;lt;tt&amp;gt;arange&amp;lt;/tt&amp;gt; trzeci argument, to definiuje on nową różnicę ciągu, u nas wynosi on &amp;lt;tt&amp;gt;0.01&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Tak więc zmienna &amp;lt;tt&amp;gt;x&amp;lt;/tt&amp;gt; jest tablicą-wektorem zawierającą ciąg liczb od 0 do 1,99 co 0,01 (czyli 0, 0,01, 0,02, ..., 1,98, 1,99).&lt;br /&gt;
&lt;br /&gt;
Funkcja &amp;lt;tt&amp;gt;sin&amp;lt;/tt&amp;gt; służy do obliczania wartości funkcji sinus dla argumentu podanego w radianach. A co u nas jest argumentem tej funkcji? Wyrażenie będące argumentem zawiera mnożenie liczby &amp;lt;tt&amp;gt;2.0&amp;lt;/tt&amp;gt; przez &amp;lt;tt&amp;gt;pi&amp;lt;/tt&amp;gt; (pochodzące z pakietu NumPy), a następnie mnożenie wyniku przez tablicę &amp;lt;tt&amp;gt;x&amp;lt;/tt&amp;gt;. Zmienna &amp;lt;tt&amp;gt;pi&amp;lt;/tt&amp;gt; zawiera przybliżoną wartość matematycznej stałej &amp;amp;pi; &amp;amp;asymp; 3,1415926... Mnożenie liczby i tablicy, jak wiemy z poprzedniego punktu, daje w wyniku tablicę. Oznacza to, że argumentem funkcji &amp;lt;tt&amp;gt;sin&amp;lt;/tt&amp;gt; jest nie liczba, ale tablica! Taka możliwość jest przewidziana przez twórców pakietu Numpy; wynikiem wywołania funkcji jest wtedy  również tablica. Jest ona tej samej długości co tablica będąca argumentem wywołania funkcji.&lt;br /&gt;
&lt;br /&gt;
Tak więc zmienna &amp;lt;tt&amp;gt;y&amp;lt;/tt&amp;gt; zawiera ciąg wartości funkcji sinus policzonych dla wartości zawartych w zmiennej &amp;lt;tt&amp;gt;x&amp;lt;/tt&amp;gt; pomnożonych każda przez 2&amp;amp;pi; (czyli sin(2&amp;amp;pi;&amp;amp;middot;0), sin(2&amp;amp;pi;&amp;amp;middot;0,01), sin(2&amp;amp;pi;&amp;amp;middot;0,02), ..., sin(2&amp;amp;pi;&amp;amp;middot;1,98), sin(2&amp;amp;pi;&amp;amp;middot;1,99)).&lt;br /&gt;
&lt;br /&gt;
Funkcja &amp;lt;tt&amp;gt;plot(x,y)&amp;lt;/tt&amp;gt; narysuje zestaw punktów o współrzędnych (0, sin(2&amp;amp;pi;&amp;amp;middot;0)), (0,01, sin(2&amp;amp;pi;&amp;amp;middot;0,01)), (0,02, sin(2&amp;amp;pi;&amp;amp;middot;0,02)), ..., (1,98, sin(2&amp;amp;pi;&amp;amp;middot;1,98)), (1,99, sin(2&amp;amp;pi;&amp;amp;middot;1,99)) połączonych niebieską linią.&lt;br /&gt;
&lt;br /&gt;
=== Ulepszamy wykres ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang = python&amp;gt;&lt;br /&gt;
import numpy as np&lt;br /&gt;
import matplotlib.pyplot as plt&lt;br /&gt;
&lt;br /&gt;
x = np.arange(0.0, 2.0, 0.01)&lt;br /&gt;
y = np.sin(2.0*p.pi*x)&lt;br /&gt;
plt.plot(x,y,'r:',linewidth=6)&lt;br /&gt;
&lt;br /&gt;
plt.xlabel('Czas')&lt;br /&gt;
plt.ylabel('Pozycja')&lt;br /&gt;
plt.title('Nasz pierwszy wykres')&lt;br /&gt;
plt.grid(True)&lt;br /&gt;
plt.show()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
; Rezultat&lt;br /&gt;
[[Grafika:Wykres3.gif]]&lt;br /&gt;
&lt;br /&gt;
; Jak to działa?&lt;br /&gt;
&lt;br /&gt;
W porównaniu z poprzednim przykładem pojawiło się na wykresie kilka drobnych zmian i &amp;amp;bdquo;ozdobników&amp;amp;rdquo;.&lt;br /&gt;
&lt;br /&gt;
W funkcji &amp;lt;tt&amp;gt;plot&amp;lt;/tt&amp;gt; pojawiły się dwa nowe parametry:&lt;br /&gt;
# &amp;lt;tt&amp;gt;'r:'&amp;lt;/tt&amp;gt; &amp;amp;mdash; ten parametr steruje wyglądem rysowanej linii wykresu. Pierwsza litera tego napisu określa kolor linii (na przykład &amp;lt;tt&amp;gt;r&amp;lt;/tt&amp;gt;: czerwony, &amp;lt;tt&amp;gt;b&amp;lt;/tt&amp;gt;: niebieski, &amp;lt;tt&amp;gt;g&amp;lt;/tt&amp;gt;: zielony, &amp;lt;tt&amp;gt;y&amp;lt;/tt&amp;gt;: żółty, &amp;lt;tt&amp;gt;k&amp;lt;/tt&amp;gt;: czarny). Drugi znak napisu określa wygląd samej linii (np. &amp;lt;tt&amp;gt;-&amp;lt;/tt&amp;gt;: ciągła, &amp;lt;tt&amp;gt;:&amp;lt;/tt&amp;gt;: kropkowana, &amp;lt;tt&amp;gt;o&amp;lt;/tt&amp;gt;: okrągłe punkty bez linii, &amp;lt;tt&amp;gt;+&amp;lt;/tt&amp;gt;: krzyżyki bez linii, itd.).&lt;br /&gt;
# &amp;lt;tt&amp;gt;linewidth=6&amp;lt;/tt&amp;gt; &amp;amp;mdash; ten parametr zmienia grubość rysowanej linii.&lt;br /&gt;
&lt;br /&gt;
Dodaliśmy też wywołania funkcji &amp;lt;tt&amp;gt;xlabel&amp;lt;/tt&amp;gt; i &amp;lt;tt&amp;gt;ylabel&amp;lt;/tt&amp;gt;. Ich argumentami są napisy, które pojawią się jako opisy osi, odpowiednio poziomej i pionowej.&lt;br /&gt;
Wywołanie funkcji &amp;lt;tt&amp;gt;title&amp;lt;/tt&amp;gt; wypisuje przekazany jej napis jako tytuł całego wykresu.&lt;br /&gt;
&lt;br /&gt;
Funkcja &amp;lt;tt&amp;gt;grid&amp;lt;/tt&amp;gt; dorysowuje siatkę prostokątną na wykresie w wybranych punktach opisujących wartości na osiach wykresu. Punkty, w których wybierane są wartości opisane na osiach (ang. ''tick'') są wybierane automatycznie (oczywiście jeśli chcemy, możemy zmieniać ich położenie i opisy odpowiednią funkcją, powiemy o tym później).&lt;br /&gt;
&lt;br /&gt;
=== Kilka wykresów we wspólnych osiach - Pierwsza wersja ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang = python&amp;gt;&lt;br /&gt;
import numpy as np&lt;br /&gt;
import matplotlib.pyplot as plt&lt;br /&gt;
&lt;br /&gt;
x = np.arange(0.0, 2.0, 0.01)&lt;br /&gt;
y1 = np.sin(2.0*p.pi*x)&lt;br /&gt;
y2 = np.cos(2.0*p.pi*x)&lt;br /&gt;
plt.plot(x,y1,'r:',x,y2,'g')&lt;br /&gt;
plt.legend(('dane y1','dane y2'))&lt;br /&gt;
plt.xlabel('Czas')&lt;br /&gt;
plt.ylabel('Pozycja')&lt;br /&gt;
plt.title('Wykres ')&lt;br /&gt;
plt.grid(True)&lt;br /&gt;
plt.show()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
'''Rezultat:'''&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
[[Grafika:Wykres_2_linie.svg‎]]&lt;br /&gt;
&lt;br /&gt;
;Jak to działa?&lt;br /&gt;
&lt;br /&gt;
W jednym układzie współrzędnych możemy narysować wiele wykresów. Robimy to podając w jednym poleceniu &amp;lt;tt&amp;gt;plot&amp;lt;/tt&amp;gt; kolejno zestawy parametrów opisujące poszczególne linie: współrzędne x, współrzędne y, sposób wykreślania linii. Aby łatwo identyfikować linie można dodać legendę poleceniem &amp;lt;tt&amp;gt;legend()&amp;lt;/tt&amp;gt;. Sposób kontrolowania wyglądu i położenia legendy: &amp;lt;tt&amp;gt;help(plt.legend)&amp;lt;/tt&amp;gt; (oczywiście po zaimportowaniu modułu: &amp;lt;tt&amp;gt;import matplotlib.pyplot as plt&amp;lt;/tt&amp;gt; ).&lt;br /&gt;
&lt;br /&gt;
=== Kilka wykresów we wspólnych osiach - Druga wersja ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang = python&amp;gt;&lt;br /&gt;
import numpy as np&lt;br /&gt;
import matplotlib.pyplot as plt&lt;br /&gt;
&lt;br /&gt;
x = np.arange(0.0, 2.0, 0.01)&lt;br /&gt;
y1 = np.sin(2.0*p.pi*x)&lt;br /&gt;
y2 = np.cos(2.0*p.pi*x)&lt;br /&gt;
y = y1*y2&lt;br /&gt;
l1, = plt.plot(x,y,'b')&lt;br /&gt;
l2,l3 = plt.plot(x,y1,'r:',x,y2,'g')&lt;br /&gt;
plt.legend((l2,l3,l1),('dane y1','dane y2','y1*y2'))&lt;br /&gt;
plt.xlabel('Czas')&lt;br /&gt;
plt.ylabel('Pozycja')&lt;br /&gt;
plt.title('Wykres ')&lt;br /&gt;
plt.grid(True)&lt;br /&gt;
plt.show()&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
'''Rezultat:'''&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
[[Grafika:Wykres_3_linie.svg‎]]&lt;br /&gt;
&lt;br /&gt;
;Jak to działa?&lt;br /&gt;
&lt;br /&gt;
Wykresy możemy dodawać do współrzędnych kolejnymi poleceniami &amp;lt;tt&amp;gt;plot&amp;lt;/tt&amp;gt;.&lt;br /&gt;
Funkcja &amp;lt;tt&amp;gt;plot&amp;lt;/tt&amp;gt; zwraca listę linii. Notacja &amp;lt;tt&amp;gt;l1, = plt.plot(x,y,'b')&amp;lt;/tt&amp;gt; wydobywa z listy pierwszą linię (Gdyby po &amp;lt;tt&amp;gt;l1&amp;lt;/tt&amp;gt; nie było przecinka to &amp;lt;tt&amp;gt;l1&amp;lt;/tt&amp;gt; byłoby listą zawierającą jeden obiekt klasy linia ).&lt;br /&gt;
&lt;br /&gt;
Dzięki nazwaniu poszczególnych obiektów linii możemy kontrolować ich kolejność (i obecność) na legendzie.&lt;br /&gt;
&lt;br /&gt;
==Histogram (diagram liczebności)==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
import matplotlib.pyplot as plt&lt;br /&gt;
&lt;br /&gt;
zliczenia = [0, 1, 2, 2, 3, 3, 3, 3, 3, 3, 4, 4, 4, 5, 7]&lt;br /&gt;
plt.hist(zliczenia)&lt;br /&gt;
plt.show()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Rezultat:'''&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
[[Grafika:Hist1.gif]]&lt;br /&gt;
&lt;br /&gt;
;Jak to działa ? &lt;br /&gt;
&lt;br /&gt;
Do zmiennej &amp;lt;tt&amp;gt;zliczenia&amp;lt;/tt&amp;gt; przypisujemy sekwencję z ręcznie podanymi wartościami. &lt;br /&gt;
Zakres zmienności badanych zliczeń (odkładany na osi ''X'') zostanie podzielony na przedziały (ang. ''bin'') o jednakowej &amp;amp;bdquo;szerokości&amp;amp;rdquo;; domyślnie będzie ich 10. Funkcja &amp;lt;tt&amp;gt;hist()&amp;lt;/tt&amp;gt; zlicza wystąpienia wartości w binach i rysuje histogram. Funkcja ta zwraca krotkę (array ze zliczeniami, array z binami, lista zawierająca prostokąty, które histogram rysuje, tzw. obiekty Patch).&lt;br /&gt;
&lt;br /&gt;
Porządek wartości, których histogram zostanie stworzony nie ma znaczenia. Mogą one oczywiście być umieszczone również w tablicy NumPy.&lt;br /&gt;
 &lt;br /&gt;
===Przykład bardziej zaawansowany===&lt;br /&gt;
&lt;br /&gt;
Wyjaśnienie działania znajduje się w komentarzach do programu:&lt;br /&gt;
&amp;lt;source lang = python&amp;gt;&lt;br /&gt;
import numpy as np&lt;br /&gt;
import matplotlib.pyplot as plt&lt;br /&gt;
from scipy.stats import norm&lt;br /&gt;
&lt;br /&gt;
mi, sigma = 100, 15&lt;br /&gt;
x = mi + sigma * np.random.randn(10000)&lt;br /&gt;
# numpy.random.randn zwraca array z liczbami pseudolosowymi&lt;br /&gt;
# pochodzącymi z rozkładu normalnego o średniej 0 i wariancji 1&lt;br /&gt;
# przemnożenie przez odchylenie standandardowe sigma i dodanie śreniej mi&lt;br /&gt;
# transformuje rozkład do rozkładu normalnego o średniej mi i wariancji sigma**2&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
n, bins, patches = plt.hist(x, 50, density=True, &lt;br /&gt;
    facecolor='green', edgecolor='black', alpha=0.75)&lt;br /&gt;
# Tu w jawny sposób odbieramy zwracane przez plt.hist obiekty&lt;br /&gt;
# Zmieniamy też:&lt;br /&gt;
#   - ilość binów na 50&lt;br /&gt;
#   - normujemy histogram do jedności&lt;br /&gt;
#   - ustalamy kolor prostokątów na zielony&lt;br /&gt;
#   - ustawiamy (nie)przezroczystość prostokątów na 0.75&lt;br /&gt;
&lt;br /&gt;
bincenters = 0.5*(bins[1:]+bins[:-1])&lt;br /&gt;
# wytwarzamy array z centrami binów korzystając z granic binów&lt;br /&gt;
# zwróconych przez plt.hist w macierzy bins&lt;br /&gt;
&lt;br /&gt;
y = norm.pdf( bincenters, mi, sigma)&lt;br /&gt;
# obliczamy wartości w normalnym rozkładzie gęstości prawdopodobieństwa&lt;br /&gt;
# o średniej mi i wariancji sigma**2 dla wartości bincenters&lt;br /&gt;
&lt;br /&gt;
l = plt.plot(bincenters, y, 'r--', linewidth=1)&lt;br /&gt;
# do histogramu dorysowujemy linię &lt;br /&gt;
&lt;br /&gt;
plt.show()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Rezultat:'''&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
[[Grafika:Hist2.gif]]&lt;br /&gt;
&lt;br /&gt;
==Krzywa parametryczna==&lt;br /&gt;
&lt;br /&gt;
Rysowanie krzywej danej w postaci parametrycznej niewiele się różni od rysowania wykresu funkcji. Żeby było zabawniej, wykonam jeszcze przy okazji rachunek Monte Carlo oraz jego wizualizację.&lt;br /&gt;
&lt;br /&gt;
Krzywa, jaką tutaj narysujemy to tzw. [https://pl.wikipedia.org/wiki/Lemniskata_Gerona lemniskata Gerona]. Zostanie dodatkowo opisana okręgiem jednostkowym; następnie, wylosuję dużą liczbę punktów o równomiernym rozkładzie leżących w kwadracie opisanym na tym okręgu. Robię tak, ponieważ łatwo mi jest wylosować tablicę wielu liczb z zakresu (0, 1) &amp;amp;mdash; jest do tego gotowa funkcja &amp;lt;tt&amp;gt;numpy.random.random&amp;lt;/tt&amp;gt;, następnie przeskalować i przesunąć je do odcinka (-1, 1). Wreszcie, traktując je jako pary współrzędnych &amp;lt;tt&amp;gt;(x, y)&amp;lt;/tt&amp;gt;, pozostawiam tylko te, które znalazły się we wnętrzu koła jednostkowego (odrzucając pozostałe), i dzielę na te, które znalazły się w obszarze wewnątrz lemniskaty, i te, które znalazły się na zewnątrz. &lt;br /&gt;
&lt;br /&gt;
Intuicyjnie jest dość jasne, że &amp;amp;mdash; o ile losowaliśmy punkty rzeczywiście w sposób równomierny &amp;amp;mdash; stosunek liczby „trafień&amp;quot; w obszar ograniczony lemniskatą do liczby wszystkich „trafień&amp;quot; w obszar koła będzie w przybliżeniu równy stosunkowi pól powierzchni tych obszarów. I na tym tu poprzestaniemy; to, jak dokładne to może być przybliżenie, czyli jakiej wielkości błędu możemy oczekiwać, to już problem na inne zajęcia...&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
import numpy as np&lt;br /&gt;
import matplotlib.pyplot as plt&lt;br /&gt;
&lt;br /&gt;
Φ = np.arange(0, 2*np.pi, 2*np.pi/600)&lt;br /&gt;
X = np.cos(Φ)&lt;br /&gt;
Y = np.sin(2*Φ) / 2 # = np.sin(Φ) * np.cos(Φ)&lt;br /&gt;
plt.axes(aspect='equal') # to mi gwarantuje, że okrąg nie wyjdzie „spłaszczony&amp;quot;&lt;br /&gt;
plt.plot(X, Y, 'b')&lt;br /&gt;
YO = np.sin(Φ)&lt;br /&gt;
plt.plot(X, YO, 'k')&lt;br /&gt;
# biorę całą kupę losowych punktów z przedziału (-1, 1)&lt;br /&gt;
P = np.random.random((100000, 2)) * 2 - 1 # milion par (x, y)&lt;br /&gt;
# wyrzucam te, które są poza kołem x**2 + y**2 &amp;lt; 1&lt;br /&gt;
P = P[(P**2).sum(axis=1) &amp;lt; 1]&lt;br /&gt;
# dzielę na te co wewnątrz lemniskaty, i te co na zewnątrz&lt;br /&gt;
I_in = np.abs(P[:,1]) &amp;lt; np.abs(P[:,0]) * np.sqrt(1 - P[:,0]**2)&lt;br /&gt;
P_in = P[I_in]&lt;br /&gt;
P_out = P[~I_in]&lt;br /&gt;
# maluję wewnętrzne na niebiesko&lt;br /&gt;
plt.plot(P_in[:,0], P_in[:,1], 'b,')&lt;br /&gt;
# a zewnętrzne na czerwono&lt;br /&gt;
plt.plot(P_out[:,0], P_out[:,1], 'r,')&lt;br /&gt;
# powierzchnia to z grubsza stosunek l. punktów wewnętrznych do wszystkich&lt;br /&gt;
S = P_in.size / P.size&lt;br /&gt;
plt.title('Pole pow. wnętrza lemniskaty to ok. {:.3f} pola pow. koła'.format(S))&lt;br /&gt;
plt.show()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Przy okazji, jak widać w kodzie Pythona (wersja 3) można bezproblemowo używać liter z innych alfabetów, nie tylko łacińskiego. Niestety nie wszystkie systemy operacyjne zapewniają bezproblemową obsługę pełnego zestawu liter wszelkich języków, dlatego na ogół wykorzystywanie liter z egzotycznych systemów pisma nie jest szczególnie zalecane.&lt;br /&gt;
&lt;br /&gt;
W wyniku uruchomienia tego programu powinno pojawić się okno z obrazkiem podobnym do poniższego:&lt;br /&gt;
&lt;br /&gt;
[[File:Lemniskata.png]]&lt;br /&gt;
&lt;br /&gt;
==Wizualizacja zawartości tablicy dwuwymiarowej==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
import numpy as np&lt;br /&gt;
import matplotlib.pyplot as plt&lt;br /&gt;
&lt;br /&gt;
A = np.arange(20)&lt;br /&gt;
X, Y = np.meshgrid(A, A)&lt;br /&gt;
Z = X + Y&lt;br /&gt;
plt.imshow(Z, cmap='hot', interpolation='none')&lt;br /&gt;
plt.colorbar()&lt;br /&gt;
plt.show()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Wynik:'''&lt;br /&gt;
&lt;br /&gt;
[[Grafika:Imshow1.png]]&lt;br /&gt;
&lt;br /&gt;
Jak można się domyślić, parametr &amp;lt;tt&amp;gt;cmap&amp;lt;/tt&amp;gt; wywołania funkcji &amp;lt;tt&amp;gt;imshow&amp;lt;/tt&amp;gt; odpowiada za odwzorowanie pomiędzy wartościami elementów tablicy a barwami - jest wiele predefiniowanych takich odwzorowań (''colormaps''), opisanych w dokumentacji. Za pomocą wartości &amp;lt;tt&amp;gt;'none'&amp;lt;/tt&amp;gt; parametru &amp;lt;tt&amp;gt;interpolation&amp;lt;/tt&amp;gt; wyłączyliśmy ,,wygładzanie&amp;quot; obrazu, inne możliwe wartości umożliwiają wybór różnych algorytmów wygładzania. Wywołanie &amp;lt;tt&amp;gt;colorbar&amp;lt;/tt&amp;gt; dostarcza paska wizualizującego odpowiedniość pomiędzy wartościami liczbowy i barwami.&lt;br /&gt;
&lt;br /&gt;
==Plik graficzny jako źródło danych==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
import numpy as np&lt;br /&gt;
import matplotlib.pyplot as plt&lt;br /&gt;
&lt;br /&gt;
img = plt.imread('reading-girl.jpg')&lt;br /&gt;
plt.imshow()&lt;br /&gt;
plt.show()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Wynik:'''&lt;br /&gt;
&lt;br /&gt;
[[Grafika:Imshow-girl-1.jpg]]&lt;br /&gt;
&lt;br /&gt;
Wynikiem wywołania &amp;lt;tt&amp;gt;imread&amp;lt;/tt&amp;gt; jest tablica o kształcie ''(wysokość, szerokość, 3)'' zawierająca dla każdego piksela obrazu wartości jego składowych RGB, tj. natężeń barw: czerwonej, zielonej, i niebieskiej - jako liczby w zakresie od 0 do 255 włącznie. Oczywiście na tej tablicy możemy wykonywać najróżniejsze operacje, analizując treść obrazu czy przekształcając go. Przykładowo:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
img1 = img[:400, -400:] # przycinam obraz do kształtu 400x400 pikseli&lt;br /&gt;
img2 = img1.sum(axis=2)&lt;br /&gt;
img3 = img2 / img2.max()&lt;br /&gt;
plt.imgshow(img3, cmap='bone')&lt;br /&gt;
plt.show()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Wynik:'''&lt;br /&gt;
&lt;br /&gt;
[[Grafika:reading-girl-bone.jpg]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
plt.hist(img3.flatten(), bins=100)&lt;br /&gt;
plt.show()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Wynik:'''&lt;br /&gt;
&lt;br /&gt;
[[Grafika:reading-girl-hist.png]]&lt;br /&gt;
&lt;br /&gt;
Wykonaliśmy w ten sposób histogram opisujący rozkład natężenia pikseli obrazka.&lt;br /&gt;
&lt;br /&gt;
==Wiele wykresów w jednym oknie==&lt;br /&gt;
&lt;br /&gt;
==Ćwiczenia==&lt;br /&gt;
&lt;br /&gt;
1. Spróbuj znaleźć sposób przekształcenia obrazka takiego, jak poniższy portret autora skryptu:&lt;br /&gt;
&lt;br /&gt;
[[Grafika:rjb_small.jpg]]  &lt;br /&gt;
&lt;br /&gt;
do postaci przypominającej &lt;br /&gt;
&lt;br /&gt;
[[Grafika:rjb_bw.png]]&lt;br /&gt;
&lt;br /&gt;
2. (''Nieco złożone'') Napisz program symulujący „bilard na kółku&amp;quot;. Dokładniej: wewnątrz koła jednostkowego na płaszczyźnie porusza się cząstka (punkt), zachowując stałą prędkość &amp;amp;mdash; dopóki nie napotka brzegu, czyli okręgu; wówczas odbija się zgodnie z zasadą, że kąt padania równa się kątowi odbicia; chodzi o kąt pomiędzy wektorem prędkości a promieniem okręgu jednostkowego w miejscu, gdzie tor ruchu przecina się z okręgiem, po odbiciu jest on taki sam co do wartości ale ''po drugiej stronie'' promienia. Program rysuje okręg jednostkowy oraz tor ruchu cząstki wewnątrz tego okręgu, w zależności od początkowego położenia, kierunku początkowej prędkości (wartość prędkości jest nieistotna, ponieważ jest stała), i czasu obserwacji. &lt;br /&gt;
&lt;br /&gt;
Wynikiem programu są wykresy podobne do poniższego:&lt;br /&gt;
&lt;br /&gt;
[[Grafika:bilard_na_kole.png]]&lt;br /&gt;
&lt;br /&gt;
czarną kropką oznaczono położenie początkowe, a na zielono &amp;amp;mdash; końcowe.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
[[PPy3/NumPy|poprzednie]] | [[&amp;quot;Programowanie z Pythonem3&amp;quot;|strona główna]] | [[PPy3/TematyDodatkowe]]&lt;br /&gt;
&lt;br /&gt;
--[[Użytkownik:RobertJB|RobertJB]] ([[Dyskusja użytkownika:RobertJB|dyskusja]]) 14:05, 10 kwi 2017 (CEST)&lt;/div&gt;</summary>
		<author><name>RobertJB</name></author>
		
	</entry>
	<entry>
		<id>http://brain.fuw.edu.pl/edu/index.php?title=PPy3/Matplotlib&amp;diff=8499</id>
		<title>PPy3/Matplotlib</title>
		<link rel="alternate" type="text/html" href="http://brain.fuw.edu.pl/edu/index.php?title=PPy3/Matplotlib&amp;diff=8499"/>
		<updated>2021-01-08T09:44:15Z</updated>

		<summary type="html">&lt;p&gt;RobertJB: /* Przykład bardziej zaawansowany */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Matplotlib - wizualizacja danych = &lt;br /&gt;
&lt;br /&gt;
== Wprowadzenie do pakietu Matplotlib na przykładach ==&lt;br /&gt;
&lt;br /&gt;
Pakiet Matplotlib bazuje na pakiecie numerycznym Numpy i korzysta z obiektów w nim zawartych. Pokażemy, jak z jego pomocą rysować różnorodne wykresy prezentujące graficznie przetwarzane dane i wyniki obliczeń. Zamiast wyliczać zawartość pakietu  pokażemy ich użyteczność na przykładach. Zaczniemy od prostych i będziemy po drodze omawiać zastosowane w nich konstrukcje.&lt;br /&gt;
&lt;br /&gt;
== Wykresy funkcji ==&lt;br /&gt;
&lt;br /&gt;
===''y'' = ''f''(''x'')===&lt;br /&gt;
&lt;br /&gt;
Prześledźmy działanie poniższego programu:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang = python&amp;gt;&lt;br /&gt;
import matplotlib.pyplot as plt&lt;br /&gt;
x = [1,2,3]&lt;br /&gt;
y = [4,6,5]&lt;br /&gt;
plt.plot(x,y)&lt;br /&gt;
plt.show()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
; Rezultat&lt;br /&gt;
[[Grafika:Wykres1.gif]]&lt;br /&gt;
&lt;br /&gt;
; Jak to działa?&lt;br /&gt;
&lt;br /&gt;
Aby skorzystać z pakietu graficznego Matplotlib importujemy go do naszego programu poleceniem &amp;lt;tt&amp;gt;import&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&lt;br /&gt;
Pod-pakiet pyplot jest jednym z paru nieco różnych ''interfejsów'' do Matplotlib - tj. sposobów wykorzystania&lt;br /&gt;
jego funkcjonalności. Inny, też często wykorzystywany, nazywa się &amp;lt;tt&amp;gt;pylab&amp;lt;/tt&amp;gt; i można go importować wprost&lt;br /&gt;
(&amp;lt;tt&amp;gt;import pylab&amp;lt;/tt&amp;gt;). Pyplot zapewnie nieco większą elastyczność, chociaż dla najprostszych przykładów - &lt;br /&gt;
takich, jakie tu omówimy - nie ma istotnej różnicy.&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wytwarzamy dwie listy &amp;lt;tt&amp;gt;x&amp;lt;/tt&amp;gt; i &amp;lt;tt&amp;gt;y&amp;lt;/tt&amp;gt; zawierające ciągi liczb 1, 2, 3 oraz 4, 6, 5. &lt;br /&gt;
&lt;br /&gt;
Funkcja &amp;lt;tt&amp;gt;plot&amp;lt;/tt&amp;gt; rysuje wykres i umieszcza na nim punkty o współrzędnych zawartych w listach przekazanych jej jako argumenty. Pierwszy argument zawiera współrzędne ''x''-owe kolejnych punktów, a drugi argument współrzędne ''y''-owe kolejnych punktów wykresu. Ponieważ listy mają po trzy elementy, tak więc wykres zawierać będzie trzy punkty o współrzędnych (1, 4), (2, 6) oraz (3, 5). Domyślnie punkty na wykresie łączone są ze sobą niebieską linią ciągłą. To &lt;br /&gt;
oczywiście można zmienić - dodając opcjonalne parametry do wywołania &amp;lt;tt&amp;gt;plot&amp;lt;/tt&amp;gt; można uzyskać linię o innym kolorze, &lt;br /&gt;
linię przerywaną, z kropek, albo w ogóle brak linii - a za to np. duże kropki (trójkąty, gwiazdki, ...) w miejscach&lt;br /&gt;
odpowiadających punktom danych.&lt;br /&gt;
&lt;br /&gt;
Po wywołaniu funkcji &amp;lt;tt&amp;gt;plot&amp;lt;/tt&amp;gt; wykres nie pokazuje się jeszcze na ekranie. Aby go pokazać, używamy funkcji &amp;lt;tt&amp;gt;show&amp;lt;/tt&amp;gt;. Wykres pojawia się na ekranie w osobnym oknie, a Python czeka z wykonywaniem kolejnych instrukcji do momentu zamknięcia okna z wykresem.&lt;br /&gt;
&lt;br /&gt;
W okienku wykresu mamy kilka guzików (po lewej stronie na dole). Służą one do manipulowania wyglądem rysunku. Guzikiem z krzyżykiem możemy zmniejszać/zwiększać skalę na osiach (wciskając prawy guzik myszy i przesuwając kursor po obrazku) oraz przesuwać cały wykres (wciskając lewy guzik myszy i przesuwając kursor po obrazku). Guzik z okienkiem i strzałkami pozwala także zmieniać rozmiar i położenie osi wykresu wewnątrz okna wybierając właściwe wartości. Guzik z domkiem przywraca wyjściowe ustawienia rysunku. Guzik z obrazkiem dyskietki (czy ktoś jeszcze wie, co to takiego?) pozwala&lt;br /&gt;
zachować wykres (jego aktualny stan, czyli z uwzględnieniem dokonanych interaktywnie modyfikacji) jako plik graficzny&lt;br /&gt;
jednego z kilku formatów.&lt;br /&gt;
&lt;br /&gt;
=== Rysujemy wykres funkcji sinus ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang = python&amp;gt;&lt;br /&gt;
import numpy as np&lt;br /&gt;
import matplotlib.pyplot as plt&lt;br /&gt;
x = np.arange(0.0, 2.0, 0.01)&lt;br /&gt;
y = np.sin(2.0*np.pi*x)&lt;br /&gt;
plt.plot(x,y)&lt;br /&gt;
plt.show()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
; Rezultat&lt;br /&gt;
[[Grafika:Wykres2.gif]]&lt;br /&gt;
&lt;br /&gt;
; Jak to działa?&lt;br /&gt;
&lt;br /&gt;
Oprócz funkcji z Matplotlib będziemu tu odwoływać się również wprost do elementów z pakietu NumPy.&lt;br /&gt;
&lt;br /&gt;
Funkcja &amp;lt;tt&amp;gt;arange&amp;lt;/tt&amp;gt; jest podobna do standardowej funkcji &amp;lt;tt&amp;gt;range&amp;lt;/tt&amp;gt; wytwarzającej określone sekwencje liczb w postaci listy. Funkcja &amp;lt;tt&amp;gt;arange&amp;lt;/tt&amp;gt; zamiast listy wytwarza tablicę zawierającą ciąg liczb zmiennoprzecinkowych zaczynający się od pierwszego podanego argumentu funkcji &amp;lt;tt&amp;gt;arange&amp;lt;/tt&amp;gt; (u nas &amp;lt;tt&amp;gt;0.0&amp;lt;/tt&amp;gt;), a kończący się przed drugim argumentem (tradycyjnie, ciąg wynikowy nie zawiera wartości podanej jako drugi argument, u nas &amp;lt;tt&amp;gt;2.0&amp;lt;/tt&amp;gt;). Różnica między elementami wytworzonego ciągu domyślnie wynosi 1, ale jeśli podamy funkcji &amp;lt;tt&amp;gt;arange&amp;lt;/tt&amp;gt; trzeci argument, to definiuje on nową różnicę ciągu, u nas wynosi on &amp;lt;tt&amp;gt;0.01&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Tak więc zmienna &amp;lt;tt&amp;gt;x&amp;lt;/tt&amp;gt; jest tablicą-wektorem zawierającą ciąg liczb od 0 do 1,99 co 0,01 (czyli 0, 0,01, 0,02, ..., 1,98, 1,99).&lt;br /&gt;
&lt;br /&gt;
Funkcja &amp;lt;tt&amp;gt;sin&amp;lt;/tt&amp;gt; służy do obliczania wartości funkcji sinus dla argumentu podanego w radianach. A co u nas jest argumentem tej funkcji? Wyrażenie będące argumentem zawiera mnożenie liczby &amp;lt;tt&amp;gt;2.0&amp;lt;/tt&amp;gt; przez &amp;lt;tt&amp;gt;pi&amp;lt;/tt&amp;gt; (pochodzące z pakietu NumPy), a następnie mnożenie wyniku przez tablicę &amp;lt;tt&amp;gt;x&amp;lt;/tt&amp;gt;. Zmienna &amp;lt;tt&amp;gt;pi&amp;lt;/tt&amp;gt; zawiera przybliżoną wartość matematycznej stałej &amp;amp;pi; &amp;amp;asymp; 3,1415926... Mnożenie liczby i tablicy, jak wiemy z poprzedniego punktu, daje w wyniku tablicę. Oznacza to, że argumentem funkcji &amp;lt;tt&amp;gt;sin&amp;lt;/tt&amp;gt; jest nie liczba, ale tablica! Taka możliwość jest przewidziana przez twórców pakietu Numpy; wynikiem wywołania funkcji jest wtedy  również tablica. Jest ona tej samej długości co tablica będąca argumentem wywołania funkcji.&lt;br /&gt;
&lt;br /&gt;
Tak więc zmienna &amp;lt;tt&amp;gt;y&amp;lt;/tt&amp;gt; zawiera ciąg wartości funkcji sinus policzonych dla wartości zawartych w zmiennej &amp;lt;tt&amp;gt;x&amp;lt;/tt&amp;gt; pomnożonych każda przez 2&amp;amp;pi; (czyli sin(2&amp;amp;pi;&amp;amp;middot;0), sin(2&amp;amp;pi;&amp;amp;middot;0,01), sin(2&amp;amp;pi;&amp;amp;middot;0,02), ..., sin(2&amp;amp;pi;&amp;amp;middot;1,98), sin(2&amp;amp;pi;&amp;amp;middot;1,99)).&lt;br /&gt;
&lt;br /&gt;
Funkcja &amp;lt;tt&amp;gt;plot(x,y)&amp;lt;/tt&amp;gt; narysuje zestaw punktów o współrzędnych (0, sin(2&amp;amp;pi;&amp;amp;middot;0)), (0,01, sin(2&amp;amp;pi;&amp;amp;middot;0,01)), (0,02, sin(2&amp;amp;pi;&amp;amp;middot;0,02)), ..., (1,98, sin(2&amp;amp;pi;&amp;amp;middot;1,98)), (1,99, sin(2&amp;amp;pi;&amp;amp;middot;1,99)) połączonych niebieską linią.&lt;br /&gt;
&lt;br /&gt;
=== Ulepszamy wykres ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang = python&amp;gt;&lt;br /&gt;
import numpy as np&lt;br /&gt;
import matplotlib.pyplot as plt&lt;br /&gt;
&lt;br /&gt;
x = np.arange(0.0, 2.0, 0.01)&lt;br /&gt;
y = np.sin(2.0*p.pi*x)&lt;br /&gt;
plt.plot(x,y,'r:',linewidth=6)&lt;br /&gt;
&lt;br /&gt;
plt.xlabel('Czas')&lt;br /&gt;
plt.ylabel('Pozycja')&lt;br /&gt;
plt.title('Nasz pierwszy wykres')&lt;br /&gt;
plt.grid(True)&lt;br /&gt;
plt.show()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
; Rezultat&lt;br /&gt;
[[Grafika:Wykres3.gif]]&lt;br /&gt;
&lt;br /&gt;
; Jak to działa?&lt;br /&gt;
&lt;br /&gt;
W porównaniu z poprzednim przykładem pojawiło się na wykresie kilka drobnych zmian i &amp;amp;bdquo;ozdobników&amp;amp;rdquo;.&lt;br /&gt;
&lt;br /&gt;
W funkcji &amp;lt;tt&amp;gt;plot&amp;lt;/tt&amp;gt; pojawiły się dwa nowe parametry:&lt;br /&gt;
# &amp;lt;tt&amp;gt;'r:'&amp;lt;/tt&amp;gt; &amp;amp;mdash; ten parametr steruje wyglądem rysowanej linii wykresu. Pierwsza litera tego napisu określa kolor linii (na przykład &amp;lt;tt&amp;gt;r&amp;lt;/tt&amp;gt;: czerwony, &amp;lt;tt&amp;gt;b&amp;lt;/tt&amp;gt;: niebieski, &amp;lt;tt&amp;gt;g&amp;lt;/tt&amp;gt;: zielony, &amp;lt;tt&amp;gt;y&amp;lt;/tt&amp;gt;: żółty, &amp;lt;tt&amp;gt;k&amp;lt;/tt&amp;gt;: czarny). Drugi znak napisu określa wygląd samej linii (np. &amp;lt;tt&amp;gt;-&amp;lt;/tt&amp;gt;: ciągła, &amp;lt;tt&amp;gt;:&amp;lt;/tt&amp;gt;: kropkowana, &amp;lt;tt&amp;gt;o&amp;lt;/tt&amp;gt;: okrągłe punkty bez linii, &amp;lt;tt&amp;gt;+&amp;lt;/tt&amp;gt;: krzyżyki bez linii, itd.).&lt;br /&gt;
# &amp;lt;tt&amp;gt;linewidth=6&amp;lt;/tt&amp;gt; &amp;amp;mdash; ten parametr zmienia grubość rysowanej linii.&lt;br /&gt;
&lt;br /&gt;
Dodaliśmy też wywołania funkcji &amp;lt;tt&amp;gt;xlabel&amp;lt;/tt&amp;gt; i &amp;lt;tt&amp;gt;ylabel&amp;lt;/tt&amp;gt;. Ich argumentami są napisy, które pojawią się jako opisy osi, odpowiednio poziomej i pionowej.&lt;br /&gt;
Wywołanie funkcji &amp;lt;tt&amp;gt;title&amp;lt;/tt&amp;gt; wypisuje przekazany jej napis jako tytuł całego wykresu.&lt;br /&gt;
&lt;br /&gt;
Funkcja &amp;lt;tt&amp;gt;grid&amp;lt;/tt&amp;gt; dorysowuje siatkę prostokątną na wykresie w wybranych punktach opisujących wartości na osiach wykresu. Punkty, w których wybierane są wartości opisane na osiach (ang. ''tick'') są wybierane automatycznie (oczywiście jeśli chcemy, możemy zmieniać ich położenie i opisy odpowiednią funkcją, powiemy o tym później).&lt;br /&gt;
&lt;br /&gt;
=== Kilka wykresów we wspólnych osiach - Pierwsza wersja ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang = python&amp;gt;&lt;br /&gt;
import numpy as np&lt;br /&gt;
import matplotlib.pyplot as plt&lt;br /&gt;
&lt;br /&gt;
x = np.arange(0.0, 2.0, 0.01)&lt;br /&gt;
y1 = np.sin(2.0*p.pi*x)&lt;br /&gt;
y2 = np.cos(2.0*p.pi*x)&lt;br /&gt;
plt.plot(x,y1,'r:',x,y2,'g')&lt;br /&gt;
plt.legend(('dane y1','dane y2'))&lt;br /&gt;
plt.xlabel('Czas')&lt;br /&gt;
plt.ylabel('Pozycja')&lt;br /&gt;
plt.title('Wykres ')&lt;br /&gt;
plt.grid(True)&lt;br /&gt;
plt.show()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
'''Rezultat:'''&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
[[Grafika:Wykres_2_linie.svg‎]]&lt;br /&gt;
&lt;br /&gt;
;Jak to działa?&lt;br /&gt;
&lt;br /&gt;
W jednym układzie współrzędnych możemy narysować wiele wykresów. Robimy to podając w jednym poleceniu &amp;lt;tt&amp;gt;plot&amp;lt;/tt&amp;gt; kolejno zestawy parametrów opisujące poszczególne linie: współrzędne x, współrzędne y, sposób wykreślania linii. Aby łatwo identyfikować linie można dodać legendę poleceniem &amp;lt;tt&amp;gt;legend()&amp;lt;/tt&amp;gt;. Sposób kontrolowania wyglądu i położenia legendy: &amp;lt;tt&amp;gt;help(plt.legend)&amp;lt;/tt&amp;gt; (oczywiście po zaimportowaniu modułu: &amp;lt;tt&amp;gt;import matplotlib.pyplot as plt&amp;lt;/tt&amp;gt; ).&lt;br /&gt;
&lt;br /&gt;
=== Kilka wykresów we wspólnych osiach - Druga wersja ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang = python&amp;gt;&lt;br /&gt;
import numpy as np&lt;br /&gt;
import matplotlib.pyplot as plt&lt;br /&gt;
&lt;br /&gt;
x = np.arange(0.0, 2.0, 0.01)&lt;br /&gt;
y1 = np.sin(2.0*p.pi*x)&lt;br /&gt;
y2 = np.cos(2.0*p.pi*x)&lt;br /&gt;
y = y1*y2&lt;br /&gt;
l1, = plt.plot(x,y,'b')&lt;br /&gt;
l2,l3 = plt.plot(x,y1,'r:',x,y2,'g')&lt;br /&gt;
plt.legend((l2,l3,l1),('dane y1','dane y2','y1*y2'))&lt;br /&gt;
plt.xlabel('Czas')&lt;br /&gt;
plt.ylabel('Pozycja')&lt;br /&gt;
plt.title('Wykres ')&lt;br /&gt;
plt.grid(True)&lt;br /&gt;
plt.show()&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
'''Rezultat:'''&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
[[Grafika:Wykres_3_linie.svg‎]]&lt;br /&gt;
&lt;br /&gt;
;Jak to działa?&lt;br /&gt;
&lt;br /&gt;
Wykresy możemy dodawać do współrzędnych kolejnymi poleceniami &amp;lt;tt&amp;gt;plot&amp;lt;/tt&amp;gt;.&lt;br /&gt;
Funkcja &amp;lt;tt&amp;gt;plot&amp;lt;/tt&amp;gt; zwraca listę linii. Notacja &amp;lt;tt&amp;gt;l1, = plt.plot(x,y,'b')&amp;lt;/tt&amp;gt; wydobywa z listy pierwszą linię (Gdyby po &amp;lt;tt&amp;gt;l1&amp;lt;/tt&amp;gt; nie było przecinka to &amp;lt;tt&amp;gt;l1&amp;lt;/tt&amp;gt; byłoby listą zawierającą jeden obiekt klasy linia ).&lt;br /&gt;
&lt;br /&gt;
Dzięki nazwaniu poszczególnych obiektów linii możemy kontrolować ich kolejność (i obecność) na legendzie.&lt;br /&gt;
&lt;br /&gt;
==Histogram (diagram liczebności)==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
import matplotlib.pyplot as plt&lt;br /&gt;
&lt;br /&gt;
zliczenia = [0, 1, 2, 2, 3, 3, 3, 3, 3, 3, 4, 4, 4, 5, 7]&lt;br /&gt;
plt.hist(zliczenia)&lt;br /&gt;
plt.show()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Rezultat:'''&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
[[Grafika:Hist1.gif]]&lt;br /&gt;
&lt;br /&gt;
;Jak to działa ? &lt;br /&gt;
&lt;br /&gt;
Do zmiennej &amp;lt;tt&amp;gt;zliczenia&amp;lt;/tt&amp;gt; przypisujemy sekwencję z ręcznie podanymi wartościami. &lt;br /&gt;
Zakres zmienności badanych zliczeń (odkładany na osi ''X'') zostanie podzielony na przedziały (ang. ''bin'') o jednakowej &amp;amp;bdquo;szerokości&amp;amp;rdquo;; domyślnie będzie ich 10. Funkcja &amp;lt;tt&amp;gt;hist()&amp;lt;/tt&amp;gt; zlicza wystąpienia wartości w binach i rysuje histogram. Funkcja ta zwraca krotkę (array ze zliczeniami, array z binami, lista zawierająca prostokąty, które histogram rysuje, tzw. obiekty Patch).&lt;br /&gt;
&lt;br /&gt;
Porządek wartości, których histogram zostanie stworzony nie ma znaczenia. Mogą one oczywiście być umieszczone również w tablicy NumPy.&lt;br /&gt;
 &lt;br /&gt;
===Przykład bardziej zaawansowany===&lt;br /&gt;
&lt;br /&gt;
Wyjaśnienie działania znajduje się w komentarzach do programu:&lt;br /&gt;
&amp;lt;source lang = python&amp;gt;&lt;br /&gt;
import numpy as np&lt;br /&gt;
import matplotlib.pyplot as plt&lt;br /&gt;
from scipy.stats import norm&lt;br /&gt;
&lt;br /&gt;
mi, sigma = 100, 15&lt;br /&gt;
x = mi + sigma * np.random.randn(10000)&lt;br /&gt;
# numpy.random.randn zwraca array z liczbami pseudolosowymi&lt;br /&gt;
# pochodzącymi z rozkładu normalnego o średniej 0 i wariancji 1&lt;br /&gt;
# przemnożenie przez odchylenie standandardowe sigma i dodanie śreniej mi&lt;br /&gt;
# transformuje rozkład do rozkładu normalnego o średniej mi i wariancji sigma**2&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
n, bins, patches = plt.hist(x, 50, normed=True, &lt;br /&gt;
    facecolor='green', edgecolor='black', alpha=0.75)&lt;br /&gt;
# Tu w jawny sposób odbieramy zwracane przez plt.hist obiekty&lt;br /&gt;
# Zmieniamy też:&lt;br /&gt;
#   - ilość binów na 50&lt;br /&gt;
#   - normujemy histogram do jedności&lt;br /&gt;
#   - ustalamy kolor prostokątów na zielony&lt;br /&gt;
#   - ustawiamy (nie)przezroczystość prostokątów na 0.75&lt;br /&gt;
&lt;br /&gt;
bincenters = 0.5*(bins[1:]+bins[:-1])&lt;br /&gt;
# wytwarzamy array z centrami binów korzystając z granic binów&lt;br /&gt;
# zwróconych przez plt.hist w macierzy bins&lt;br /&gt;
&lt;br /&gt;
y = norm.pdf( bincenters, mi, sigma)&lt;br /&gt;
# obliczamy wartości w normalnym rozkładzie gęstości prawdopodobieństwa&lt;br /&gt;
# o średniej mi i wariancji sigma**2 dla wartości bincenters&lt;br /&gt;
&lt;br /&gt;
l = plt.plot(bincenters, y, 'r--', linewidth=1)&lt;br /&gt;
# do histogramu dorysowujemy linię &lt;br /&gt;
&lt;br /&gt;
plt.show()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Rezultat:'''&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
[[Grafika:Hist2.gif]]&lt;br /&gt;
&lt;br /&gt;
==Krzywa parametryczna==&lt;br /&gt;
&lt;br /&gt;
Rysowanie krzywej danej w postaci parametrycznej niewiele się różni od rysowania wykresu funkcji. Żeby było zabawniej, wykonam jeszcze przy okazji rachunek Monte Carlo oraz jego wizualizację.&lt;br /&gt;
&lt;br /&gt;
Krzywa, jaką tutaj narysujemy to tzw. [https://pl.wikipedia.org/wiki/Lemniskata_Gerona lemniskata Gerona]. Zostanie dodatkowo opisana okręgiem jednostkowym; następnie, wylosuję dużą liczbę punktów o równomiernym rozkładzie leżących w kwadracie opisanym na tym okręgu. Robię tak, ponieważ łatwo mi jest wylosować tablicę wielu liczb z zakresu (0, 1) &amp;amp;mdash; jest do tego gotowa funkcja &amp;lt;tt&amp;gt;numpy.random.random&amp;lt;/tt&amp;gt;, następnie przeskalować i przesunąć je do odcinka (-1, 1). Wreszcie, traktując je jako pary współrzędnych &amp;lt;tt&amp;gt;(x, y)&amp;lt;/tt&amp;gt;, pozostawiam tylko te, które znalazły się we wnętrzu koła jednostkowego (odrzucając pozostałe), i dzielę na te, które znalazły się w obszarze wewnątrz lemniskaty, i te, które znalazły się na zewnątrz. &lt;br /&gt;
&lt;br /&gt;
Intuicyjnie jest dość jasne, że &amp;amp;mdash; o ile losowaliśmy punkty rzeczywiście w sposób równomierny &amp;amp;mdash; stosunek liczby „trafień&amp;quot; w obszar ograniczony lemniskatą do liczby wszystkich „trafień&amp;quot; w obszar koła będzie w przybliżeniu równy stosunkowi pól powierzchni tych obszarów. I na tym tu poprzestaniemy; to, jak dokładne to może być przybliżenie, czyli jakiej wielkości błędu możemy oczekiwać, to już problem na inne zajęcia...&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
import numpy as np&lt;br /&gt;
import matplotlib.pyplot as plt&lt;br /&gt;
&lt;br /&gt;
Φ = np.arange(0, 2*np.pi, 2*np.pi/600)&lt;br /&gt;
X = np.cos(Φ)&lt;br /&gt;
Y = np.sin(2*Φ) / 2 # = np.sin(Φ) * np.cos(Φ)&lt;br /&gt;
plt.axes(aspect='equal') # to mi gwarantuje, że okrąg nie wyjdzie „spłaszczony&amp;quot;&lt;br /&gt;
plt.plot(X, Y, 'b')&lt;br /&gt;
YO = np.sin(Φ)&lt;br /&gt;
plt.plot(X, YO, 'k')&lt;br /&gt;
# biorę całą kupę losowych punktów z przedziału (-1, 1)&lt;br /&gt;
P = np.random.random((100000, 2)) * 2 - 1 # milion par (x, y)&lt;br /&gt;
# wyrzucam te, które są poza kołem x**2 + y**2 &amp;lt; 1&lt;br /&gt;
P = P[(P**2).sum(axis=1) &amp;lt; 1]&lt;br /&gt;
# dzielę na te co wewnątrz lemniskaty, i te co na zewnątrz&lt;br /&gt;
I_in = np.abs(P[:,1]) &amp;lt; np.abs(P[:,0]) * np.sqrt(1 - P[:,0]**2)&lt;br /&gt;
P_in = P[I_in]&lt;br /&gt;
P_out = P[~I_in]&lt;br /&gt;
# maluję wewnętrzne na niebiesko&lt;br /&gt;
plt.plot(P_in[:,0], P_in[:,1], 'b,')&lt;br /&gt;
# a zewnętrzne na czerwono&lt;br /&gt;
plt.plot(P_out[:,0], P_out[:,1], 'r,')&lt;br /&gt;
# powierzchnia to z grubsza stosunek l. punktów wewnętrznych do wszystkich&lt;br /&gt;
S = P_in.size / P.size&lt;br /&gt;
plt.title('Pole pow. wnętrza lemniskaty to ok. {:.3f} pola pow. koła'.format(S))&lt;br /&gt;
plt.show()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Przy okazji, jak widać w kodzie Pythona (wersja 3) można bezproblemowo używać liter z innych alfabetów, nie tylko łacińskiego. Niestety nie wszystkie systemy operacyjne zapewniają bezproblemową obsługę pełnego zestawu liter wszelkich języków, dlatego na ogół wykorzystywanie liter z egzotycznych systemów pisma nie jest szczególnie zalecane.&lt;br /&gt;
&lt;br /&gt;
W wyniku uruchomienia tego programu powinno pojawić się okno z obrazkiem podobnym do poniższego:&lt;br /&gt;
&lt;br /&gt;
[[File:Lemniskata.png]]&lt;br /&gt;
&lt;br /&gt;
==Wizualizacja zawartości tablicy dwuwymiarowej==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
import numpy as np&lt;br /&gt;
import matplotlib.pyplot as plt&lt;br /&gt;
&lt;br /&gt;
A = np.arange(20)&lt;br /&gt;
X, Y = np.meshgrid(A, A)&lt;br /&gt;
Z = X + Y&lt;br /&gt;
plt.imshow(Z, cmap='hot', interpolation='none')&lt;br /&gt;
plt.colorbar()&lt;br /&gt;
plt.show()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Wynik:'''&lt;br /&gt;
&lt;br /&gt;
[[Grafika:Imshow1.png]]&lt;br /&gt;
&lt;br /&gt;
Jak można się domyślić, parametr &amp;lt;tt&amp;gt;cmap&amp;lt;/tt&amp;gt; wywołania funkcji &amp;lt;tt&amp;gt;imshow&amp;lt;/tt&amp;gt; odpowiada za odwzorowanie pomiędzy wartościami elementów tablicy a barwami - jest wiele predefiniowanych takich odwzorowań (''colormaps''), opisanych w dokumentacji. Za pomocą wartości &amp;lt;tt&amp;gt;'none'&amp;lt;/tt&amp;gt; parametru &amp;lt;tt&amp;gt;interpolation&amp;lt;/tt&amp;gt; wyłączyliśmy ,,wygładzanie&amp;quot; obrazu, inne możliwe wartości umożliwiają wybór różnych algorytmów wygładzania. Wywołanie &amp;lt;tt&amp;gt;colorbar&amp;lt;/tt&amp;gt; dostarcza paska wizualizującego odpowiedniość pomiędzy wartościami liczbowy i barwami.&lt;br /&gt;
&lt;br /&gt;
==Plik graficzny jako źródło danych==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
import numpy as np&lt;br /&gt;
import matplotlib.pyplot as plt&lt;br /&gt;
&lt;br /&gt;
img = plt.imread('reading-girl.jpg')&lt;br /&gt;
plt.imshow()&lt;br /&gt;
plt.show()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Wynik:'''&lt;br /&gt;
&lt;br /&gt;
[[Grafika:Imshow-girl-1.jpg]]&lt;br /&gt;
&lt;br /&gt;
Wynikiem wywołania &amp;lt;tt&amp;gt;imread&amp;lt;/tt&amp;gt; jest tablica o kształcie ''(wysokość, szerokość, 3)'' zawierająca dla każdego piksela obrazu wartości jego składowych RGB, tj. natężeń barw: czerwonej, zielonej, i niebieskiej - jako liczby w zakresie od 0 do 255 włącznie. Oczywiście na tej tablicy możemy wykonywać najróżniejsze operacje, analizując treść obrazu czy przekształcając go. Przykładowo:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
img1 = img[:400, -400:] # przycinam obraz do kształtu 400x400 pikseli&lt;br /&gt;
img2 = img1.sum(axis=2)&lt;br /&gt;
img3 = img2 / img2.max()&lt;br /&gt;
plt.imgshow(img3, cmap='bone')&lt;br /&gt;
plt.show()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Wynik:'''&lt;br /&gt;
&lt;br /&gt;
[[Grafika:reading-girl-bone.jpg]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
plt.hist(img3.flatten(), bins=100)&lt;br /&gt;
plt.show()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Wynik:'''&lt;br /&gt;
&lt;br /&gt;
[[Grafika:reading-girl-hist.png]]&lt;br /&gt;
&lt;br /&gt;
Wykonaliśmy w ten sposób histogram opisujący rozkład natężenia pikseli obrazka.&lt;br /&gt;
&lt;br /&gt;
==Wiele wykresów w jednym oknie==&lt;br /&gt;
&lt;br /&gt;
==Ćwiczenia==&lt;br /&gt;
&lt;br /&gt;
1. Spróbuj znaleźć sposób przekształcenia obrazka takiego, jak poniższy portret autora skryptu:&lt;br /&gt;
&lt;br /&gt;
[[Grafika:rjb_small.jpg]]  &lt;br /&gt;
&lt;br /&gt;
do postaci przypominającej &lt;br /&gt;
&lt;br /&gt;
[[Grafika:rjb_bw.png]]&lt;br /&gt;
&lt;br /&gt;
2. (''Nieco złożone'') Napisz program symulujący „bilard na kółku&amp;quot;. Dokładniej: wewnątrz koła jednostkowego na płaszczyźnie porusza się cząstka (punkt), zachowując stałą prędkość &amp;amp;mdash; dopóki nie napotka brzegu, czyli okręgu; wówczas odbija się zgodnie z zasadą, że kąt padania równa się kątowi odbicia; chodzi o kąt pomiędzy wektorem prędkości a promieniem okręgu jednostkowego w miejscu, gdzie tor ruchu przecina się z okręgiem, po odbiciu jest on taki sam co do wartości ale ''po drugiej stronie'' promienia. Program rysuje okręg jednostkowy oraz tor ruchu cząstki wewnątrz tego okręgu, w zależności od początkowego położenia, kierunku początkowej prędkości (wartość prędkości jest nieistotna, ponieważ jest stała), i czasu obserwacji. &lt;br /&gt;
&lt;br /&gt;
Wynikiem programu są wykresy podobne do poniższego:&lt;br /&gt;
&lt;br /&gt;
[[Grafika:bilard_na_kole.png]]&lt;br /&gt;
&lt;br /&gt;
czarną kropką oznaczono położenie początkowe, a na zielono &amp;amp;mdash; końcowe.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
[[PPy3/NumPy|poprzednie]] | [[&amp;quot;Programowanie z Pythonem3&amp;quot;|strona główna]] | [[PPy3/TematyDodatkowe]]&lt;br /&gt;
&lt;br /&gt;
--[[Użytkownik:RobertJB|RobertJB]] ([[Dyskusja użytkownika:RobertJB|dyskusja]]) 14:05, 10 kwi 2017 (CEST)&lt;/div&gt;</summary>
		<author><name>RobertJB</name></author>
		
	</entry>
	<entry>
		<id>http://brain.fuw.edu.pl/edu/index.php?title=PPy3/Matplotlib&amp;diff=8498</id>
		<title>PPy3/Matplotlib</title>
		<link rel="alternate" type="text/html" href="http://brain.fuw.edu.pl/edu/index.php?title=PPy3/Matplotlib&amp;diff=8498"/>
		<updated>2021-01-08T09:40:05Z</updated>

		<summary type="html">&lt;p&gt;RobertJB: /* Przykład bardziej zaawansowany */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Matplotlib - wizualizacja danych = &lt;br /&gt;
&lt;br /&gt;
== Wprowadzenie do pakietu Matplotlib na przykładach ==&lt;br /&gt;
&lt;br /&gt;
Pakiet Matplotlib bazuje na pakiecie numerycznym Numpy i korzysta z obiektów w nim zawartych. Pokażemy, jak z jego pomocą rysować różnorodne wykresy prezentujące graficznie przetwarzane dane i wyniki obliczeń. Zamiast wyliczać zawartość pakietu  pokażemy ich użyteczność na przykładach. Zaczniemy od prostych i będziemy po drodze omawiać zastosowane w nich konstrukcje.&lt;br /&gt;
&lt;br /&gt;
== Wykresy funkcji ==&lt;br /&gt;
&lt;br /&gt;
===''y'' = ''f''(''x'')===&lt;br /&gt;
&lt;br /&gt;
Prześledźmy działanie poniższego programu:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang = python&amp;gt;&lt;br /&gt;
import matplotlib.pyplot as plt&lt;br /&gt;
x = [1,2,3]&lt;br /&gt;
y = [4,6,5]&lt;br /&gt;
plt.plot(x,y)&lt;br /&gt;
plt.show()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
; Rezultat&lt;br /&gt;
[[Grafika:Wykres1.gif]]&lt;br /&gt;
&lt;br /&gt;
; Jak to działa?&lt;br /&gt;
&lt;br /&gt;
Aby skorzystać z pakietu graficznego Matplotlib importujemy go do naszego programu poleceniem &amp;lt;tt&amp;gt;import&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&lt;br /&gt;
Pod-pakiet pyplot jest jednym z paru nieco różnych ''interfejsów'' do Matplotlib - tj. sposobów wykorzystania&lt;br /&gt;
jego funkcjonalności. Inny, też często wykorzystywany, nazywa się &amp;lt;tt&amp;gt;pylab&amp;lt;/tt&amp;gt; i można go importować wprost&lt;br /&gt;
(&amp;lt;tt&amp;gt;import pylab&amp;lt;/tt&amp;gt;). Pyplot zapewnie nieco większą elastyczność, chociaż dla najprostszych przykładów - &lt;br /&gt;
takich, jakie tu omówimy - nie ma istotnej różnicy.&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wytwarzamy dwie listy &amp;lt;tt&amp;gt;x&amp;lt;/tt&amp;gt; i &amp;lt;tt&amp;gt;y&amp;lt;/tt&amp;gt; zawierające ciągi liczb 1, 2, 3 oraz 4, 6, 5. &lt;br /&gt;
&lt;br /&gt;
Funkcja &amp;lt;tt&amp;gt;plot&amp;lt;/tt&amp;gt; rysuje wykres i umieszcza na nim punkty o współrzędnych zawartych w listach przekazanych jej jako argumenty. Pierwszy argument zawiera współrzędne ''x''-owe kolejnych punktów, a drugi argument współrzędne ''y''-owe kolejnych punktów wykresu. Ponieważ listy mają po trzy elementy, tak więc wykres zawierać będzie trzy punkty o współrzędnych (1, 4), (2, 6) oraz (3, 5). Domyślnie punkty na wykresie łączone są ze sobą niebieską linią ciągłą. To &lt;br /&gt;
oczywiście można zmienić - dodając opcjonalne parametry do wywołania &amp;lt;tt&amp;gt;plot&amp;lt;/tt&amp;gt; można uzyskać linię o innym kolorze, &lt;br /&gt;
linię przerywaną, z kropek, albo w ogóle brak linii - a za to np. duże kropki (trójkąty, gwiazdki, ...) w miejscach&lt;br /&gt;
odpowiadających punktom danych.&lt;br /&gt;
&lt;br /&gt;
Po wywołaniu funkcji &amp;lt;tt&amp;gt;plot&amp;lt;/tt&amp;gt; wykres nie pokazuje się jeszcze na ekranie. Aby go pokazać, używamy funkcji &amp;lt;tt&amp;gt;show&amp;lt;/tt&amp;gt;. Wykres pojawia się na ekranie w osobnym oknie, a Python czeka z wykonywaniem kolejnych instrukcji do momentu zamknięcia okna z wykresem.&lt;br /&gt;
&lt;br /&gt;
W okienku wykresu mamy kilka guzików (po lewej stronie na dole). Służą one do manipulowania wyglądem rysunku. Guzikiem z krzyżykiem możemy zmniejszać/zwiększać skalę na osiach (wciskając prawy guzik myszy i przesuwając kursor po obrazku) oraz przesuwać cały wykres (wciskając lewy guzik myszy i przesuwając kursor po obrazku). Guzik z okienkiem i strzałkami pozwala także zmieniać rozmiar i położenie osi wykresu wewnątrz okna wybierając właściwe wartości. Guzik z domkiem przywraca wyjściowe ustawienia rysunku. Guzik z obrazkiem dyskietki (czy ktoś jeszcze wie, co to takiego?) pozwala&lt;br /&gt;
zachować wykres (jego aktualny stan, czyli z uwzględnieniem dokonanych interaktywnie modyfikacji) jako plik graficzny&lt;br /&gt;
jednego z kilku formatów.&lt;br /&gt;
&lt;br /&gt;
=== Rysujemy wykres funkcji sinus ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang = python&amp;gt;&lt;br /&gt;
import numpy as np&lt;br /&gt;
import matplotlib.pyplot as plt&lt;br /&gt;
x = np.arange(0.0, 2.0, 0.01)&lt;br /&gt;
y = np.sin(2.0*np.pi*x)&lt;br /&gt;
plt.plot(x,y)&lt;br /&gt;
plt.show()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
; Rezultat&lt;br /&gt;
[[Grafika:Wykres2.gif]]&lt;br /&gt;
&lt;br /&gt;
; Jak to działa?&lt;br /&gt;
&lt;br /&gt;
Oprócz funkcji z Matplotlib będziemu tu odwoływać się również wprost do elementów z pakietu NumPy.&lt;br /&gt;
&lt;br /&gt;
Funkcja &amp;lt;tt&amp;gt;arange&amp;lt;/tt&amp;gt; jest podobna do standardowej funkcji &amp;lt;tt&amp;gt;range&amp;lt;/tt&amp;gt; wytwarzającej określone sekwencje liczb w postaci listy. Funkcja &amp;lt;tt&amp;gt;arange&amp;lt;/tt&amp;gt; zamiast listy wytwarza tablicę zawierającą ciąg liczb zmiennoprzecinkowych zaczynający się od pierwszego podanego argumentu funkcji &amp;lt;tt&amp;gt;arange&amp;lt;/tt&amp;gt; (u nas &amp;lt;tt&amp;gt;0.0&amp;lt;/tt&amp;gt;), a kończący się przed drugim argumentem (tradycyjnie, ciąg wynikowy nie zawiera wartości podanej jako drugi argument, u nas &amp;lt;tt&amp;gt;2.0&amp;lt;/tt&amp;gt;). Różnica między elementami wytworzonego ciągu domyślnie wynosi 1, ale jeśli podamy funkcji &amp;lt;tt&amp;gt;arange&amp;lt;/tt&amp;gt; trzeci argument, to definiuje on nową różnicę ciągu, u nas wynosi on &amp;lt;tt&amp;gt;0.01&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Tak więc zmienna &amp;lt;tt&amp;gt;x&amp;lt;/tt&amp;gt; jest tablicą-wektorem zawierającą ciąg liczb od 0 do 1,99 co 0,01 (czyli 0, 0,01, 0,02, ..., 1,98, 1,99).&lt;br /&gt;
&lt;br /&gt;
Funkcja &amp;lt;tt&amp;gt;sin&amp;lt;/tt&amp;gt; służy do obliczania wartości funkcji sinus dla argumentu podanego w radianach. A co u nas jest argumentem tej funkcji? Wyrażenie będące argumentem zawiera mnożenie liczby &amp;lt;tt&amp;gt;2.0&amp;lt;/tt&amp;gt; przez &amp;lt;tt&amp;gt;pi&amp;lt;/tt&amp;gt; (pochodzące z pakietu NumPy), a następnie mnożenie wyniku przez tablicę &amp;lt;tt&amp;gt;x&amp;lt;/tt&amp;gt;. Zmienna &amp;lt;tt&amp;gt;pi&amp;lt;/tt&amp;gt; zawiera przybliżoną wartość matematycznej stałej &amp;amp;pi; &amp;amp;asymp; 3,1415926... Mnożenie liczby i tablicy, jak wiemy z poprzedniego punktu, daje w wyniku tablicę. Oznacza to, że argumentem funkcji &amp;lt;tt&amp;gt;sin&amp;lt;/tt&amp;gt; jest nie liczba, ale tablica! Taka możliwość jest przewidziana przez twórców pakietu Numpy; wynikiem wywołania funkcji jest wtedy  również tablica. Jest ona tej samej długości co tablica będąca argumentem wywołania funkcji.&lt;br /&gt;
&lt;br /&gt;
Tak więc zmienna &amp;lt;tt&amp;gt;y&amp;lt;/tt&amp;gt; zawiera ciąg wartości funkcji sinus policzonych dla wartości zawartych w zmiennej &amp;lt;tt&amp;gt;x&amp;lt;/tt&amp;gt; pomnożonych każda przez 2&amp;amp;pi; (czyli sin(2&amp;amp;pi;&amp;amp;middot;0), sin(2&amp;amp;pi;&amp;amp;middot;0,01), sin(2&amp;amp;pi;&amp;amp;middot;0,02), ..., sin(2&amp;amp;pi;&amp;amp;middot;1,98), sin(2&amp;amp;pi;&amp;amp;middot;1,99)).&lt;br /&gt;
&lt;br /&gt;
Funkcja &amp;lt;tt&amp;gt;plot(x,y)&amp;lt;/tt&amp;gt; narysuje zestaw punktów o współrzędnych (0, sin(2&amp;amp;pi;&amp;amp;middot;0)), (0,01, sin(2&amp;amp;pi;&amp;amp;middot;0,01)), (0,02, sin(2&amp;amp;pi;&amp;amp;middot;0,02)), ..., (1,98, sin(2&amp;amp;pi;&amp;amp;middot;1,98)), (1,99, sin(2&amp;amp;pi;&amp;amp;middot;1,99)) połączonych niebieską linią.&lt;br /&gt;
&lt;br /&gt;
=== Ulepszamy wykres ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang = python&amp;gt;&lt;br /&gt;
import numpy as np&lt;br /&gt;
import matplotlib.pyplot as plt&lt;br /&gt;
&lt;br /&gt;
x = np.arange(0.0, 2.0, 0.01)&lt;br /&gt;
y = np.sin(2.0*p.pi*x)&lt;br /&gt;
plt.plot(x,y,'r:',linewidth=6)&lt;br /&gt;
&lt;br /&gt;
plt.xlabel('Czas')&lt;br /&gt;
plt.ylabel('Pozycja')&lt;br /&gt;
plt.title('Nasz pierwszy wykres')&lt;br /&gt;
plt.grid(True)&lt;br /&gt;
plt.show()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
; Rezultat&lt;br /&gt;
[[Grafika:Wykres3.gif]]&lt;br /&gt;
&lt;br /&gt;
; Jak to działa?&lt;br /&gt;
&lt;br /&gt;
W porównaniu z poprzednim przykładem pojawiło się na wykresie kilka drobnych zmian i &amp;amp;bdquo;ozdobników&amp;amp;rdquo;.&lt;br /&gt;
&lt;br /&gt;
W funkcji &amp;lt;tt&amp;gt;plot&amp;lt;/tt&amp;gt; pojawiły się dwa nowe parametry:&lt;br /&gt;
# &amp;lt;tt&amp;gt;'r:'&amp;lt;/tt&amp;gt; &amp;amp;mdash; ten parametr steruje wyglądem rysowanej linii wykresu. Pierwsza litera tego napisu określa kolor linii (na przykład &amp;lt;tt&amp;gt;r&amp;lt;/tt&amp;gt;: czerwony, &amp;lt;tt&amp;gt;b&amp;lt;/tt&amp;gt;: niebieski, &amp;lt;tt&amp;gt;g&amp;lt;/tt&amp;gt;: zielony, &amp;lt;tt&amp;gt;y&amp;lt;/tt&amp;gt;: żółty, &amp;lt;tt&amp;gt;k&amp;lt;/tt&amp;gt;: czarny). Drugi znak napisu określa wygląd samej linii (np. &amp;lt;tt&amp;gt;-&amp;lt;/tt&amp;gt;: ciągła, &amp;lt;tt&amp;gt;:&amp;lt;/tt&amp;gt;: kropkowana, &amp;lt;tt&amp;gt;o&amp;lt;/tt&amp;gt;: okrągłe punkty bez linii, &amp;lt;tt&amp;gt;+&amp;lt;/tt&amp;gt;: krzyżyki bez linii, itd.).&lt;br /&gt;
# &amp;lt;tt&amp;gt;linewidth=6&amp;lt;/tt&amp;gt; &amp;amp;mdash; ten parametr zmienia grubość rysowanej linii.&lt;br /&gt;
&lt;br /&gt;
Dodaliśmy też wywołania funkcji &amp;lt;tt&amp;gt;xlabel&amp;lt;/tt&amp;gt; i &amp;lt;tt&amp;gt;ylabel&amp;lt;/tt&amp;gt;. Ich argumentami są napisy, które pojawią się jako opisy osi, odpowiednio poziomej i pionowej.&lt;br /&gt;
Wywołanie funkcji &amp;lt;tt&amp;gt;title&amp;lt;/tt&amp;gt; wypisuje przekazany jej napis jako tytuł całego wykresu.&lt;br /&gt;
&lt;br /&gt;
Funkcja &amp;lt;tt&amp;gt;grid&amp;lt;/tt&amp;gt; dorysowuje siatkę prostokątną na wykresie w wybranych punktach opisujących wartości na osiach wykresu. Punkty, w których wybierane są wartości opisane na osiach (ang. ''tick'') są wybierane automatycznie (oczywiście jeśli chcemy, możemy zmieniać ich położenie i opisy odpowiednią funkcją, powiemy o tym później).&lt;br /&gt;
&lt;br /&gt;
=== Kilka wykresów we wspólnych osiach - Pierwsza wersja ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang = python&amp;gt;&lt;br /&gt;
import numpy as np&lt;br /&gt;
import matplotlib.pyplot as plt&lt;br /&gt;
&lt;br /&gt;
x = np.arange(0.0, 2.0, 0.01)&lt;br /&gt;
y1 = np.sin(2.0*p.pi*x)&lt;br /&gt;
y2 = np.cos(2.0*p.pi*x)&lt;br /&gt;
plt.plot(x,y1,'r:',x,y2,'g')&lt;br /&gt;
plt.legend(('dane y1','dane y2'))&lt;br /&gt;
plt.xlabel('Czas')&lt;br /&gt;
plt.ylabel('Pozycja')&lt;br /&gt;
plt.title('Wykres ')&lt;br /&gt;
plt.grid(True)&lt;br /&gt;
plt.show()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
'''Rezultat:'''&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
[[Grafika:Wykres_2_linie.svg‎]]&lt;br /&gt;
&lt;br /&gt;
;Jak to działa?&lt;br /&gt;
&lt;br /&gt;
W jednym układzie współrzędnych możemy narysować wiele wykresów. Robimy to podając w jednym poleceniu &amp;lt;tt&amp;gt;plot&amp;lt;/tt&amp;gt; kolejno zestawy parametrów opisujące poszczególne linie: współrzędne x, współrzędne y, sposób wykreślania linii. Aby łatwo identyfikować linie można dodać legendę poleceniem &amp;lt;tt&amp;gt;legend()&amp;lt;/tt&amp;gt;. Sposób kontrolowania wyglądu i położenia legendy: &amp;lt;tt&amp;gt;help(plt.legend)&amp;lt;/tt&amp;gt; (oczywiście po zaimportowaniu modułu: &amp;lt;tt&amp;gt;import matplotlib.pyplot as plt&amp;lt;/tt&amp;gt; ).&lt;br /&gt;
&lt;br /&gt;
=== Kilka wykresów we wspólnych osiach - Druga wersja ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang = python&amp;gt;&lt;br /&gt;
import numpy as np&lt;br /&gt;
import matplotlib.pyplot as plt&lt;br /&gt;
&lt;br /&gt;
x = np.arange(0.0, 2.0, 0.01)&lt;br /&gt;
y1 = np.sin(2.0*p.pi*x)&lt;br /&gt;
y2 = np.cos(2.0*p.pi*x)&lt;br /&gt;
y = y1*y2&lt;br /&gt;
l1, = plt.plot(x,y,'b')&lt;br /&gt;
l2,l3 = plt.plot(x,y1,'r:',x,y2,'g')&lt;br /&gt;
plt.legend((l2,l3,l1),('dane y1','dane y2','y1*y2'))&lt;br /&gt;
plt.xlabel('Czas')&lt;br /&gt;
plt.ylabel('Pozycja')&lt;br /&gt;
plt.title('Wykres ')&lt;br /&gt;
plt.grid(True)&lt;br /&gt;
plt.show()&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
'''Rezultat:'''&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
[[Grafika:Wykres_3_linie.svg‎]]&lt;br /&gt;
&lt;br /&gt;
;Jak to działa?&lt;br /&gt;
&lt;br /&gt;
Wykresy możemy dodawać do współrzędnych kolejnymi poleceniami &amp;lt;tt&amp;gt;plot&amp;lt;/tt&amp;gt;.&lt;br /&gt;
Funkcja &amp;lt;tt&amp;gt;plot&amp;lt;/tt&amp;gt; zwraca listę linii. Notacja &amp;lt;tt&amp;gt;l1, = plt.plot(x,y,'b')&amp;lt;/tt&amp;gt; wydobywa z listy pierwszą linię (Gdyby po &amp;lt;tt&amp;gt;l1&amp;lt;/tt&amp;gt; nie było przecinka to &amp;lt;tt&amp;gt;l1&amp;lt;/tt&amp;gt; byłoby listą zawierającą jeden obiekt klasy linia ).&lt;br /&gt;
&lt;br /&gt;
Dzięki nazwaniu poszczególnych obiektów linii możemy kontrolować ich kolejność (i obecność) na legendzie.&lt;br /&gt;
&lt;br /&gt;
==Histogram (diagram liczebności)==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
import matplotlib.pyplot as plt&lt;br /&gt;
&lt;br /&gt;
zliczenia = [0, 1, 2, 2, 3, 3, 3, 3, 3, 3, 4, 4, 4, 5, 7]&lt;br /&gt;
plt.hist(zliczenia)&lt;br /&gt;
plt.show()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Rezultat:'''&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
[[Grafika:Hist1.gif]]&lt;br /&gt;
&lt;br /&gt;
;Jak to działa ? &lt;br /&gt;
&lt;br /&gt;
Do zmiennej &amp;lt;tt&amp;gt;zliczenia&amp;lt;/tt&amp;gt; przypisujemy sekwencję z ręcznie podanymi wartościami. &lt;br /&gt;
Zakres zmienności badanych zliczeń (odkładany na osi ''X'') zostanie podzielony na przedziały (ang. ''bin'') o jednakowej &amp;amp;bdquo;szerokości&amp;amp;rdquo;; domyślnie będzie ich 10. Funkcja &amp;lt;tt&amp;gt;hist()&amp;lt;/tt&amp;gt; zlicza wystąpienia wartości w binach i rysuje histogram. Funkcja ta zwraca krotkę (array ze zliczeniami, array z binami, lista zawierająca prostokąty, które histogram rysuje, tzw. obiekty Patch).&lt;br /&gt;
&lt;br /&gt;
Porządek wartości, których histogram zostanie stworzony nie ma znaczenia. Mogą one oczywiście być umieszczone również w tablicy NumPy.&lt;br /&gt;
 &lt;br /&gt;
===Przykład bardziej zaawansowany===&lt;br /&gt;
&lt;br /&gt;
Wyjaśnienie działania znajduje się w komentarzach do programu:&lt;br /&gt;
&amp;lt;source lang = python&amp;gt;&lt;br /&gt;
import numpy as np&lt;br /&gt;
import matplotlib.pyplot as plt&lt;br /&gt;
from scipy.stats import norm&lt;br /&gt;
&lt;br /&gt;
mi, sigma = 100, 15&lt;br /&gt;
x = mi + sigma * np.random.randn(10000)&lt;br /&gt;
# numpy.random.randn zwraca array z liczbami pseudolosowymi&lt;br /&gt;
# pochodzącymi z rozkładu normalnego o średniej 0 i wariancji 1&lt;br /&gt;
# przemnożenie przez odchylenie standandardowe sigma i dodanie śreniej mi&lt;br /&gt;
# transformuje rozkład do rozkładu normalnego o średniej mi i wariancji sigma**2&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
n, bins, patches = plt.hist(x, 50, normed=True, facecolor='green', alpha=0.75)&lt;br /&gt;
# Tu w jawny sposób odbieramy zwracane przez plt.hist obiekty&lt;br /&gt;
# Zmieniamy też:&lt;br /&gt;
#   - ilość binów na 50&lt;br /&gt;
#   - normujemy histogram do jedności&lt;br /&gt;
#   - ustalamy kolor prostokątów na zielony&lt;br /&gt;
#   - ustawiamy (nie)przezroczystość prostokątów na 0.75&lt;br /&gt;
&lt;br /&gt;
bincenters = 0.5*(bins[1:]+bins[:-1])&lt;br /&gt;
# wytwarzamy array z centrami binów korzystając z granic binów&lt;br /&gt;
# zwróconych przez plt.hist w macierzy bins&lt;br /&gt;
&lt;br /&gt;
y = norm.pdf( bincenters, mi, sigma)&lt;br /&gt;
# obliczamy wartości w normalnym rozkładzie gęstości prawdopodobieństwa&lt;br /&gt;
# o średniej mi i wariancji sigma**2 dla wartości bincenters&lt;br /&gt;
&lt;br /&gt;
l = plt.plot(bincenters, y, 'r--', linewidth=1)&lt;br /&gt;
# do histogramu dorysowujemy linię &lt;br /&gt;
&lt;br /&gt;
plt.show()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Rezultat:'''&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
[[Grafika:Hist2.gif]]&lt;br /&gt;
&lt;br /&gt;
==Krzywa parametryczna==&lt;br /&gt;
&lt;br /&gt;
Rysowanie krzywej danej w postaci parametrycznej niewiele się różni od rysowania wykresu funkcji. Żeby było zabawniej, wykonam jeszcze przy okazji rachunek Monte Carlo oraz jego wizualizację.&lt;br /&gt;
&lt;br /&gt;
Krzywa, jaką tutaj narysujemy to tzw. [https://pl.wikipedia.org/wiki/Lemniskata_Gerona lemniskata Gerona]. Zostanie dodatkowo opisana okręgiem jednostkowym; następnie, wylosuję dużą liczbę punktów o równomiernym rozkładzie leżących w kwadracie opisanym na tym okręgu. Robię tak, ponieważ łatwo mi jest wylosować tablicę wielu liczb z zakresu (0, 1) &amp;amp;mdash; jest do tego gotowa funkcja &amp;lt;tt&amp;gt;numpy.random.random&amp;lt;/tt&amp;gt;, następnie przeskalować i przesunąć je do odcinka (-1, 1). Wreszcie, traktując je jako pary współrzędnych &amp;lt;tt&amp;gt;(x, y)&amp;lt;/tt&amp;gt;, pozostawiam tylko te, które znalazły się we wnętrzu koła jednostkowego (odrzucając pozostałe), i dzielę na te, które znalazły się w obszarze wewnątrz lemniskaty, i te, które znalazły się na zewnątrz. &lt;br /&gt;
&lt;br /&gt;
Intuicyjnie jest dość jasne, że &amp;amp;mdash; o ile losowaliśmy punkty rzeczywiście w sposób równomierny &amp;amp;mdash; stosunek liczby „trafień&amp;quot; w obszar ograniczony lemniskatą do liczby wszystkich „trafień&amp;quot; w obszar koła będzie w przybliżeniu równy stosunkowi pól powierzchni tych obszarów. I na tym tu poprzestaniemy; to, jak dokładne to może być przybliżenie, czyli jakiej wielkości błędu możemy oczekiwać, to już problem na inne zajęcia...&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
import numpy as np&lt;br /&gt;
import matplotlib.pyplot as plt&lt;br /&gt;
&lt;br /&gt;
Φ = np.arange(0, 2*np.pi, 2*np.pi/600)&lt;br /&gt;
X = np.cos(Φ)&lt;br /&gt;
Y = np.sin(2*Φ) / 2 # = np.sin(Φ) * np.cos(Φ)&lt;br /&gt;
plt.axes(aspect='equal') # to mi gwarantuje, że okrąg nie wyjdzie „spłaszczony&amp;quot;&lt;br /&gt;
plt.plot(X, Y, 'b')&lt;br /&gt;
YO = np.sin(Φ)&lt;br /&gt;
plt.plot(X, YO, 'k')&lt;br /&gt;
# biorę całą kupę losowych punktów z przedziału (-1, 1)&lt;br /&gt;
P = np.random.random((100000, 2)) * 2 - 1 # milion par (x, y)&lt;br /&gt;
# wyrzucam te, które są poza kołem x**2 + y**2 &amp;lt; 1&lt;br /&gt;
P = P[(P**2).sum(axis=1) &amp;lt; 1]&lt;br /&gt;
# dzielę na te co wewnątrz lemniskaty, i te co na zewnątrz&lt;br /&gt;
I_in = np.abs(P[:,1]) &amp;lt; np.abs(P[:,0]) * np.sqrt(1 - P[:,0]**2)&lt;br /&gt;
P_in = P[I_in]&lt;br /&gt;
P_out = P[~I_in]&lt;br /&gt;
# maluję wewnętrzne na niebiesko&lt;br /&gt;
plt.plot(P_in[:,0], P_in[:,1], 'b,')&lt;br /&gt;
# a zewnętrzne na czerwono&lt;br /&gt;
plt.plot(P_out[:,0], P_out[:,1], 'r,')&lt;br /&gt;
# powierzchnia to z grubsza stosunek l. punktów wewnętrznych do wszystkich&lt;br /&gt;
S = P_in.size / P.size&lt;br /&gt;
plt.title('Pole pow. wnętrza lemniskaty to ok. {:.3f} pola pow. koła'.format(S))&lt;br /&gt;
plt.show()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Przy okazji, jak widać w kodzie Pythona (wersja 3) można bezproblemowo używać liter z innych alfabetów, nie tylko łacińskiego. Niestety nie wszystkie systemy operacyjne zapewniają bezproblemową obsługę pełnego zestawu liter wszelkich języków, dlatego na ogół wykorzystywanie liter z egzotycznych systemów pisma nie jest szczególnie zalecane.&lt;br /&gt;
&lt;br /&gt;
W wyniku uruchomienia tego programu powinno pojawić się okno z obrazkiem podobnym do poniższego:&lt;br /&gt;
&lt;br /&gt;
[[File:Lemniskata.png]]&lt;br /&gt;
&lt;br /&gt;
==Wizualizacja zawartości tablicy dwuwymiarowej==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
import numpy as np&lt;br /&gt;
import matplotlib.pyplot as plt&lt;br /&gt;
&lt;br /&gt;
A = np.arange(20)&lt;br /&gt;
X, Y = np.meshgrid(A, A)&lt;br /&gt;
Z = X + Y&lt;br /&gt;
plt.imshow(Z, cmap='hot', interpolation='none')&lt;br /&gt;
plt.colorbar()&lt;br /&gt;
plt.show()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Wynik:'''&lt;br /&gt;
&lt;br /&gt;
[[Grafika:Imshow1.png]]&lt;br /&gt;
&lt;br /&gt;
Jak można się domyślić, parametr &amp;lt;tt&amp;gt;cmap&amp;lt;/tt&amp;gt; wywołania funkcji &amp;lt;tt&amp;gt;imshow&amp;lt;/tt&amp;gt; odpowiada za odwzorowanie pomiędzy wartościami elementów tablicy a barwami - jest wiele predefiniowanych takich odwzorowań (''colormaps''), opisanych w dokumentacji. Za pomocą wartości &amp;lt;tt&amp;gt;'none'&amp;lt;/tt&amp;gt; parametru &amp;lt;tt&amp;gt;interpolation&amp;lt;/tt&amp;gt; wyłączyliśmy ,,wygładzanie&amp;quot; obrazu, inne możliwe wartości umożliwiają wybór różnych algorytmów wygładzania. Wywołanie &amp;lt;tt&amp;gt;colorbar&amp;lt;/tt&amp;gt; dostarcza paska wizualizującego odpowiedniość pomiędzy wartościami liczbowy i barwami.&lt;br /&gt;
&lt;br /&gt;
==Plik graficzny jako źródło danych==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
import numpy as np&lt;br /&gt;
import matplotlib.pyplot as plt&lt;br /&gt;
&lt;br /&gt;
img = plt.imread('reading-girl.jpg')&lt;br /&gt;
plt.imshow()&lt;br /&gt;
plt.show()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Wynik:'''&lt;br /&gt;
&lt;br /&gt;
[[Grafika:Imshow-girl-1.jpg]]&lt;br /&gt;
&lt;br /&gt;
Wynikiem wywołania &amp;lt;tt&amp;gt;imread&amp;lt;/tt&amp;gt; jest tablica o kształcie ''(wysokość, szerokość, 3)'' zawierająca dla każdego piksela obrazu wartości jego składowych RGB, tj. natężeń barw: czerwonej, zielonej, i niebieskiej - jako liczby w zakresie od 0 do 255 włącznie. Oczywiście na tej tablicy możemy wykonywać najróżniejsze operacje, analizując treść obrazu czy przekształcając go. Przykładowo:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
img1 = img[:400, -400:] # przycinam obraz do kształtu 400x400 pikseli&lt;br /&gt;
img2 = img1.sum(axis=2)&lt;br /&gt;
img3 = img2 / img2.max()&lt;br /&gt;
plt.imgshow(img3, cmap='bone')&lt;br /&gt;
plt.show()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Wynik:'''&lt;br /&gt;
&lt;br /&gt;
[[Grafika:reading-girl-bone.jpg]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
plt.hist(img3.flatten(), bins=100)&lt;br /&gt;
plt.show()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Wynik:'''&lt;br /&gt;
&lt;br /&gt;
[[Grafika:reading-girl-hist.png]]&lt;br /&gt;
&lt;br /&gt;
Wykonaliśmy w ten sposób histogram opisujący rozkład natężenia pikseli obrazka.&lt;br /&gt;
&lt;br /&gt;
==Wiele wykresów w jednym oknie==&lt;br /&gt;
&lt;br /&gt;
==Ćwiczenia==&lt;br /&gt;
&lt;br /&gt;
1. Spróbuj znaleźć sposób przekształcenia obrazka takiego, jak poniższy portret autora skryptu:&lt;br /&gt;
&lt;br /&gt;
[[Grafika:rjb_small.jpg]]  &lt;br /&gt;
&lt;br /&gt;
do postaci przypominającej &lt;br /&gt;
&lt;br /&gt;
[[Grafika:rjb_bw.png]]&lt;br /&gt;
&lt;br /&gt;
2. (''Nieco złożone'') Napisz program symulujący „bilard na kółku&amp;quot;. Dokładniej: wewnątrz koła jednostkowego na płaszczyźnie porusza się cząstka (punkt), zachowując stałą prędkość &amp;amp;mdash; dopóki nie napotka brzegu, czyli okręgu; wówczas odbija się zgodnie z zasadą, że kąt padania równa się kątowi odbicia; chodzi o kąt pomiędzy wektorem prędkości a promieniem okręgu jednostkowego w miejscu, gdzie tor ruchu przecina się z okręgiem, po odbiciu jest on taki sam co do wartości ale ''po drugiej stronie'' promienia. Program rysuje okręg jednostkowy oraz tor ruchu cząstki wewnątrz tego okręgu, w zależności od początkowego położenia, kierunku początkowej prędkości (wartość prędkości jest nieistotna, ponieważ jest stała), i czasu obserwacji. &lt;br /&gt;
&lt;br /&gt;
Wynikiem programu są wykresy podobne do poniższego:&lt;br /&gt;
&lt;br /&gt;
[[Grafika:bilard_na_kole.png]]&lt;br /&gt;
&lt;br /&gt;
czarną kropką oznaczono położenie początkowe, a na zielono &amp;amp;mdash; końcowe.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
[[PPy3/NumPy|poprzednie]] | [[&amp;quot;Programowanie z Pythonem3&amp;quot;|strona główna]] | [[PPy3/TematyDodatkowe]]&lt;br /&gt;
&lt;br /&gt;
--[[Użytkownik:RobertJB|RobertJB]] ([[Dyskusja użytkownika:RobertJB|dyskusja]]) 14:05, 10 kwi 2017 (CEST)&lt;/div&gt;</summary>
		<author><name>RobertJB</name></author>
		
	</entry>
</feed>