Pole / Arrays. Jan Kybic.

Podobné dokumenty
SPJA, cvičení 1. ipython, python, skripty. základy syntaxe: základní datové typy, řetězce. podmínky: if-elif-else, vyhodnocení logických výrazů

Programování: základní konstrukce, příklady, aplikace. IB111 Programování a algoritmizace

IB111 Úvod do programování skrze Python Přednáška 7

Konečný automat. Jan Kybic.

Funkce, řetězce, moduly

Časová složitost / Time complexity

Programy na PODMÍNĚNÝ příkaz IF a CASE

Programování v Pythonu

Výčtový typ strana 67

Třídění a vyhledávání Searching and sorting

Obsah. Předmluva 13 Zpětná vazba od čtenářů 14 Zdrojové kódy ke knize 15 Errata 15

Funkce, podmíněný příkaz if-else, příkaz cyklu for

IB111 Základy programování Radek Pelánek

(a kryptografické odbočky) IB111 Úvod do programování skrze Python

Vyučovací hodina. 1vyučovací hodina: 2vyučovací hodiny: Opakování z minulé hodiny. Procvičení nové látky

Algoritmizace a programování

Programování v Pythonu

B3B33ALP - Algoritmy a programování - Zkouška z předmětu B3B33ALP. Marek Boháč bohacm11

IB111 Úvod do programování skrze Python

Čtvrtek 8. prosince. Pascal - opakování základů. Struktura programu:

6. Příkazy a řídící struktury v Javě

Prioritní fronta, halda

B3B33ALP - Algoritmy a programování - Zkouška z předmětu B3B33ALP. Marek Boháč bohacm11

Úvod do programovacích jazyků (Java)

Programovací jazyk Pascal

Kolekce, cyklus foreach

IAJCE Přednáška č. 8. double tprumer = (t1 + t2 + t3 + t4 + t5 + t6 + t7) / 7; Console.Write("\nPrumerna teplota je {0}", tprumer);

Programy a algoritmy pracující s čísly. IB111 Úvod do programování skrze Python

Maturitní otázky z předmětu PROGRAMOVÁNÍ

(a kryptografické odbočky) IB111 Úvod do programování skrze Python

IB111 Základy programování Radek Pelánek

Algoritmizace a programování

Rozptylovací tabulky

Spojový seznam. Jan Kybic.

Paměť počítače. alg2 1

Pravděpodobnost, náhoda, kostky

VISUAL BASIC. Práce se soubory

Výrazy a operátory. Operátory Unární - unární a unární + Např.: a +b

II. Úlohy na vložené cykly a podprogramy

Pascal. Katedra aplikované kybernetiky. Ing. Miroslav Vavroušek. Verze 7

Rekurze a rychlé třídění

Dynamické programování

NPRG030 Programování I, 2017/18 1 / :22:16

Pole a kolekce. v C#, Javě a C++

Algoritmizace a programování

Předmluva k aktuálnímu vydání Úvod k prvnímu vydání z roku Typografické a syntaktické konvence... 20

5 Přehled operátorů, příkazy, přetypování

Vyhledávání. doc. Mgr. Jiří Dvorský, Ph.D. Katedra informatiky Fakulta elektrotechniky a informatiky VŠB TU Ostrava. Prezentace ke dni 21.

Chyby a výjimky. Chyba. Odkud se chyby berou? Kdo chyby opravuje? Co můžete dělat jako programátor? Dvě hlavní metody práce s chybami.

Komplexní čísla, Kombinatorika, pravděpodobnost a statistika, Posloupnosti a řady

Logické operace. Datový typ bool. Relační operátory. Logické operátory. IAJCE Přednáška č. 3. může nabýt hodnot: o true o false

int t1, t2, t3, t4, t5, t6, t7, prumer; t1=sys.readint();... t7=sys.readint(); prume pru r = r = ( 1+t 1+t t3+ t3+ t4 t5+ t5+ +t7 +t7 )/ ;

Programování v Pythonu

Programy a algoritmy pracující s čísly. IB111 Úvod do programování skrze Python

Datové typy a struktury

Programování v Pythonu

Kombinatorika, výpočty

Datové typy v Javě. Tomáš Pitner, upravil Marek Šabo

Da D to t v o é v ty t py IB111: Datové typy

IB111 Úvod do programování skrze Python

Datové struktury. Obsah přednášky: Definice pojmů. Abstraktní datové typy a jejich implementace. Algoritmizace (Y36ALG), Šumperk - 12.

Algoritmy a programování - Úvod

VÝUKOVÝ MATERIÁL. Bratislavská 2166, Varnsdorf, IČO: tel Číslo projektu

Sada 1 - Základy programování

EVROPSKÝ SOCIÁLNÍ FOND. Úvod do PHP PRAHA & EU INVESTUJEME DO VAŠÍ BUDOUCNOSTI

Algoritmizace prostorových úloh

while cyklus s podmínkou na začátku cyklus bez udání počtu opakování while podmínka příkazy; příkazy; příkazy; end; % další pokračování programu

MATEMATICKÁ STATISTIKA. Katedra matematiky a didaktiky matematiky Technická univerzita v Liberci

8. lekce Úvod do jazyka C 3. část Základní příkazy jazyka C Miroslav Jílek

1. Téma 03 - Rozhodování

Přednáška 7. Celočíselná aritmetika. Návratový kód. Příkazy pro větvení výpočtu. Cykly. Předčasné ukončení cyklu.

Neměnné objekty. Tomáš Pitner, upravil Marek Šabo

Základy programování (IZP)

Programy a algoritmy pracující s čísly. IB111 Úvod do programování

Inovace a zkvalitnění výuky prostřednictvím ICT Základy programování a algoritmizace úloh. Ing. Hodál Jaroslav, Ph.D. VY_32_INOVACE_25 09

Algoritmy a datové struktury

PHP tutoriál (základy PHP snadno a rychle)

Programování v Pythonu

Algoritmizace Dynamické programování. Jiří Vyskočil, Marko Genyg-Berezovskyj 2010

Booleovská algebra. Booleovské binární a unární funkce. Základní zákony.

Algoritmizace prostorových úloh

1/1 ČESKÁ ZEMĚDĚLSKÁ UNIVERZITA V PRAZE PROVOZNĚ EKONOMICKÁ FAKULTA PŘIJÍMACÍ ŘÍZENÍ 2017/2018

3. Řízení běhu programu

Zápis programu v jazyce C#

Elementární datové typy

Kombinatorika, pravděpodobnost a statistika, Posloupnosti a řady

7 Formátovaný výstup, třídy, objekty, pole, chyby v programech

PROGRAMOVÁNÍ V SHELLU

typová konverze typová inference

Pravděpodobnost, náhoda, kostky

9. přednáška - třídy, objekty

Programování v Pythonu

Michal Krátký. Úvod do programovacích jazyků (Java), 2006/2007

DSA, První krok: máme dokázat, že pro left = right vrátí volání f(array, elem, left, right)

Algoritmizace a programování

10. cvičení z PST. 5. prosince T = (n 1) S2 X. (n 1) s2 x σ 2 q χ 2 (n 1) (1 α 2 ). q χ 2 (n 1) 2. 2 x. (n 1) s. x = 1 6. x i = 457.

Obsah přednášky 7. Základy programování (IZAPR) Přednáška 7. Parametry metod. Parametry, argumenty. Parametry metod.

Rekurze. IB111 Úvod do programování skrze Python

Python 3 základní ukázky kódu

Příklad : String txt1 = new String( Ahoj vsichni! ); //vytvoří instanci třídy String a přiřadí ji vnitřní hodnotu Ahoj vsichni!

Transkript:

Pole / Arrays Jan Kybic http://cmp.felk.cvut.cz/~kybic kybic@fel.cvut.cz 2016 2018 1 / 67

Pole Hodnoty a reference Další příklady 2 / 67

Datové typy v Pythonu Jednoduché typy: (primitive data type) celé číslo, reálné číslo, logická hodnota, Složené typy / datové struktury: (composite/compound data type, data structures) řetězec, n-tice (tuple), pole 3 / 67

Složené typy / datové struktury Hierarchicky sdružují data Slouží k organizaci dat, související data jsou uložena a manipulována spolu Pro zvýšení efektivity programování i vykonávání Operace na datových strukturách Vytvoření Čtení jednotlivých složek (elementů) Modifikace jednotlivých složek Vyhledávání Přidávání, odebírání,... 4 / 67

Pole (Array) Obsahuje N elementů (objektů,prvků) Přímý přístup (random access) Pro čtení i zápis V konstantním čase 5 / 67

Pole v Pythonu Vytvoření >>> a=[0.3,0.6,0.1] >>> a [0.3, 0.6, 0.1] Čtení prvku >>> a[1] 0.6 >>> a[0] 0.3 V Pythonu má první prvek index 0. 6 / 67

Pole v Pythonu Vytvoření >>> a=[0.3,0.6,0.1] >>> a [0.3, 0.6, 0.1] Čtení prvku >>> a[1] 0.6 >>> a[0] 0.3 Změna prvku >>> a[2]=1.5 >>> a [0.3, 0.6, 1.5] V Pythonu má první prvek index 0. 6 / 67

Pole bez polí Vytvoření >>> a0=0.3 ; a1=0.6 ; a2=0.1 Čtení prvku >>> a1 0.6 >>> a0 0.3 Změna prvku >>> a2=1.5 7 / 67

S polem je to pohodlnější... Operace s celým polem a=[0.3,0.6,0.1] print(a) [0.3, 0.6, 0.1] Index může být výraz s=0. for i in range(3): s+=a[i] print("a[%d]=%f" % (i,a[i])) print(s) a[0]=0.300000 a[1]=0.600000 a[2]=0.100000 0.9999999999999999 8 / 67

Pole různých typů a=[0.3,0.6,0.1] print(a[0]) 0.3 b=[3,1,4,1,5,9,2] print(b[2]) 4 barvy=["srdce","listy","kule","žaludy"] print(barvy[3]) žaludy bits=[true,false] print(bits) [True, False] Homogenní pole = všechny prvky jsou stejného typu. 9 / 67

Funkce a pole Unární operace >>> a=[0.3,0.6,0.1] >>> print(a) [0.3, 0.6, 0.1] >>> len(a) 3 >>> sum(a) 0.9999999999999999 >>> max(a) 0.6 >>> bits=[true,false] >>> all(bits) False >>> any(bits) True 10 / 67

Funkce a pole Binární operace Spojování, opakování >>> a=[0.3,0.6,0.1] >>> b=[0.7,0.9] >>> a+b [0.3, 0.6, 0.1, 0.7, 0.9] >>> b*3 [0.7, 0.9, 0.7, 0.9, 0.7, 0.9] 11 / 67

Vytvoření pole Výčtem >>> a=[0.3,0.6,0.1] opakováním prvků >>> a=10*[0] Opakování používejte pouze pro primitivní nebo neměnné typy. 12 / 67

Vytvoření pole Výčtem >>> a=[0.3,0.6,0.1] opakováním prvků >>> a=10*[0] Opakování používejte pouze pro primitivní nebo neměnné typy. >>> a=3*[[1,2]] >>> a [[1, 2], [1, 2], [1, 2]] >>> a[1][0]=10 >>> a [[10, 2], [10, 2], [10, 2]] 12 / 67

Vytvoření pole (2) z posloupnosti >>> list(range(1,11)) [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] V Pythonu se tento druh pole jmenuje list 13 / 67

Vytvoření pole (2) z posloupnosti >>> list(range(1,11)) [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] V Pythonu se tento druh pole jmenuje list přidáváním na konec a=[] for i in range(10): a+=[0.0] print(a) [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0] Přidávání může být časově náročné. V jiných jazycích je délka pole pevná. 13 / 67

Vytvoření pole (3) výrazem (list comprehension) >>> [i for i in range(1,11)] [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] >>> [i*i for i in range(1,11)] [1, 4, 9, 16, 25, 36, 49, 64, 81, 100] >>> [0. for i in range(1,11)] [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0] Elegantní, ale specialita Pythonu nemusíte si pamatovat. 14 / 67

Indexace x[i] i-tý prvek x pro sekvenční typy: pole, řetězce, n-tice 15 / 67

Indexace x[i] i-tý prvek x pro sekvenční typy: pole, řetězce, n-tice a=[2,7,1] print(a[2]) 15 / 67

Indexace x[i] i-tý prvek x pro sekvenční typy: pole, řetězce, n-tice a=[2,7,1] print(a[2]) 1 15 / 67

Indexace x[i] i-tý prvek x pro sekvenční typy: pole, řetězce, n-tice a=[2,7,1] print(a[2]) 1 s="ferda" print(s[2]) 15 / 67

Indexace x[i] i-tý prvek x pro sekvenční typy: pole, řetězce, n-tice a=[2,7,1] print(a[2]) 1 s="ferda" print(s[2]) r 15 / 67

Indexace x[i] i-tý prvek x pro sekvenční typy: pole, řetězce, n-tice a=[2,7,1] print(a[2]) 1 s="ferda" print(s[2]) r t=(1,2) print(t[0]) 1 15 / 67

Indexace (2) Záporné indexy Specialita Pythonu nemusíte si pamatovat. x[i] pro i < 0 16 / 67

Indexace (2) Záporné indexy Specialita Pythonu nemusíte si pamatovat. >>> a=[6,7,5,2,9] >>> a [6, 7, 5, 2, 9] >>> a[-1] 9 >>> a[2] 5 >>> a[-2] 2 x[i] pro i < 0 x[i]=x[len(x)+i] 16 / 67

Řezy pole (array slicing) Specialita Pythonu nemusíte si pamatovat. x[i:j] = [ x[i], x[i+1],..., x[j-1] ] Příklad: a=[6,7,5,2,9] print(a[2:4]) 17 / 67

Řezy pole (array slicing) Specialita Pythonu nemusíte si pamatovat. x[i:j] = [ x[i], x[i+1],..., x[j-1] ] Příklad: a=[6,7,5,2,9] print(a[2:4]) [5, 2] 17 / 67

Řezy pole (2) (vynechané argumenty) x[i:]=x[i:len(x)] x[:j]=x[0:j] x[:]=x[0:len(x)]=x a=[6,7,5,2,9] print(a[:3]) 18 / 67

Řezy pole (2) (vynechané argumenty) x[i:]=x[i:len(x)] x[:j]=x[0:j] x[:]=x[0:len(x)]=x a=[6,7,5,2,9] print(a[:3]) [6, 7, 5] 18 / 67

Řezy pole (2) (vynechané argumenty) x[i:]=x[i:len(x)] x[:j]=x[0:j] x[:]=x[0:len(x)]=x a=[6,7,5,2,9] print(a[:3]) [6, 7, 5] print(a[-2:]) 18 / 67

Řezy pole (2) (vynechané argumenty) x[i:]=x[i:len(x)] x[:j]=x[0:j] x[:]=x[0:len(x)]=x a=[6,7,5,2,9] print(a[:3]) [6, 7, 5] print(a[-2:]) [2, 9] 18 / 67

Řezy pole (2) (vynechané argumenty) x[i:]=x[i:len(x)] x[:j]=x[0:j] x[:]=x[0:len(x)]=x a=[6,7,5,2,9] print(a[:3]) [6, 7, 5] print(a[-2:]) [2, 9] s="rakousko" print(s[3:]) ousko 18 / 67

Příklad: Jména dnů v týdnu Úkol: převeďte i {0,..., 6} na jméno dne. def jmeno_dne(i): if i==0: return "pondělí" elif i==1: return "úterý" elif i==2: return "středa" elif i==3: return "čtvrtek" elif i==4: return "pátek" elif i==5: return "sobota" elif i==6: return "neděle" else: return "???" 19 / 67

Příklad: Jména dnů v týdnu (2) print(jmeno_dne(3)) čtvrtek 20 / 67

Příklad: Jména dnů v týdnu (3) Řešení pomocí pole jmena_dni=["pondělí","úterý","středa","čtvrtek", "pátek","sobota","neděle"] print(jmena_dni[3]) 21 / 67

Příklad: Jména dnů v týdnu (3) Řešení pomocí pole jmena_dni=["pondělí","úterý","středa","čtvrtek", "pátek","sobota","neděle"] print(jmena_dni[3]) čtvrtek 21 / 67

Příklad: Jména dnů v týdnu (3) Řešení pomocí pole jmena_dni=["pondělí","úterý","středa","čtvrtek", "pátek","sobota","neděle"] print(jmena_dni[3]) čtvrtek def jmeno_dne(i): return jmena_dni[i] print(jmeno_dne(3)) 21 / 67

Příklad: Jména dnů v týdnu (3) Řešení pomocí pole jmena_dni=["pondělí","úterý","středa","čtvrtek", "pátek","sobota","neděle"] print(jmena_dni[3]) čtvrtek def jmeno_dne(i): return jmena_dni[i] print(jmeno_dne(3)) čtvrtek 21 / 67

Příklad: Jména dnů v týdnu (3) Řešení pomocí pole jmena_dni=["pondělí","úterý","středa","čtvrtek", "pátek","sobota","neděle"] print(jmena_dni[3]) čtvrtek def jmeno_dne(i): return jmena_dni[i] print(jmeno_dne(3)) čtvrtek Uzávorkovaný výraz lze rozdělit na více řádek. 21 / 67

Příklad: průměr a směrodatná odchylka Odhad ze vzorků µ x = 1 N N x i, σ x = 1 N (x i µ x ) N 1 2 i=1 def mean(v): "Calculate a mean of a vector" s=0. for i in range(len(v)): s+=v[i] return(s/len(v)) i=1 Řetězec za hlavičkou funkce slouží k dokumentaci. Lze ho zobrazit příkazem help(mean). 22 / 67

Příklad: průměr a směrodatná odchylka (2) µ x = 1 N import math N x i, σ x = 1 N (x i µ x ) N 1 2 i=1 def stdev(v): "Calculate a corrected sample standard deviation" m=mean(v) s=0. for i in range(len(v)): s+=(v[i]-m)**2 return math.sqrt(s/(len(v)-1)) i=1 23 / 67

Příklad: průměr a směrodatná odchylka (3) Vypočítáme µ, σ pro x 1 = 0,..., x 1001 = 1000 a=list(range(1001)) print("mean=",mean(a)," sigma=",stdev(a)) mean= 500.0 sigma= 289.10811126635656 Pro spojitou uniformní distribuci [0, 1000] je µ = 500 a σ = 1000 12 288.67. 24 / 67

Pole jako argument cyklu Průměr podruhé Místo def mean(v): "Calculate a mean of a vector" s=0. for i in range(len(v)): s+=v[i] return(s/len(v)) Můžeme psát def mean(v): "Calculate a mean of a vector" s=0. for x in v: s+=x return(s/len(v)) Argumentem cyklu for je sekvence, například pole. 25 / 67

Pole jako argument cyklu (2) Výsledek je stejný def mean(v): "Calculate a mean of a vector" s=0. for x in v: s+=x return(s/len(v)) a=list(range(1001)) print("mean=",mean(a)) mean= 500.0 26 / 67

Použití funkcí pole Průměr potřetí Místo: def mean(v): s=0. for x in v: s+=x return(s/len(v)) Můžeme psát def mean(v): "Calculate a mean of a vector" return(sum(v)/len(v)) Pokud můžete, používejte existující funkce. 27 / 67

Použití funkcí pole (2) Směrodatná odchylka podruhé Místo: def stdev(v): "Calculate a corrected sample standard deviation" m=mean(v) s=0. for i in range(len(v)): s+=(v[i]-m)**2 return math.sqrt(s/(len(v)-1)) Můžeme psát def stdev(v): "Calculate a corrected sample standard deviation" m=mean(v) s=sum([(x-m)**2 for x in v]) return math.sqrt(s/(len(v)-1)) 28 / 67

Použití funkcí pole (2) def stdev(v): "Calculate a corrected sample standard deviation" m=mean(v) s=sum([(x-m)**2 for x in v]) return math.sqrt(s/(len(v)-1)) lze dále zkrátit def stdev(v): return math.sqrt(sum([(x-mean(v))**2 for x in v])/ (len(v)-1)) 29 / 67

Použití funkcí pole (2) def stdev(v): "Calculate a corrected sample standard deviation" m=mean(v) s=sum([(x-m)**2 for x in v]) return math.sqrt(s/(len(v)-1)) lze dále zkrátit def stdev(v): return math.sqrt(sum([(x-mean(v))**2 for x in v])/ (len(v)-1)) Výsledek se nezměnil print("mean=",mean(a)," sigma=",stdev(a)) mean= 500.0 sigma= 289.10811126635656 Zkracování může zhoršit srozumitelnost kódu. 29 / 67

Příklad: Náhodná permutace Vytvořte náhodnou permutace čísel 0, 1,..., N 1 30 / 67

Příklad: Náhodná permutace Vytvořte náhodnou permutace čísel 0, 1,..., N 1 Myšlenka Uložíme do pole počáteční permutací 0, 1,..., N 1 Budeme vyměňovat vždy dva prvky Aktuální prvek i = 0,..., N 2 vyměníme s náhodně vybraným prvkem na pozici j = i, i + 1,..., N 1 30 / 67

Příklad: Náhodná permutace (2) import random def permutation(n): "Create a random permutation of integers 0..n-1" p=list(range(n)) for i in range(n-1): r=random.randrange(i,n) temp=p[r] p[r]=p[i] p[i]=temp return(p) 31 / 67

Příklad: Náhodná permutace (3) Vyzkoušíme: print(permutation(10)) [9, 5, 3, 2, 4, 8, 0, 6, 1, 7] print(permutation(10)) [7, 0, 6, 4, 2, 9, 3, 8, 5, 1] print(permutation(10)) [5, 8, 1, 7, 0, 9, 6, 4, 2, 3] 32 / 67

Kontrolní tisky Jak to vlastně funguje def permutation(n): "Create a random permutation of integers 0..n-1" p=list(range(n)) print("p=",p) for i in range(n-1): r=random.randrange(i,n) temp=p[r] p[r]=p[i] p[i]=temp print("i=%d r=%d p=%s" % (i,r,str(p))) return(p) permutation(5) 33 / 67

Kontrolní tisky (2) p= [0, 1, 2, 3, 4] i=0 r=0 p=[0, 1, 2, 3, 4] i=1 r=4 p=[0, 4, 2, 3, 1] i=2 r=3 p=[0, 4, 3, 2, 1] i=3 r=4 p=[0, 4, 3, 1, 2] Toto je velmi obecná a užitečná technika ověření funkčnosti programů. 34 / 67

Permutace pole Vytiskneme prvky pole v náhodném pořadí: barvy=["srdce","listy","kule","žaludy"] p=permutation(len(barvy)) for i in range(len(barvy)): print(barvy[p[i]]) 35 / 67

Permutace pole Vytiskneme prvky pole v náhodném pořadí: barvy=["srdce","listy","kule","žaludy"] p=permutation(len(barvy)) for i in range(len(barvy)): print(barvy[p[i]]) žaludy kule listy srdce 35 / 67

Permutace pole Vytiskneme prvky pole v náhodném pořadí: barvy=["srdce","listy","kule","žaludy"] p=permutation(len(barvy)) for i in range(len(barvy)): print(barvy[p[i]]) žaludy kule listy srdce Pole v novém pořadí: print([ barvy[i] for i in p]) ['žaludy', 'kule', 'listy', 'srdce'] 35 / 67

Příklad: Házení dvěma kostkami Jaká je pravděpodobnost, že padne součet s? 36 / 67

Příklad: Házení dvěma kostkami Jaká je pravděpodobnost, že padne součet s? P(s) = počet příznivých počet celkem = 6 s 7 6 2 s počet možností P(s) 2 1 0.028 3 2 0.056 4 3 0.083 5 4 0.111 6 5 0.139 7 6 0.167 8 5 0.139 9 4 0.111 10 3 0.083 11 2 0.056 12 1 0.028 36 / 67

Simulace házení dvěma kostkami import random h=[0]*13 # četnost výskytu součtu h[s] n=100000 # Simulace n dvojic hodů for i in range(n): x=random.randrange(1,7) y=random.randrange(1,7) s=x+y h[s]+=1 Soubor dve_kostky.py 37 / 67

Simulace házení dvěma kostkami (2) # Tisk výsledných pravděpodobností for s in range(2,13): anal=(6-abs(s-7))/36 simul=h[s]/n print("s=%2d P(s)=analyticky %0.3f " "simulace %0.3f chyba %6.3f" % (s,anal,simul,anal-simul)) Soubor dve_kostky.py 38 / 67

Simulace házení dvěma kostkami (2) Terminal> python3 dve_kostky.py s= 2 P(s)=analyticky 0.028 simulace 0.028 chyba -0.000 s= 3 P(s)=analyticky 0.056 simulace 0.056 chyba -0.000 s= 4 P(s)=analyticky 0.083 simulace 0.083 chyba 0.001 s= 5 P(s)=analyticky 0.111 simulace 0.113 chyba -0.001 s= 6 P(s)=analyticky 0.139 simulace 0.137 chyba 0.002 s= 7 P(s)=analyticky 0.167 simulace 0.168 chyba -0.001 s= 8 P(s)=analyticky 0.139 simulace 0.138 chyba 0.001 s= 9 P(s)=analyticky 0.111 simulace 0.113 chyba -0.002 s=10 P(s)=analyticky 0.083 simulace 0.083 chyba 0.001 s=11 P(s)=analyticky 0.056 simulace 0.054 chyba 0.001 s=12 P(s)=analyticky 0.028 simulace 0.028 chyba -0.000 39 / 67

Pole Hodnoty a reference Další příklady 40 / 67

Hodnotová semantika (value semantics) U objektu je důležitá hodnota, nikoliv identita. Proměnná reprezentuje hodnotu. Primitivní typy v Pythonu se chovají jako hodnoty (values) Přiřazení vytvoří nový objekt. a=7 b=a a=6 print(a) 41 / 67

Hodnotová semantika (value semantics) U objektu je důležitá hodnota, nikoliv identita. Proměnná reprezentuje hodnotu. Primitivní typy v Pythonu se chovají jako hodnoty (values) Přiřazení vytvoří nový objekt. a=7 b=a a=6 print(a) 6 41 / 67

Hodnotová semantika (value semantics) U objektu je důležitá hodnota, nikoliv identita. Proměnná reprezentuje hodnotu. Primitivní typy v Pythonu se chovají jako hodnoty (values) Přiřazení vytvoří nový objekt. a=7 b=a a=6 print(a) 6 print(b) 41 / 67

Hodnotová semantika (value semantics) U objektu je důležitá hodnota, nikoliv identita. Proměnná reprezentuje hodnotu. Primitivní typy v Pythonu se chovají jako hodnoty (values) Přiřazení vytvoří nový objekt. a=7 b=a a=6 print(a) 6 print(b) 7 41 / 67

Referenční semantika (reference semantics) Proměnná typu pole je referencí/odkazem (reference,link) Přiřazení vytvoří nový odkaz na existující objekt. a=[7,3] b=a a[1]=6 print(a) 42 / 67

Referenční semantika (reference semantics) Proměnná typu pole je referencí/odkazem (reference,link) Přiřazení vytvoří nový odkaz na existující objekt. a=[7,3] b=a a[1]=6 print(a) [7, 6] 42 / 67

Referenční semantika (reference semantics) Proměnná typu pole je referencí/odkazem (reference,link) Přiřazení vytvoří nový odkaz na existující objekt. a=[7,3] b=a a[1]=6 print(a) [7, 6] print(b) 42 / 67

Referenční semantika (reference semantics) Proměnná typu pole je referencí/odkazem (reference,link) Přiřazení vytvoří nový odkaz na existující objekt. a=[7,3] b=a a[1]=6 print(a) [7, 6] print(b) [7, 6] Pole lze měnit (mutable) Sdílení odkazů (sharing,aliasing) 42 / 67

Neměnnost (immutability) Vlastnost datového typu. Neměnné objekty po vytvoření změnit nelze řetězce,n-tice >>> s="ahoj" >>> s[0]="a" TypeError: 'str' object does not support item assignment 43 / 67

Neměnnost (immutability) Vlastnost datového typu. Neměnné objekty po vytvoření změnit nelze řetězce,n-tice >>> s="ahoj" >>> s[0]="a" TypeError: 'str' object does not support item assignment Neměnné typy (řetězce,n-tice) se také chovají jako hodnoty a="raz" b=a a="dva" print(a) dva 43 / 67

Neměnnost (immutability) Vlastnost datového typu. Neměnné objekty po vytvoření změnit nelze řetězce,n-tice >>> s="ahoj" >>> s[0]="a" TypeError: 'str' object does not support item assignment Neměnné typy (řetězce,n-tice) se také chovají jako hodnoty a="raz" b=a a="dva" print(a) dva print(b) 43 / 67

Neměnnost (immutability) Vlastnost datového typu. Neměnné objekty po vytvoření změnit nelze řetězce,n-tice >>> s="ahoj" >>> s[0]="a" TypeError: 'str' object does not support item assignment Neměnné typy (řetězce,n-tice) se také chovají jako hodnoty a="raz" b=a a="dva" print(a) dva print(b) raz 43 / 67

Neměnnost (immutability) Vlastnost datového typu. Neměnné objekty po vytvoření změnit nelze řetězce,n-tice >>> s="ahoj" >>> s[0]="a" TypeError: 'str' object does not support item assignment Neměnné typy (řetězce,n-tice) se také chovají jako hodnoty a="raz" b=a a="dva" print(a) dva print(b) raz Proměnné v Pythonu nejsou hodnoty, ale odkazy (references). 43 / 67

Práce s neměnnými objekty Jak lze s neměnnými objekty pracovat? 44 / 67

Práce s neměnnými objekty Jak lze s neměnnými objekty pracovat? Vytvoříme objekt nový, nezávislý na starém. >>> s="ahoj" >>> r="a"+s[1:] >>> r ahoj >>> s Ahoj 44 / 67

Vedlejší efekty funkcí Funkce může změnit své změnitelné (mutable) parametry def add_one(x): for i in range(len(x)): x[i]+=1 v=[1,2,3] add_one(v) print(v) 45 / 67

Vedlejší efekty funkcí Funkce může změnit své změnitelné (mutable) parametry def add_one(x): for i in range(len(x)): x[i]+=1 v=[1,2,3] add_one(v) print(v) [2, 3, 4] 45 / 67

Vedlejší efekty funkcí Funkce může změnit své změnitelné (mutable) parametry def add_one(x): for i in range(len(x)): x[i]+=1 v=[1,2,3] add_one(v) print(v) [2, 3, 4] Funkce není čistá (impure). Vedlejším efektům se pokud možno vyhněte. 45 / 67

Nahrazení vedlejších efektů def add_one_clean(x): return [ x[i]+1 for i in range(len(x))] v=[1,2,3] v=add_one_clean(v) print(v) [2, 3, 4] 46 / 67

Kopírování polí Přiřazení proměnné typu pole vytvoří nový odkaz na stejné pole a=[7,3] b=a a[1]=6 print("a=",a, "b=",b) a= [7, 6] b= [7, 6] 47 / 67

Kopírování polí Přiřazení proměnné typu pole vytvoří nový odkaz na stejné pole a=[7,3] b=a a[1]=6 print("a=",a, "b=",b) a= [7, 6] b= [7, 6] Kopírováním se vytvoří nový objekt se stejným obsahem a=[7,3] b=a.copy() a[1]=6 print("a=",a, "b=",b) a= [7, 6] b= [7, 3] Lze psát též b=a[:] 47 / 67

Kopírování polí Přiřazení proměnné typu pole vytvoří nový odkaz na stejné pole a=[7,3] b=a a[1]=6 print("a=",a, "b=",b) a= [7, 6] b= [7, 6] Kopírováním se vytvoří nový objekt se stejným obsahem a=[7,3] b=a.copy() a[1]=6 print("a=",a, "b=",b) a= [7, 6] b= [7, 3] Lze psát též b=a[:] Kopírování je mělké (shallow), jen jedna úroveň. 47 / 67

Neměnost Immutability Výhody Vyloučení vedlejších efektů Méně chyb Kdy kopírovat, co lze přepsat Vzdálený kód mění proměnné Snazší optimalizace Snazší paralelizace 48 / 67

Neměnost Immutability Výhody Vyloučení vedlejších efektů Méně chyb Kdy kopírovat, co lze přepsat Vzdálený kód mění proměnné Snazší optimalizace Snazší paralelizace Nevýhody Trochu menší expresivita. Objektů vzniká velké množství, alokace/dealokace paměti. Nutnost kopírování. Paměťová a výpočetní náročnost. 48 / 67

Neměnost Immutability Výhody Vyloučení vedlejších efektů Méně chyb Kdy kopírovat, co lze přepsat Vzdálený kód mění proměnné Snazší optimalizace Snazší paralelizace Nevýhody Trochu menší expresivita. Objektů vzniká velké množství, alokace/dealokace paměti. Nutnost kopírování. Paměťová a výpočetní náročnost. Existují techniky jak kopírování omezit. 48 / 67

Pole Hodnoty a reference Další příklady 49 / 67

Příklad: Problém sběratele Coupon collector Kolikrát musíme náhodně s opakováním vybrat z množiny N prvků, než vybereme každý prvek alespoň jednou? 50 / 67

Příklad: Problém sběratele Coupon collector Kolikrát musíme náhodně s opakováním vybrat z množiny N prvků, než vybereme každý prvek alespoň jednou? Matematická analýza počet výběrů = T (N) = N H N N(log N + 0.577) + 0.5 T (50) = 225 50 / 67

coupon_collector.py # -*- coding: utf-8 -*- # Simulace problému sběratele, import random import sys n=int(sys.argv[1]) # počet různých prvků collectedcount=0 # počet již vybraných různých prvků iscollected=[false]*n # již jsme viděli tento prvek count=0 # kolik prvků jsme již vybrali while collectedcount < n: r=random.randrange(n) # náhodný prvek 0..n-1 count+=1 if not iscollected[r]: # nový prvek collectedcount+=1 iscollected[r]=true print("pro n=%d bylo potřeba %d výběrů." % (n,count)) 51 / 67

Terminal> python3 coupon_collector.py 50 Pro n=50 bylo potřeba 352 výběrů. Terminal> python3 coupon_collector.py 50 Pro n=50 bylo potřeba 258 výběrů. Terminal> python3 coupon_collector.py 50 Pro n=50 bylo potřeba 157 výběrů. Terminal> python3 coupon_collector.py 50 Pro n=50 bylo potřeba 218 výběrů. 52 / 67

Prvočísla prvocislo3.py # prvocislo3.py - Vypíše prvočísla menší než zadaný limit import sys m=int(sys.argv[1]) for n in range(2,m): # cyklus 2..m-1 p=2 # začátek testu while p*p<=n: if n % p == 0: break p+=1 if p*p > n: # n je prvočíslo print(n,end=", ") print() # závěrečný konec řádky 53 / 67

Terminal> python3 prvocislo3.py 1000 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 127, 131, 137, 139, 149, 151, 157, 163, 167, 173, 179, 181, 191, 193, 197, 199, 211, 223, 227, 229, 233, 239, 241, 251, 257, 263, 269, 271, 277, 281, 283, 293, 307, 311, 313, 317, 331, 337, 347, 349, 353, 359, 367, 373, 379, 383, 389, 397, 401, 409, 419, 421, 431, 433, 439, 443, 449, 457, 461, 463, 467, 479, 487, 491, 499, 503, 509, 521, 523, 541, 547, 557, 563, 569, 571, 577, 587, 593, 599, 601, 607, 613, 617, 619, 631, 641, 643, 647, 653, 659, 661, 673, 677, 683, 691, 701, 709, 719, 727, 733, 739, 743, 751, 757, 761, 769, 773, 787, 797, 809, 811, 821, 823, 827, 829, 839, 853, 857, 859, 863, 877, 881, 883, 887, 907, 911, 919, 929, 937, 941, 947, 953, 967, 971, 977, 983, 991, 997, 54 / 67

Eratosthenovo síto eratosthenes.py # -*- coding: utf-8 -*- # eratosthenes3.py - Vypíše prvočísla menší než zadaný limit import sys n=int(sys.argv[1]) p=[true]*n # p[i] = je i prvočíslo? for i in range(2,n): if p[i]: # je to prvočíslo print(i,end=", ") j=2*i # označ j=2i,3i,... < n while j<n: p[j]=false j=j+i print() # závěrečný konec řádky 55 / 67

Terminal> python3 eratosthenes.py 1000 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 127, 131, 137, 139, 149, 151, 157, 163, 167, 173, 179, 181, 191, 193, 197, 199, 211, 223, 227, 229, 233, 239, 241, 251, 257, 263, 269, 271, 277, 281, 283, 293, 307, 311, 313, 317, 331, 337, 347, 349, 353, 359, 367, 373, 379, 383, 389, 397, 401, 409, 419, 421, 431, 433, 439, 443, 449, 457, 461, 463, 467, 479, 487, 491, 499, 503, 509, 521, 523, 541, 547, 557, 563, 569, 571, 577, 587, 593, 599, 601, 607, 613, 617, 619, 631, 641, 643, 647, 653, 659, 661, 673, 677, 683, 691, 701, 709, 719, 727, 733, 739, 743, 751, 757, 761, 769, 773, 787, 797, 809, 811, 821, 823, 827, 829, 839, 853, 857, 859, 863, 877, 881, 883, 887, 907, 911, 919, 929, 937, 941, 947, 953, 967, 971, 977, 983, 991, 997, 56 / 67

Porovnání rychlosti time -p python3 prvocislo3.py 10000 >/dev/null time -p python3 eratosthenes.py 10000 >/dev/null čas [s] N prvocislo3 Eratosthenes 10 3 0.05 0.05 10 4 0.15 0.06 10 5 2.11 0.24 10 6 53.11 2.19 57 / 67

Dvourozměrné matice pole polí a=[[1,0,2,3],[0,2,3,1],[3,0,2,5]] print(a) [[1, 0, 2, 3], [0, 2, 3, 1], [3, 0, 2, 5]] 58 / 67

Dvourozměrné matice pole polí a=[[1,0,2,3],[0,2,3,1],[3,0,2,5]] print(a) [[1, 0, 2, 3], [0, 2, 3, 1], [3, 0, 2, 5]] print(len(a)) 58 / 67

Dvourozměrné matice pole polí a=[[1,0,2,3],[0,2,3,1],[3,0,2,5]] print(a) [[1, 0, 2, 3], [0, 2, 3, 1], [3, 0, 2, 5]] print(len(a)) 3 58 / 67

Dvourozměrné matice pole polí a=[[1,0,2,3],[0,2,3,1],[3,0,2,5]] print(a) [[1, 0, 2, 3], [0, 2, 3, 1], [3, 0, 2, 5]] print(len(a)) 3 print(a[1]) 58 / 67

Dvourozměrné matice pole polí a=[[1,0,2,3],[0,2,3,1],[3,0,2,5]] print(a) [[1, 0, 2, 3], [0, 2, 3, 1], [3, 0, 2, 5]] print(len(a)) 3 print(a[1]) [0, 2, 3, 1] 58 / 67

Dvourozměrné matice pole polí a=[[1,0,2,3],[0,2,3,1],[3,0,2,5]] print(a) [[1, 0, 2, 3], [0, 2, 3, 1], [3, 0, 2, 5]] print(len(a)) 3 print(a[1]) [0, 2, 3, 1] print(a[1][2]) 58 / 67

Dvourozměrné matice pole polí a=[[1,0,2,3],[0,2,3,1],[3,0,2,5]] print(a) [[1, 0, 2, 3], [0, 2, 3, 1], [3, 0, 2, 5]] print(len(a)) 3 print(a[1]) [0, 2, 3, 1] print(a[1][2]) 3 58 / 67

Tisk matice def print_2d_matrix(a): for i in range(len(a)): print(a[i]) print_2d_matrix(a) [1, 0, 2, 3] [0, 2, 3, 1] [3, 0, 2, 5] 59 / 67

Vytvoření dvourozměrné matice a=[[0.]*4]*2 print_2d_matrix(a) [0.0, 0.0, 0.0, 0.0] [0.0, 0.0, 0.0, 0.0] 60 / 67

Vytvoření dvourozměrné matice a=[[0.]*4]*2 print_2d_matrix(a) [0.0, 0.0, 0.0, 0.0] [0.0, 0.0, 0.0, 0.0] a[0][1]=1.0 print_2d_matrix(a) 60 / 67

Vytvoření dvourozměrné matice a=[[0.]*4]*2 print_2d_matrix(a) [0.0, 0.0, 0.0, 0.0] [0.0, 0.0, 0.0, 0.0] a[0][1]=1.0 print_2d_matrix(a) [0.0, 1.0, 0.0, 0.0] [0.0, 1.0, 0.0, 0.0] 60 / 67

Vytvoření dvourozměrné matice a=[[0.]*4]*2 print_2d_matrix(a) [0.0, 0.0, 0.0, 0.0] [0.0, 0.0, 0.0, 0.0] a[0][1]=1.0 print_2d_matrix(a) [0.0, 1.0, 0.0, 0.0] [0.0, 1.0, 0.0, 0.0] Nefunguje jak chceme, kvůli aliasingu. 60 / 67

Vytvoření dvourozměrné matice (2) def create_2d_matrix(n,m,v): "Creates a n-by-m matrix with initial value v " a=[] for i in range(n): a+=[ [v]*m ] return a 61 / 67

Vytvoření dvourozměrné matice (2) def create_2d_matrix(n,m,v): "Creates a n-by-m matrix with initial value v " a=[] for i in range(n): a+=[ [v]*m ] return a a=create_2d_matrix(2,4,0.0) a[0][1]=1.0 print_2d_matrix(a) [0.0, 1.0, 0.0, 0.0] [0.0, 0.0, 0.0, 0.0] 61 / 67

Vytvoření dvourozměrné matice (2) def create_2d_matrix(n,m,v): "Creates a n-by-m matrix with initial value v " a=[] for i in range(n): a+=[ [v]*m ] return a a=create_2d_matrix(2,4,0.0) a[0][1]=1.0 print_2d_matrix(a) [0.0, 1.0, 0.0, 0.0] [0.0, 0.0, 0.0, 0.0] Toto je specialita Pythonu 61 / 67

Vytvoření dvourozměrné matice (3) (array/list comprehension) def create_2d_matrix(n,m,v): "Creates a n-by-m matrix with initial value v " return [ [v]*m for i in range(n) ] 62 / 67

Vytvoření dvourozměrné matice (3) (array/list comprehension) def create_2d_matrix(n,m,v): "Creates a n-by-m matrix with initial value v " return [ [v]*m for i in range(n) ] a=create_2d_matrix(2,4,0.0) a[0][1]=1.0 print_2d_matrix(a) [0.0, 1.0, 0.0, 0.0] [0.0, 0.0, 0.0, 0.0] 62 / 67

Binomický koeficient (kombinační číslo) ( ) n n! = k k!(n k)! počet k prvkových podmnožin z n ( ) 3 = 3, 1 for n k 0 ( ) 4 = 6 2 63 / 67

Binomický koeficient (kombinační číslo) ( ) n n! = k k!(n k)! počet k prvkových podmnožin z n ( ) 3 = 3, 1 for n k 0 ( ) 4 = 6 2 koeficient v binomické větě n ( ) n (x + y) n = x n k y k k k=0 (x + y) 1 = x + y (x + y) 2 = x 2 + 2xy + y 2 (x + y) 3 = x 3 + 3x 2 y + 3y 2 x + y 3 (x + y) 4 = x 4 + 4x 3 y + 6x 2 y 2 + 4xy 3 + y 3 63 / 67

Pascalův trojúhelník Pascal s triangle k = 0 k = 1 k = 2 k = 3 k = 4 n = 0 1 n = 1 1 1 n = 2 1 2 1 n = 3 1 3 3 1 n = 4 1 4 6 4 1 Platí rekurze ( ) n = k ( ) n 1 + k 1 ( ) n 1 k 64 / 67

Pascalův trojúhelník v Pythonu Vypočítejte pole p, tak aby p[n][k]= ( ) n k def pascal_triangle(n): p=[[1]] for n in range(2,n+1): prev=p[n-2] # předchozí řada p+=[[1] + [ prev[k-1] + prev[k] for k in range(1,n-1) ] + [1]] return p 65 / 67

print_2d_matrix(pascal_triangle(5)) [1] [1, 1] [1, 2, 1] [1, 3, 3, 1] [1, 4, 6, 4, 1] Řádky pole nemusí mít stejnou délku. 66 / 67

Závěr Pole často používaná datová struktura obsahuje n prvků (nejčastěji stejného typu) k prvkům přistupujeme pomocí celočíselného indexu prvky pole mohou být i složené datové typy Proměnné jsou reference, aliasing Neměnné (immutable) typy, hodnotová semantika Příklady použití polí 67 / 67