Autorské riešenie
[stiahni py]

  • Počet riešiteľov: 14 / 15 = 93 %

  • Úspešnosť riešenia: 4,21 / 5 = 84,29 %

Pri riešení tejto grafickej úlohy si pomôžeme náčrtom obrázka. Vykreslenie celého obrázka si môžeme rozdeliť na dva podproblémy:

  1. vykreslenie jedného riadku obrázka so zadanou šírkou,
    Vykreslenie riadku

  2. vykreslenie celého obrázka pozostavajúceho so zadaného počtu riadkov.
    Vykreslenie obrázka

Pri riešení úlohy využijeme už vytvorenú funkciu kresli_pixel na vykreslenie jedného pixelu obrázka:

def kresli_pixel(cislo_farby):
    ''' Vykreslí štvorec so zadanou farbou výplne '''
    farby = ['yellow', 'green', 'red']
    pero.pencolor(farby[2])
    pero.fillcolor(farby[cislo_farby])
    pero.begin_fill()
    for idx in range(4):
        pero.forward(25)
        pero.right(90)
    pero.end_fill()

Na vykreslenie pixelov jedného riadku použijeme funkciu kresli_riadok pre zadané číslo riadka (parameter riadok) a zadaný počet pixelov v riadku (parameter sirka). Čísla farieb jednotlivých pixelov riadku určíme pomocou výrazu obrazok[2 + stlpec + sirka * riadok]. Na konci vykreslenia riadku sa vrátime na počiatočnú pozíciu kreslenia riadku. 

def kresli_riadok(obrazok, riadok, sirka):
    ''' Vykreslí riadok obrázka zadaný zoznamom hodnôt
        so zadaným počtom pixelov v riadku '''

    for stlpec in range(sirka):
        cislo_farby = obrazok[2 + stlpec + sirka * riadok]
        kresli_pixel(cislo_farby)
        pero.forward(25)
    pero.forward(-25 * sirka)

Na vykreslenie celého obrázku použijeme funkciu kresli_obrazok. Z parametra obrazok určíme šírku a výšku obrázka a následne v cykle budeme vykresľovať jednotlivé riadky obrázka a presúvať sa na počiatočmú pozíciu nasledovného riadku. Celé kreslenie ukončíme v rovnakom bode, z ktorého sme začali kresliť.

def kresli_obrazok(obrazok):
    ''' Vykreslí obrázok zadaný zoznamom hodnôt '''
    sirka_obrazka = obrazok[0]
    vyska_obrazka = obrazok[1]
    for riadok in range(vyska_obrazka):
        kresli_riadok(obrazok, riadok, sirka_obrazka)
        pero.right(90)
        pero.forward(25)
        pero.left(90)

Výsledné riešenie úlohy zapísané v programovacom jazyku Python môže vyzerať nasledovne:

import turtle


def kresli_obrazok(obrazok):
    ''' Vykreslí obrázok zadaný zoznamom hodnôt '''
    sirka_obrazka = obrazok[0]
    vyska_obrazka = obrazok[1]
    for riadok in range(vyska_obrazka):
        kresli_riadok(obrazok, riadok, sirka_obrazka)
        pero.right(90)
        pero.forward(25)
        pero.left(90)


def kresli_riadok(obrazok, riadok, sirka):
    ''' Vykreslí riadok obrázka zadaný zoznamom hodnôt
        so zadaným počtom pixelov v riadku '''

    for stlpec in range(sirka):
        cislo_farby = obrazok[2 + stlpec + sirka * riadok]
        kresli_pixel(cislo_farby)
        pero.forward(25)
    pero.forward(-25 * sirka)


def kresli_pixel(cislo_farby):
    ''' Vykreslí štvorec so zadanou farbou výplne '''
    farby = ['yellow', 'green', 'red']
    pero.pencolor(farby[2])
    pero.fillcolor(farby[cislo_farby])
    pero.begin_fill()
    for idx in range(4):
        pero.forward(25)
        pero.right(90)
    pero.end_fill()


obrazok = [3, 6, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 0, 0, 1, 0, 1, 1, 1]
tabula = turtle.Screen()
pero = turtle.Turtle()
kresli_obrazok(obrazok)
tabula.mainloop()

Táto úloha je zameraná na: 

  • použitie rôznych stratégii riešenia problémov (dekompozície problému na podproblémy, vykreslenie obrázka),

  • precvičenie príkazov opakovania, volania funkcií s parametrami, príkazov korytnačej grafiky, prácu s dátovým typom zoznam.

Vaše zaujímavé riešenia a najčastejšie chyby

Do riešenia tejto úlohy sa zapojilo 14 tímov z  kategórie EXPERT.  Plný počet bodov dosiahlo 6 tímov (_NegaPyro_, byg, File-Open, HFD, Master, Oliver Seman), ktorým gratulujeme.

Všetci súťažiaci pri vykresľovaní obrázka použili dva vnorené for cykly. V dvoch riešeniach súťažiaci ošetrovali korektnosť vstupov, ktoré sme pri tejto úlohe nutne nevyžadovali.

Len 7 tímov použilo vo svojich riešeniach komentáre (byg, File-Open, HFD, GLSTN BOYZ, GLŠTN masters, Master a Oliver Seman), za čo ich chválime.

V riešeniach sme zaregistrovali nasledovné nedostatky, vychádzajúce najčastejšie z nedôslednej analýzy problému, tvorby menej efektívneho riešenia či z pretrvávajúcich programátorských zlozvykov:

  • nezohľadńenie formátu obrázku, ktorý sa vykresľuje zhora nadol, nie zdola nahor, čím sa vykreslia zrkadlovo preklopené obrázky podľa vodorovnej osi,

  • nesprávne určenie indexov farieb pixelov ako prvkov zoznamu (uvedenie nesprávneho výrazu nezohľadňujúceho širku obrázku),

  •  použitie metódy setheading s nastavením absolútneho natočenia, ktoré by spôsobilo problém, ak by sme požadovali vykreslenie pootočeného obrázku,

  • pri ošetrovaní vstupov použitie logickej spojky AND namiesto spojky OR,

  • zrušenie alebo upravenie pripravenej funkcie kresli_pixel, ktoré by pri tímových projektoch mohlo spôsobiť chaos, ak by viacerí programátori chceli použiť túto funkciu, 

  • namiesto použitia funkcií s parametrami použitie globálnych premenných s príkazom input a funkciami bez parametrov,

  • namiesto plnovýznamových identifikátorov premenných použitie málohovoriacich jednopísmenových identifikátorov.