přejít na obsah přejít na navigaci

Linux E X P R E S, Python 3 (3): funkcie dátových typov a vstup od užívateľa

Python 3 (3): funkcie dátových typov a vstup od užívateľa

python.png

V tejto časti sa pozrieme na manipuláciu s dátovými typmi, ktoré sme si predstavili v minulej časti. Taktiež si vytvoríme program, na ktorom si na jednoduchom príklade ukážeme, ako spracovať vstup od užívateľa.


Ako sme si už v minulej časti povedali, dáta uložené v premennej predstavujú objekt istého dátového typu. Tieto objekty majú v závislosti od rôznych dátových typov rôzne funkcie, ktoré nám umožňujú manipulovať s obsahom premennej, čiže s dátami, pričom tieto funkcie sa väčšinou využívajú pri „pokročilejších“ dátových typoch ako sú rôzne zoznamy a reťazce.

Takisto môžeme medzi jednotlivými dátovými typmi premieňať, a tak napríklad číslo dátového typu integer premeniť na reťazec a ďalej s ním manipulovať ako s reťazcom.

Zoznamy

Ako prvému dátovému typu sa budem venovať zoznamu (list). Zoznamy obsahujú viacej položiek a pokiaľ potrebujeme dostať len obsah jednej položky zoznamu, použijeme zápis:

názov_premennej[pozícia]. Zoznamy sú v Pythone, tak ako vo väčšine programovacích jazykov, číslované od nuly. To znamená, že prvá položka zoznamu sa nachádza na nulovej pozícii, druhá na pozícii 1, tretia položka na pozícii 2 atď.

>>> list = [1, 2, 3, 5, 9, 11]
>>> print(list[0])
1

Poznámka autora (5. 5. 2015): Pri volení názvov premenných sa vyhýbajte pomenovaniam vstavaných funkcii Pythonu. Ja som teraz vytvoril a pracoval s premennou, ktorú som nazval list. Tým som však prepísal odkaz na vstavanú funkciu list(), ktorá slúži na vytváranie listov z iných dátových typov, a preto túto funkciu už ďalej nieje možné takýmto spôsobom volať. Za upozornenie ďakujem čitateľovi Lukášovi.

Pokiaľ chceme dostať poslednú položku zoznamu a nevieme, aký dlhý je celý list, môžeme použiť aj zápornú pozíciu, kedy -1 je pozícia poslednej položky, -2 predposlednej atď.. Dĺžku listu mimochodom určíme pomocou funkcie len(názov_premennej).

>>> print(list)
[1, 2, 3, 5, 9, 11]
>>> print(list[-1])
11

Obsah položky v liste môžeme prepísať spôsobom definovania premenných. Položka však v zozname musí existovať. Pokiaľ zadáme neplatnú pozíciu, Python sa bude sťažovať.

>>> print(list)
[1, 2, 3, 5, 9, 11]
>>> list[4] = 7
>>> print(list)
[1, 2, 3, 5, 7, 11]

Z listu môžeme naraz dostať (vystrihnúť) aj viac ako len jednu položku. Pre vybratie určitej časti listu použijeme zápis: názov_premennej[začiatočná_pozícia:konečná_pozícia].

>>> print(list)
[1, 2, 3, 5, 7, 11]
>>> print(list[2:4])
[3, 5]

Ak necháme začiatočnú pozíciu prázdnu [:4], dostaneme všetky položky od začiatku po konečnú pozíciu. Naopak, ak vyplníme len začiatočnú pozíciu a konečnú necháme voľnú [2:], dostaneme položky od začiatočnej pozícii až po koniec listu. V prípadne, že nevyplníme ani jednu pozíciu [:] dostaneme celý list.

>>> print(list)
[1, 2, 3, 5, 7, 11]
>>> print(list[2:])
[3, 5, 7, 11]
>>> print(list[:4])
[1, 2, 3, 5]
>>> print(list[:])
[1, 2, 3, 5, 7, 11]

Položky listu môžeme vybrať aj podľa určeného kroku: [začiatočná_pozícia:konečná_pozícia:krok].  Môžeme tak vypísať napríklad každú druhú [::2], tretiu [::3] alebo každú siedmu [::7] položku listu. Krok môžeme zadať aj záporný. Vtedy sa položky zoradia z opačnej strany, a preto pokiaľ určíme napríklad krok -1 [::-1] dostaneme zoznam v opačnom poradí.

>>> print(list[:])
[1, 2, 3, 5, 7, 11]
>>> print(list[::2])
[1, 3, 7]
>>> print(list[1::2])
[2, 5, 11]
>>> print(list[::-1])
[11, 7, 5, 3, 2, 1]
>>> print(list[::-3])
[11, 3]

Určovanie pozície a počtu

Teraz sa už konečne dostávame k spomínaným funkciám dátového typu list. Jednotlivé funkcie voláme spôsobom: názov_premennej.funkcia() tak, ako je to aj pri používaní modulov.

V prípade, že chceme určiť pozíciu položky s určitým obsahom, môžeme použiť funkciu index().

>>> print(list)
[1, 2, 3, 5, 7, 11]
>>> print(list.index(5))
3

Teraz vidíme, že pozícia položky, ktorá obsahuje číslo 5, je 3. Čo ak by sme chceli vedieť počet položiek s určitým obsahom? Použijeme funkciu count().

>>> print(list)
[1, 2, 3, 5, 7, 11]
>>> print(list.count(7))
1

Položka obsahujúca číslo 7 sa v zozname v premennej list naozaj nachádza len raz.

Pridávanie a odoberanie

Najjednoduchším spôsobom pre priradenie ďalších položiek do zoznamu je „pripočítanie“ ich k nemu. V Pythone sa znamienko + okrem matematickej operácii sčítania často využíva aj na spájanie niektorých dátových typov. Sčítavať, resp. spájať, je vždy možné len premenné rovnakého dátového typu, takže pokiaľ chceme k listu priradiť nejaké ďalšie položky, musíme ich takisto vložiť do listu.

>>> print(list)
[1, 2, 3, 5, 7, 11]
>>> list = list+[13, 17, 19]
>>> print(list)
[1, 2, 3, 5, 7, 11, 13, 17, 19]

Okrem takéhoto spôsobu môžeme pre priradenie položiek na koniec zoznamu použiť funkciu append().

>>> list.append(21)
>>> print(list)
[1, 2, 3, 5, 7, 11, 13, 17, 19, 21]

Všimnite si, že pri prvom spôsobe sme priraďovali premennej list novovzniknutý objekt listu ktorý bol kombináciu starého obsahu premennej list a zoznamu [13, 17]. Pri druhom spôsobe sme premennej list nemuseli nič nové priraďovať, pretože sme priamo manipulovali s obsahom danej premennej. Prvý spôsob je teda pomalší, pretože sa pri ňom vytvára nový objekt a starý maže. Druhý spôsob len upravuje už existujúci objekt.

Pre odstraňovanie položiek tu máme funkcie remove()pop(). Funkcia remove() odstraňuje položky podľa obsahu, zatiaľ čo funkcia pop() odstráni a zároveň vráti položku podľa pozície. Pokiaľ pri funkcii pop() neurčíme pozíciu, automaticky maže poslednú položku.

>>> print(list)
[1, 2, 3, 5, 7, 11, 13, 17, 19, 21]
>>> list.remove(1)
>>> print(list)
[2, 3, 5, 7, 11, 13, 17, 19, 21]
>>> list.pop()
21
>>> print(list)
[2, 3, 5, 7, 11, 13, 17, 19]

Z funkcii, ktoré sú dostupné pre dátový typ list som ešte nespomenul funkcie clear(), copy(), extend(), insert(), reverse()sort(). Názvy funkcií väčšinou zodpovedajú tomu, čo tie funkcie robia, ale pokiaľ by ste chceli vedieť viac, môžete sa pozrieť do oficiálnej dokumentácii Pythonu.



Reťazce

V minulej časti som spomenul, že reťazec môže byť zhluk akýchkoľvek znakov. Znaky v reťazcoch si môžeme predstaviť aj ako jednotlivé položky, a preto s reťazcom môžeme manipulovať podobne ako so zoznamom. Rezať, resp. vyberať jednotlivé znaky môžeme rovnakým spôsobom ako pri zoznamoch.

>>> string = "abcdefghijklmnopqrstuvwxyz0123456789"
>>> print(string[-1])
9
>>> print(string[0:5])
abcde
>>> print(string[:10:-2])
97531zxvtrpnl

Spájanie

Tak ako aj pri zoznamoch, reťazce môžeme spájať viacerými spôsobmi. Zrejme najjednoduchším ale zároveň takisto najpomalším spôsobom je použitie sčítania dvoch alebo viacerých reťazcov pomocou +. Okrem tohto spôsobu má dátový typ string aj iné možnosti, pričom sa nejedná len o priradenie iného reťazca na koniec druhého, ale taktiež je možné vložiť ľubovoľný počet reťazcov na rôzne miesta v inom reťazci.

>>> sentence = "Toto je len"
>>> sentence = sentence + " náhodná veta."
>>> print(sentence)
Toto je len náhodná veta.

Ďalším spôsobom je použitie %, pričom tento znak v kombinácii s reťazcom slúži na mnoho užitočných formátovacích vecí. Pre jednoduché vloženie reťazca do reťazca sa používa spolu s písmenom s (string) takto:

>>> name = "Štefan"
>>> sentence2 = "Volám sa %s." % name
>>> print(sentence2)
Volám sa Štefan.

Podrobnejšiemu formátovaniu s pomocou % sa určite ešte niekedy budem venovať. Ďalej tu máme funkciu format(). Reťazec pri použití tejto funkcie musí na miestach vloženia obsahovať zátvorky {} s prípadným číslovaním alebo kľúčovým slovom vo vnútri, podľa toho, čo chceme do reťazca vložiť.

>>> name = "Rex"
>>> age = 2
>>> weight = 29
>>> print("Ten pes sa volá {}, má {} rokov a váži {}kg.".format(name, age, weight))
Ten pes sa volá Rex, má 2 rokov a váži 29kg.

Vidíme, že jednotlivý obsah premenných bol do reťazca pridaný presne podľa poradia. Pokiaľ použijeme číslovanie, môžeme určiť, kde sa obsah presnej premennej bude nachádzať. Samozrejme číslujeme od nuly.

>>> print("Ten pes sa volá {0}, má {2} rokov a váži {1}kg.".format(name, age, weight))
Ten pes sa volá Rex, má 29 rokov a váži 2kg.

Polohu môžeme označiť aj pomocou zvolených kľúčových slov, a to tak, že vo vstupe funkcie format() si každé jedno definujeme ako premennú.

>>> print("Ten pes sa volá {meno}, má {vek} rokov a váži {váha}kg.".format(vek=age, váha=weight, meno=name))
Ten pes sa volá Rex, má 2 rokov a váži 29kg.

Upráva textu

Keďže reťazce väčšinou obsahujú text, dostupných je niekoľko funkcii pre string, ktoré rôzne tento text upravujú. Jedná sa napríklad o centrovanie textu, premenenie na kapitálky, prípadne len vytvorenie veľkého písmena na začiatku každého slova či celého reťazca. Najlepšie bude si rovno uviesť niekoľko príkladov.

>>> st = "toto je LEN náhodná Veta."
>>> print(st.center(80))
                           toto je LEN náhodná Veta.
>>> print(st.lower())
toto je len náhodná veta.                            
>>> print(st.capitalize())
Toto je len náhodná veta.
>>> print(st.title())
Toto Je Len Náhodná Veta.
>>> print(st.upper())
TOTO JE LEN NÁHODNÁ VETA.

Program so vstupom od užívateľa

Konečne sa dostávame k vytvoreniu spustiteľného Python skriptu, ktorý bude robiť to, čo mu predprogramujeme. Teraz budeme okrem Python interpreteru potrebovať aj nejaký textový editor najlepšie s podporou zvýrazňovania syntaxi Python 3. Môžete použiť napríklad známy editor Geany alebo Sublime Text či terminálový Vim. Ja už dlhšiu dobu používam Komodo Edit a som s ním maximálne spokojný.

Začnime teda tým, že si vo zvolenom editore vytvoríme nový súbor a vložíme doň jednoduchý „Hello, World!“ skript:

print("Hello, World!")

Ukážka zvýraznenia syntaxe v editore Komodo Edit 9 Ukážka zvýraznenia syntaxe v editore Komodo Edit 9

Súbor uložíme pod názvom napríklad first.py a následne spustíme z terminálu pomocou Python interpreteru:

$ python3 first.py
Hello, World!
$

Teraz skúsime pridať vstup od užívateľa, tak aby bol užívateľ vyzvaný k napísaniu svojho mena a program ho následne pozdraví. Pre vyžiadanie vstupu použijeme funkciu input("voliteľný text") tak, že do nejakej premennej zapíšeme práve jej výstup, čiže vstup, ktorý zadá užívateľ.

name = input("Zadajte svoje meno: ")

Použijeme aj funkciu format(), aby sme meno ktoré zadá užívateľ vložili do pripraveného reťazca.

name = input("Zadajte svoje meno: ")
print("Ahoj, {}.".format(name))

Python program first.py, ktorý sa Vám pozdraví. Python program first.py, ktorý sa Vám pozdraví.

Môžeme skúsiť niečo komplikovanejšie – vytvoriť nový program (vytvorte si nový súbor, napríklad second.py), ktorý bude počítať povrch a objem kocky. Teraz budeme od užívateľa vyžadovať, aby zadal dĺžku strany kocky, čiže číslo. Avšak funkcia input() všetko, čo zadá užívateľ, ukladá v podobe reťazca, s ktorým samozrejme nemôžeme počítať. Preto musíme tento reťazec, ktorý bude obsahovať iba číslo, premeniť na dátový typ integer a to pomocou funkcie int(premenná).

inp = input("Zadajte dĺžku strany kocky (bez jednotiek): ")
a = int(inp)

Vstup od užívateľa a zmenu na číslo by sme týmto mali vyriešenú. Teraz už len vypočítať obsah a objem podľa jednotlivých vzorcov a vypísať výsledok užívateľovi. Celý kód by mohol vyzerať takto:

inp = input("Zadajte dĺžku strany kocky (bez jednotiek): ")
a = int(inp)
volume = a**3
surface_area = 6*a**2
print("Objem kocky je: {}".format(volume))
print("Príklad: {a}^3={result}".format(a=a, result=volume))
print("Povrch kocky je: {}".format(surface_area))
print("Príklad: 6×{a}^2={result}".format(a=a, result=surface_area))

Ukážka výsledného programu pre počítanie objemu a povrchu kocky. Ukážka výsledného programu pre počítanie objemu a povrchu kocky.

Záver

Pokiaľ by ste do posledného programu namiesto čísla pri vstupe napísali niečo, čo číslom nieje, dostali by ste ValueError, pretože nič iné ako číslo sa na číslo zmeniť nedá (okrem True (1)False (0)). V ďalšej časti sa preto pozrieme, ako s týmito chybami pracovať, takisto si ukážeme podmienky (pretože kocka nemôže mať mínusový rozmer) a možno nám ostane nejaké miesto aj na cyklus while.

Nahoru

Příspěvky

Python 3 (3): funkcie dátových typov a vstup od užívateľa
jneterda 5. 05. 2015, 12:29:12
Odpovědět  Odkaz 
Seriál je velice dobře pojat, určitě bych ho použil, až budu svého vnuka učit Python (naučí se taky trochu slovensky). Zajímalo by mě, jak chce autor tutorial zaměřit - Python umí prakticky cokoliv (pokud se k tomu vyberou vhodné importy). Co chybí jsou např.tutoriály s jednoduchými příklady použití Pythonu pro úlohy, které řeší jiné jazyky složitě nebo vůbec ne. Autor možná už tím směrem trochu jde. R-Pi je také super zajímavá disciplina pro Python.
Štefan Uram Re: Python 3 (3): funkcie dátových typov a vstup od užívateľa
Štefan Uram 5. 05. 2015, 16:04:27
Odpovědět  Odkaz 
Som rád, že sa vám seriál páči.
Autor zatiaľ ani sám nevie, kam sa bude tento tutoriál vyvíjať a kde skončí :). Ku príkladom použitia sa ale určite dostanem...
RPi (zatiaľ) nevlastním.
Python 3 (3): funkcie dátových typov a vstup od užívateľa
Lukáš 5. 05. 2015, 12:52:23
Odpovědět  Odkaz 
Předně díky za skvělý seriál, rád na něj budu odkazovat :-)

Jen bych si dal pozor na konstrukce typu "list = [1, 2, 3, 5, 9, 11]". Programátor, který nevidí do objektového modelu Pythonu, se bude divit, co se stalo s funkcí list() :-)
Štefan Uram Re: Python 3 (3): funkcie dátových typov a vstup od užívateľa
Štefan Uram 5. 05. 2015, 16:07:37
Odpovědět  Odkaz 
Díky a vďaka za upozornenie. Toto mi, úprimne, ani nenapadlo.
Python 3 (3): funkcie dátových typov a vstup od užívateľa
Ondrej 5. 05. 2015, 15:40:31
Odpovědět  Odkaz 
% bych nepoužíval, sám mám sice toto raději než format, ale je to zastaralé a dříve nebo později % bude z pythonu odebráno a zůstane jen format, tak je lepší bych řekl již % nepoužívat, obzvláště pokud člověk začíná...
Python 3 (3): funkcie dátových typov a vstup od užívateľa
Wrunx 5. 05. 2015, 18:15:23
Odpovědět  Odkaz 
Maličký zásek.
Pokud je obsah listu [2, 3, 5, 7, 11, 13, 17, 19, 21] jak v příkladu, tak volání pop() vrátí 21, ne 19. Pop() je dle mě prosté sejmutí vrchního prvku hromady.
Každopádně ale kdo zažil Pascalské trápení s pekelnými spojovými seznamy, toho funkce remove a insert svojí přímočarou prostotou přivedou rovnou do nebe.
A protože seznam v Pythonu je objekt, lze do číselného seznamu s=[1,2,3] klidně vložit znaky s.insert(1,"ahoj") což má za výsledek [1, 'ahoj', 2, 3], nebo celý nový seznam s.insert(2,[5,55]) což má za výsledek [1, 'ahoj', [5, 55], 2, 3], nebo prakticky libovolný další objekt. Jde si tak třeba udělat list funkcí nebo list grafických objektů...

def def xe():
print("funkce!") #

s.insert(0,xe) # nultý prvek pole teď "obsahuje" funkci xe

# fakt?
>>>s[0]()
funkce!
# jo! :-D
Štefan Uram Re: Python 3 (3): funkcie dátových typov a vstup od užívateľa
Štefan Uram 6. 05. 2015, 15:15:34
Odpovědět  Odkaz 
Ďakujem za upozornenie, chybička je opravená.
Čo sa týka ďalších funkcií atp., je toho celkom veľa a pokiaľ by som chcel spomenúť úplne všetko, bolo by to oveľa dlhšie, čo by nebolo zrovna ideálne. Snažím sa preto písať len o základných, často používaných alebo zaujímavých veciach :) Každopádne vďaka za postreh.
Re: Re: Python 3 (3): funkcie dátových typov a vstup od užívateľa
Wrunx 6. 05. 2015, 18:53:48
Odpovědět  Odkaz 
Jo a přidávám se k těm, co se tu těší na pokračování :-)
Re: Python 3 (3): funkcie dátových typov a vstup od užívateľa
Pavel Šimerda 25. 05. 2015, 12:51:10
Odpovědět  Odkaz 
„Každopádně ale kdo zažil Pascalské trápení s pekelnými spojovými seznamy, toho funkce remove a insert svojí přímočarou prostotou přivedou rovnou do nebe.“

Vidím dva zásadní problémy. Jednak to v případě Pascalu není ani tak chyba jazyka jako přímý důsledek tradiční výuky ve stylu „udělej si sám“, kdy se úmyslně používají jen elementární nástroje.

Ale co mi připadá horší je míchat pythoní seznam a ručně implementovaný spojový seznam. Prvním a nejvíce viditelným rozdílem je to, že zatímco pythoní seznam je abstraktní datový typ, ke kterému se přistupuje pomocí API, v tom druhém případě se zjevně bavíme o aplikaci (1) dynamické alokace prvků seznamu, (2) ukazatelů pro vytvoření vazeb a (3) konkrétního modelu spojového seznamu jako je například cyklický obousměrně řetězený seznam s hlavou.

Pokud bych měl srovnávat s ručně tvořeným seznamem v Pascalu nebo C, dával bych na druhou stranu dynamické pole s realokací (což je mimochodem implementace schovaná za pythoním API), kde je při každém přidání prvku potřeba se starat o případnou realokaci a údržbu informací o alokaci.

Jinak srovnání mezi školským přístupem k Pascalu a běžným užíváním Pythonu bude ještě divočejší než srovnání jazyků a nástrojů jako takových. :)
Vojtěch Zeisek Python 3 (3): funkcie dátových typov a vstup od užívateľa
Vojta 22. 05. 2015, 18:41:40
Odpovědět  Odkaz 
Dobrý seriál, díky za něj. Jen bych se zeptal, jak to je s tečkami v názvech proměnných. V R si proměnné s oblibou pojmenovávám s tečkami, ale v Pythonu by to mohlo být velmi zmatečné vzhledem k dalším funkcím... Je na to nějaká konvence/pravidlo?
Re: Python 3 (3): funkcie dátových typov a vstup od užívateľa
Pavel Šimerda 25. 05. 2015, 12:55:01
Odpovědět  Odkaz 
Vzhledem k tomu, že má tečka v Pythonu syntaktický význam, tak asi těžko bude člověk běžným způsobem pracovat s proměnnými s tečkou v názvu.
Python 3 (3): funkcie dátových typov a vstup od užívateľa
Pavel Šimerda 25. 05. 2015, 12:53:07
Odpovědět  Odkaz 
Mimochodem, přičítat k seznamu jiný seznam a výsledek ukládat do proměnné, kde byl původní seznam, je v Pythonu zbytečně krkolomné.

>>> l = [1,2,3]
>>> l += [4,5]
>>> l
[1, 2, 3, 4, 5]
Re: Python 3 (3): funkcie dátových typov a vstup od užívateľa
Pavel Šimerda 25. 05. 2015, 12:54:01
Odpovědět  Odkaz 
Měl jsem namysli otrocký způsob použitý v článku, za lepší považuju způsob uvedený zde.
Python 3 (3): funkcie dátových typov a vstup od užívateľa
Félix 30. 07. 2015, 14:32:19
Odpovědět  Odkaz 
Len taká otázočka...

inp = input("Zadajte dĺžku strany kocky (bez jednotiek): ")
a = int(inp)
volume = a**3
surface_area = 6*a**2
print("Objem kocky je: {}".format(volume))
...

Prečo sa riadok
print("Objem kocky je: {}".format(volume))
nezapísal napríklad takto:
print("Objem kocky je: ",volume)
? Len sa to učím a tak sa mi to zdá jednoduchšie, tak sa pýtam.
Štefan Uram Re: Python 3 (3): funkcie dátových typov a vstup od užívateľa
Štefan Uram 1. 08. 2015, 08:31:52
Odpovědět  Odkaz 
V tomto prípade je použitie print("Objem kocky je:", volume) skutočne jednoduchšie a funkčné. Do príkladu som to však nechcel miešať, keďže som tento spôsob "spájania" dát pri printe (bez ohľadu na dátový typ) zatiaľ nespomenul.
Upozorním však, že pri použití print("A", "B") sú tieto reťazce oddelené medzerou, takže print("A ", "B") by spôsobilo výstup: "A B" [A(medzera)(medzera)B].
A samozrejme ďakujem za skvelú poznámku.

Odpovědět

Nejsou podporovány žádné značky, komentáře jsou jen čistě textové. Více o diskuzích a pravidlech najdete v nápovědě.
Diskuzi můžete sledovat pomocí RSS kanálu rss



 
 

Top články z OpenOffice.cz