Čtení ze souborů
V praxi často máme data uložena v nějakém souboru na disku v nějakém textovém formátu. Ukážeme si, jak takový soubor v Pythonu otevřít a data z něj přečíst.
Pro naše první experimenty si stáhněte soubor mereni.txt. Ten obsahuje naměřené teploty během týdne, které jsme už několikrát v našich programech používali.
Pokud chceme otevřít tento soubor v nějakém našem programu, nejjednodušší je zkopírovat jej do téže složky, ve které máme program uložený. Potom v programu použijeme funkci open()
, která slouží k otevírání souborů. Nejčastěji se soubor otevírá v kombinaci se klíčovým slovem with
. Tím automaticky zajistíme uzavření souboru a nebudeme ho blokovat. Současně si otevřený soubor musíme pojmenovat. Jméno vložíme za další klíčové slovo as
. Náš soubor mereni.text
tedy dostal "přezdívku" vstup
.
Všimni si, že prostřední řádek je odsazený o jedno odsazení vpravo. To není náhoda, tento řádek se totiž nachází v bloku. Pomocí bloku říkáme, v jaké části programu chceme pracovat s naším souborem a kdy ho již Python může uzavřít. Mezi řádkem 2 a 3 tedy v tichosti dojde k uzavření souboru. Nám to ale vůbec nevadí, protože obsah souboru máme překopírovaný do seznamu radky
a ten nám nikam nezmizí.
Na konci úvodního řádku bloku vkládáme dvojtečku. Dvojtečka na konci řádku pak pro nás bude sloužit jako připomenutí, abychom alespoň jeden následující řádek odsadili. Ve stresu z toho ale být nemusíme, protože editor kódu to většinou udělá za nás.
Různé možnosti načítání souboru
Nejjednodušší je načíst si obsah souboru do jednoho řetězce. Slouží k tomu metoda read()
u objektu otevřený soubor. Tento způsob se hodí, pokud máme v souboru uložený pouze jeden řádek nebo z nějakého důvodu chceme mít řetězec, který přesně odpovídá uloženému souboru.
with open('mereni.txt', encoding='utf-8') as vstup:
text = vstup.read()
print(text)
Častěji však budeme potřebovat rozdělit soubor na řádky. Celý obsah souboru uložíme do seznamu radky
pomocí metody readlines()
. Ta uloží každý řádek souboru jako jeden prvek seznamu.
Náš kód pak může vypadat například takto:
with open('mereni.txt', encoding='utf-8') as vstup:
radky = vstup.readlines()
print(radky)
Výstup z našeho programu pak bude vypadat takto:
['po\t17.3\n', 'út\t16.8\n', 'st\t15.1\n', 'čt\t13.2\n', 'pá\t14.0\n', 'so\t13.9\n', 'ne\t15.8\n']
Výstupem je skutečně seznam řetězců, které ale obsahují znaky zpětných lomítek. Tato zpětná lomítka slouží k vyjádření speciálních znaků, které by jinak nešly do řetězce vložit. Anglicko/česky se jim říká escape sekvence a my si představíme základní dvě. Nový řádek se píše jako '\n'
, tabulátor jako '\t'
. Existuje jich ještě mnoho dalších, ale tyto nám zatím postačí.
Vidíme tedy, že každý náš řádek končí znakem nového řádku a hodnoty na něm jsou odděleny tabulátorem. Pokud bychom chtěli načtené řádky rozdělit na jednotlivé hodnoty, využijeme toho, že otevřený soubor můžeme také načítat v cyklu for
. Do proměnné radek
se nám uloží vždy jeden řádek souboru jako řetězec. Tento způsob má také tu výhodu, že po řádcích můžeme načíst i dost velký soubor, které by se nám jinak nevešel do operační paměti počítače, kdybychom ho načetli pomocí metod read()
nebo readlines()
.
vystup = []
with open('mereni.txt', encoding='utf-8') as vstup:
for radek in vstup:
den, teplota = radek.split('\t')
vystup.append([den, float(teplota)])
print(vystup)
V předchozí ukázce vidíme elegantní uložení dvou hodnot na řádku rozdělené podle znaku tabulátor do samostatných proměnných den
a teplota
. Jedná se o praktické využití datového typu tuplen-tice. Toto si můžeme dovolit díky tomu, že přesně známe strukturu dat, se kterými pracujeme.
Cvičení: Čtení ze souborů
Výplata přesněji
Zatím jsme výplatu počítali za předpokladu, že každý měsíc odpracujeme stejný počet hodin, což není příliš realistické. Vytvořte proto textový soubor vykaz.txt
, který bude obsahovat 12 řádků a na každém řádku počet odpracovaných hodin za každý měsíc za poslední rok.
- Otevřete tento soubor ve svém programu a načtěte hodnoty na řádcích do seznamu
vykaz
. Vytiskněte tento seznam do terminálu funkcíprint()
abyste si ověřili, že jste soubor načetli správně. - Nechte uživatele zadat na příkazovém řádku hodinovou mzdu. Spočítejte a na výstup vytiskněte celkovou výplatu za celý rok a průměrnou výplatu na jeden měsíc.
Počet slov
Stáhněte si odevzdanou slohovou práci. Zadání bylo sepsat text o nejméně 150ti slovech pojednávající o našem hlavním městě. Napište program, který spočítá počet slov v tomto textu, abychom věděli, zda bylo zadání formálně splněno. Nechte se vést následujícím návodem.
- Nechte váš program otevřít soubor a načíst jednotlivé řádky do seznamu.
- Každý řádek převeďte na seznam slov. Slovem se rozumí vše, co je odděleno mezerou nebo novým řádkem.
- Vypište na výstup seznam hodnot udávající počty slov na každém řádku.
- Vypište na výstup celkový počet všech slov v souboru.
Bonus
Půjčovna
Půjčovna aut má v každém kraji ČR jedno auto s danou SPZ. Ke konci roku chce zjistit, kolik všechna auta najezdila dohromady kilometrů. V souboru auta.txt je pro každou SPZ zaznamenáno kolik dané auto ujelo kilometrů za daný rok. Hodnoty jsou v tisících kilometrů. Bohužel se v jednotlivých krajích blbě zkoordinovali a někdo používal desetinnou čárku, někdo zase tečku.
V souboru s daty je ještě jeden problém, který není na první pohled vidět. Dá se vyřešit pomocí list comprehension s podmínkou uvedeném v předchozím čtení na doma.
- Napište program, který na výstup vypíše součet všech ujetých kilometrů. Jistě se vám bude hodit metoda řetězců jménem
replace()
. - Upravte váš program tak, aby jméno souboru k otevření dostal na příkazové řádce, abychom mohli takto zpracovávat výkazy z různých souborů, aniž bychom museli upravovat samotný kód programu.