Muuttujat ja tietorakenteet

Muuttujat ja tietorakenteet

Tähän mennessä olemme oppineet ohjelmoimaan Scratchilla käyttäen hyväksi erilaisia ohjelman suorituksen kulkua hallinnoivia ohjausrakenteita, kuten toistorakenteita ja ehtolauseita. Eräs tärkeä aihe, mihin emme kuitenkaan ole vielä paneutuneet, on se, miten tietokone voidaan käskeä muistamaan sille välitettyä tietoa. Monienhan tosielämänkin ohjeiden seuraaminen olisi mahdotonta, ellei niiden noudattaja osaisi painaa asioita mieleensä. Näin on esimerkiksi edellisessä luvussa esittelemämme AasiSvengaa-pelin tapauksessa, jota käytämme nyt aasinsiltanamme aiheeseen.

AasiSvengaa-pelin säännöt

Kasvatettavan luvun tämänhetkinen arvo on yksi.
Nuorin pelaaja on vuorossa.
Toista niin kauan, kunnes jäljellä on vain yksi pelaaja:
	- Jos luku on jaollinen kolmella ja viidellä:
		- Oikea vastaus on "aasisvengaa".
	- Muuten: 
		- Jos luku on jaollinen kolmella:
			- Oikea vastaus on "aasi".
		- Muuten:
			- Jos luku on jaollinen viidellä:
				- Oikea vastaus on "svengaa".
			- Muuten:
				- Oikea vastaus on luvun tämänhetkinen arvo.
	- Jos pelaaja ei vastaa oikeaa vastausta:
		- Pelaaja putoaa pois pelistä.
	- Luvun arvoa kasvatetaan yhdellä.
        - Vuorossa oleva pelaaja on seuraava pelaaja myötäpäivään kiertäen.
Jäljelle jäänyt pelaaja on voittaja.

AasiSvengaa-peliä pelatessa on muistettava vuorossa oleva pelaaja ja kasvatettavan luvun arvo kullakin kierroksella. Lisäksi on oltava tiedossa peliin osallistuvat pelaajat, heidän keskinäinen järjestyksensä ja heistä nuorin henkilö.

Kaikeksi onneksi tietokoneilla, kuten ihmisilläkin, on muisti, jossa tietoa voidaan säilyttää. Ohjelmoinnissa tietokoneen muistissaan pitämä tieto on jäsenneltävä jonkinlaiseen tietovarastoon, josta kone pystyy sen tarvittaessa noutamaan. Tällaisia tietovarastoja ovat muun muassa muuttujat ja tietorakenteet.




Muuttajan muistilista

Muuttuja on tuttu käsite jo yläkoulumatematiikasta. Matematiikassa muuttujat tarkoittavat symboleja ja nimiä, joita käytetään esittämään tuntemattomia tai tilanteesta riippuvia arvoja. Ohjelmoinnissa muuttujilla on paljon yhteistä matemaattisten muuttujien kanssa, sillä nekin kuvastavat arvoja, jotka voivat muuttua eri vaiheissa ohjelman suoritusta.

v = s / t
nopeus = matka / aika

Fysiikan nopeuden yhtälössä niin, v, s kuin t:kin ovat muuttujia, jotka kuvastavat nopeutta, matkaa ja matkaan kulunutta aikaa. Nopeus, matka ja kulunut aika voivat vaihdella tilanteen mukaan, mutta niiden suhde pysyy aina samana. Nämä molemmat rivit ovat myös täysin pätevää Python-koodia!

Ohjelmoinnissa, toisin kuin matematiikassa, muuttujat ovat kuitenkin tarkalleen ottaen tietokoneen muistista varattuja paikkoja, joille on annettu jokin nimi. Näihin muistipaikkoihin voidaan sijoittaa talteen tietokoneohjelman tarvitsemaa dataa, kuten lukuja, merkkejä tai totuusarvoja.

Myös ihmiset voivat luoda päässään muuttujia. Jos esimerkiksi päivän ruokatunti pidetään kello 11.30, voimme painaa kyseisen ajankohdan mieleemme ja nimetä sen ajatuksissamme ”ruokailuajaksi”. Tällöin olemme muodostaneet mielessämme ruokailuaika-nimisen muuttujan. Kellonaikaa 11.30 kutsutaan puolestaan tämän muuttujan arvoksi. Jos seuraavana päivänä ruokailu pidetään puolestaan kello 12.15, voimme vaihtaa tuolloin mielessämme ruokailuaika-muuttujan arvoksi tämän uuden kellonajan.




Otetaan selvää Scratch-editorissa, mitä muuttujat tarkoittavat ohjelmoinnissa käytännön tasolla. Ehtolauseet-luvussa loimme tehtävässä 4 koodin kissan ohjastamiseksi nuolinäppäimillä. Jatketaan sen pohjalta. Jos olet ehtinyt poistaa ratkaisusi tehtävään, kokoa se tässä vaiheessa uudelleen. Jos sitä vastoin tallensit projektisi ohjeiden mukaisesti, voit kerrata ohjeet projektin lataamiseksi täältä.

Luodaan ohjelmaamme muuttuja nimeltä matka. Tämän muuttujan on tarkoitus pitää sisällään lukuarvo, joka määrää kissan etenemän matkan kullakin silmukan kierroksella. Voit luoda ja nimetä uuden muuttujan klikkaamalla Tieto-valikon alta Tee muuttuja -nappia. Kirjoita muuttujan nimi tekstikenttään ja paina OK-nappia. Katso kuvasta mallia.


Tee muuttuja -nappia klikkaamalla voit luoda uuden muuttujan Scratch-editoriin.

Seurauksena Tieto-valikkoon ilmestyy joukko uusia ohjepalikoita, joilla voimme hallita muuttujaamme. Lisäksi kissan alueen vasempaan yläkulmaan ilmestyy muuttujan nimi ja tämänhetkinen arvo. Vaihdetaan seuraavaksi muuttujan arvo nollasta viitoseksi. Tuplaklikkaa muuttujanäyttöä kahdesti, niin saat näkyviin liukusäätimen, jota vetämällä muuttujan arvon voi asettaa mieleisekseen, kuten animaatiossa alla tehdään.



Muuttujanäytön kaksinkertainen tuplaklikkaus tuo esiin liukusäätimen, jolla muuttujan arvoa voi muokata.

Vielä on varsin epäselvää, mitä muuttujastamme onkaan hyötyä. Otetaan siis käyttöön Tieto-valikosta sinne ilmestynyt matka-palikka. Tämän palikan voi sijoittaa minkä tahansa ohjepalikan sisään, johon aiemmin olet kirjoittanut itse käsin lukuarvoja. Yksi esimerkki tällaisesta ohjepalikasta on liiku n askelta -palikka.


Muuttujan nimipalikan voi asettaa minkä tahansa lukuarvon paikalle.

Aseta matka-palikka paikoilleen, kuten kuvassa. Sen jälkeen testaa uutta komentoasi klikkaamalla sitä. Kissan tulisi nytkähtää eteenpäin viiden pykälän matka. Muokkaa muuttujan arvoa viidestä esimerkiksi sataan ja kokeile klikata liiku n askelta -palikkaa uudelleen. Pane merkille ero kissan siirtymässä.

Harjoitellaan vielä, miten muuttujan uudelleennimeäminen tapahtuu. Seuraavassa tehtävässä esimerkiksi nopeus voisi olla osuvampi nimi muuttujamme kuvastamalle lukuarvolle. Klikkaa muuttujan nimipalikkaa oikealla hiirennäppäimellä tai Shift-näppäin pohjassa vasemmalla hiirennäppäimellä, kuten teit viime luvussa luomiasi hahmoja poistaessa.


Tästä valikosta voit tarvittaessa myös poistaa muuttujan uudelleennimeämisen lisäksi.

Klikkaa tekstiä ”uudelleennimeä muuttuja”, kirjoita muuttujan uudeksi nimeksi nopeus ja paina OK-nappia. Huomaa, että ohjelmoinnissa nimiä antaessa myös kirjainten koolla on väliä. Tässä tapauksessa nimi kuuluu olla kirjoitettu kokonaan pienellä.

Tehtävä 1: Kissa vauhdissa

Käytä hyväksesi luomaasi nopeus-muuttujaa ja muokkaa Ehtolauseet-luvun tehtävän 4 koodia. Nyt haluamme että kissa liikkuu eteenpäin jokaisella silmukan kierroksella kolmen pykälän sijaan nopeus-muuttujan ilmoittaman lukuarvon verran. Lisäksi haluamme, että kissan liikenopeutta voi sekä kiihdyttää että jarruttaa. Sallitut kissan nopeuden arvot ovat 0...5.

Aseta aivan ohjelman alussa nopeus-muuttujan arvoksi luku kolme käyttämällä Tieto-valikon alta löytyvää aseta nopeus arvoon n -palikkaa.

Aiemmassa tehtävässä nuoli oikealle -näppäimen painaminen kiihdytti kissan nopeutta vakioarvon 3 verran. Muokkaa tätä toiminnallisuutta siten, että joka silmukan kierroksella suoritetaan sen sijaan seuraavat tarkistukset:

  • Jos nuoli oikealle -näppäintä painetaan ja nopeus-muuttujan arvo on pienempi kuin viisi, kasvatetaan nopeus-muuttujan arvoa yhdellä. Käytä tähän Tieto-valikon alle ilmestyneellä muuta muuttujan nopeus arvoa n -palikkaa
  • Jos puolestaan nuoli vasemmalle -näppäintä painetaan ja nopeus-muuttujan arvo on suurempi kuin nolla, vähennetään nopeus-muuttujan arvoa yhdellä.

Käytä tätä palikkaa nopeus-muuttujan arvon muokkauksiin.

Nopeus-muuttujan arvon suuruutta pystyy vertailemaan lukuihin nolla ja viisi käyttämällä Toiminnot-valikon alta löytyviä vertailuoperaattoreita (> ja <).

Vinkki: tarvitset ohjelman ehtolauseissa myös yhtä Toiminnot-valikon alla sijaitsevista loogisista operaattoreista (ja, tai, ei).

Muuten ohjelman toiminta säilyy samanlaisena kuin ennenkin. Voit kuitenkin halutessasi määrätä sen käynnistymään vihreän lipun klikkauksesta. Et tarvitse edellisen luvun tehtävässä 9 koodiin lisättyjä ominaisuuksia, mutta ohjelman pitää edelleen loppua välilyönnin painalluksesta ja kissan kääntyä nuoli ylös- ja nuoli alas -näppäimistä, samoin kuin aiemmin.

Huomaa, että jos kissa karkaa ruudun ulkopuolelle, voit palauttaa sen keskelle kenttää klikkaamalla peräjälkeen Liike-valikon alta aseta x:lle arvo 0- ja aseta y:lle arvo 0 -palikoita. Näitä palikoita et tarvitse itse ohjelmassa.


Operaatio aritmetiikka

Esitellään muuttujien yhteydessä lyhyesti ohjelmoinnissa hyödynnettävät matemaattiset operaattorit. Näihin lukeutuvat kaikille tutut yhteenlasku, vähennyslasku, kertolasku, jakolasku ja jakojäännös. Nämä viisi operaattoria myös Scratch tarjoaa ohjelmoijan käyttöön. Muihin tavanomaisiin operaattorehin ohjelmoinnissa kuuluu muun muassa potenssiin korotus, jota Scratchissa ei kuitenkaan ole.


Kuvissa Scratchin matemaattiset operaattorit.

Näillä operaattoreilla voimme suorittaa laskutoimituksia kirjoittamalla niiden tekstikenttiin lukuja. Operaattoripalikoita voidaan puolestaan asettaa minkä tahansa lukua odottavan ohjepalikan sisään, kuten esimerkiksi liiku n askelta -palikkaan tai vertailuoperaattorien palikoihin.


Matemaattisia operaattoripalikoita voidaan sijoittaa operandeiksi vertailuoperaattoripalikoille.

Varsinaista hyötyä matemaattisista operaattoreista on kuitenkin vasta muuttujien yhteydessä. Muuttujia voikin käyttää laskutoimituksiin paljaiden lukujen sijaan, aivan kuten yläkoulumatematiikassa. Näin on mahdollista luoda laskutoimituksia, joiden lopputulos riippuu siitä, mikä muuttujan tai muuttujien arvo kullakin hetkellä on!


Tämän operaation arvo on muuttujien arvojen summa.

Harjoitellaan matemaattisia operaattoreita pienillä pulmapähkinöillä. Yritä päätellä, mikä seuraavien Scratch-kielisten lauseiden arvo on annetuilla muuttujien arvoilla. Anna vastaukseksi luku tai, jos kyseessä on totuusarvo, joko tosi tai epätosi.

Scratch-pähkinä 1



Scratch-pähkinä 2

Huomaa, että yllä oleva lause koostuu useasta palikasta. Laskutoimitukset aloitetaan järjestyksessä päällimmäisestä palikasta. Siksi tässä yhteenlasku suoritetaan, ennen jakolaskua.

Scratch-pähkinä 3



Muutos on kaikkialla

Kuten luvun alussa todettiin, myös ihminen pystyy luomaan mielessään muuttujia. Siksipä ei olekaan yllätys, että muuttujiin törmää monissa tosielämän tilanteissa. Esimerkiksi jalkapallo-ottelua seuratessa ottelun tilanne ilmoitetaan yleensä tulostaululla kotijoukkueen ja vierasjoukkueen maaleina. Tulostaululla nimiä ”koti” ja ”vieras” voidaankin ajatella muuttujina, joiden arvo on niitä vastaavien joukkueiden senhetkinen maalimäärä.




Kuvassa nimet ”home” ja ”visitor” ovat muuttujia, joiden arvot ovat 8 ja 21.


Eräs toinen esimerkki tosielämän muuttujista ovat kilometrimääriä kohteeseen ilmoittavat etäisyystaulut. Esimerkiksi kyltissä, jossa lukee ”Oulu 100” voidaan nimeä Oulu ajatella muuttujana ja lukua 100 sen arvona. Seuraavan tienviitan tullessa vastaan Oulu-muuttuja voikin saada uuden arvon, esimerkiksi 70.


Taulussa nimet Turku ja Salo ovat muuttujia, joiden arvot ovat 70 ja 25. (Kuva 4)

Tosielämästä löytyy myös paljon muuttujia, joiden arvo on tyypiltään jotain muuta kuin luku. Ne voivat sisältää esimerkiksi tekstiä. Yksi tällainen on esimerkiksi hirsipuupelin arvattava sana, joka muuttuu, kun peli alkaa alusta.

Miltä muuttujat sitten näyttävät varsinaisissa ohjelmointikielissä? Python-esimerkeissämme olemme törmänneet jo moniin muuttujiin. Ne ovat itse asiassa niin perustavanlaatuinen asia käskymuotoisessa ohjelmoinnissa, että hyvin usein ohjelmoinnin opetus lähtee yleensä liikkeelle juuri niistä.

Python-pähkinä 1

Alla on esitetty uudestaan kolikonheittopelin Python-koodi, jota kummasteltiin jo Johdanto-luvussa.

import random

puolet = ("kruuna", "klaava")

# Pyydetään pelaajaa 1 arvaamaan.
pyyntö = "Pelaaja 1, valitse joko kruuna tai klaava: "
arvaus = input(pyyntö)
while arvaus not in puolet:
    print("Arvauksesi ei ole sallittu!")
    arvaus = input(pyyntö)

# Päätellään pelaajalle 2 jäänyt vaihtoehto.
päätelty = 0 if puolet.index(arvaus) == 1 else 1
puoli = puolet[päätelty]
print("Pelaaja 2:lle jää {puoli}".format(puoli=puoli))

# Arvotaan lopputulos ja ilmoitetaan voittaja.
tulos = random.choice(puolet)
print("Arvottiin {tulos}".format(tulos=tulos))
if tulos == arvaus:
    print("Pelaaja 1 voittaa!")
else:
    print("Pelaaja 2 voittaa!")

Keksitkö, minkä nimisiä muuttujia koodista löytyy? Niitä on yhteensä kuusi. Yksi niistä on puolet. Tutki koodia ja pähkäile, mitkä muut viisi muuttujaa voisivat olla.

Anna viiden muun muuttujan nimet vastaukseksi alla olevaan tekstikenttään pilkuilla tai välilyönneillä erotettuna siinä järjestyksessä, kuin ne koodissa ensimmäistä kertaa esiintyvät.

Pythonissa, kuten Scratchissakin, muuttuja on nimi muistipaikalle, jonne on tallennettu jokin arvo. Esimerkiksi yllä olevassa koodissa puolet-nimisen muuttujan muistipaikkaan tallennetaan arvo ("kruuna", "klaava") eli kolikon kaksi puolta tekstinä. Kun muuttujan muistipaikkaan tallennetaan jokin arvo, sen jälkeen muuttujan nimi viittaa tallennettuun arvoon. Koodissa siis puolet-muuttujan nimeä käytetään synonyymina arvolle ("kruuna", "klaava").

Muuttujaan arvon tallentamista kutsutaan ohjelmoinnissa myös sijoittamiseksi. Sijoittaminen tapahtuu siten, että yhtä suuri kuin- eli =-merkin vasemmalle puolelle kirjoitetaan muuttuja, johon arvo halutaan sijoittaa, ja sen oikealle puolelle itse sijoitettava arvo. Pythonissa =-merkillä ei olekaan aivan sama merkitys kuin matematiikassa tai Scratchissa, sillä se ei ilmaise yhtäsuuruutta. Sen sijaan se käskee tietokonetta painamaan muistiinsa, että tiettyä nimitystä käytetään tästä eteenpäin jostakin uudesta arvosta.

Python-pähkinä 2

Eräs esimerkki arvon sijoittamisesta muuttujaan voisi Pythonissa olla arvon 1 sijoittaminen muuttujaan erä. Tämä voisi tulla tarpeen muun muassa jääkiekko-ottelun kulkua mallintavalle ohjelmalle, jonka pitäisi painaa muistiinsa, että ottelu alkaa ensimmäisestä erästä. Sijoitus tapahtuisi koodissa näin:

erä = 1

Tämän jälkeen tietokoneella olisi painettuna muistiin nimitys erä, joka viittaisi arvoon 1. Osaatko tämän perusteella keksiä, miten vuorostaan käskisit Python-kielellä tietokonetta painamaan muistiinsa, että ottelussa jäljellä olevien minuuttien määrä on ottelun alussa 60? Päätämme käyttää minuuttien määrästä nimeäminuutit.

Anna vastaukseksi koodirivi, joka suorittaa arvon sijoituksen muuttujaan.

Hämmästellään seuraavaksi konkreettista eroa matemaattisen yhtäsuuruuden ja muuttujaan sijoittamisen välillä. Matematiikassahan seuraava ilmaisu olisi järjetön tai vähintäänkin epätosi:

erä = 1
erä = 2

Tämä on joko matemaattisesti epätosi väite tai muuttujan arvon muokkaus ohjelmakoodissa.

Python-kielellä kuitenkin yllä olevat rivit olisivat aivan kelvollista koodia. Nämä rivit kertovat tietokoneelle, että sen pitää varata aluksi muistista paikka, jolle annetaan nimeksi erä, ja säilöä sinne arvo yksi. Seuraava rivi käskee unohtamaan erä-muistipaikasta aiemman arvon yksi ja sijoittamaan samaan muistipaikkaan uuden arvon eli kakkosen.

Nämä koodirivit toimivat siis samoin, kuin ihminen pitäessään mielessään kirjaa urheiluottelun eristä. Kun erä vaihtuu ensimmäisestä toiseksi, myös me ihmisinä päivitämme muistiimme painaman erä-muuttujan lukuarvoa.

Seuraavat rivit vastaisivat puolestaan matematiikassa täsmälleen toisiaan, mutta Python-ohjelmoinnissa jälkimmäinen rivi olisi sitä vastoin virheellinen:

erä = 1
1 = erä

Tämä toimii matematiikassa muttei ohjelmoinnissa.

Kun ohjemoinnissa halutaankin tietokoneen painavan muistiinsa jonkin arvon, on aina ensimmäiseksi ilmoitettava muistipaikkaa vastaavan muuttujan nimi, ja vasta =-merkin jälkeen arvo, joka muistipaikkaan tahdotaan sijoittaa. Koska 1 ei ole muuttujanimi, ei jälkimmäinen rivi kelpaa Pythonille.

Tiedon rakennuspalikat

Tässä luvussa olemme opetelleet muuttujien käyttöä. Muuttujat ovat jotakuinkin yksinkertaisin tapa varastoida dataa ohjelmoinnissa ja antaa sille merkityksiä. Joustavaan tiedonkäsittelyyn vaaditaan kuitenkin myös monipuolisempia työkaluja. Tässä avuksemme rientävät tietorakenteet.

Ohjelmoinnissa tietorakenteet ovat erilaisia tapoja organisoida dataa tehokkaasti. Antamalla nimiä muistipaikoille, joihin dataa varastoidaan, ei nimittäin päästä vielä pitkälle. Myös datan välisiä suhteita on pystyttävä kuvaamaan jollakin tapaa.




Tietorakenteista Scratch tarjoaa ohjelmoijansa käyttöön listan. Lista on joukko mielivaltaisia arvoja, joilla on tietty järjestys, aivan kuten mikä tahansa ihmisenkin muodostama lista. Näitä listan sisältämiä arvoja kutsutaanalkioiksi. Niiden paikkaa listassa puolestaan kutsutaan indeksiksi.

Luodaan ensimmäinen listamme Scratchissa. Avaa Tieto-valikko ja klikkaa Tee lista -nappia. Kirjoita listalle nimeksi tekstikenttään ”tunnit” ja klikkaa OK-nappia. Editorisi tulisi näyttää nyt tältä:


Tunnit-lista näkyy kissan alueen vasemmassa ylälaidassa. Lisäksi Tieto-valikkoon on ilmestynyt lukuisia uusia ohjepalikoita.

Lisätään nyt listaamme alkioita. Uuden alkion voi luoda painamalla pienestä plus-merkistä listan vasemmassa alalaidassa ja kirjoittamalla sille arvon. Muokkaa tunnit-lista seuraavan näköiseksi:


Lisää kuvassa näkyvät alkiot listaan.

Tässä vaiheessa alkaa mietityttää, mitä listoilla voikaan tehdä. Ohjepalikoita niiden käsittelyyn on kuitenkin runsaasti.

Kokeillaan aluksi luoda yksinkertainen ohjelma, joka käskee kissaa ajattelemaan listan sisältämät tunnit läpi yksi kerrallaan ajatuskuplassa. Tätä varten tarvitsemme muuttujan, joka ilmoittaa, monettako listan tuntia kullakin hetkellä käsitellään. Luo siis uusi muuttuja ja anna sille nimeksi ”indeksi”. Sen jälkeen rakenna vastaava koodi kuin alla esitetyssä kuvassa. Etsi uusi ohjepalikka Ulkonäkö-valikon alta käskeäksesi kissaa ajattelemaan ajatuskuplassa.


Tämä ohjelma komentaa kissaa ajattelemaan listan alkiot läpi.

Klikkaa ohjelmaa testataksesi sitä ja tarkastele lopputulosta. Ohjelmassa asetamme aluksi indeksi-muuttujan arvon ykköseksi. Tämä tehdään, koska kissan halutaan aloittavan listan ajattelun sen ensimmäisestä alkiosta eli liikunta-sanasta. Toistorakenteen toistojen määräksi puolestaan asetetaan listan pituus, koska kissan tahdotaan ajattelevan kaikki listan viisi alkiota eli tuntia läpi.

Toistorakenteen sisällä kissaa ohjeistetaan ajattelemaan ajatuskuplassa yhtä listan tunneista joka silmukan kierroksella. Vuorossa oleva tunti päätetään indeksi-muuttujan arvon perusteella. Indeksi-muuttujan sanotaankin arvollaan osoittavan tiettyyn listan alkioon. Jos indeksi-muuttujan arvo on esimerkiksi tietyllä silmukan kierroksella 3, kissa ajattelee sillä silmukan kierroksella listan kolmatta alkiota eli äidinkieltä.

Indeksi-muuttuja osoittaa yhteen listan alkioista. Muuttujan arvoa kasvatetaan joka silmukan kierroksella.

Joka silmukan kierroksella indeksi-muuttujan arvoa kasvatetaankin yhdellä, jotta se osoittaisi seuraavalla kierroksella aina seuraavaan listan sisältämään tuntiin. Näin voimme käydä listan alkiot läpi vuorotellen kasvattamalla muuttujan arvoa silmukan kierros kerrallaan. Tällainen tietorakenteen alkioiden läpikäynti eliiterointi onkin hyvin yleinen tapa hyödyntää toista n kertaa -tyyppistä toistorakennetta.


Tehtävä 2: Reittiopas

Luo ohjelma, joka käskee kissaa kääntymään järjestyksessä seuraavien astelukemien suuruiset käännökset myötäpäivään: 90, -90, 60, -60, 45, -45. Käännösten välissä liikutaan 30 pykälää eteenpäin senhetkiseen suuntaan, vaihdetaan seuraavaan asusteeseen ja odotetaan sekunti. Käytä tehtävässä listaa nimeltä kulmat ja muuttujaa nimeltä indeksi, jonka arvo asetetaan ohjelman alussa ykköseksi.

Luo tällaiset muuttuja ja lista ohjelmaasi.

Katso mallia yllä olevasta ohjelmasta: tarvitset kaikki samat vaiheet, mutta nyt ajatuskuplassa ajattelemisen sijaan kääntyillään myötäpäivään! Voit asettaa oman ohjelmasi käynnistymään vihreän lipun klikkauksesta.

Sattumoisin listat ovat myös yleisin Pythonissa käytetty tietorakenne. Alla on esitetty Python-ohjelma, joka osaa päätellä, kuinka monta päivää vuoden alusta alkaen on kulunut käyttäjän antaman kuukauden loppuun mennessä. Ohjelmassa muuttujaan päivät sijoitetaan arvoksi lista kaikkien kuukausien päivistä.

import sys

päivät = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
syöte = input("Anna kuukausi lukuna: ")

# Yritetään käsitellä syötettä lukuna:
try:
    kuukausi = int(syöte)
except ValueError:
    print("Et antanut lukua!")
    sys.exit() # Lopetetaan ohjelma, koska annettu syöte oli virheellinen.

# Tarkistetaan, onko kuukausi sallituissa rajoissa, ja lasketaan lopputulos:
if 1 <= kuukausi <= 12:
    yhteensä = sum(päivät[:kuukausi])
    print("Yhteensä päiviä on kertynyt {yhteensä}.".format(yhteensä=yhteensä))
else:
    print("Sallitut kuukausien lukuarvot ovat 1-12!")

Muuttujaan päivät on tässä Python-ohjelmassa sijoitettu kokonaislukuja sisältävä lista.

Pythonissa lista merkitään siis hakasuluilla. Listan alkiot puolestaan kirjoitetaan hakasulkujen sisään pilkulla ja välilyönnillä erotettuina.

Python-pähkinä 3

Osaatko päätellä, miltä Pythonissa näyttäisi lista, jonka alkiot ovat järjestyksessä kokonaisluvut viisi, kaksi ja kolme?

Rakennustyömaan järjestyssäännöt

Päättämällä, millä tavalla käsittelemme listan alkioita, on listojen avulla mahdollista toteuttaa myös yksinkertaisempia tietorakenteita. Näitä tietorakenteita ovat muun muassa pino ja jono.

Sekä pino- että jonorakenne toimivat siten, että niihin voi lisätä ja niistä voi poistaa alkioita. Ero on siinä, miten poistaminen tapahtuu: pinoa käytettäessä poistetaan aina järjestyksessä viimeksi tietorakenteeseen lisätty alkio. Jonoa käyttäessä poistetaan puolestaan ensimmäisenä lisätty alkio. Havainnollistetaan molempia tietorakenteita tehtävän kautta.

Tehtävä 3: Poikki ja pinoon

Luo ohjelma, jonka ohjeita toistetaan, kunnes käyttäjä painaa välilyöntiä. Ohjelmassa tarvitset listaa nimeltäpino, jonka sisältö on alussa tyhjä. Tyhjennä lista ohjelman alussa poista kaikki listasta pino -palikkaa käyttämällä.

Seuraavat tarkistukset suoritetaan joka silmukan kierroksella:

  • Jos käyttäjä painaa ohjelman ollessa käynnissä L-näppäintä, kissan pitää kysyä käyttäjältä: ”Minkä alkion haluat lisätä?” Käyttäjän annettua vastauksensa vastaus lisätään listan viimeiseksi.
  • Jos käyttäjä puolestaan painaa P-näppäintä ja listassa on alkioita, kissa sanoo listan viimeisen alkion puhekuplassa sekunnin ajan. Tämän jälkeen viimeinen alkio poistetaan listasta.
    • Voit tarkastaa, onko listassa alkioita, tutkimalla, onko listan pituus suurempi kuin nolla.

Kun L-näppäintä painetaan, esitetään kysymys käyttäjälle ja lisätään vastaus listaan.

Kun P-näppäintä painetaan ja listassa on alkioita, sanotaan viimeinen listan alkio puhekuplassa ja poistetaan se.

Puhekuplan tuottamista varten löydät ohjepalikan Ulkonäkö-valikosta. Käyttäjälle kysymyksen esittämistä ja vastauksen käsittelyä varten on puolestaan tarjolla ohjepalikat Tuntoaisti-valikossa. Huomaa, että vastaus-palikka toimii kuin muuttuja. Ohjelman voit asettaa käynnistymään vihreän lipun klikkauksesta.

Tehtävä 4: Jonossa, mars!

Luo ohjelma, jonka ohjeita toistetaan, kunnes käyttäjä painaa välilyöntiä. Ohjelmassa tarvitset listaa nimeltäjono, jonka sisältö tyhjennetään ohjelman käynnistyessä.

Seuraavat tarkistukset suoritetaan joka silmukan kierroksella:

  • Jos käyttäjä painaa ohjelman ollessa käynnissä L-näppäintä, kissa kysyy käyttäjältä: ”Minkä alkion haluat lisätä?” Käyttäjän annettua vastauksensa, vastaus lisätään listaan viimeiseksi.
  • Jos käyttäjä puolestaan painaa P-näppäintä ja listassa on alkioita, kissa sanoo listan ensimmäisen alkion puhekuplassa sekunnin ajan. Tämän jälkeen ensimmäinen alkio poistetaan listasta.

Ohjelman voit asettaa käynnistymään vihreän lipun klikkauksesta.

Ötökät ojennukseen

Muuttujien yhteydessä on syytä opetella muutamia menetelmiä epätoivottavien toiminnallisuuksien paikantamiseen ohjelmistamme. Toisin kuin todellisilla ohjelmointikielillä ohjelmoidessa, Scratchissa ohjelmat eivät voi varsinaisesti lakata virheellisten ohjeiden vuoksi toimimasta kokonaan eli niin sanotusti kaatua. Pythonissa esimerkiksi nollalla jakaminen aiheuttaisi virheen, ja jos virhettä ei käsiteltäisi, ohjelma lakkaisi toimimasta. Scratchissa taas nollalla jakaminen antaa arvoksi äärettömän, ja ohjelma jatkaa toimintaansa, kuten ennenkin. Todellisissa ohjelmissa tämä ei kuitenkaan ole usein toivottua, sillä silloin emme välttämättä osaa paikantaa virhettä tai edes huomaa, että jotain virheellistä on edes tapahtunut!

Python-ohjelmassa nollalla jakaminen, jonka aiheuttamaa virhettä ei käsitellä, saa ohjelman kaatumaan. Tällöin Python tulostaa näytölle virhettä kuvaavan ilmoituksen.

Tästä huolimatta myös Scratchissa on kuitenkin mahdollista, että ohjelma toimii tavalla, mikä ei ollut sen alkuperäisen ohjelmoijan tarkoitus. Tällaisia epätoivottuja toiminnallisuuksia ja ominaisuuksia kutsutaan ohjelmoinnin arkikielessä bugeiksi ja niiden korjaamista debuggaamiseksi.



Scratch-ohjelmat voivat myös jäädä virheellisten ohjeiden seurauksena kokonaan jumiin. Tällaisen tilanteen aiheuttaisi esimerkiksi toistorakenne, jonka lopetusehtoa ei koskaan saavuteta. Näin toimivia toistorakenteita kutsutaankin ikuisiksi silmukoiksi. Ikuisen silmukan tapahtuessa voit lopettaa ohjelman, kuten tavallisesti: painamalla stop-merkkiä tai klikkaamalla ohjelman ohjepalikoita uudestaan.


Tämä toistorakenne jäisi jumiin ikuiseen silmukkaan, koska sen lopetusehto ei käy koskaan toteen. Kokeile itse!

Scratchissa debuggaamiseen eli virheiden jäljittämiseen ja korjaamiseen on erilaisia menetelmiä. Virheiden löytämistä auttaa muun muassa se, että pitää muuttujien arvot näkyvissä ja seuraa, miten ne muuttuvat ohjelman suorituksen aikana. Jos arvot käyttäytyvät toisin kuin niiden pitäisi, voi koodista alkaa analysoimaan, mikä kyseisen käytöksen aiheuttaa.


Tämä ruutu näyttää, miten muuttujan arvo muuttuu.

Debuggaamisessa voi käyttää myös hyödyksi koodiin sijoitettuja ylimääräisiä ohjepalikoita, joiden avulla ohjelman suoritusta voi seurata helpommin. Esimerkiksi puhekuplaan viestin tuottavia sano-ohjepalikoita voi käyttää merkkinä siitä, että ohjeiden suorituksessa ollaan tietyllä hetkellä tietyssä pisteessä. Tästä on hyötyä esimerkiksi ohjelmissa, joissa monimutkaisten toistorakenteiden ja ehtolauseiden vuoksi ei ole selvää etukäteen, missä järjestyksessä ohjeet suoritetaan. Lisäksi on mahdollista käyttää myös odota n sekuntia- ja odota kunnes x -palikoita pysäyttämään ohjelman suoritus hetkeksi tietyissä määrätyissä kohdissa, jotta muuttujien arvojen ja listojen sisältöjen muuttumista on helpompi seurata.


Tähän ohjelmaan on lisätty muutamia ylimääräisiä sano-ohjepalikoita, jotta sitä testatessa olisi helppo seurata, milloin ehtolauseet toteutuvat.

Soveltaminen

Ratkotaan lopuksi muutama tavallista monimutkaisempi tehtävä tällä kertaa alusta loppuun mahdollisimman vähin välivaihein. Joudutkin suorittamaan tehtävien osaongelmiin jakamisen itse. Ohjeet ratkaisuun on silti annettu edelleen kohta kohdalta. Etene pulmia pähkäillessäsi näin:

  1. Mieti millaisista pienemmistä kokonaisuuksista ongelma muodostuu. Keskity yhteen osaongelmaan kerrallaan. Jaa myös nämä osaongelmat pienempiin kokonaisuuksiin.
  2. Aseta itsellesi välitavoitteita ja tähtää ensin niiden saavuttamiseen.
  3. Älä jumiudu vaan kokeile rohkeasti. Monesti laajoissa tehtävissä on vaikea keksiä, mistä aloittaa, joten lähde liikeelle parhaimmasta arvauksestasi ja katso, mihin se johtaa!
  4. Jos jokin ideasi ei johda oikeaan tulokseen, pohdi, mitä tämänhetkinen ratkaisusi saa aikaan. Miten lopputulos tarkalleen ottaen eroaa halutusta toiminnasta? Analysoi, mistä ero johtuu ja mitä ohjelmassasi pitäisi muuttaa. Mieti sen jälkeen, miten muutos pitäisi toteuttaa!
  5. Lopuksi mieti, miten ratkaisusi osaongelmiin voisi yhdistää yhdeksi kokonaisuudeksi.

Tehtävä 5: Läpimurto pingiksessä

Luodaan ensimmäiseksi uutta muuttujaosaamistamme ja vanhoja taitojamme yhdistelemällä yksinkertainen peli, jossa liikutaan kissalla pystysuunnassa torjuen liikkuvaa palloa. Pallo pomppii ympäriinsä reunoista, ja pelaajan on yritettävä olla päästämästä sitä kissan takana sijaitsevaan maaliin. Maalien laskemista varten peliin pitää luoda maalit-niminen muuttuja.

Ohjelman toiminnallisuus on kissalle seuraavanlainen:

  • Aloita ohjeiden noudattaminen, kun käyttäjä painaa vihreätä lippua.
  • Osoita oikealle.
  • Mene ruudun laitaan kohtaan -190 vaakasuunnassa ja nolla pystysuunnassa. Tätä varten löydät ohjepalikan Liike-valikosta.
  • Toista alla olevia ohjeita, kunnes maalit-muuttuja saavuttaa arvon kolme tai käyttäjä painaa välilyöntiä:
    • Jos nuoli ylös -näppäintä painetaan, liiku pystysuunnassa 10 pykälää ylöspäin.
    • Jos nuoli alas -näppäintä painetaan, liiku pystysuunnassa 10 pykälää alaspäin.

Lisää kissan rinnalle vastaavanlainen pallohahmo, jota käytettiin myös edellisessä luvussa. Ohjeet pallon lisäämiseksi voit kerrata täältä. Anna pallolle nämä ohjeet paikoilleen asettumiseen:

  • Aloita ohjeiden noudatus, kun käyttäjä painaa vihreätä lippua.
  • Aseta maalit-muuttujan arvo nollaksi.
  • Mene kohtaan 200 vaakasuunnassa ja nolla pystysuunnassa (toteuta tämä yhdellä palikalla!).
  • Osoita vasemmalle. Tätä varten löydät ohjepalikan Liike-valikosta.
  • Odota 2 sekuntia.

Paikoilleen asettumisensa jälkeen pallon on toistettava alla olevia ohjeita, kunnes maalit-muuttuja saavuttaa arvon kolme tai käyttäjä painaa välilyöntiä:

    • Liiku joka kierroksella kymmenen pykälää eteenpäin siihen suuntaan, mihin sillä hetkellä osoitetaan.
    • Jos sijainti vaakasuunnassa on alle -200, on pallo maalissa. Tällöin sen pitää palata aloituspaikalleen seuraavia ohjeita noudattaen:
      • Kasvata muuttujan maalit arvoa yhdellä.
      • Mene kohtaan 200 vaakasuunnassa ja nolla pystysuunnassa.
      • Osoita vasemmalle.
      • Odota kaksi sekuntia. Odottamista varten voit käyttää ohjepalikkaa Ohjaus-valikosta.
    • Jos kosketetaan kissaa (Sprite1), on pallon kimmottava siitä seuraavin komennoin:
      • Liiku kohtaan -125 vaakasuunnassa.
      • Käänny myötäpäivään satunnainen astemäärä väliltä 130...230. Satunnaisen luvun voit tuottaa Toiminnot-valikosta löytyvällä valitse satunnaisluku väliltä -ohjepalikalla.
    • Jos kosketetaan reunaa:
      • Pomppaa reunasta.
      • Liiku 10 pykälää eteenpäin siihen suuntaan, mihin sillä hetkellä osoitetaan.

Toteuta ohjelma yksi ongelma kerrallaan edeten. Lopuksi testaa luomaasi peliä. Voit helpottaa tai vaikeuttaa sitä muokkaamalla pallon kullakin silmukan kierroksella etenemää matkaa.

Tehtävä 6: Plussan puolella*

Tässä tehtävässä tarkoituksena on luoda yksinkertainen yhteenlaskuohjelma. Ohjelma ottaa käyttäjältä kaksi lukua ja kertoo niiden summan.

Ohjelmamme halutaan toimivan siten, että kissa ajattelee ajatuskuplassa aluksi yhteenlaskun ensimmäistä lukua ja sitten toista. Lopuksi kissa laskee nämä luvut eli yhteenlaskun operandit yhteen ja ilmoittaa summan puhekuplassa.

Kun kissa ajattelee jompaakumpaa lukua, luvun arvoa voi kasvattaa yhdellä painamalla nuoli oikealle -näppäintä ja laskea yhdellä painamalla nuoli vasemmalle -näppäintä. Jos ajateltavana on yhteenlaskun ensimmäinen luku, P-näppäimen painalluksesta kissa odottaa sekunnin ja alkaa puolestaan ajatella jälkimmäistä lukua.

Kissa ajattelemassa lukua.

Jos kissa ajattelee yhteenlaskun toista lukua ja käyttäjä painaa P-näppäintä, on kissan laskettava ajateltujen lukujen arvot yhteen ja sanottava summa puhekuplassa kahden sekunnin ajan. Tämän jälkeen molempien lukujen arvot nollataan ja palataan ajattelemaan ensimmäistä lukua.

Kun kissan ajatuksissa on yhteenlaskun jälkimmäinen luku ja P-näppäintä painetaan, sanotaan kahden luvun summa puhekuplassa.

Tarvitset tehtävää varten kolme muuttujaa:

  • yhden ensimmäistä lukua varten,
  • toisen jälkimmäistä lukua varten ja
  • kolmannen, jolla pidetään kirjaa, kumpaa lukua kissa milloinkin ajattelee.

Kolmannen muuttujan perusteella päätetään myös, kumpaa luvun arvoa pitää muuttaa, jos käyttäjä painaa nuoli oikealle- tai nuoli vasemmalle -näppäintä. Anna tälle kolmannelle muuttujalle nimeksi ”mielessä”. Sen arvon täytyy olla yksi silloin, kun kissa ajattelee yhteenlaskun ensimmäistä lukua, ja kaksi silloin, kun kissa ajattelee jälkimmäistä lukua.

Ohjelma alkaa vihreän lipun klikkauksesta. Sen alussa lukumuuttujien arvoiksi asetetaan 0. Anna niiden nimiksi operandi1 ja operandi2. Mielessä-muuttuja asetetaan arvoon 1.

Käytä näitä palikoita ohjelmasi aloituskomentoina.

Ohjelman toteuttamiseksi käytä seuraavaa apukoodia. Kaikkien loppujen ohjepalikoiden tulisi mennä jos mielessä = 1, niin -ehtolauseen kahden haaran sisään.

Käytä tätä koodinpätkää ohjelmassasi. Lukuun ottamatta yllä annettuja aloituskomentoja sijoita loput palikat ehtolauseen kahden haaran sisään.

Vihje: koodissa täytyy olla tarkistukset nuoli vasemmalle- ja nuoli oikealle -näppäimien painallukselle molemmissa ehtolauseen haaroissa. Lisäksi molemmissa haaroissa tarvitsee tarkistaa, painetaanko näppäintäP. Mieti myös, milloin muuttujien arvoja tulee muuttaa ja milloin niiden pitää palata alkuperäisiin arvoihinsa! Pohdi lisäksi, milloin on järkevä käyttää muuta muuttujan arvoa- ja milloin aseta muuttujan arvo -komentoa.

Tehtävä 7: Väriä eläimeen*

Luo ohjelma, joka antaa käyttäjän valita kissalleen uuden värin kahdeksasta eri vaihtoehdosta. Värivaihtoehdot ovat järjestyksessä vaaleanvihreä, vihreä, turkoosi, sininen, violetti, purppura, punainen ja oranssi. Scratchin väriarvoina nämä vastaavat lukuarvoja 25, 50, 75, …, 200.

Ohjelma käynnistyy vihreän lipun klikkauksesta. Tämän jälkeen kissa kysyy käyttäjältä: ”Mihin väriin haluat vaihtaa?” Jos käyttäjän vastaus on yksi ylläluetelluista väreistä, ohjelma vaihtaa kissan värin sen mukaiseksi.Muussa tapauksessa kissa sanoo ”Haluamaasi väriä ei ole saatavilla!” kahden sekunnin ajan.

Värejä varten ohjelmaan tulee luoda lista. Käyttäjän antaman värin paikka pitää puolestaan etsiä ohjelmassa tästä listasta.

Hyödynnä tällaista värit-listaa ohjelmassasi.

Jotta voit selvittää käyttäjän antaman värin paikan listassa, tarvitset toistorakennetta ja indeksimuuttujaa. Kun käyttäjän antama vastaus löytyy värit-listasta, anna indeksimuuttujalle arvo 1. Käy sitten toistorakenteessa läpi listan sisältämiä värejä muuttujan arvoa kasvattaen, kunnes muuttujan arvo osoittaa väriin, joka on sama kuin käyttäjän antama vastaus. Huomaa, että jos annat toistorakenteelle vahingossa lopetusehdon, joka ei koskaan käy toteen, voi ohjelma päätyä ikuiseen silmukkaan.

Värin varsinaisen lukuarvon voit laskea sen perusteella, mikä sen paikka on värilistassa. Hyödynnä tähän kertolaskua ja arvoa 25. Käytä kissan värin asettamiseen Ulkonäkö-valikosta löytyvää aseta tehoste väri arvoon n -palikkaa. Anna värilistallesi nimeksi värit ja indeksimuuttujalle indeksi.


Leikki- ja peli-ideoita

Koska muuttujilla ohjelmoinnissa on paljon yhteneväisyyksiä matematiikan muuttujien kanssa, niiden opetteluun soveltuvat monet matemaattiset pähkinät. Annamme kuitenkin tässä esimerkin, miten muuttujien ideaa voi soveltaa myös äidinkieleen yksinkertaisella harjoituksella.

Harjoituksessa opettaja valmistelee oppilailleen joukon lauseita, joista puuttuvat tietyt lauseenjäsenet, esimerkiksi subjekti, predikaatti ja objekti. Niiden paikka lauseessa on kuitenkin annettu valmiiksi. Lisäksi oppilailla on käytössään joukko erilaisia sanoja. Jokaista sanaa saa käyttää vain tehtävässä kertaalleen. Oppilaiden tehtävä onkin keksiä, mihin lauseeseen ja mille lauseenjäsenen paikalle kukin sana kuuluu. Yksinkertainen versio tehtävästä voisi näyttää esimerkiksi tältä:

Sanat: innokkaat, esiintyjä, urheilua, laskee, yleisön, voitti, oppilas, matematiikkaa, harrastavat

subjekti = ?
predikaatti = ?
objekti = ?

Koulussa {subjekti} {predikaatti} tohkeissaan {objekti}.

subjekti = ?
predikaatti = ?
objekti = ?

Lahjakas {subjekti} {predikaatti} vaativan {objekti} puolelleen.

subjekti = ?
predikaatti = ?
objekti = ?

{objekti} {predikaatti} monet {subjekti} vapaa-ajallaan.

Ohjelmoinnin kannalta harjoituksesta on tärkeintä oppia seuraavat asiat:

  • Subjekti, objekti ja predikaatti, tai muut valinnaiset lauseenjäsenet, ovat tehtävässä muuttujia.
  • Näihin muuttujiin sijoitetaan arvoja eli sanoja.
  • Muuttujien arvot voivat vaihtua.
  • Kun muuttujaan on sijoitettu arvo, sitä voidaan käyttää tehtävässä lauseen muodostamiseen.

Tietorakenteiden periaatteita voi puolestaan harjoitella yksinkertaisella sota-korttipelin muunnelmalla. Kyseessä on kahden pelaajan korttipeli, jossa perinteinen korttipakka sekoitetaan ja jaetaan neljään yhtä suureen osaan. Näistä muodostetaan molemmille pelaajille kaksi tietorakennetta: jono ja pino. Kortteja ei saa katsoa, vaan ne asetetaan pelaajien eteen päällimmäinen kortti selkäpuoli ylöspäin. Peli etenee seuraavasti:

  • Joka vuorolla kumpikin pelaaja valitsee päällimmäisen kortin joko jonostaan tai pinostaan.
  • Valitut kortit asetetaan vastakkain ja kortti, jolla on suurempi numeroarvo, voittaa. Ässät lasketaan ykkösiksi.
  • Jos päädytään tasapeliin, molemmat pelaajat valitsevat joko jonostaan tai pinostaan uuden kortin ja asettavat puolestaan ne vastakkain. Tätä toistetaan, kunnes jompikumpi korteista osoittautuu arvoltaan toista suuremmaksi.
  • Pienempiarvoisen kortin pelannut pelaaja joutuu ottamaan vastaan kaikki vuorolla pelatut kortit. Suurempiarvoisen kortin pelannut pelaaja päättää, asetetaanko ne toisen pelaajan jonoon vai pinoon. Jonoon kortit asetetaan järjestyksessä pohjalle, kun taas pinoon ne asetetaan päällimmäisiksi.
  • Pelaaja voittaa pelin, kun joko hänen pinostaan tai jonostaan loppuvat kortit.
Jono- ja pino-tietorakenteiden toimintaa opettava korttipeli näyttää tältä.

Tärkeintä pelistä on oppia seuraavat asiat:

  • Sekä jono että pino ovat tietorakenteita, joihin tallennetaan tietoa.
  • Kortit ovat näiden tietorakenteiden sisältämä tieto eli alkiot.
  • Korteilla eli alkioilla on jokin arvo.
  • Jono ja pino eroavat tietorakenteina siinä, miten niistä noudetaan niihin tallennettua tietoa.

Kuvalähteet

  1. Alcester - smiling donkey, muffinn, lisenssi: CC BY 2.0, muokkaus: teksti lisätty, kuvaa rajattu.
  2. 88/365 - 1/4/2011, Gabriela Pinto, lisenssi: CC BY 2.0, muokkaus: teksti lisätty, kuvaa rajattu.
  3. Westover Scoreboard, Gerry Dincher, lisenssi: CC BY-SA 2.0, muokkaus: kuvaa rajattu.
  4. Etäisyystaulu, Liikennevirasto, lisenssi: Liikenneviraston avoimen tietoaineiston lisenssi, muokkaus: formaatti muutettu
  5. legos, Kevin Jarrett, lisenssi: CC BY 2.0, muokkaus: teksti lisätty, kuvaa rajattu.
  6. Computerkatze, Tim Bartel, lisenssi: CC BY-SA 2.0, muokkaus: teksti lisätty, kuvaa rajattu.
  7. Rio the Black Mixed-Breed Dog in Glasses, Found Animals Foundation, lisenssi: CC BY-SA 2.0, muokkaus: teksti lisätty, kuvaa rajattu, koiran silmää muokattu.