Pierwsze kroki w Pythonie#

Niniejszy skrypt będzie wykorzystywał niewielką liczbę opcji, które oferuje programowanie w języku Python. Aby zrozumieć pojawiające się w dalszej części programy wystarczą nam podstawowe operacje na obiektach liczbowych, zmiennych logicznych, operacje na listach i definiowanie funkcji oraz instrukcji warunkowych. Specyficzne funkcje związane z konkretnym zagadnieniem będą wprowadzane w toku tego kursu i pojawią się w odpowiednich rozdziałach.

Wykonywanie operacji arytmetycznych na liczbach całkowitych.#

Na liczbach całkowitych możemy w języku Python wykonywać w sposób dokładny, tzn. bez utraty precyzji operacjie dodawania +, odejmowania -, mnożenia * oraz obliczania reszty z dzielenia, tzw. operacji modulo %. Dzielenie całkowitoliczbowe, tj.

1+1   #dodawanie

12-3  #odejmowanie

2*3   #mnożenie

10//4 #to jest komentarz, dzielenie całkowitoliczbowe

10/4  #to jest dzielenie zmiennoprzecinkowe

10%4  #reszta z dzielenia

10//4
2

Zadanie 1: a/b = a//b + ( a%b ) /b

Jaki jest związek między a//b, a%b i a/b ?

Obliczenia symboliczne#

W Pythonie możemy wykonywać wygodnie obliczenia symboliczne zbliżone do stylu jaki jest obecny w typowych rozumowaniach matematycznych.

z=var('z')
x=var('x')
10/4
2.5
((z+x)**100).expand()
x^100 + 100*x^99*z + 4950*x^98*z^2 + 161700*x^97*z^3 + 3921225*x^96*z^4 + 75287520*x^95*z^5 + 1192052400*x^94*z^6 + 16007560800*x^93*z^7 + 186087894300*x^92*z^8 + 1902231808400*x^91*z^9 + 17310309456440*x^90*z^10 + 141629804643600*x^89*z^11 + 1050421051106700*x^88*z^12 + 7110542499799200*x^87*z^13 + 44186942677323600*x^86*z^14 + 253338471349988640*x^85*z^15 + 1345860629046814650*x^84*z^16 + 6650134872937201800*x^83*z^17 + 30664510802988208300*x^82*z^18 + 132341572939212267400*x^81*z^19 + 535983370403809682970*x^80*z^20 + 2041841411062132125600*x^79*z^21 + 7332066885177656269200*x^78*z^22 + 24865270306254660391200*x^77*z^23 + 79776075565900368755100*x^76*z^24 + 242519269720337121015504*x^75*z^25 + 699574816500972464467800*x^74*z^26 + 1917353200780443050763600*x^73*z^27 + 4998813702034726525205100*x^72*z^28 + 12410847811948286545336800*x^71*z^29 + 29372339821610944823963760*x^70*z^30 + 66324638306863423796047200*x^69*z^31 + 143012501349174257560226775*x^68*z^32 + 294692427022540894366527900*x^67*z^33 + 580717429720889409486981450*x^66*z^34 + 1095067153187962886461165020*x^65*z^35 + 1977204582144932989443770175*x^64*z^36 + 3420029547493938143902737600*x^63*z^37 + 5670048986634686922786117600*x^62*z^38 + 9013924030034630492634340800*x^61*z^39 + 13746234145802811501267369720*x^60*z^40 + 20116440213369968050635175200*x^59*z^41 + 28258808871162574166368460400*x^58*z^42 + 38116532895986727945334202400*x^57*z^43 + 49378235797073715747364762200*x^56*z^44 + 61448471214136179596720592960*x^55*z^45 + 73470998190814997343905056800*x^54*z^46 + 84413487283064039501507937600*x^53*z^47 + 93206558875049876949581681100*x^52*z^48 + 98913082887808032681188722800*x^51*z^49 + 100891344545564193334812497256*x^50*z^50 + 98913082887808032681188722800*x^49*z^51 + 93206558875049876949581681100*x^48*z^52 + 84413487283064039501507937600*x^47*z^53 + 73470998190814997343905056800*x^46*z^54 + 61448471214136179596720592960*x^45*z^55 + 49378235797073715747364762200*x^44*z^56 + 38116532895986727945334202400*x^43*z^57 + 28258808871162574166368460400*x^42*z^58 + 20116440213369968050635175200*x^41*z^59 + 13746234145802811501267369720*x^40*z^60 + 9013924030034630492634340800*x^39*z^61 + 5670048986634686922786117600*x^38*z^62 + 3420029547493938143902737600*x^37*z^63 + 1977204582144932989443770175*x^36*z^64 + 1095067153187962886461165020*x^35*z^65 + 580717429720889409486981450*x^34*z^66 + 294692427022540894366527900*x^33*z^67 + 143012501349174257560226775*x^32*z^68 + 66324638306863423796047200*x^31*z^69 + 29372339821610944823963760*x^30*z^70 + 12410847811948286545336800*x^29*z^71 + 4998813702034726525205100*x^28*z^72 + 1917353200780443050763600*x^27*z^73 + 699574816500972464467800*x^26*z^74 + 242519269720337121015504*x^25*z^75 + 79776075565900368755100*x^24*z^76 + 24865270306254660391200*x^23*z^77 + 7332066885177656269200*x^22*z^78 + 2041841411062132125600*x^21*z^79 + 535983370403809682970*x^20*z^80 + 132341572939212267400*x^19*z^81 + 30664510802988208300*x^18*z^82 + 6650134872937201800*x^17*z^83 + 1345860629046814650*x^16*z^84 + 253338471349988640*x^15*z^85 + 44186942677323600*x^14*z^86 + 7110542499799200*x^13*z^87 + 1050421051106700*x^12*z^88 + 141629804643600*x^11*z^89 + 17310309456440*x^10*z^90 + 1902231808400*x^9*z^91 + 186087894300*x^8*z^92 + 16007560800*x^7*z^93 + 1192052400*x^6*z^94 + 75287520*x^5*z^95 + 3921225*x^4*z^96 + 161700*x^3*z^97 + 4950*x^2*z^98 + 100*x*z^99 + z^100

Oblicznia możemy wykonywać na bardzo dużych liczbach, wynik będzie dokładny.

10%4
2
1267650600228229401496703205376//3948394
321054737756219212544822
5/2
5/2
2**10
1024
1/0 #otrzymujemy komunikat o błędzie
---------------------------------------------------------------------------
ZeroDivisionError                         Traceback (most recent call last)
<ipython-input-22-9e1622b385b6> in <module>
----> 1 1/0

ZeroDivisionError: division by zero

Kluczowe jest sprawdzanie typu obiektów, które używamy. Do tego służy słowo kluczowe type.

type(1+1)
int
type(3/4)
float

Typ int oznacza liczby całkowite. W Python 3.x są one nieograniczone w rozmiarze.

Typ float oznacza liczby zmiennopozycyjne.

z=var('z')
x=var('x')
a=438572349857234857234809572348952438957243890572349805723489573249857234089574398572045
b=198192819281928192819281934895724789562497856243785643278562439785624783562347895629348
((z+x)**100).expand()
x^100 + 100*x^99*z + 4950*x^98*z^2 + 161700*x^97*z^3 + 3921225*x^96*z^4 + 75287520*x^95*z^5 + 1192052400*x^94*z^6 + 16007560800*x^93*z^7 + 186087894300*x^92*z^8 + 1902231808400*x^91*z^9 + 17310309456440*x^90*z^10 + 141629804643600*x^89*z^11 + 1050421051106700*x^88*z^12 + 7110542499799200*x^87*z^13 + 44186942677323600*x^86*z^14 + 253338471349988640*x^85*z^15 + 1345860629046814650*x^84*z^16 + 6650134872937201800*x^83*z^17 + 30664510802988208300*x^82*z^18 + 132341572939212267400*x^81*z^19 + 535983370403809682970*x^80*z^20 + 2041841411062132125600*x^79*z^21 + 7332066885177656269200*x^78*z^22 + 24865270306254660391200*x^77*z^23 + 79776075565900368755100*x^76*z^24 + 242519269720337121015504*x^75*z^25 + 699574816500972464467800*x^74*z^26 + 1917353200780443050763600*x^73*z^27 + 4998813702034726525205100*x^72*z^28 + 12410847811948286545336800*x^71*z^29 + 29372339821610944823963760*x^70*z^30 + 66324638306863423796047200*x^69*z^31 + 143012501349174257560226775*x^68*z^32 + 294692427022540894366527900*x^67*z^33 + 580717429720889409486981450*x^66*z^34 + 1095067153187962886461165020*x^65*z^35 + 1977204582144932989443770175*x^64*z^36 + 3420029547493938143902737600*x^63*z^37 + 5670048986634686922786117600*x^62*z^38 + 9013924030034630492634340800*x^61*z^39 + 13746234145802811501267369720*x^60*z^40 + 20116440213369968050635175200*x^59*z^41 + 28258808871162574166368460400*x^58*z^42 + 38116532895986727945334202400*x^57*z^43 + 49378235797073715747364762200*x^56*z^44 + 61448471214136179596720592960*x^55*z^45 + 73470998190814997343905056800*x^54*z^46 + 84413487283064039501507937600*x^53*z^47 + 93206558875049876949581681100*x^52*z^48 + 98913082887808032681188722800*x^51*z^49 + 100891344545564193334812497256*x^50*z^50 + 98913082887808032681188722800*x^49*z^51 + 93206558875049876949581681100*x^48*z^52 + 84413487283064039501507937600*x^47*z^53 + 73470998190814997343905056800*x^46*z^54 + 61448471214136179596720592960*x^45*z^55 + 49378235797073715747364762200*x^44*z^56 + 38116532895986727945334202400*x^43*z^57 + 28258808871162574166368460400*x^42*z^58 + 20116440213369968050635175200*x^41*z^59 + 13746234145802811501267369720*x^40*z^60 + 9013924030034630492634340800*x^39*z^61 + 5670048986634686922786117600*x^38*z^62 + 3420029547493938143902737600*x^37*z^63 + 1977204582144932989443770175*x^36*z^64 + 1095067153187962886461165020*x^35*z^65 + 580717429720889409486981450*x^34*z^66 + 294692427022540894366527900*x^33*z^67 + 143012501349174257560226775*x^32*z^68 + 66324638306863423796047200*x^31*z^69 + 29372339821610944823963760*x^30*z^70 + 12410847811948286545336800*x^29*z^71 + 4998813702034726525205100*x^28*z^72 + 1917353200780443050763600*x^27*z^73 + 699574816500972464467800*x^26*z^74 + 242519269720337121015504*x^25*z^75 + 79776075565900368755100*x^24*z^76 + 24865270306254660391200*x^23*z^77 + 7332066885177656269200*x^22*z^78 + 2041841411062132125600*x^21*z^79 + 535983370403809682970*x^20*z^80 + 132341572939212267400*x^19*z^81 + 30664510802988208300*x^18*z^82 + 6650134872937201800*x^17*z^83 + 1345860629046814650*x^16*z^84 + 253338471349988640*x^15*z^85 + 44186942677323600*x^14*z^86 + 7110542499799200*x^13*z^87 + 1050421051106700*x^12*z^88 + 141629804643600*x^11*z^89 + 17310309456440*x^10*z^90 + 1902231808400*x^9*z^91 + 186087894300*x^8*z^92 + 16007560800*x^7*z^93 + 1192052400*x^6*z^94 + 75287520*x^5*z^95 + 3921225*x^4*z^96 + 161700*x^3*z^97 + 4950*x^2*z^98 + 100*x*z^99 + z^100
a+b
636765169139163050054091507244677228519741746816135449002052013035482017651922294201393
a/b #to jest typ float
2.2128569109931684
a//b #to jest typ int
2

Uwaga: symbol ^ nie oznacza potęgowania w standardowym Pythonie, tylko operację dodawania bitowego XOR!

Potęgowanie wykonujemy symbolem **

2^2
0
2**2
4
2**100
1267650600228229401496703205376

Operacje porównywania. Zakładamy, że \(a=5\) i \(b=10\).

Operator Opis Przykład
== Jeśli wartości argumentów są równe, warunk będzie prawdziwy. (a == b) nie jest prawdziwe.
!= Jeśli wartości argumentów nie są równe, warunk będzie prawdziwy. (a!= b) jest prawdziwe.
> Jeśli wartość lewego argumentu jest większa niż prawego argumentu, warunk będzie prawdziwy. (a > b) nie jest prawdziwe.
< Jeśli wartość lewego argumentu jest mniejsza niż prawego argumentu, warunk będzie prawdziwy. (a < b) jest prawdziwe.
>= Jeśli wartość lewego argumentu jest większa lub równa od prawego argumentu, warunk będzie prawdziwy. (a >= b) nie jest prawdziwe.
<= Jeśli wartość lewego argumentu jest mniejsza lub równa od prawego argumentu, warunk będzie prawdziwy. (a <= b) jest prawdziwe.

Wzorowane na Python3 tutorial.

Operatory logiczne and, or, not oraz wyrażenia True, False.

False and False
False
x=var('x')
z=var('z')
(z+x)**100
(x + z)^100
True or False
True
not True
False
True==1 # wartość True utożsamić można z dowolną liczbą niezerową
True
False==0 # wartość False utożsamić można z zerem
True

Możemy podstawiać wartości do etykiet (to są zmienne).

a=int("5")
print(a) #drukowanie wartości
5

Mamy też operatory skrócone:

Zamiast pisać a=a+5 co wyprodukuje wartość 10

wystarczy napisać a+=5. Podobnie dla pozostałych operatorów arymemtycznych.

Usuwanie zmiennej odbywa się za pomocą komendy del <zmienna>

del a

Nazwy zmiennych mogą być dowolną kombinacją liter (małych i dużych), podkreślników, cyfr

KKKKjfskdafasklfjasl_1_kdfjal___1111=1

Skrócone operacje arytmetyczne, np.

a+=5 zamiast a=a+5

a-=5 zamiast a=a-5

a*=5 zamiast a=a*5

a/=5 zamiast a=a/5

a//=5 zamiast a=a//5

a%=5 zamiast a=a%5

a=5
a%=5
print(a)
0
a=5
a*=5 #a=a*5
print(a)
25

Standardowe typy danych#

Znamy już dwa typy zmiennych float i int. Poznamy teraz typu string, który odnosi się napisów.

Napis umieszczamy w apostrofach '<tekst>', lub podwójnych apostrofach ''<tekst>'' lub cydzysłowach "<tekst>". W ten sposób możemy pisać ciąg znaków w jednej linii.

W potrójnych apostrofach '''<tekst>''' możemy wprowadzać tekst wieloliniowy.

napis='Ala ma'
napis2='kota'
print(napis,napis2)
Ala ma kota
type('a')
str
'aaaa'=="aaaa" #zapis 'tekst' i "tekst" są identyczne
True
'a'=='''a''' # drugi zapis pozwala wprowadzać wiele linii
True
s='''jlkgkjdslf
sdksjdksdjs
wowiowiwow
'''
print('''Ala 
ma 
kota''') #ciąg znaków wieloliniowy
Ala 
ma 
kota

Za pomocą jednoliniowych ciągów można uzyskać podobny efekt stosując symbol \n

print("Ala\nma\nkota")
Ala
ma
kota

Na typie str można wykonywać operacje arytmetyczne łączenia dwóch ciągów

<tekst1>+<tekst2>

i mnożenia

<tekst>*n. Liczba n jest dodatnia całkowita i oznacza n-krotne złączenie <tekst> ze sobą.

print('Ala'+' ma '+'kota.')
Ala ma  kota.
print('Ala'*10)
AlaAlaAlaAlaAlaAlaAlaAlaAlaAla

Lista jako typ danych. Python posiada funkcjonalność list jako typu danych

[<element1>,<element2>,...]

print([1,2,'pies','kot',3])
[1, 2, 'pies', 'kot', 3]
type([1,2,3])
list
lista1=[1,2,3] #inaczej range(1,4) 
type(range(1,4)) #UWAGA! range to nie to samo co lista!
range

Zadanie: Wypisz wszystkie obiekty, które są elementami listy

[[],[[],[[]]]]

[[],[[],[[]]]] #lista zagnieżdzona
[[], [[], [[]]]]

Na liście elementy mogą się powtarzać

[1,2,3,3]
[1, 2, 3, 3]
lista1 = [ 'abcd', 786 , 2.23, 'jaś', 70.2 ]
malalista = [123, 'jaś']

print(lista1)          # drukujemy całą listę
print(lista1[0])       # drukujemy pierwszy element listy
print(lista1[1:3])     # drukujemy elementy od drugiego do trzeciej
print(lista1[2:])      # drukujemy wszystkie elementy począwszy od trzeciego
print(malalista * 2)  # drukujemy podwojenie listy
print(lista1 + malalista) # drukujemy połączenie list
['abcd', 786, 2.23, 'jaś', 70.2]
abcd
[786, 2.23]
[2.23, 'jaś', 70.2]
[123, 'jaś', 123, 'jaś']
['abcd', 786, 2.23, 'jaś', 70.2, 123, 'jaś']
[11,13,15][-1] #stosowanie ujemnych indeksów przesuwa nas od końca listy w lewo
15

Nazwy podstawowych typów str, int,float oznaczają również nazwę funkcji, które pozwalają na konwersję do danego typu

type(str(2))
str
str(2)=='2'
True
float(1)
1.0

Zadanie:

Sprawdź ręcznie co wypisze następująca komenda

str(int(str(int('1001')+2)[0])*10+2)

str(int(str(int('1001')+2)[0])*10+2) = '22'
int('a') #Dlaczego otrzymaliśmy błąd?
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-145-233884bacd4e> in <module>
----> 1 int('a')

ValueError: invalid literal for int() with base 10: 'a'

Długość listy sprawdzamy komendą len

#Długość listy
len([1,2])
2
len([[],[[[]],[]]])
2
len([1,[2,[3]]]+[4,[5,[6]]])
4

Operator <lista>[a::b] wypisuje elementy z listy startując od pozycji a i skacząc co b pozycji

[0,1,2,3,4,5,6,7,8,9][3::4]
[3, 7]
[0,1,2,3,4,5,6,7,8,9][9::-2]
[9, 7, 5, 3, 1]

Przydatny trik: ignorując pierwszy argument możemy odwrócić listę

<lista>[::-1] == <odwrócona lista>

[1,2,3,4][::-1] #odwrócenie listy
[4, 3, 2, 1]

Typ danych set jest podobny do listy, ale jego elementy muszą być unikatowe

{1,1,1,1,1,1,1,3}
{1, 3}
set([1,1,1,1,1,1,3])
{1, 3}
{1,1,2}=={1,2}
True
[1,1,2]==[1,2]
False
a={1,2}
{} #zbiór pusty
{}

Na zbiorach możemy wykonywać standardowe operacje sumy, różnicy, dopełnienia korzystając z wbudowanych metod (operator kropki)

a={1,2}
print(a.union({2,3}))
print(a.difference({2,5}))
print(a.intersection({2,5}))
{1, 2, 3}
{1}
{2}

Konwersje pomiędzy typem set i list pozwalają usunąć powtarzające się elementy.

list(set([1,1,1,3]))
[1, 3]

Funkcja eval oblicza wartość argumentu.

eval('[3*%d]*%d'%(13,17)) #wyjaśnij!
[39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39]

Funkcje chr i ord pozwalają zamieniać symbole na kody ASCII i na odwrót

chr(ord('a')+3) #ord -> kod ASCII, chr -> symbol z numeru kodu ASCII
'd'

Iteracja#

Wykorzystamy pojęcie iteracji do wykonania wielokrotnego tej samej instrukcji

for i in ['Ala','ma','kota']:
    print(i)
Ala
ma
kota

Możemy również iterować wewnątrz listy i wykonywać pewne dodatkowe operacje

[i*2 for i in ['Ala','ma','kota']]
['AlaAla', 'mama', 'kotakota']
[j**2 for j in [1,2,3,4,5,6]]
[1, 4, 9, 16, 25, 36]
[j**2 for j in range(1,7)] # komenda range zastępuję generowanie zbioru; uwaga range(1,7)!=[1,2,3,4,5,6]
[1, 4, 9, 16, 25, 36]
range(1,7)!=[1,2,3,4,5,6]
True
['*'*i+'\n' for i in [1,2,3,4,5,6]]
['*\n', '**\n', '***\n', '****\n', '*****\n', '******\n']

Krotka (…) jest niemodyfikowalną wersją listy (zajmuje mniej miejsca i może być używana jako klucz w słowniku)

krotka=(1,2,3)
lista1=[1,2,3]
type(krotka)
tuple
type(lista1)
list
lista1[2]='pies'
print(lista1)
[1, 2, 'pies']
krotka[2]='pies' #krotek nie można modyfikować...
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-173-b73d72580ac5> in <module>
----> 1 krotka[2]='pies'

TypeError: 'tuple' object does not support item assignment
(1,2,3)+(4,5,6) #... ale można nadal łączyć
(1, 2, 3, 4, 5, 6)

Jak zapisać krotkę jednoelementową?

type((1)) #to nie jest krotka 1-elementowa
int
type((1,)) #operator przecinka ma pusty argument
tuple
1,2
(1, 2)