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

Feedback k domácím projektům

Zvířátka

Najdi chyby, nejasnosti či nepřesnosti v tomto kódu:

In [ ]:
zvirata = [ "pes", "kočka", "králík", "had", "ježek"]
znak = "k"

def pismeno(jmeno):
    for i in range(5):
        if znak in jmeno[i][0]:
            print(jmeno[i])
    return

pismeno(zvirata)

Takto by to mohlo vypadat přehlednější a pochopitelnější

In [ ]:
zvirata = [ "pes", "kočka", "králík", "had", "ježek"]

def s_prvnim_pismenem(seznam_zvirat, pismeno):
    for zvire in seznam_zvirat:
        if zvire.startswith(pismeno):
            print(zvire)

s_prvnim_pismenem(zvirata, 'k')

Další podobná funkce:

In [ ]:
def kratke(jmeno = zvirata):
    for i in range(len(jmeno)):
        if len(jmeno[i]) < 5:
            print(jmeno[i])
        else:
            print(end = "")
    return jmeno

kratke(zvirata)

A její přehlednější varianta:

In [ ]:
def kratke(seznam_zvirat):
    for jmeno in seznam_zvirat:
        if len(jmeno) < 5:
            print(jmeno)

kratke(zvirata)

Je možné tuto funkci zkrátit a zjednodušit?

In [ ]:
def overeni(seznam):
    "ověří, zda je zadané slovo v seznamu a vrátí True/False"
    otazka = input("Zadej název zvířete, jež chceš ověřit: ")
    if otazka in seznam:
        return True
    else:
        return False

Ano, je to možné

In [ ]:
def overeni(seznam):
    "ověří, zda je zadané slovo v seznamu a vrátí True/False"
    otazka = input("Zadej název zvířete, jež chceš ověřit: ")
    return otazka in seznam

Básnička

Obrácené pořadí veršů

In [1]:
with open("static/basnicka.txt", encoding="utf-8") as soubor_s_bacnickou:
    basnicka = soubor_s_bacnickou.read()

seznam_versu = basnicka.split("\n")  # Rozdělí básničku na jednotlivé verše (řádky) [seznam]
seznam_versu.reverse()  # Obrátí pořadí veršů v seznamu
obracena_basnicka = "\n".join(seznam_versu)  # Složí zpět seznam na řetězec a mezi verše vloží \n
print(obracena_basnicka)
Anyway the wind blows doesn't really matter to me, to me.
Little high, little low,
Because I'm easy come, easy go,
I'm just a poor boy, I need no sympathy,
Look up to the skies and see,
Open your eyes,

No escape from reality.
Caught in a landslide,
Is this just fantasy?
Is this the real life?
In [2]:
with open("static/basnicka.txt", encoding="utf-8") as soubor_s_bacnickou:
    seznam_versu = soubor_s_bacnickou.readlines()

for vers in seznam_versu[::-1]:
    print(vers, end="")
Anyway the wind blows doesn't really matter to me, to me.
Little high, little low,
Because I'm easy come, easy go,
I'm just a poor boy, I need no sympathy,
Look up to the skies and see,
Open your eyes,

No escape from reality.
Caught in a landslide,
Is this just fantasy?
Is this the real life?

Obrácené pořadí slov ve verších

In [3]:
with open("static/basnicka.txt", encoding="utf-8") as soubor_s_bacnickou:
    basnicka = soubor_s_bacnickou.read()

seznam_versu = basnicka.split("\n")  # Rozdělí básničku na jednotlivé verše (řádky) [seznam]

nova_basnicka = []  # Seznam pro novou básničku, která obrácením pořadí slov vznikne

for vers in seznam_versu:  # Pro každý verš v originální básničce
    slova = vers.split()  # Rozdělí verš na slova [seznam]
    slova.reverse()  # Obrátí pořádí slov
    novy_vers = " ".join(slova)  # Spojí obrázená slova zpět do řetězce
    nova_basnicka.append(novy_vers)  # Přidá nový verš do nové básničky

obracena_basnicka = "\n".join(nova_basnicka)  # Složí zpět seznam na řetězec a mezi verše vloží \n
print(obracena_basnicka)
life? real the this Is
fantasy? just this Is
landslide, a in Caught
reality. from escape No

eyes, your Open
see, and skies the to up Look
sympathy, no need I boy, poor a just I'm
go, easy come, easy I'm Because
low, little high, Little
me. to me, to matter really doesn't blows wind the Anyway

In [4]:
with open("static/basnicka.txt", encoding="utf-8") as soubor_s_bacnickou:
    seznam_versu = soubor_s_bacnickou.readlines()

for i, vers in enumerate(seznam_versu):
    slova = vers.split()
    slova.reverse()
    seznam_versu[i] = " ".join(slova)

print("\n".join(seznam_versu))
life? real the this Is
fantasy? just this Is
landslide, a in Caught
reality. from escape No

eyes, your Open
see, and skies the to up Look
sympathy, no need I boy, poor a just I'm
go, easy come, easy I'm Because
low, little high, Little
me. to me, to matter really doesn't blows wind the Anyway

Obrácené pořadí slok

In [5]:
with open("static/basnicka.txt", encoding="utf-8") as soubor_s_bacnickou:
    basnicka = soubor_s_bacnickou.read()

seznam_slok = basnicka.split("\n\n")  # Rozdělí básničku na jednotlivé sloky [seznam]
seznam_slok.reverse()
basnicka = "\n".join(seznam_slok)
print(basnicka)
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.

Is this the real life?
Is this just fantasy?
Caught in a landslide,
No escape from reality.

Slova v náhodném pořadí (Mr. Yoda style)

In [6]:
from random import shuffle

with open("static/basnicka.txt", encoding="utf-8") as soubor_s_bacnickou:
    seznam_versu = soubor_s_bacnickou.readlines()

for i, vers in enumerate(seznam_versu):
    slova = vers.split()
    shuffle(slova)
    seznam_versu[i] = " ".join(slova)

print("\n".join(seznam_versu))
life? this Is real the
Is this just fantasy?
Caught in a landslide,
reality. from escape No

your eyes, Open
up see, and to Look skies the
just sympathy, I poor no need a I'm boy,
I'm come, easy easy go, Because
Little little high, low,
me. to blows the matter me, really wind to doesn't Anyway

Funkce jako stavební blok programu

Takto použitá funkce situaci spíše komplikuje, než aby něčemu pomohla.

In [19]:
zvirata = ['had', 'andulka', 'pes', 'kočka', 'králík']
dvojice = []
vysledek = []

def razeni_had(seznam1, seznam2, seznam3):
    '''seřadí výchozí seznam1 podle abecedy, ale bude ignorovat první písmeno'''
    for slovo in seznam1:
        seznam2.append([slovo[1:], slovo])
    seznam2.sort()
    for item in seznam2:
        seznam3.append(item[1])
    seznam3

razeni_had(zvirata, dvojice, vysledek)
print(vysledek)
['had', 'pes', 'andulka', 'kočka', 'králík']

Co se asi stane, když takovou funkci zavoláme vícekrát?

In [20]:
zvirata = ['had', 'andulka', 'pes', 'kočka', 'králík']
dvojice = []
vysledek = []

def razeni_had(seznam1, seznam2, seznam3):
    '''seřadí výchozí seznam1 podle abecedy, ale bude ignorovat první písmeno'''
    for slovo in seznam1:
        seznam2.append([slovo[1:], slovo])
    seznam2.sort()
    for item in seznam2:
        seznam3.append(item[1])
    seznam3

razeni_had(zvirata, dvojice, vysledek)
print(vysledek)
razeni_had(zvirata, dvojice, vysledek)
print(vysledek)
['had', 'pes', 'andulka', 'kočka', 'králík']
['had', 'pes', 'andulka', 'kočka', 'králík', 'had', 'had', 'pes', 'pes', 'andulka', 'andulka', 'kočka', 'kočka', 'králík', 'králík']

Ověření, že funkce funguje

Nejsnazší je funkci prostě spustit s různými argumenty a podívat se, zda dělá to, co by dělat měla.

In [7]:
def absolutni_soucet(a, b):
    if a < 0:
        a = -a
    if b < 0:
        b = -b
    return a + b
In [8]:
print(absolutni_soucet(1, 2))
print(absolutni_soucet(100, 200))
print(absolutni_soucet(-1, -2))
print(absolutni_soucet(-1, 2))
print(absolutni_soucet(100, -2))
3
300
3
3
102

List comprehensions

Jedná se o zápis s Pythonu s jehož pomocí se dají jednoduše vytvářet seznamy.

In [9]:
seznam_mocnin = []

for x in range(10):
    seznam_mocnin.append(x ** 2)

seznam_mocnin
Out[9]:
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
In [10]:
[x for x in range(10)]
Out[10]:
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
In [11]:
[x**2 for x in range(10)]
Out[11]:
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
In [12]:
[x**2 for x in range(10) if x % 2 == 0]
Out[12]:
[0, 4, 16, 36, 64]
In [13]:
[(x, x**2) for x in range(10)]
Out[13]:
[(0, 0),
 (1, 1),
 (2, 4),
 (3, 9),
 (4, 16),
 (5, 25),
 (6, 36),
 (7, 49),
 (8, 64),
 (9, 81)]
In [14]:
[[y for y in range(3)] for x in range(10)]
Out[14]:
[[0, 1, 2],
 [0, 1, 2],
 [0, 1, 2],
 [0, 1, 2],
 [0, 1, 2],
 [0, 1, 2],
 [0, 1, 2],
 [0, 1, 2],
 [0, 1, 2],
 [0, 1, 2]]

Tabulka s hracím polem

Řešení 1

In [ ]:
def vytvor_tabulku():
    zap_tabulka = []

    for rada_x in '.', '.', '.', '.', '.', '.', '.', '.', '.', '.':
        radek = []
        for rada_y in '.', '.', '.', '.', '.', '.', '.', '.', '.', '.':
            radek.append(rada_y)
        zap_tabulka.append(radek)
    return zap_tabulka

Řešení 2

In [ ]:
def vytvor_prazdne_herni_pole(r,s):
    seznam_radku = []
    for a in range(r):
        radek = ["."]
        for b in range(s-1):
            radek.append(".")
        seznam_radku.append(radek)
    return seznam_radku

Správné řešení

In [ ]:
def vytvor_tabulku(velikost):
    seznam_radku = []
    for a in range(velikost):
        radek = []
        for b in range(velikost):
            radek.append(".")
        seznam_radku.append(radek)
    return seznam_radku

Správné a krátké řešení

In [ ]:
def vytvor_tabulku(velikost):
    seznam_radku = []
    for a in range(velikost):
        radek = ["."] * velikost
        seznam_radku.append(radek)
    return seznam_radku

Krátké řešení (s pomocí list comprehensions)

In [ ]:
def vytvor_tabulku(velikost):
    tabulka = []
    for x in range(velikost):
        radek = ['.' for x in range(velikost)]
        tabulka.append(radek)
    return tabulka

Nejkratší řešení (je nejlepší?)

In [ ]:
def vytvor_tabulku(velikost):
    return [list('.' * velikost) for x in range(velikost)]

Je vytvoření kompletní tabulky se všemi hracími políčky vážně potřeba?

Had

In [ ]:
def velikost_hraciho_pole():
    """Zjistí od uživatele rozumnou velikost herního pole"""
    while True:
        odpoved = input('Zadej velikost pole pro hada: ')
        try:
            velikost = int(odpoved)
        except ValueError:
            print('Velikost musí být celé číslo')
        else:
            if velikost > 5:
                break
            else:
                print('Pole musí být rozumně veliké!')

    return velikost
In [15]:
def vykresli_mapu(velikost, had, ovoce):
    """Vykreslí herní mapu s ovocem a hadem na správných místech"""
    for x in range(velikost):
        for y in range(velikost):
            if (x, y) in had:
                print('X', end=' ')
            elif (x, y) in ovoce:
                print('?', end=' ')
            else:
                print('.', end=' ')
        print()
In [16]:
def posun(velikost, had, ovoce):
    """Posune hada v určitém směru a zajistí jeho prodloužení při snězení jídla"""
    while True:
        smer = input('Zadej smer posunu [s, j, v, z]: ')
        smer = smer.lower().strip()
        if smer not in ('s', 'j', 'v', 'z'):
            print('Nekorektni smer!')
        else:
            break

    hlava = had[-1]
    x, y = hlava
    if smer == 's':
        nova_hlava = x-1, y
    elif smer == 'j':
        nova_hlava = x+1, y
    elif smer == 'v':
        nova_hlava = x, y+1
    elif smer == 'z':
        nova_hlava = x, y-1

    if nova_hlava in had:
        raise ValueError('GAME OVER! Narazil si sam do sebe')

    x, y = nova_hlava

    if x < 0 or x > velikost-1 or y < 0 or y > velikost-1:
        raise ValueError('GAME OVER! Vyjel si mimo herni pole')

    if nova_hlava in ovoce:
        ovoce.remove(nova_hlava)
    else:
        del had[0]

    had.append(nova_hlava)
    return True
In [17]:
from random import randrange

def pridej_ovoce(velikost, had, ovoce):
    """Přidá další ovoce na herní plochu mimo souřadnice hada"""
    ovoce.append((randrange(0, velikost), randrange(0, velikost)))
    while ovoce[-1] in had:
        del ovoce[-1]
        ovoce.append((randrange(0, velikost), randrange(0, velikost)))
In [ ]:
def hra():
    """Hlavní části hry spojeny ve finální celek"""
    velikost = velikost_hraciho_pole()

    had = [(0, 0), (0, 1), (0, 2)]
    ovoce = []
    pridej_ovoce(velikost, had, ovoce)

    vykresli_mapu(velikost, had, ovoce)

    while posun(velikost, had, ovoce):
        vykresli_mapu(velikost, had, ovoce)
        if not ovoce:
            pridej_ovoce(velikost, had, ovoce)
In [ ]:
hra()

Rubber duck problem solving

Jde o techniku řešení problému, při které se svůj problém snažíte vysvětlit někomu (nebo v případě gumové kachny něčemu), kdo programování nemusí vůbec rozumět. Když řešenou problematiku a vaše současné řešení popisujete nahlas, uvědomíte si, co váš program aktuálně dělá a co by dělat měl, což zpravidla vede k vyřešení problému.

Obecné rady a poznatky

Snažte se!!!


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