Grafiikkaa Pythonilla

Tässä artikkelissa tutkimme Python-ohjelmointikielen soveltuvuutta grafiikan ohjelmointiin. Käymme tässä artikkelissa läpi replit.com-sivustolla olevia selainpohjaisia Pythoniin liitettäviä grafiikkakirjastoja ja vertaamme koodia niiden välillä ja soveltuvuutta opetukseen. Kaikki artikkelin koodit on testattu replit.com-sivustolla.

Alankomaalainen Guido Van Rossum kehitti tulkattavan Python-ohjelmointikielen 1980-luvun lopussa. Vuonna 2000 julkaistiin Python 2 ja vuonna 2008 Python 3. Tässä Pythonin uusimmassa versiossa on paljon uusia komentoja ja rakenteellisia uudistuksia, joten Python 1 ja Python 2 -ohjelmat eivät enää pyöri uusimmalla Python 3 versiolla. Tämän ongelman kiertämiseksi on kuitenkin kehitetty sovelluksia, jotka muuttavat esimerkiksi Python 2 -koodin Python 3 -koodiksi. Koodin yksinkertaisuus ja avoin lähdekoodi on tehneet Pythonista yhden maailman suosituimmista ohjelmointikielistä niin työelämässä kuin opetuksessakin. Kun katsoo Pythonilla tehtyjä opetusmateriaaleja, niin huomaa, että opetusmateriaaleissa on pysytty tiukasti tekstipohjaisissa ohjelmissa, jossa tulostus tapahtuu konsoli-ikkunaan. Mutta kuinka Pythonilla onnistuu grafiikan tekeminen? Miten se onnistuu ja voisiko se antaa lisämaustetta ohjelmoinnin opetukseen?

Turtle

Turtle grafiikan historia on paljon vanhempi kuin Pythonin. Turtle-kilpikonnan ohjelmointi juontaa juurensa vuoteen 1969, jolloin Logo-kielessä haluttiin lasten oppivan ohjelmoinnin perusideat komentamalla Turtle-robottia. Turtle-kirjasto on sen jälkeen kehitetty lähes jokaiselle suositulle ohjelmointikielelle ja Python ei ole tässä poikkeus. Turtle-kirjasto on Pythonissa vakiokirjasto ja se antaa mahdollisuuden yhdistää Pythonin peruskomentoja ja Turtle-kirjaston komentoja. Siksi Turtlesta on tullut suosittu tapa tutustua Pythoniin kielen perusteisiin. Katsotaan seuraavaksi, millainen koodi tarvitaan suorakulmion piirtämiseen.

Turtle-ohjelmoinnissa idea on antaa ohjeita kilpikonnalle, jolla on tietty sijainti xy-koordinaatistossa ja liikkumissuunta. Lisäksi kilpikonnalla on kynä, jonka avulla kilpikonnan kulkema reitti saadaan näkyväksi. Katsotaan seuraavaksi, kuinka Turtle-grafiikalla voidaan piirtää neliö.

Kuva 1: Neliön piirtäminen Python Turtle -grafiikalla

Mitä yllä olevat koodit tarkoittavat? Puretaan kuvan 1 mukainen koodi osiin.

  1. Komento import turtle ottaa Turtle-kirjaston käyttöön.
  2. Komennolla asetetaan ikkunan koko (leveys = 400, korkeus = 400) ja ikkunan taustaväri (valkea).
  3. Määrittelemme muuttujan t, joka on kilpikonna-olio. Muuttujan t avulla lyhennämme koodia.
  4. Kilpikonna-oliolle t:lle asetetaan kynän paksuudeksi 5.
  5. Kilpikonna-oliolle t:lle asetetaan kynän väriksi mustan ja täyttöväriksi syaani.
  6. Asetetaan kilpikonna-oliolle t täyttömoodi päälle.
  7. Luodaan for-silmukka, jossa on 4 toistoa (tässä muuttuja i saa arvot 0, 1, 2, 3).
  8. Kilpikonna-olio t liikkuu eteenpäin 100 askelta (pikseliä).
  9. Kilpikonna-olio t kääntyy oikealle 90 astetta.
  10. Otetaan kilpikonna t:ltä täyttömoodi pois päältä.
  11. Kilpikonna-olio t:n kynä nostetaan ylös.

Havaitaan, että komennot ovat selkeät, mutta aloittelijan pitäisi jo ymmärtää, että tässä hyödynnetään ohjelmointikielen olio-ominaisuutta, joka luonnollisesti pidentää koodia. Jos käsitteet olio ja funktio ovat epäselvät, tämä voi aiheuttaa turhaa hämmennystä aluksi. Turtle-grafiikan piirtämisessä on kuitenkin sama idea kuin Scratch-ohjelmoinnissakin, joten voi miettiä, että olisiko parempi piirtää kuitenkin Scratchillä. Turtle-grafiikka on kuitenkin tarkoitettu johdannoksi ohjelmointiin, joten kannattaisi käyttää ensisijaisesti rinnan Pythonin peruskomentojen kanssa, kun niitä aletaan opiskelemaan. Turtlen eräs ongelma on myös piirtämisen hitaus, joten voisi myös miettiä muita vaihtoehtoja graafiseen ohjelmointiin.

Turtle-ohjelmoinnista Pythonilla lisää aiemmassa Dimensio-artikkelissa Joh­da­tus Pyt­hon-oh­jel­moin­tiin Turt­le-gra­fii­kan avul­la (Dimensio 19.4.2022).

Pygame

Pygame on vapaalla GNU-lisenssillä julkaistu joukko Pythonin grafiikka- ja äänikirjastoja, joka on suunniteltu ensisijaisesti videopelien tekemiseen. Pohjatyön Pygame-kirjastolle on tehnyt Pete Shinners, mutta vuodesta 2000 alkaen se on ollut yhteisöprojekti. Kirjastosta on tullut suosittu peliohjelmoijien keskuudessa ja vuonna 2020 Pygame-kirjastosta on julkaistu versio 2. Piirretään seuraavaksi neliö käyttäen Pygame-kirjastoa.

Kuva 2: Neliön piirtäminen Python Pygame -grafiikalla

Mitä yllä olevat koodit tarkoittavat? Puretaan kuvan 2 mukainen koodi osiin.

  1. Komento: import pygame ottaa pygame-kirjaston käyttöön.
  2. init() -komento alustaa eli resetoi kaikki pygame-moduulit.
  3. Asettaa ikkunan, jonka koko on 400 x 400 pikseliä.
  4. Asettaa ikkunan otsikkoriviin tekstin.
  5. Määritellään done-muuttuja, joka saa arvon True.
  6. Määritellään clock-muuttuja, jonka arvo luetaan tietokoneen kellosta.
  7. Määritellään while-silmukka, jota toistetaan, niin kauan arvo on True.
  8. Aikaa käytetään 10 ms/ikkunan päivitys.
  9. Käydään läpi jonon kaikki tapahtumakutsut.
  10. Jos tapahtumakutsuna on lopeta, niin
  11. aseta done-muuttujalle arvo False. False-arvo lopettaa While-silmukan.
  12. Aseta ikkunan taustaväriksi valkoinen (= tyhjentää samalla ikkunan).
  13. Piirrä täytetty suorakulmio ilman reunaviivaa, jonka väri on syaani (0,255,255) ja aloituspaikka (100, 100) ja leveys 100 ja korkeus 100.
  14. Piirrä suorakulmio ilman täyttöä, jonka väri on musta (0,0,0) ja aloituspaikka (100, 100) ja leveys 100 ja korkeus 100. Aseta viivan paksuudeksi arvo 5.
  15. Päivittää näytön ikkunaan.
  16. Lopeta pygame-ohjelma. (Tämä suoritetaan, kun olemme poistuneet while-silmukasta).

Havaitaan, että meidän pitää laittaa piirtokomennot pelimoottorin (while-silmukka) sisälle. Itse suorakulmio-piirtokomento on hieman kömpelö, koska esimerkiksi joudumme piirtämään kaksi neliötä päällekkäin, jotta saamme halutun lopputuloksen eli saamme kuvioon sekä täytön, että reunaviivan. Pygame poikkeaa paljon perus Pythonista, joten sen soveltuvuus perusgrafiikan tekemiseen tuntuu hieman hankalalta. Peliprojekteissa yleensä grafiikka ladataan png-kuvina, joten Pygame sopii käytettävyyden puolesta siihen mihin se on tarkoitettu eli pelien tekemiseen, ei niinkään perus Pythonin rinnalle.

Tkinter

Tkinter on vapaalla lisenssillä (GNU) julkaistu graafinen käyttöliittymä (Graphical User Interface) Python-ohjelmointikielelle. Tkinterin avulla Python ohjelmaan voidaan lisätä painikkeita, vierityspalkkeja, valikoita, tekstiä ja grafiikkaa, joita nimitetään Tk-pienoisohjelmiksi (widget). Piirretään Tkinter-ohjelmalla neliö.

Kuva 3: Neliön piirtäminen Tkinter-ohjelmalla

Mitä yllä olevat koodit tarkoittavat? Puretaan kuvan 3 mukainen koodi osiin.

  1. Otetaan Tkinter-ohjelman komennot käyttöön kutsumalla Tkinter-kirjastoa.
  2. Alustaa Tk-luokan komennot ja luo ns. juuri-ikkunan.
  3. Luodaan ikkuna, jonka leveys on 400 px ja korkeus 400 px.
  4. Asetetaan ikkunaan taustaväriksi valkoinen (#FFFFFF).
  5. Asettaa Tk-pienoisohjelmat lohkoihin ennen sijoittamista juuri-ikkunaan.
  6. Piirretään suorakulmio, jonka vasen ylänurkka on paikassa (100,100) ja oikea alanurkka on paikassa (200,200). Täyttöväri on syaani ja reunaviivan väri musta ja reunaviivan paksuus 5.
  7. Päivitetään ikkuna ja odotetaan poikkeuksia.

Ensimmäinen havainto on koodin vähyys verrattuna Pygame-ohjelmointiin, mikä on helpotus. While-silmukkaa ei tarvita ”pelimoottoriksi” vaan mainloop() riittää loppukomennoksi, joka päivittää näytön ja tarkkailee ohjelman saamia poikkeuksia. Toinen havainto on, että piirtokomennoissa ei käytetä RGB-värejä, vaan hex-koodia värin luomiseen. Havaitaan selviä yhtenevyyksiä html-koodiin. Komennot ovat kuitenkin selkeitä ja grafiikka hyvänlaatuista. Ensivaikutelma on hyvä.  

Processing for Python

Processing oli alun perin Java-kirjasto, joka kehitettiin MIT-medialaboratoriossa Design By Numbers -projektin myötä, jotta taiteilijat saisivat helpon tavan koodata vuorovaikutteista taidetta ohjelmoimalla. Tästä projektista syntyi uusi ohjelmointikieli Processing, joka käyttää taustalla Javan kääntäjää ja Javan kirjastoja. Kielestä on myös tehty Python-versio, jossa kielen ulkoasu on Pythonin, mutta grafiikkakomennot ovat samoja kuin Processing-kielessä. Piirretään neliö käyttäen Processing for Python -ohjelmointikieltä.

Kuva 4: Neliön piirtäminen Processing for Python-ohjelmalla

Mitä yllä olevat koodit tarkoittavat? Puretaan kuvan 4 mukainen koodi osiin.

  1. Luodaan aliohjelma setup(), joka suoritetaan kerran. Tähän aliohjelmaan voidaan laittaa komennot, jotka ovat pysyviä koko ohjelman suorituksen ajan.
  2. Luodaan ikkuna, jonka koko on 400 x 400.
  3. Luodaan aliohjelma draw(), joka on ikuisessa silmukassa. Tämä on varsinainen pääohjelma.
  4. Asetetaan taustaväriksi valkoinen (255,255,255) ja samalla tyhjennetään ikkuna.
  5. Asetetaan reunaviivan väriksi musta (0,0,0).
  6. Asetetaan reunaviivan paksuudeksi 5.
  7. Asetetaan täyttöväriksi syaani (0,255,255).
  8. Piirretään suorakulmio, jonka nurkkapiste on (100,100), leveys on 100 ja korkeus on 100.

Ohjelman rakenne on selkeä, samoin komennot ovat selkeitä. Koska värikomennot ovat erillisiä komentoja, niin grafiikkakomennoista tulee lyhyitä ja samalla korostuu ohjelmoinnin peräkkäisrakenne. Pedagogisesti ajatellen ohjelman rakenne on looginen ja yksinkertainen, mikä on hyvä. Replit.com:ssa ohjelman suorituksen aikana tuli virheilmoituksia, vaikka koodi suoritettiin ongelmitta. Tietysti tässä yhteydessä aina voi miettiä, että käyttäisikö mieluummin perus Processing-versiota, jolloin ulkoasu muistuttaisi enemmän Javaa, kuin Pythonia. Processing-ohjelmasta on myös saatavana JavaScript-versio, joka tunnetaan nimellä P5js. Kehitteillä on myös P5js-ohjelmasta Python-versio, joka tunnetaan nimellä: Pyp5js. Myös siihen kannattaa tutustua.

Yhteenvetoa

Kun ajatellaan tekstipohjaista perus-Pythonia, niin aloittelijalle sopiva lähestymistapa grafiikan ohjelmointiin löytyy Turtle-kirjastosta. Turtlea kannattaa käyttää rinnan Pythonin peruskurssilla tavallisen tekstipohjaisen koodaamisen kanssa. Tällöin ohjelmoinnin harjoitukset tulevat monipuolisemmaksi, mielenkiintoisemmaksi ja jopa hauskaksikin. Turtle-ohjelmointia ei kannata käydä omana irrallisena kokonaisuutena, koska Turtle-ohjelmointi on tarkoitettu johdannoksi ohjelmointiin ja siitä voi saada väärän kuvan graafisesta ohjelmoinnista. Turtle-ohjelmointi alkaa pidemmän päälle enemmänkin ärsyttämään sen hitauden ja hankalan toimintalogiikan ansiosta, joten vaihtoehtoja tarvitaan.

Pygame on nimensä mukaisesti suunniteltu Python pelien ohjelmointiin ja sitä voi suositella vain peliohjelmointikursseille, jossa rinnan käydään grafiikan piirtämistä piirrosohjelmilla. Pienen kokeilun perusteella Pygamen grafiikkakomennot ovat pitkiä ja kömpelöitä käyttää. Selvästi parempi ja selkeämpi lähestymistapa grafiikan tekemiseen on Tkinter ja Processing for Python -ohjelmilla. Molemmilla pystyy järkevästi käymään perusgrafiikan tekemisen läpi, joka olisi seuraava suositeltava askel siirtyä perus-Pythonin jälkeen graafiseen ohjelmointiin. Se kumpi näistä kahdesta kannattaa valita, riippuu omasta mieltymyksestä ja siitä onko tarkoitus pyrkiä viemään grafiikan ohjelmointia johonkin tiettyyn suuntaan. Tkinterssä korostuu web- ja käyttöliittymäohjelmointi, Processing for Pythonissa korostuu taiteellinen luovuus ja koodin helppous. Tkinter on alun perin suunniteltu Pythonille ja se on siinä vakiokirjastona, mikä on selkeä etu. Processing for Python on alun perin suunniteltu Javalle, joka näkyy myös koodissa. Se onko Java rasite vai rikkaus riippuu omasta näkökannasta. Processing for Pythonista löytyy tietokoneelle oma työpöytäsovellus (PC/McOS/Linux), joten se voisi olla luontevampi tapa ohjelmoida grafiikkaa sen kanssa. Lopullinen valinta jätetään lukijalle, mutta suosittelen tutustumaan molempiin ohjelmointiympäristöihin. Toivottavasti näemme tulevaisuudessa suomenkielistä ohjelmointimateriaalia myös Tkinteristä ja/tai Processing for Pythonista.

Lähteet ja lisää luettavaa

https://docs.python.org/3/library/turtle.html

https://www.pygame.org

https://realpython.com/python-gui-tkinter/

https://docs.python.org/3/library/tkinter.html

https://py.processing.org/

https://pypi.org/project/pyp5js/

https://berinhard.github.io/pyp5js/

https://en.wikipedia.org/wiki/Pygame

https://en.wikipedia.org/wiki/Tkinter

https://en.wikipedia.org/wiki/Python_(programming_language)

Kirjoittaja