Nauč se Python > Kurzy > Začátečnický kurz PyLadies > Slovníky > Zpětná vazba k domácím projektům

Feedback k domácím projektům

Globální proměnné nebrat

V tomto příkladu sice máme funkce, ale ty nejsou příliš užitečné, protože ke svému fungování potřebují množství globálních proměnných.

In [ ]:
#Vytvoření prázdného slovníku
slovnik_mocniny = dict()
slovnik_klicu_a_hodnot = dict()

#Uživatel zadá číslo n, n+1 zajistí, že se později vypíše číslo přesně do výše,
#jakou uživatel zadal
n = int(input('Zadej číslo, program vypočítá druhé mocniny od 1 až po toto číslo: '))
n = n+1

#Funkce k úkolu č. 0 - vypíše mocniny až do čísla daného uživatelem
def mocniny():
    for x in range(1,n):
        slovnik_mocniny[x]=x**2
    return(slovnik_mocniny)

#Funkce k úkolu č. 1 - sečte klíče a hodnoty ve slovníku mocniny, přidá je do
#slovníku soucet_klicu_a_hodnot
def soucet_klicu_a_hodnot():
    soucet_klicu = sum(slovnik_mocniny.keys())
    soucet_hodnot = sum(slovnik_mocniny.values())
    slovnik_klicu_a_hodnot = {soucet_klicu, soucet_hodnot}
    return slovnik_klicu_a_hodnot

Mnohem lepší přístup:

In [ ]:
def mocniny(n):
    """ Vytvori slovnik mocnin o velikosti n """
    slovnik = {}
    for j in range(1, n+1):
        slovnik[(j)] = j**2
    return slovnik


def soucet_klicu_a_hodnot(slovnik):
    """ vrati soucty vsech klicu a vsech hodnot"""
    return sum(slovnik.keys()), sum(slovnik.values())


def vypis_slovnik(slovnik):
    """ vypise obsah slovniku """
    for objekt in slovnik:
        print("Klic ", objekt, ", hodnota ", slovnik[objekt], sep='')


print(mocniny(4))
print(soucet_klicu_a_hodnot(mocniny(4)))
print(pocet_znaku("hello world"))
vypis_slovnik(mocniny(4))

Skautská hra

In [ ]:
import random

while True:
    odpoved = input('Na kolik odpovědí chceš hrát? ')
    try:
        odpoved = int(odpoved)
        break
    except ValueError:
        print('Musíš napsat celé číslo!')

kdo = []
s_kym = []
co_delali = []
kde = []
kdy = []
proc = []

vsechno = [kdo,s_kym,co_delali,kde,kdy,proc]

for i in range (odpoved):
    kdo1 = input ('Kdo? ')
    s_kym1 = input ('S kým? ')
    co_delali1 = input ('Co dělali? ')
    kde1 = input ('Kde? ')
    kdy1 = input ('Kdy? ')
    proc1 = input ('Proč? ')
    print('')

    kdo.append(kdo1)
    s_kym.append(s_kym1)
    co_delali.append(co_delali1)
    kde.append(kde1)
    kdy.append(kdy1)
    proc.append(proc1)

a=random.choice(kdo)
b=random.choice(s_kym)
c=random.choice(co_delali)
d=random.choice(kde)
e=random.choice(kdy)
f=random.choice(proc)

print(a, b, c, d, e, f)

Řešení bez slovníků, ale hlavně takové, kde by nebylo úplně snadné přidat další otázky.

In [ ]:
import random

kdo_seznam = []
s_kym_seznam = []
kde_seznam = []
co_delali_seznam = []
proc_seznam = []
for pocet in range(3):
    kdo = input('Kdo? ')
    kdo_seznam.append(kdo)
    s_kym = input('S kým? ')
    s_kym_seznam.append(s_kym)
    kde = input('Kde? ')
    kde_seznam.append(kde)
    co_delali = input('Co dělali? ')
    co_delali_seznam.append(co_delali)
    proc = input('Proč? ')
    proc_seznam.append(proc)
print(random.choice(kdo_seznam), 's', random.choice(s_kym_seznam),'v', random.choice(kde_seznam), random.choice(co_delali_seznam), random.choice(proc_seznam))

Řešení, kde přidání, změna či odebrání jakékoli otázky znamená jen změnu na jednom míste v seznamu otázek.

In [ ]:
from random import choice

otazky = ['Kdo', 'S kym', 'Co delali', 'Kde']

odpovedi = {}
for otazka in otazky:
    odpovedi[otazka] = []

# Alternativní cesta
# odpovedi = {otazka: [] for otazka in otazky}
    
for otazka in otazky:
    while True:
        odpoved = input('Zadej odpoved na otazku {}? '.format(otazka))
        if not odpoved:
            break
        else:
            odpovedi[otazka].append(odpoved)

veta = ''

for otazka in otazky:
    veta = veta + choice(odpovedi[otazka]) + ' '

print(veta)

Seznam sám v sobě

In [3]:
seznam = [5] * 6
seznam
Out[3]:
[5, 5, 5, 5, 5, 5]
In [6]:
seznam[5] = seznam
seznam
Out[6]:
[5, 5, 5, 5, 5, [...]]
In [12]:
seznam[5]
Out[12]:
[5, 5, 5, 5, 5, [...]]
In [8]:
seznam[5][5][5][5]
Out[8]:
[5, 5, 5, 5, 5, [...]]
In [9]:
seznam[5][5][5][5][5][5][5][5][5][5][5][5][5][5][5][5]
Out[9]:
[5, 5, 5, 5, 5, [...]]
In [11]:
seznam[5][5][5][5][5][5][5][5][5][5][5][5][5][5][5][5][5][5][5][5][5][5][5][5][5][5][5][5][5][5][5][5]
Out[11]:
[5, 5, 5, 5, 5, [...]]
In [10]:
seznam[5][5][5][5][5][5][5][5][5][5][5][5][5][5][5][5][0]
Out[10]:
5

Ukázky jednoduchých API

In [14]:
import requests

Ano nebo ne?

In [29]:
response = requests.get("https://yesno.wtf/api")

response.raise_for_status()

data = response.json()

data
Out[29]:
{'answer': 'yes',
 'forced': False,
 'image': 'https://yesno.wtf/assets/yes/13-c3082a998e7758be8e582276f35d1336.gif'}
In [30]:
data["answer"]
Out[30]:
'yes'
In [31]:
data["image"]
Out[31]:
'https://yesno.wtf/assets/yes/13-c3082a998e7758be8e582276f35d1336.gif'

image

Náhodná rada do života

In [12]:
response = requests.get("https://api.adviceslip.com/advice")

response.raise_for_status()

data = response.json()

data
Out[12]:
{'slip': {'advice': 'A nod is as good as a wink to a blind horse.',
  'slip_id': '120'}}
In [13]:
data["slip"]["advice"]
Out[13]:
'A nod is as good as a wink to a blind horse.'

Texty písní

In [5]:
artist = "Queen"
title = "Bohemian Rhapsody"

response = requests.get("https://api.lyrics.ovh/v1/{}/{}".format(artist, title))

response.raise_for_status()

data = response.json()
text = data["lyrics"]

print(text)
Is this the real life? Is this just fantasy?
Caught in a landslide, no escape from reality
Open your eyes, look up to the skies and see

I'm just a poor boy, I need no sympathy
Because I'm easy come, easy go, little high, little low
Anyway the wind blows, doesn't really matter to me, to me

Mama, just killed a man
Put a gun against his head, pulled my trigger, now he's dead
Mama, life had just begun
But now I've gone and thrown it all away

Mama, ooh, didn't mean to make you cry
If I'm not back again this time tomorrow
Carry on, carry on, as if nothing really matters

Too late, my time has come
Sends shivers down my spine, body's aching all the time
Goodbye, everybody, I've got to go
Gotta leave you all behind and face the truth

Mama, ooh, (Any way the wind blows) I don't wanna die
I sometimes wish I'd never been born at all

I see a little silhouetto of a man
Scaramouche, Scaramouche, will you do the Fandango?
Thunderbolts and lightning, very, very frightening me

Galileo (Galileo), Galileo (Galileo)
Galileo, Figaro, Magnifico, oh, oh, oh, oh, oh

I'm just a poor boy, nobody loves me
He's just a poor boy from a poor family
Spare him his life from this monstrosity

Easy come, easy go, will you let me go?
Bismillah, no, we will not let you go (Let him go)
Bismillah, we will not let you go (Let him go)
Bismillah, we will not let you go (Let me go)
Never let you go (Let me go)
Never let you go (Never, never, never let me go, oh, oh, oh)
No, no, no, no, no, no, no

Oh, mamma mia, mamma mia
Mamma mia, let me go
Beelzebub has a devil put aside
For me, for me, for me

So you think you can stone me and spit in my eye?
So you think you can love me and leave me to die?
Oh baby, can't do this to me, baby
Just gotta get out, just gotta get right out of here

Ooh-ooh-ooh
Ooh-yeah, ooh-yeah

Nothing really matters, anyone can see
Nothing really matters, nothing really matters to me

Any way the wind blows

Počasí

In [36]:
location = "551801"

response = requests.get("https://www.metaweather.com/api/location/{}/".format(location))

response.raise_for_status()

data = response.json()

data
Out[36]:
{'consolidated_weather': [{'id': 4827330616754176,
   'weather_state_name': 'Light Cloud',
   'weather_state_abbr': 'lc',
   'wind_direction_compass': 'NNE',
   'created': '2019-04-01T15:40:43.519403Z',
   'applicable_date': '2019-04-01',
   'min_temp': 6.23,
   'max_temp': 16.87,
   'the_temp': 16.0,
   'wind_speed': 5.624506348275404,
   'wind_direction': 15.843933712230228,
   'air_pressure': 1021.44,
   'humidity': 53,
   'visibility': 14.091766583154378,
   'predictability': 70},
  {'id': 5566602449780736,
   'weather_state_name': 'Light Cloud',
   'weather_state_abbr': 'lc',
   'wind_direction_compass': 'SE',
   'created': '2019-04-01T15:40:46.702324Z',
   'applicable_date': '2019-04-02',
   'min_temp': 6.324999999999999,
   'max_temp': 16.495,
   'the_temp': 14.040000000000001,
   'wind_speed': 8.848418440266178,
   'wind_direction': 141.6650057162162,
   'air_pressure': 1016.7,
   'humidity': 51,
   'visibility': 15.103980255308995,
   'predictability': 70},
  {'id': 6239291585855488,
   'weather_state_name': 'Heavy Cloud',
   'weather_state_abbr': 'hc',
   'wind_direction_compass': 'SSE',
   'created': '2019-04-01T15:40:50.333305Z',
   'applicable_date': '2019-04-03',
   'min_temp': 8.459999999999999,
   'max_temp': 18.935,
   'the_temp': 17.6,
   'wind_speed': 10.249016933365146,
   'wind_direction': 152.0369435066321,
   'air_pressure': 1007.515,
   'humidity': 56,
   'visibility': 13.653078521434821,
   'predictability': 71},
  {'id': 5814165388132352,
   'weather_state_name': 'Light Cloud',
   'weather_state_abbr': 'lc',
   'wind_direction_compass': 'SSE',
   'created': '2019-04-01T15:40:52.521424Z',
   'applicable_date': '2019-04-04',
   'min_temp': 10.945,
   'max_temp': 16.915,
   'the_temp': 16.5,
   'wind_speed': 11.391530074339192,
   'wind_direction': 160.16280146794102,
   'air_pressure': 1002.565,
   'humidity': 55,
   'visibility': 13.370976000159072,
   'predictability': 70},
  {'id': 5800497996890112,
   'weather_state_name': 'Showers',
   'weather_state_abbr': 's',
   'wind_direction_compass': 'SE',
   'created': '2019-04-01T15:40:55.517305Z',
   'applicable_date': '2019-04-05',
   'min_temp': 5.91,
   'max_temp': 10.305,
   'the_temp': 9.469999999999999,
   'wind_speed': 6.654490472305734,
   'wind_direction': 133.01467370354433,
   'air_pressure': 1005.3655,
   'humidity': 71,
   'visibility': 7.865937922532411,
   'predictability': 73},
  {'id': 5218222536130560,
   'weather_state_name': 'Heavy Cloud',
   'weather_state_abbr': 'hc',
   'wind_direction_compass': 'NNE',
   'created': '2019-04-01T15:40:58.514664Z',
   'applicable_date': '2019-04-06',
   'min_temp': 4.58,
   'max_temp': 13.9,
   'the_temp': 6.1,
   'wind_speed': 2.9785608048993875,
   'wind_direction': 22.50000000000001,
   'air_pressure': 1010.0,
   'humidity': 75,
   'visibility': 9.997862483098704,
   'predictability': 71}],
 'time': '2019-04-01T20:37:07.101346+02:00',
 'sun_rise': '2019-04-01T06:33:42.385539+02:00',
 'sun_set': '2019-04-01T19:24:13.588295+02:00',
 'timezone_name': 'LMT',
 'parent': {'title': 'Austria',
  'location_type': 'Country',
  'woeid': 23424750,
  'latt_long': '47.696510,13.345770'},
 'sources': [{'title': 'BBC',
   'slug': 'bbc',
   'url': 'http://www.bbc.co.uk/weather/',
   'crawl_rate': 180},
  {'title': 'Forecast.io',
   'slug': 'forecast-io',
   'url': 'http://forecast.io/',
   'crawl_rate': 480},
  {'title': 'HAMweather',
   'slug': 'hamweather',
   'url': 'http://www.hamweather.com/',
   'crawl_rate': 360},
  {'title': 'Met Office',
   'slug': 'met-office',
   'url': 'http://www.metoffice.gov.uk/',
   'crawl_rate': 180},
  {'title': 'OpenWeatherMap',
   'slug': 'openweathermap',
   'url': 'http://openweathermap.org/',
   'crawl_rate': 360},
  {'title': 'Weather Underground',
   'slug': 'wunderground',
   'url': 'https://www.wunderground.com/?apiref=fc30dc3cd224e19b',
   'crawl_rate': 720},
  {'title': 'World Weather Online',
   'slug': 'world-weather-online',
   'url': 'http://www.worldweatheronline.com/',
   'crawl_rate': 360},
  {'title': 'Yahoo',
   'slug': 'yahoo',
   'url': 'http://weather.yahoo.com/',
   'crawl_rate': 180}],
 'title': 'Vienna',
 'location_type': 'City',
 'woeid': 551801,
 'latt_long': '48.202541,16.368799',
 'timezone': 'Europe/Vienna'}
In [37]:
for day in data["consolidated_weather"]:
    print(day["applicable_date"], round(day["min_temp"], 2), round(day["max_temp"], 2))
2019-04-01 6.23 16.87
2019-04-02 6.32 16.5
2019-04-03 8.46 18.93
2019-04-04 10.95 16.91
2019-04-05 5.91 10.3
2019-04-06 4.58 13.9

Oxford dictionary

In [32]:
app_id = '8206c2a3'
app_key = 'bf9aacede374e4d731fb020edd801642'
language = 'en'
word = 'python'

url = "https://od-api.oxforddictionaries.com:443/api/v1/entries/{}/{}".format(language, word)
response = requests.get(url, headers = {'app_id' : app_id, 'app_key' : app_key})

data = response.json()

data
Out[32]:
{'metadata': {'provider': 'Oxford University Press'},
 'results': [{'id': 'python',
   'language': 'en',
   'lexicalEntries': [{'derivatives': [{'id': 'pythonic', 'text': 'pythonic'}],
     'entries': [{'etymologies': ['late 16th century (in the Greek sense): via Latin from Greek Puthōn, the name of a huge serpent killed by Apollo. The main current sense dates from the mid 19th century'],
       'grammaticalFeatures': [{'text': 'Singular', 'type': 'Number'}],
       'homographNumber': '000',
       'senses': [{'definitions': ['a large heavy-bodied non-venomous snake occurring throughout the Old World tropics, killing prey by constriction and asphyxiation.'],
         'domains': ['Reptile'],
         'id': 'm_en_gbus0833540.009',
         'notes': [{'text': 'Family Pythonidae: genera Python (of Asia and Africa), and Morelia and Aspidites (of Australasia)',
           'type': 'technicalNote'}],
         'short_definitions': ['large heavy-bodied non-venomous snake occurring throughout Old World tropics']},
        {'definitions': ['a high-level general-purpose programming language.'],
         'domains': ['Computing'],
         'id': 'm_en_gbus0833540.014',
         'notes': [{'text': 'mass noun', 'type': 'grammaticalNote'}],
         'short_definitions': ['high-level general-purpose programming language'],
         'variantForms': [{'text': 'Python'}]}]}],
     'language': 'en',
     'lexicalCategory': 'Noun',
     'pronunciations': [{'audioFile': 'http://audio.oxforddictionaries.com/en/mp3/python_gb_1.mp3',
       'dialects': ['British English'],
       'phoneticNotation': 'IPA',
       'phoneticSpelling': 'ˈpʌɪθ(ə)n'}],
     'text': 'python'}],
   'type': 'headword',
   'word': 'python'}]}
In [33]:
data["results"][0]["lexicalEntries"][0]["entries"][0]["senses"]
Out[33]:
[{'definitions': ['a large heavy-bodied non-venomous snake occurring throughout the Old World tropics, killing prey by constriction and asphyxiation.'],
  'domains': ['Reptile'],
  'id': 'm_en_gbus0833540.009',
  'notes': [{'text': 'Family Pythonidae: genera Python (of Asia and Africa), and Morelia and Aspidites (of Australasia)',
    'type': 'technicalNote'}],
  'short_definitions': ['large heavy-bodied non-venomous snake occurring throughout Old World tropics']},
 {'definitions': ['a high-level general-purpose programming language.'],
  'domains': ['Computing'],
  'id': 'm_en_gbus0833540.014',
  'notes': [{'text': 'mass noun', 'type': 'grammaticalNote'}],
  'short_definitions': ['high-level general-purpose programming language'],
  'variantForms': [{'text': 'Python'}]}]

Obecné rady a postřehy

  • Ptejte se na Slacku na cokoli. Co bude zajímavé pro více lidí, to zpracujeme do hodiny.
  • Pokud máte úkoly na githubu:
    • Odevzdejte na Dropbox jen odkaz v souboru .txt nikoli .docx
    • Pokud vám Martin nezaloží issue, je ve vašem úkolu vše v pořádku
  • Pochvala za validaci inputů
    • Ještě větší pochvala za validaci s pomocí výjimek
  • Pochvala za dokumentační řetězce
    • Ještě větší pochvala za dokumentační řetězce ve třech uvozovkách
      • A ještě větší pochvala těm, kdož jsou konzistentní a dávají dokumentační řetězce úplně všude

Toto je stránka lekce z kurzu, který probíhá nebo proběhl naživo s instruktorem.