LWP: Lamerskie Wprowadzenie do Pythona
Autor: Artur Skura (arturs [bzium] linuxpl.org)
podziękowania dla Wojtka Warczakowskiego (wowar [bzium] poczta.onet.pl)
gdzieniegdzie tekst modyfikował Maciej " MACiAS" Pilichowski (macias [bzium] torun.pdi.net)
Dokument ten przedstawia podstawowe właściwości potężnego języka, jakim jest Python. Przeznaczony jest dla nie-programistów i hobbystów. Proszę zgłaszać wszystkie błędy (zapewne jest ich mnóstwo) i nie irytować się łopatologią ;-)
1. Wstęp
Wiele osób pragnąc nauczyć się programować staje przed dylematem: "Od jakiego języka programowania zacząć?" . Pytanie jest dość istotne, ponieważ negatywne nawyki, którymi przesiąknie początkujący bardzo trudno potem wykorzenić.
Eric S. Raymond w swoim eseju " Jak zostać hackerem?" proponuje Pythona. Istnieje wiele argumentów przemawiających za wykorzystaniem tego języka. Niektóre aspekty C (np. wskaźniki) mogą sprawić początkującym wiele trudności; utrzymanie porządku w programach napisanych w Perlu staje się po pewnym czasie bardzo trudne (podobnie jest z Tcl/Tk); Java wymaga zrozumienia pewnych podstaw, a narzędzia do niej -- wymagań sprzętowych wyższych niż przeciętne... Nauka Pythona jest rozsądnym kompromisem: z jednej strony otrzymujemy język, którego stosunkowo łatwo można się nauczyć, z drugiej zaś -- potężne narzędzie używane przez profesjonalistów, w swej podstawowej postaci bardzo użyteczne wszędzie tam, gdzie np. zachodzi konieczność wykonywania skomplikowanych operacji na łańcuchach znaków.
Twórca Pythona, Guido van Rossum, zaleca jego naukę na samym początku, przed wprowadzeniem do takich języków jak Java czy C++. Dzięki temu, po zakończeniu kursu uczeń będzie potrafił programować na przyzwoitym poziomie i rozumiał podstawy programowania obiektowego, co znacznie ułatwi mu naukę w/w języków.
2. Zaczynamy
Aby zorientować się w możliwościach języka, uruchomimy interpreter Pythona:
$ python
Pojawi się napis podobny do poniższego:
Python 1.5.2 (#1, Feb 1 2000, 16:32:16) [GCC egcs-2.91.66 19990314/Linux (egcs- on linux-i386
Copyright 1991-1995 Stichting Mathematisch Centrum, Amsterdam
>>>
Możemy teraz wydawać polecenia, które zostaną wykonane od razu. Napiszmy:
>>> print "Mamusiu, jak tu pięknie!"
W rezultacie powinniśmy otrzymać napis " Mamusiu, jak tu pięknie!" . Python zazwyczaj robi dokładnie to, co mu każemy.
2.1 Wstępnych uwag parę
Zaczynamy gubić przykłady
Chociaż w dalszym tekście nadal jest zachowana konwencja wpisywania poleceń bezpośrednio interpreterowi Pythona, to jednak aby oszczędzić sobie czasu i nerwów możemy korzystając w edytorze tekstu (który pozwala na zapis plików ASCII) stworzyć plik o rozszerzeniu " py"
--- np. " tescik.py" . W nim możemy pisać program w Pythonie, a po zapisaniu wydać polecenie:
python tescik.py
Jeśli popełniliśmy tzw. głupi błąd --- literówkę --- to wracamy do edycji pliku i poprawiamy co trzeba.
Jak łatwo zauważyć...
print x[zk]*f/u[ol],we[d[m]]*r
Ok, to i tak nie jest jeszcze największy galimatias jaki można uczynić z kodu. Python pozwala Ci opisać takie kawałki własnymi słowami --- aby odróżnić Twój opis od kodu programu użyj znaku " #" i po nim wpisz komentarz. Np:
# o rrrany, w ogóle nie wiem co się tutaj dzieje
Ale tak naprawdę powinieneś pisać kod tak, aby był samodokumentujący się --- tj. aby faktycznie było " łatwo zauważyć, że..." nawet bez dodatkowego komentarza z Twojej strony.
A bo mnie się shift nacisnął...
Jeszcze nie wiemy, jak Python działa, ale już na wstępie:
>>> Q = 100
>>> print q
dostajemy piękny błąd. Dla Pythona stanowi różnicę pisownia małymi i wielkimi literami!
3. Wbudowane typy danych
3.1 Łańcuchy
Zaimplementowano w nim wiele cech innych języków eliminując związane z nimi niedogodności, dzięki czemu programista może skupić się na pracy a nie na semantyce.
Przypiszmy teraz zmiennej " a" napis " Dajcie mi kredki" :
>>> a = "Dajcie mi kredki."
>>> print a
Dajcie mi kredki.
Idźmy dalej: łączenie napisów:
>>> a = "Dajcie"
>>> b = "mi w końcu te kredki!!!"
>>> print a, b
Dajcie mi w końcu te kredki!!!
Można też inaczej:
>>> a = "No, "
>>> b = "wreszcie!"
>>> print a+b
No, wreszcie!
Można łączyć jeszcze bardziej:
>>> print "Jarek powiedział:", a + b
Jarek powiedział: No, Wreszcie!
Co ciekawe, łańcuchy można nie tylko dodawać -- można je również " mnożyć" :
>>> s = "Nie!"
>>> print 3*s
Nie!Nie!Nie!
Możemy także w prosty sposób zamienić tekst na liczbę (o ile ma to sens):
>>> x = "7"
>>> print x*3
777
>>> x = eval(x) # obliczenie wartości
21
Gdybyśmy nie pracowali w trybie interaktywnym, a zapisywali kod do pliku, moglibyśmy przekształcenie zapisać prościej:
x = `x` # odwrotne apostrofy, to samo co "
eval"
Ciekawym elementem Pythona są tzw. plasterki (ang. slices). Łańcuch znaków zostaje pocięty na " plasterki" , oznaczane nawiasami kwadratowymi. I tak łańcuch [0] oznacza pierwszy znak łańcucha, łańcuch [1] -- drugi, itd.:
>>> s = "lajkonik"
>>> print s[0]
l
>>> print s[1]
a
Prawda, że proste? Python idzie nieco dalej -- ogólniejsze " krojenie" polega na wskazaniu dolnego indeksu i górnego (w ten sposób dostaniemy się do fragmentu od wskazanego dolnego indeksu do górnego, ale bez niego). Jeśli opuścimy, któryś z indeksów, to Python przyjmie domyślnie skrajne wartości (odpowiednio -- 0 i długość łańcucha).
Łańcuch [:2] odnosi się do pierwszych dwóch znaków łańcucha (czyli znaków o indeksie 0 i 1), zaś łańcuch [2:] -- do wszystkiego oprócz pierwszych dwóch znaków:
>>> print s[2:]
jkonik
>>> print s[:2]
la
Jak można się domyślić, łańcuch [1:5] zwraca od drugiego do piątego (od znaku o indeksie 1 do znaku o indeksie 4) znaku łańcucha:
>>> print s[1:5]
ajko
Nierzadko zdarza się, że końcowa pozycja interesuje nas w odniesieniu do długości podawanego łańcucha, np.:
>>> print s[:len(s)-1]
lajkoni
Czyli dostaliśmy napis bez ostatniego znaku. Ale Python upraszcza nam życie jeszcze bardziej --- indeksować można z pominięciem obliczenia długości, podając samą (ujemną) wartość. Czyli:
>>> print s[:-1]
Czy to jasne? Poprosiliśmy Pythona o podanie łańcucha począwszy od znaku o indeksie 0 (pierwszego) do przedostatniego.
Pisanie pod lupą
Powyżej używaliśmy polecenia print z rozmaitymi operatorami. Teraz opiszemy je nieco dokładniej.
print "ala ma kota"
wypisze podany tekst i wstawi znak [enter]. Jeżeli chcemy tego uniknąć musimy postawić na samym końcu podanego tekstu znak przecinka:
print "ala ma kota",
A teraz spróbujmy w ten sposób:
print "ala", "ma","kota"
Jak powinieneś zauważyć tekst zostanie wydrukowany ze spacjami pomiędzy wyrazami. Przecinek bowiem między podanymi napisami wstawia odstęp. A jeśli chcielibyśmy tego uniknąć? Voila:
print "ala"+"ma"+"kota"
dostaniemy zbitkę słów bez rozdzielającej spacji.
3.2 Liczby
Operacje na liczbach również odbywają się w sposób intuicyjny, Rozważmy prosty przykład:
>>> a = 10
>>> b = 10
10 10
Dwom zmiennym, a i b, przypisaliśmy wartość dziesięć. Nie ma problemu ze standardowymi operacjami na liczbach:
>>> print a+b, a-b, a*b, a/b
20 0 100 1
Zaokrąglanie:
>>> round(10.5)
11.0
Potęgowanie:
>>> pow(5,2)
25
Albo i tak:
>>> 5 ** 2
Operacje bitowe (odpowiednio --- bitowe or, dopełnienie, przesunięcie w lewo):
>>> 4|1, ~4, 4>>1
(5, -5, 2)
Jeśli chcemy natomiast dokonać operacji logicznych, to musimy pisać pełnymi słowami (poniższy przykład nie ma znaczenia w sensie zdrowego rozsądku):
>>> 4 or 2, 5 and 3
(4, 3)
Konwersja między różnymi systemami:
>>> hex(10), oct(10)
('0xa', '012')
Od wersji Pythona w okolicach 2.0 można stosować nienadmiarowe dodawanie (znane dobrze z C):
>>> x = 10
>>> x += 5
>>> print x
15
Zapis:
X operator= ...
jest skrótem od
X = X operator (...)
ale nie jest w 100% mu tożsamy (o tym później). W każdym razie mamy do dyspozycji wszystkie sensowne skrótowce istniejące w Pythonie także w wersji pełnej (" +=" , " -" , " *=" , etc. --- chyba nie ma potrzeby wymieniać tu całej menażerii?).
3.3 Listy
Listy przypominają nieco tablice w innych językach. Charakteryzują się umieszczeniem elementów w nawiasach kwadratowych. Rozważmy prosty przykład:
>>> lista = ["Polak", "Rosjanin", "Niemiec"]
>>> print lista
['Polak', 'Rosjanin', 'Niemiec']
Na listach możemy dokonywać standardowych operacji: dodawać nowe elementy, usuwać stare, sortować, wyłapywać fragmenty (tak jak dla napisów -- napis jest tak naprawdę listą znaków)... Jeśli wydamy polecenie dir(nazwa typu), otrzymamy listing nazw operacji, które można przeprowadzać na danym typie:
>>> dir(lista)
['append', 'count', 'extend', 'index', 'insert', 'pop', 'remove', 'reverse', 'sort']
>>> lista.append("Maciej")
['Polak', 'Rosjanin', 'Niemiec', 'Maciej']
>>> lista.sort()
['Maciej', 'Niemiec', 'Polak', 'Rosjanin']
Co ciekawe, w Pythonie mamy dostęp do prostej " dokumentacji" używanych funkcji przy pomocy atrybutu .__doc__. Np.:
>>> print lista.append.__doc__
L.append(object) -- append object to end
...co się przydaje, jeśli nie jesteśmy pewni, jak użyć danej funkcji:
['Tytus', 'Romek', 'Atomek']
>>> lista.insert.__doc__
'L.insert(index, object) -- insert object before index'
>>> lista.insert(1, "Szarik")
['Tytus', 'Szarik', 'Romek', 'Atomek']
Jak widać używanie list jest o niebo prostsze niż w innych językach.
3.4 Zbiory (tuple) i słowniki
Na marginesie: bardzo formalnie rzecz biorąc tłumaczenie słowa " tuple" jako " zbiór" nie jest poprawne; w polskojęzycznej literaturze stosuje się inne, bardziej poprawne merytorycznie zwroty, ale są one tak szkaradne, iż nie ośmielamy się ich przytoczyć nawet małą czcionką.
Zbiór to typ danych bardzo przypominający listę, wizualnie różni się brakiem nawiasów.
>>> kolejka = 'Jacek', 'Wacek', 'Pankracek'
>>> print kolejka
('Jacek', 'Wacek', 'Pankracek')
>>> print kolejka[1]
Wacek
W przeciwieństwie do list, wartości zbiorów są niezmienne:
>>> kolejka[1] = 'Agatka'
Traceback (innermost last):
File "<stdin>", line 1, in ?
TypeError: object doesn't support item assignment
Słowniki zaś przypominają tablice asocjacyjne: z każdą wartością jest skojarzony jakiś klucz. Kolejność w słowniku nie ma żadnego znaczenia, dlatego zwykłe indeksowanie nie zadziała. Najlepiej wyjaśnić to na przykładzie:
>>> slownik = { 'Ania':96, 'Gosia':69}
>>> slownik['Ania']
96
Zobaczmy, jakich funkcji możemy użyć, by manipulować słownikami:
>>> dir(slownik)
['clear', 'copy', 'get', 'has_key', 'items', 'keys', 'update', 'values']
Keys() służy do wyświetlania kluczy:
>>> print slownik.keys()
['Ania', 'Gosia']
Zaś values() do wyświetlania wartości:
>>> print slownik.values()
[96, 69]
Do poszczególnych par możemy się dostać w ten sposób:
>>> print slownik.items()[1]
('Gosia', 69)
4. Podstawy sterowania programem
...odbywa się przy pomocy standardowych mechanizmów znanych z innych języków. Należy zauważyć, że w Pythonie indentacja (" wcięcia" ) spełniają rolę ograniczników ({}, BEGIN..END) z innych języków.
4.1 Konstrukcje warunkowe
if (jeśli)
>>> if 2+2==4:
... print "2+2=4!"
...
2+2=4!
Należy zwrócić uwagę na dwukropek kończący warunek oraz wcięcie poprzedzające instrukcję.
elif ("jeśli natomiast...")
>>> if 2+2==5:
... print "tego raczej nie wydrukujemy"
... elif 2+2==4:
... print "a to właśnie powinniśmy zobaczyć"
Konstrukcje " if-elif-elif-..." możemy ciągnąć dość długo -- w Pythonie zastępują one znane z innych języków " case/switch" . else ("a jeśli nie, to...")
... print "Murphy powiedziałby..."
... else:
xyzgeo