09_Soubory_CSVJSON C2184 Úvod do programování v Pythonu 9. Práce se soubory CSV a JSON Formát CSV • CSV = comma-separated values • Slouží pro ukládání tabulkových dat • Hodnoty jsou do sloupečků rozdělené pomocí separátoru {delimiter, většinou čárka) a do řádků pomocí znaku nového řádku • https://cs.wikipedia.org/wiki/CSV • Tabulka: Rok výroby Značka Model Cena 1995 Opel Vect ra 45 000 1998 Škoda Felicia 80 000 2002 Škoda Octavia 70 000 J • CSV: Rok výroby,Značka,Model,Cena 1995,Opel,Vect ra,45000 1998,Škoda,Felicia,80000 2002,Škoda,Octavia,70000 Modul csv v Pythonu • csv. reader - načítání formátu CSV • csv.writer - ukládání ve formátu CSV • https://docs.python.org/3/library/csv.html 1 Čtení [1] with open('tabulka_auta.csv', 'r', encodingsutf8') as f print(f.read()) Rok výroby,Značka,Model,Cena 1995,Opel,Vect ra,45000 1998,Škoda,Felícia,80000 2002,Škoda,Octavia,70000 [2] : import csv with open('tabulka_auta.csv', 'r', encoding= reader = csv.reader(f) for line in reader: print(line) utf8') as f: ['Rok výroby', 'Značka', 'Model', 'Cena'] ['1995', 'Opel', 'Vectra', '45000'] ['1998', 'Škoda', 'Felicia', '80000'] ['2002', 'Škoda', 'Octavia', '70000'] [3] : with open('tabulka_auta.csv', 'r', encoding= reader = csv.reader(f) table = list(reader) table utf8') as f: [3]: [['Rok výroby', 'Značka', 'Model', 'Cena'], ['1995', 'Opel', 'Vectra', '45000'], ['1998', 'Škoda', 'Felicia', '80000'], ['2002', 'Škoda', 'Octavia', '70000']] [4] • Načtené hodnoty jsou vždy řetězce, musíme šije sami převést na číslo • DictReader - z řádků dělá slovníky with open('tabulka_auta.csv', encodingsutf8') as f: csvreader = csv.DictReader(f, ['year', 'brand', 'model', 'price']) for line in csvreader: print(diet(line)) {'year': 'Rok výroby', 'brand': 'Značka', 'model': 'Model', 'price':u ^'Cena'} {'year': '1995', 'brand': 'Opel', 'model': 'Vectra', 'price': '45000'} {'year': '1998', 'brand': 'Škoda', 'model': 'Felicia', 'price':u ^'80000'} 2 [5] {'year': '2002', 'brand': 'Škoda', 'model': 'Octavia', 'price':u ^'70000'} • DictReader bez zadaných názvů sloupců - načte první řádek jako hlavičku with open('tabulka_auta.csv', encoding='utf8') as f: csvreader = csv.DictReader(f) for line in csvreader: print(diet(line)) {'Rok výroby' ^'45000'} {'Rok výroby' ^'80000'} {'Rok výroby' ^'70000'} 1995', 'Značka': 'Opel', 'Model': 'Vectra', 'Cena':u 1998', 'Značka': 'Škoda', 'Model': 'Felicia', 'Cena' '2002', 'Značka': 'Skoda', 'Model': 'Octavia', 'Cena' Zápis [6] : distances = [[ i Brno', 'Praha', 'Ost rava'], [ Brno', 0, 202, 165], [ Praha', 202, 0, 362], [ Ost rava , 165, 362, 0]] [7] [8] : with open('distances.csv', 'w', encoding='utf8') as f csvwriter = csv.writer(f) csvwriter writerows(distances) with open('distances.csv', 'r', encoding='utf8') as f print(f.read()) ,Brno,Praha,Ostrava Brno,0,202,165 Praha,202,0,362 Ostrava,165,362,0 Zápis speciálních znaků • Tabulka: Rok výroby Značka Model Poznámka Cena 1995 Opel Vect ra klimatizace, střešni okno 45 000 1998 Škoda Felicia "Fun" 80 000 3 [9] 1 2002 1 Škoda 1 Octavia 1 klimatizace, ABS 1 70 000 1 ! ! ! j bouraná i ! ! • CSV: 1995,Opel,Vectra,"klimatizace, střešni okno",45000 1998,Škoda,"Felicia ""Fun,,80000 2002,Škoda,Octavia,"klimatizace, ABS bouraná",70000 • A proto je modul csv tak užitečný. Parametry pro upřesnění formátu • delimiter - oddělovač sloupců (default ' , ') • quotechar - vyčlenění polí se speciálními znaky (default '"') • quoting - strategie použití quotecharu (povolené hodnoty csv. QU0TE_ALL, csv.QUOTE_MINIMAL, csv.QUOTE_NONNUMERIC, csv.QU0TE_N0NE) - Reader s quoting=csv. QUOTE_NONNUMERIC konvertuje na float vše, co není v uvozovkách. • doublequote - zdvojení quotecharu ruší jeho funkci (default True) • escapechar - ruší funkci speciálních znaků (delimiteru a quotecharu) (default None) • skipinitialspace - ignoruje mezery těsně za oddělovačem (default False) • dialect - nastavení více parametrů současně (např. ' excel') with open('distances.csv', 'w', encoding='utf8') as f: csvwriter = csv.writer(f, delimiter^;', quoting=csv ^QUOTE_NONNUMERIC) csvwriter writerows(distances) [10]:[with open('distances.csv', encoding='utf8') as f: print(f.read()) "";"Brno";"Praha";"Ostrava" "Brno";0;202;165 "Praha";202;0;362 "Ostrava";165;362;0 Otázky: Jak musíme nastavit csv. reader, aby správně načetl tabulku? 4 Wednesday 16 December: ' 18 00' :'Ovečka Shaun ve filmu Farmageddon' 60 Kč Wednesday 16 December: '20 30' :Story of Tantra 100 Kč Thursday 17 December: ' 18 00' :Hungry Bear Tales 60 Kč Thursday 17 December: '21 30' :Between the Seasons 100 Kč Friday 18 December: ' 18 00' :Disco in the Cinema 60 Kč Satu rday 19 December: '20 30' :Summer of 85 100 Kč Sunday 20 December: '20 30' :Klimt & Schiele - Eros and Psyche 100 Kč • A) csv.reader(f) • B) csv. reader(f, delimiter • C) csv. reader(f, delimiter • D) csv. reader(f, delimiter skipinitialspace=True) Formát JSON • JavaScript Object Notation • http://json.org/ • Mapování na typy Pythonu: ', escapechar=) ', quotechar=) ', quotechar='"', Python JSON Poznámka int/float 5, 10.2 number 5, 10.2 string 'ahoj' string "ahoj" vždy dvojité uvozovky bool True, False boolean true, false None None null null list, tuple [], 0 array [] načte se vždy jako seznam diet {} object {} klíče musí být řetězce Modul json • json. load () - načti JSON ze souboru • j son .loads () - načti JSON z řetězce • json. dump () - zapiš JSON do souboru • j son . dumps () - zapiš JSON do řetězce • https://does.python.org/3/library/j son.html Čtení [11]:Iwith open('bob.json', encoding='utf8') as f: bob = f.read() print(type(bob)) print(bob) 5 { "name": "Bob", "age": 30, "married": false, "cars": ["Ford", "BMW", "Fiat"] [12] import json with open('bob.json', encoding='utf8') as f: bob = json.load(f) print(type(bob)) print(bob) {'name': 'Bob', 'age': 30, 'married': False, 'cars': ['Ford', 'BMW', ^' Fiat']} [13] : [14] : text = '{ "name": "John", "age": 35, "married": true, "cars" ^["Mercedes", "BMW", "Volkswagen"] }' John = json.loads(text) print(type(john)) print(john) {'name': 'John', 'age': 35, 'married': True, 'cars': ['Mercedes', ^'BMW', 'Volkswagen' ]} Zápis [15]: alice = {'name': 'Alice', 'age': 28, 'married': False, 'cars': ^('Ford', 'Trabant'), 10: 20 } [16]: with open('alice.j son', 'w', encoding='utf8') as f: j son.dump(alice, f) [17]: with open('alice.json', encoding='utf8') as f: print(f.read()) {"name": "Alice", "age": 28, "married": false, "cars": ["Ford", ^"Trabant"], "10": 20} 6 [18]: text = j son.dumps(alice) print(type(text)) print(text) {"name": "Alice", "age": 28, "married": false, "cars": ["Ford", ^"Trabant"], "10": 20} [19]: text = j son.dumps(alice, indent=4) print(type(text)) print(text) { "name": "Alice", "age": 28, "married": false, "cars": [ "Ford", "Trabant" ], "10": 20 } Otázky: Které z uvedených je validní JSON? • A) {ID: 12345, title: "Harry Potter and Learning Python", translations: ["en", "de", "cs", "sk", "hu", "pi"]} • B) {"ID": 12345, "title": "Harry Potter and Learning Python", "t ranslations": ["en", "de", "cs", "sk" , "hu", "pi"]} • C) {'ID': '12345', 'title' : 'Harry Potter and Learning Python' 't ranslations': ['en' , 'de', 'cs', 'sk' , 'hu', 'pi']} • D) {"ID": "12345", "title" : "Harry Potter and Learning Python" "t ranslations": {"en", "de", "cs", "sk" , "hu", "pi"}} Modul argparse • Předávání argumentů z příkazové řádky • Stejný účel jako sys . argv, ale sofistikovanější a hezčí pro uživatele • Argumenty z příkazové řádky (netýká se pouze Pythonu): - Poziční 7 - Volby/přepínače/optzons * Začínají - (jednopísmenné) nebo - - (vícepísmenné) * Mohou mít vlastní parametry • Soubor make_statistics . py: [ ]: import argparse parser = argparse.ArgumentParser(description='Example of argsparse.') parser.add_argument('input', help='Input CSV file', type=str) parser.add_argument('-H', '--header', help='Interpret the first line as column names', action='store_true') parser.add_argument('-v', '--verbose', help='Print extra information', action='store_true') parser.add_argument('-d', '--delimiter', help='Delimiter in the CSV file', type=str, default=',') parser.add_argument('-s', '--stat', help='Statistics to be computed', choices=['mean', 'median', 'min', 'max'], default='mean') args = parser.parse_args() print('Input file:', args.input) print('Header:', args.header) print('Verbose:', args.verbose) print('Delimiter:', args.delimiter) print('Statistics:', args.stat) • Spouštíme z příkazové řádky: python make_statistics.py python make_statistics.py --help python make_statistics.py data.csv --stat median --header --verbose python make_statistics.py data.csv -s median -H -v python make_statistics.py data.csv -Hv --stat median Další moduly - rozšiřující učivo Formát XML • Extensible Markup Language 8 • https://cs.wikipedia.org/wiki/Extensible_Markup_Language Tove Jani Reminde r Don't forget me this weekend! Jani Tove Re: Reminder I will not Modul Ixml • čtení a zápis ve formátu XML (https ://lxml .de) • Externí balíček, nutno doinstalovat pomocí pipu Modul pickle • Uložení pythonovských dat v binárním formátu • Dokáže uložit téměř libovolný objekt (např. i funkce) • Nebezpečí - pickle soubor z cizího zdroje může obsahovat škodlivý kód! Modul requests • Internetová komunikace přes protokol HTTP • Nutno doinstalovat pomocí pipu • Posíláme požadavek {request) na server pomocí metod GET POST PUT DELETE... • Server nám vrací odpověď (response) [20]:I import requests URL = 'http://endless.horse' # URL = Uniform Resource Locator =u ■^webová adresa response = requests.get(URL) # Používáme HTTP metodu GET print('STATUS:', response status_code) # Status code: 200 = OK, 404^ ^= Not Found. .. print('TEXT:', response.text[-700:]) # Posledních 700 znaků zeu ■^stáhnutého textu 9 STATUS: 200 TEXT: le="padding-top: 222px">
 , ,,)\.~,,■
(()' I
I 6^
I I
\,
)\)))
\
A
((\)))),, ''((\())) "))))'
\/
I I I / I      I / I    / \ I \    I   I I