Termipankki
  1. A
    1. Absoluuttinen polku
    2. Ajonaikainen
      konseptit
    3. Alkio
      arvot listat
    4. Alustaminen
      muuttujat arvot
    5. Argumentti
      arvot funktiot
    6. Arvo
      arvot
    7. Avain
      sanakirjat arvot
    8. Avainsana
      nimet
    9. Avainsana-argumentti
      funktiot
    10. Avausmoodi
      tiedostot
    11. Aliohjelma
      Funktio
    12. Attribuutti
      Jäsenarvo
    13. Ajaminen
      Suorittaminen
  2. B
    1. Boolen operaattori
      Looginen operaattori
    2. Bugi
      Ohjelmointivirhe
    3. break
      toistorakenteet avainsanat
  3. C
    1. Carriage return
      pakeneminen merkkijonot tiedostot windows
    2. Ctrl + C
      Näppäimistökeskeytys
    3. Callback
      Takaisinkutsu
    4. continue
      toistorakenteet avainsanat
  4. D
    1. Data
    2. Debuggaus
    3. Dokumenttimerkkijono
      dokumentointi
  5. E
    1. Elementti
      Alkio
    2. Ehto
      ohjausrakenteet
    3. Ehtolause
      ohjausrakenteet
    4. Ehtorakenne
      ehtorakenteet ohjausrakenteet
    5. Epätosi
      arvot
    6. Erotin
      merkkijonot tiedostot listat syöte
    7. Evaluointi
      lausekkeet arvot
    8. Exception
      poikkeukset ohjausrakenteet
    9. enumerate
      listat toistorakenteet
  6. F
    1. False
      Epätosi
    2. Format
      merkkijonot tulostus
    3. Funktio
      funktiot
    4. Funktiokutsu
      funktiot lauseet
    5. Funktiomäärittely
    6. for
  7. G
    1. Generaattori
      objektit toistorakenteet
    2. Globaali muuttuja
      muuttujat arvot
    3. Globaali näkyvyys
  8. H
    1. Haara
      try-rakenteet ehtorakenteet
    2. Hyppy
      ohjausrakenteet
    3. Hardkoodaus
      Kovakoodaus
  9. I
    1. if-lause
      Ehtolause
    2. if-rakenne
      Ehtorakenne
    3. Ikuinen silmukka
      toistorakenteet
    4. Indeksi
      arvot listat
    5. Indeksiosoitus
      arvot listat
    6. import
      moduulit
  10. J
    1. Jäsenarvo
      objektit
    2. Jäsenfunktio
      Metodi
  11. K
    1. Kutsu
      Funktiokutsu
    2. Kierros
      toistorakenteet
    3. Kirjasto
      moduulit
    4. Komentoriviargumentti
      terminaali
    5. Kommentti
      virheenetsintä dokumentointi
    6. Kooditiedosto
      konseptit
    7. Kovakoodaus
      arvot
    8. Kutsupyyntö
      funktiot
    9. Käsittelijä
      funktiot konseptit
    10. Käyttöliittymä
      konseptit
    11. Käyttöliittymäelementti
    12. Koodilohko
      Lohko
    13. Koodi
      Lähdekoodi
    14. KeyboardInterrupt
      Näppäimistökeskeytys
    15. Komentorivi
      Terminaali
    16. Komentokehote
      Terminaali
    17. Kahva
      Tiedostokahva
  12. L
    1. Lause
      konseptit
    2. Lauseke
      konseptit
    3. Leikkaus
      listat
    4. Lista
    5. Literaaliarvo
      arvot
    6. Liukuluku
      arvot tyypit
    7. Lohko
      ohjausrakenteet funktiot
    8. Looginen operaattori
      ohjausrakenteet operaattorit
    9. Lähdekoodi
      konseptit
  13. M
    1. Muotoilu
      Format
    2. Merkki
    3. Merkkijono
      arvot tyypit
    4. Metodi
      funktiot objektit
    5. Metodikutsu
      lausekkeet objektit
    6. Moduuli
    7. Monikko
      tietorakenteet listat
    8. Muuntumaton
      arvot merkkijonot konseptit
    9. Muuntuva
      arvot konseptit listat
    10. Muuttuja
      arvot konseptit
    11. Määrittely
      konseptit
  14. N
    1. Nimeämätön vakio
      arvot vakiot
    2. Nimi
      muuttujat funktiot
    3. Nimiavaruus
      moduulit funktiot konseptit
    4. Nimikonflikti
    5. Näkyvyysalue
      konseptit lohkot
    6. Näppäimistökeskeytys
      poikkeukset
  15. O
    1. Objekti
      konseptit
    2. Olio
      Objekti
    3. Ohjausrakenne
      try-rakenteet toistorakenteet ehtorakenteet
    4. Ohjelmointiongelma
      ongelmanratkaisu
    5. Ohjelmointityyli
    6. Ohjelmointivirhe
      ongelmanratkaisu
    7. Oletusarvo
      arvot funktiot parametrit
    8. Ominaisuus
      objektit
    9. Operaatio
      lausekkeet
    10. Operaattori
    11. Operandi
  16. P
    1. Paikallinen muuttuja
    2. Paikanpidin
      merkkijonot tulostus
    3. Pakeneminen
      merkkijonot
    4. Palauttaminen
      arvot funktiot
    5. Paluuarvo
    6. Parametri
      funktiot
    7. Parametrisaatio
    8. Poikkeus
      try-rakenteet ongelmanratkaisu
    9. Poikkeusten käsittely
      ohjausrakenteet poikkeukset
    10. Polku
    11. Python-konsoli
      työkalut
    12. Python-tulkki
      työkalut
    13. Pääohjelma
      konseptit
    14. Presedenssi
      Sidontajärjestys
  17. R
    1. Rajapinta
      moduulit funktiot konseptit
    2. Ratkaisumalli
      ongelmanratkaisu
    3. Rekursio
      funktiot konseptit
    4. Relatiivinen polku
    5. Rivinvaihtomerkki
      merkkijonot tiedostot
  18. S
    1. Sanakirja
      tietorakenteet
    2. Sapluuna
      merkkijonot konseptit
    3. Sekvenssi
      tietorakenteet konseptit toistorakenteet
    4. Sidontajärjestys
      lausekkeet konseptit
    5. Suoritusjärjestys
      Sidontajärjestys
    6. Sijoittaminen
      muuttujat arvot
    7. Sijoitusoperaattori
      muuttujat arvot operaattorit
    8. Silmukkamuuttuja
      muuttujat toistorakenteet
    9. Sisennys
      konseptit
    10. Sisäänrakennettu funktio
      funktiot
    11. Suorittaminen
      lausekkeet konseptit
    12. Suoritusjärjestys
    13. Syntaksi
      konseptit
    14. Syntaksivirhe
      poikkeukset
    15. Syöte
      merkkijonot konseptit
    16. Silmukka
      Toistorakenne
    17. Stacktrace
      Traceback
  19. T
    1. Taikaluku
      Nimeämätön vakio
    2. try-rakenne
      Poikkeusten käsittely
    3. Takaisinkutsu
      funktiot
    4. Tallennusformaatti
      merkkijonot tiedostot
    5. Tapahtuma
      konseptit
    6. Tekstitiedosto
      tiedostot
    7. Terminaali
      työkalut
    8. Testaaminen
      ongelmanratkaisu konseptit
    9. Tiedostokahva
      objektit tiedostot
    10. Tiedostonimi
      merkkijonot tiedostot
    11. Tiedostopääte
      tiedostot
    12. Tietorakenne
      sanakirjat konseptit listat
    13. Tila
      konseptit
    14. Toistorakenne
      ohjausrakenteet
    15. Tosi
      arvot
    16. True
      Tosi
    17. Totuusarvo
      ohjausrakenteet
    18. Traceback
      ongelmanratkaisu
    19. Tulostaminen
      merkkijonot konseptit
    20. Tynkäfunktio
      ongelmanratkaisu funktiot
    21. Tyylisääntö
    22. Tyyppi
      arvot konseptit
    23. Tyyppimuunnos
      arvot funktiot tyypit
  20. V
    1. Vakio
      muuttujat arvot
    2. Valinnainen argumentti
      arvot funktiot parametrit
    3. Vertailuarvo
    4. Vertailuoperaattori
      ohjausrakenteet operaattorit
    5. Viittaaminen
      muuttujat arvot objektit
    6. Virheviesti
      ongelmanratkaisu
  21. W
    1. while
      toistorakenteet
    2. with
      tiedostot
Ratkaistu: / tehtävää

4. Harjoitus: Lopunajan moduulit

Nämä ovat kurssin viimeiset harjoitukset. Miettikääpä sitä! Mieluiten kuitenkin vasta sen jälkeen kun olette miettineet itse tehtäviä. Tällä kertaa käsitellään tiedostoja ja tutustustaan hieman Pythonin moduuleihin. Viikon aihetehtävät tarjoavat myös varsin lihavia eväitä lopputyötä varten.

Osaamistavoitteet

Tämän harjoituksen jälkeen tiedostojen kanssa pläräämisen pitäisi olla jollain tapaa tuttua. Lisäksi moduulien käyttöönotto tulee entistä tutummaksi, samoin oman koodin kirjoittaminen moduulikelpoiseksi. Tutuksi tulee myös lopputyöhön suunniteltu kirjasto (tai kirjastot).

Esimerkki

Kuten materiaalissa luvattiin, tämän kerran esimerkissä tutustutaan hieman kurssia varten tehdyn haravasto-
kirjaston
käytöön. Esimerkki keskittyy pääasiassa siihen miten
käsittelijäfunktiot
käyttäytyvät. Esimerkki on myös jatkoa parille aiemmalle harjoitustehtävälle - nyt viimein nähdään miten suuntavektoria käyttävä liikkuminen toteutuu ruudulla.
Esimerkin ajaminen vaatii pyglet-kirjaston, jonka voi asentaa komentamalla
pip install pyglet

Tehtävän asettelu

Hauska olisi tehdä kokonainen peliprototyyppi, mutta siinä jouduttaisiin menemään aika paljon asioihin, joita ei ole tarpeen käydä tällä kurssilla. Tehdään siis vain yksittäinen ohjattava peliobjekti. Tavoitteena vois olla vaikka itsestään liikkuva ja animoitu pelihahmo, joka vaihtaa suuntaa kun pelaaja klikkaa pelialuetta. Sovitaan vielä, että hahmo ei liiku tasaisella nopeudella, vaan kiihtyy aina nollasta ylöspäin kun kohdepiste vaihtuu.

Ratkaisu

haravasto.py
Aivan ensimmäinen vaihe olisi saada jotain näkymään ruudulle. Tässä asiassa haravasto tulee avuksi. Toimintaperiaate on pääasiassa sama kuin materiaalissa käytetyssä ikkunastossa, eli ohjelman pääsilmukka pyörii Jossain Muualla (tm), ja varsinainen pelilogiikan käsittely tapahtuu käsittelijäfunktioissa. Tällä kertaa meillä ei kuitenkaan ole käyttöliittymäelementtejä joihin käsittelijät kiinnitetään. Jos tarkastellaan haravastoa, se tarjoaa mahdollisuuden kytkeä neljä erilaista käsittelijää:
Minimissään pelissä on oltava piirtokäsittelijä, jotta mitään saadaan näkyviin. Siinä missä ikkunaston kanssa kirjasto vastasi asioiden piirtämisestä ruudulle, tällä kertaa meidän pitää tehdä se itse. Pääero on siinä, että haravasto ei määrittele valmiita peliobjekteja samalla tavalla kuin ikkunasto määritteli käyttöliittymäkomponentit. Piirtofunktion tulee lähinnä piirtää kukin peliobjekti siihen kohtaan ruutua, jossa se on pelilogiikan mukaan menossa. Ennen kuin päästään piirtämään mitään, pitäisi grafiikat kuitenkin ladata. Tätä operaatiota ei tarvi tehdä itse miinoja haravoidessa, koska haravasto sisältää funktion, joka lataa mukana tulevat miinantallausgrafiikat. Myöskään pygletiä ei tarvitse ottaa käyttöön omassa koodissa, ja harjoitustehtävissä tätä ei edes saa tehdä. Tätä esimerkkiä varten tehdään kuitenkin oma latausfunktio, joka lataa alla olevat kaksi kuvaa annetusta
kansiosta
.
risti.zip
import pyglet
import haravasto 

LEVEYS = 800
KORKEUS = 600

def lataa_kuvat(polku):
    pyglet.resource.path = [polku]
    kuvat = {
        "0": pyglet.resource.image("plus_1.png"),
        "1": pyglet.resource.image("plus_2.png")
    }
    haravasto.grafiikka["kuvat"] = kuvat
Kuvien
avaimia
ei ole valittu sattumalta - syy valintoihin selviää myöhemmin. Lisäksi tarvitaan varsinainen piirtokäsittelijä, jossa seurataan haravaston omaa esimerkkiä - koko prosessi on selitetty varsin kattavasti haravaston
dokumenttimerkkijonoissa
. Piirretään kuva kohtaan 100, 100. Haravasto puhuu ruuduista, koska se ajattelee piirtävänsä miinaharavaa, mutta ei anneta sen häiritä.
def piirra_peli():
    haravasto.tyhjaa_ikkuna()
    haravasto.piirra_tausta()
    haravasto.aloita_ruutujen_piirto()
    haravasto.lisaa_piirrettava_ruutu("0", 100, 100)
    haravasto.piirra_ruudut()
Kun nämä kaksi funktiota laitetaan käyttöön pelin alustuksessa ja pääohjelmassa, saadaan ruudulle kaunis plus-merkki. Käsittelijöitä ei nyt siis kytketkä käyttöliittymäelementteihin, vaan suoraan itse haravastoon erikseen tätä varten luoduilla funktioilla.
def aloita_peli():
    haravasto.luo_ikkuna(LEVEYS, KORKEUS)
    haravasto.aseta_piirto_kasittelija(piirra_peli)
    haravasto.aloita()

if __name__ == "__main__":
    lataa_kuvat("spritet")
    aloita_peli()
Seuraava askel olisi luoda vuorovaikutusta. Aloitetaan siitä, että peli osaa tunnistaa käyttäjän klikkaukset, ja reagoi niihin teleporttaamalla hahmon suoraan määrättyyn kohtaan. Tässä vaiheessa otetaan käyttöön tutun näköinen
sanakirja
.
Käsittelijäfunktioilla
on edelleen sama ongelma kuin materiaalissa, eli emme voi vaikuttaa siihen mitä
argumentteja
niille annetaan. Samoin kuin materiaalissa, pelin tila kannattaa siis laittaa pääohjelmatason sanakirjaan. Annetaan sanakirjalle nimeksi tila, ja sijoitetaan pelihahmoa kuvaava sanakirja sen "pelaaja"-
avaimeen
.
tila = {
    "pelaaja": {
        "x": 0,
        "y": 0,
        "suunta": 0,
        "nopeus": 0
    }
}
Sanakirjassa näkyvät tyhjiä arvoja vastaavat nollat - tarkoitus on jälleen näyttää koodin lukijalle mitä ominaisuuksia pelaajan hahmolla on. Varsinainen arvojen asettaminen (satunnaiseen kohtaan ruudulla) tehdään luo_pelaaja-funktiossa:
def luo_pelaaja():
    tila["pelaaja"] = {
        "x": random.randint(0, LEVEYS - 1),
        "y": random.randint(0, KORKEUS - 1),
        "suunta": 0,
        "nopeus": 0
    }
Nyt kun meillä on objekti, jonka sijaintia voidaan ylläpitää, voidaan tehdä hiiren käsittelijä, joka muuttaa sijaintia. Käsittelijällä on neljä
parametria
, joista tarvitsemme tällä kertaa vain klikkauksen x- ja y-koordinaatit. Idea on edelleen hyvin samanlainen kuin aiemmin, eli käsittelijä muuttaa tila-sanakirjassa olevan "pelaaja"-avaimeen liitetyn hahmoa kuvaavan sanakirjan arvoja, jolloin muutokset näkyvät kaikkialla ohjelmassa.
def kasittele_hiiri(x, y, nappi, muokkausnapit):
    tila["pelaaja"]["x"] = x
    tila["pelaaja"]["y"] = y
Muutetaan myös piirtokäsittelijä piirtämään hahmo siihen, missä se pelin tilan mukaan sijaitsee:
def piirra_peli():
    haravasto.tyhjaa_ikkuna()
    haravasto.piirra_tausta()
    haravasto.aloita_ruutujen_piirto()
    haravasto.lisaa_piirrettava_ruutu("0", tila["pelaaja"]["x"], tila["pelaaja"]["y"])
    haravasto.piirra_ruudut()
Ja lopulta liitetään uudet funktiot pelin aloittamiseen:
def aloita_peli():
    luo_pelaaja()
    haravasto.luo_ikkuna(LEVEYS, KORKEUS)
    haravasto.aseta_piirto_kasittelija(piirra_peli)
    haravasto.aseta_hiiri_kasittelija(kasittele_hiiri)
    haravasto.aloita()
Periaatteessa näillä tiedoilla käsittelijöistä pystyy tekemään miinaharavan. Pääosa pelin logiikasta tulee hiiren käsittelyfunktioon sekä funktioihin, joita kutsutaan sieltä käsin. Tämä esimerkki ei kuitenkaan ihan vielä vastaa tehtävänantoa, joten jatketaan hieman eteenpäin. Haluttiin siis, että teleporttaamisen sijaan pelihahmo alkaisi kiihdyttää kohti klikattua pistettä. Koska pelihahmolla on jo ominaisuudet nopeus ja suunta, tarvitaan klikkauksen käsittelijä, joka muuttaa suuntaa ja asettaa nopeuden nollaan. Pelihahmolle pitää myös lisätä kiihtyvyys-ominaisuus.
Varsinainen hiiren käsittelijä muuttuu tässä vaiheessa muotoon:
def kasittele_hiiri(x, y, nappi, muokkausnapit):
    aseta_suunta(tila["pelaaja"], x, y)
    tila["pelaaja"]["nopeus"] = 0
Suunnan asetuksesta kannattaa tehdä oma funktionsa, koska funktio, joka määrittää kulman hahmon ja annetun pisteen välillä kuulostaa kohtalaisen yleishyödylliseltä. Ties vaikka peliin ilmestyisi joskus muitakin objekteja, jotka liikkuvat määritettyä pistettä kohti. Tässä vaiheessa tarvitaan hieman trigonometrian muistelua: jos tiedetään kanta ja korkeus, kulma saadaan arkustangentilla, johon on math-moduulissa funktio. Tosin pelkkä atan ei ole hyvä, koska se ei kästtele x:n ja y:n etumerkkejä erikseen - tämän tekee atan2.
def aseta_suunta(hahmo, kohde_x, kohde_y):
    etaisyys_x = kohde_x - hahmo["x"]
    etaisyys_y = kohde_y - hahmo["y"]
    hahmo["suunta"] = math.degrees(math.atan2(etaisyys_y, etaisyys_x))
Periaatteessa kulmia on vähän turha muuttaa asteiksi, kun niitä ei missään vaiheessa näytetä käyttäjälle. Asteet tekevät kuitenkin koodista helpommin lähetyttävää. Varsinkin jos toimintaa pitää jossain vaiheessa debugata ja tarkastella eri objektien suuntakulmia, asteet ovat huomattavasti miellyttävämpiä. Nyt pelaajalla on mahdollisuus ohjata pelihahmoa. Enää pitäisi toteuttaa se varsinainen liikkuminen. Tätä varten asetetaan uusi käsittelijä, jonka tehtävä on päivittää pelin tilaa jatkuvasti, eli noin 60 kertaa sekunnissa. Haravaston dokumentaatiosta selviää, että tällainen funktio saa yhden argumentin, joka on kulunut aika siitä, kun sitä kutsuttiin edellisen kerran.
def paivita_peli(kulunut_aika):
    tila["pelaaja"]["nopeus"] += tila["pelaaja"]["kiihtyvyys"]
    paivita_sijainti(tila["pelaaja"])
Kutsutun paivita_sijainti-funktion saat vaikka omasta harjoitustehtäväkoodistasi. Tällä toteutuksella luotetaan siihen, että peli todella pyörii koko ajan halutut 60 sykliä sekunnissa. Nyt jos peli ei pyöri tätä vauhtia, logiikka hidastuu. Oikeampi ratkaisu olisi käyttää hyödyksi funktion parametria siten, että kaikki ajasta riippuvat muutokset kerrotaan arvolla kulunut_aika * 60 (josta tulee tasan 1 jos peli pyörii halutulla tahdilla). Jätetään kuitenkin koodi nykyiseen muotoon, koska se on selkeämpi lukea. Kun nämä käsittelijät rekisteröidään aloita_peli-funktiossa, saadaan aikaan ohjattavaa liikettä.
def aloita_peli():
    luo_pelaaja()
    haravasto.luo_ikkuna(LEVEYS, KORKEUS)
    haravasto.aseta_piirto_kasittelija(piirra_peli)
    haravasto.aseta_hiiri_kasittelija(kasittele_hiiri)
    haravasto.aseta_toistuva_kasittelija(paivita_peli)
    haravasto.aloita()
Viimeisenä kuriositeettina toteutetaan kahden kuvan animaatio. Tätä varten hahmosanakirjaan pitää lisätä tieto siitä mikä sen nykyinen kuva on. Kuvien avaimet ladatessa olivat "0" ja "1", joten tämä avain on aina numero väliltä [0,2). Määritetään lisäksi vakio, joka säätää animaation nopeutta - 60 kertaa sekunnissa vaihtuva kuva on aivan liian rasittava silmille. Arvolla 0.1 kuva vaihtuu 6 kertaa sekunnissa.
ANIMAATIONOPEUS = 0.1

tila = {
    "pelaaja": {
        "x": 0,
        "y": 0,
        "suunta": 0,
        "nopeus": 0,
        "kiihtyvyys": 0,
        "kuva": 0
    },
}
Koska kaukaa viisaasti kuville valittiin nimiksi "0" ja "1", kuvan vaihto onnistuu kätevästi matemagiikalla. Tämä lisätään paivita_peli-funktioon. Jokaisella päivityksellä kasvatetaan kuvan arvoa animaationopeuden verran, jolloin sillä menee 10 sykliä muuttua nollasta ykköseen, ja toiset 10 sykliä ykkösestä kakkoseen. Koska animaatio loppuu kuvaan numero 1, laskenta voidaan palauttaa alkuun ottamalla jakojäännös 2:lla.
def paivita_peli(kulunut_aika):
    tila["pelaaja"]["nopeus"] += tila["pelaaja"]["kiihtyvyys"]
    tila["pelaaja"]["kuva"] = (tila["pelaaja"]["kuva"] + ANIMAATIONOPEUS) % 2
    paivita_sijainti(tila["pelaaja"])
Todettakoon, että jälleen jos haluttaisiin vakaammin toimiva peli, pitäisi animaationopeus kertoa samalla arvolla kulunut_aika * 60. Piirtofunktio vaatii myös muutoksen, jossa piirretään hahmosanakirjan "kuva"-avainta vastaava kuva. Koska tuo arvo on liukuluku väliltä [0,2), se pitää muuntaa kokonaisluvuksi. Grafiikkasanakirjan avaimet ovat
merkkijonoja
, mutta jos kurkistetaan haravaston sisälle, muunnos merkkijonoksi tehdään siellä - argumentti voi siis olla kokonaisluku. Näin saadaan aikaiseksi kaunis(?) animaatio. Lopputulosta voi ihmetellä lataamalla valmiin ohjelmankoodin alta.
ristipeli.py
import math
import pyglet
import random
import haravasto 

LEVEYS = 800
KORKEUS = 600
ANIMAATIONOPEUS = 0.1

tila = {
    "pelaaja": {
        "x": 0,
        "y": 0,
        "suunta": 0,
        "nopeus": 0,
        "kiihtyvyys": 0,
        "kuva": 0
    },
    "aika": 0.0
}

def muunna_xy_koordinaateiksi(a, r):
    x = int(round(math.cos(a) * r))
    y = int(round(math.sin(a) * r))
    return x, y

def paivita_sijainti(hahmo):
    dx, dy = muunna_xy_koordinaateiksi(math.radians(hahmo["suunta"]), hahmo["nopeus"])
    hahmo["x"] += dx
    hahmo["y"] += dy

def aseta_suunta(hahmo, kohde_x, kohde_y):
    etaisyys_x = kohde_x - hahmo["x"]
    etaisyys_y = kohde_y - hahmo["y"]
    hahmo["suunta"] = math.degrees(math.atan2(etaisyys_y, etaisyys_x))

def kasittele_hiiri(x, y, nappi, muokkausnapit):
    aseta_suunta(tila["pelaaja"], x, y)
    tila["pelaaja"]["nopeus"] = 0

def paivita_peli(kulunut_aika):
    tila["pelaaja"]["nopeus"] += tila["pelaaja"]["kiihtyvyys"]
    tila["pelaaja"]["kuva"] = (tila["pelaaja"]["kuva"] + ANIMAATIONOPEUS) % 2
    paivita_sijainti(tila["pelaaja"])
    tila["aika"] += kulunut_aika
    
def piirra_peli():
    haravasto.tyhjaa_ikkuna()
    haravasto.piirra_tausta()
    haravasto.aloita_ruutujen_piirto()
    haravasto.lisaa_piirrettava_ruutu(int(tila["pelaaja"]["kuva"]), tila["pelaaja"]["x"], tila["pelaaja"]["y"])
    haravasto.piirra_ruudut()

def luo_pelaaja():
    tila["pelaaja"] = {
        "x": random.randint(0, LEVEYS - 1),
        "y": random.randint(0, KORKEUS - 1),
        "suunta": 0,
        "nopeus": 0,
        "kiihtyvyys": 0.2,
        "kuva": 0
    }

def lataa_kuvat(polku):
    pyglet.resource.path = [polku]
    kuvat = {
        "0": pyglet.resource.image("plus_1.png"),
        "1": pyglet.resource.image("plus_2.png")
    }
    haravasto.grafiikka["kuvat"] = kuvat

def aloita_peli():
    luo_pelaaja()
    haravasto.luo_ikkuna(LEVEYS, KORKEUS)
    haravasto.aseta_piirto_kasittelija(piirra_peli)
    haravasto.aseta_hiiri_kasittelija(kasittele_hiiri)
    haravasto.aseta_toistuva_kasittelija(paivita_peli)
    haravasto.aloita()

if __name__ == "__main__":
    lataa_kuvat("spritet")
    aloita_peli()

Yhteiset tehtävät

Tuttuun tapaan nämä pitäisi kaikkien tehdä.

Lämmittelytehtävä

Spiraali suoraan tiedostosta

Tämä tehtävä on edellisen viikon spiraalitehtävän jatkokehittelyä. Ohjelmaan lisätään uusi ominaisuus: se osaa piirtää tiedostossa olevien ohjeiden avulla kuvan, joka muodostuu useista spiraaleista. Tiedostossa yksi rivi kuvaa yhden spiraalin parametrit.
Opittavat asiat: Tehtävässä kerrataan tiedostojen lukemista ja opetellaan parsimaan tiedoston sisältö muuttujiksi.
Tavoite: Toteuttaa ohjelma, joka lukee piirto-ohjeet tekstitiedostosta ja piirtää niitä sekä aiemmin luotua funktiota käyttäen kuvioita ruudulle.
Ennen kuin aloitat:
Tarvitset viime viikon spiraalitehtävässä tehdyn piirra_spiraali-funktion. Kopioi siis tämän funktion määrittely koodiin.
Toteutettava funktio: piirra_tiedostosta;
  • Parametrit
    :
    • luettavan tiedoston nimi (merkkijono).
Funktion tulee avata
tiedosto
ja lukea siellä olevia, spiraalia kuvaavia datarivejä, joissa on arvot samassa järjestyksessä kuin spiraalifunktion parametrit pilkulla toisistaan erotettuna:
  • spiraalin väri (väriarvo - värin nimi tai heksadesimaalimuotoinen värikoodi)
  • piirrettävien kaarien (neljäsosaympyrä) lukumäärä (kokonaisluku)
  • spiraalin säde (kokonaisluku)
  • säteen kasvu (liukuluku)
  • viivan paksuus (kokonaisluku)
Funktion tulee siis lukea nämä arvot kultakin riviltä, muuttaa ne tarpeen mukaan oikeaan tyyppiin ja sen jälkeen kutsua piirra_spiraali-funktiota riviltä luettuja arvoja käyttäen. Vaikka viivan paksuus on piirtofunktiolle valinnainen parametri, tiedostossa se löytyy jokaiselta riviltä - voit siis turvallisesti olettaa, että kullakin rivillä on aina 5 arvoa.
Tehtävää tehdessä voit muutenkin olettaa, että luettavassa tiedostossa ei ole virheitä.
Esimerkit toiminnasta:
Alla on esimerkki tiedostosta jollaisia piirra_tiedostosta-funktion tulee lukea, sekä tutun näköinen kuva, joka on piirretty tämän esimerkkitiedoston pohjalta.
spiraali.txt
black,20,10,3,1
red,10,20,4,3
blue,10,-20,-4,3

tuttu kuva, piirretty uudella tavalla
Varoitus: Et ole kirjautunut sisään. Et voi vastata.

Päätehtävät

Astraalinen aasigotchi

Osa ehkä muistaa lapsuudestaan Tamagotchit, nuo muoviset huomiota kerjäävät piippaajat. Tässä harjoituksessa tehtävänäsi on toteuttaa moinen virtuaalieläin – tarkemmin ottaen virtuaalinen aasi.
Tehtävässä tutustutaan omien moduulien luomiseen ja käyttämiseen syvemmin. Oheisissa tiedostoissa on annettu pari moduulia jo valmiiksi, ja tehtäväksesi jääkin pääohjelmamoduulin täydentäminen sekä käyttöliittymämoduulin laatiminen. Bittiaasin logiikka ja joukko erinäisiä määritelmiä on siis toteutettu jo valmiiksi.
Opittavat asiat: Muiden kirjoittamaan koodiin tutustuminen ja sen toiminnan täydentäminen. Omien
moduulien
kirjoittaminen.
Sanakirjojen
ja
vakioiden
käyttö koodissa.
Tavoite: Koodata käyttöliittymämoduuli muuten valmiiseen aasigotchi-sovellukseen.
Ennen kuin aloitat:
Tehtävässä käytetään kahta täysin valmista
kooditiedostoa
sekä yhtä puolivalmista. Kooditiedostojen roolit ovat seuraavat:
  • main.py: Pääohjelma, jonka tehtävänä on toimia ohjelman ”sisäänkäyntinä” ja toteuttaa ohjelman logiikan käyttöliittymään sitova pääsilmukka. Tässä tiedostossa on kysymysmerkeillä merkittyjä aukkoja, jotka tulee paikata.
  • aasimaaritelmat.py: Valmiiksi määriteltyjä
    vakioita
    , samaan tapaan kuin Pythonin oma math.pi, joita voi hyödyntää muissa moduuleissa.
  • aasilogiikka.py: Ohjelman moottori, jossa dataa luodaan ja käsitellään.
Kooditiedostot löytyvät tehtävänannon lopusta.
Korjattava kooditiedosto: main.py
Jotta ohjelma voidaan suorittaa, main.py-tiedostoon tulee paikata kysymysmerkeillä merkityt kohdat. Se, mitä niihin sijoitetaan, selviää tutkimalla aasilogiikka- ja aasimaaritelmat-moduuleja.
Toteutettava moduuli: aasikaytto.py
  • Dokumenttimerkkijono
    :
    • """Määrittelee aasigotchin käyttöliittymän toiminnot."""
  • Funktiot
    :
    • nayta_tila (yksityiskohdat alempana)
    • pyyda_syote (yksityiskohdat alempana)
1. toteutettava funktio: nayta_tila
  • Dokumenttimerkkijono
    :
"""
Tulostaa aasin tilan.
"""
  • Parametrit
    :
    • aasin tilaa kuvaava tietorakenne (
      sanakirja
      )
Funktio tulostaa aasin tilan, eli tilaa kuvaavassa sanakirjassa olevat arvot ikä, rahat, kylläisyys, onnellisuus ja jaksaminen. Lisäksi, jos aasi on eläkkeellä, tulostetaan tästä erillinen ilmoitus. Tulostuksessa käytettävät merkkijonot löydät tehtävänannon lopussa olevista suoritusesimerkeistä.
2. toteutettava funktio: pyyda_syote
  • Dokumenttimerkkijono
    :
"""
Näyttää käyttäjälle aasin tilaa vastaavat mahdolliset syötteet ja kysyy uutta
syötettä kunnes käyttäjä antaa laillisen syötteen. Saatu syöte palautetaan.
"""
  • Parametrit
    :
    • aasin tilaa kuvaava tietorakenne (sanakirja)
  • Palauttaa
    :
    • käyttäjän antaman laillisen syötteen (
      merkkijono
      )
Funktio tulostaa aasin tilasta riippuvat valinnat kerran, jonka jälkeen se kysyy syötettä käyttäjältä kunnes käyttäjä antaa aasin tilaa vastaavan laillisen syötteen. Jos aasi ei ole eläkkeellä, lailliset syötteet löytyvät aasimaaritelmat-moduulin VALINNAT-vakiosta listana; jos aasi on eläkkeellä, lailliset syötteet löytyvät saman moduulin ELAKEVALINNAT-vakiosta listana. Näitä vakioita kannattaa hyödyntää sekä valintojen tulostuksessa, että syötteiden laillisuuden tarkistamisessa. Tulostuksissa ja kyselyissä käytettävät merkkijonot löydät jälleen suoritusesimerkeistä.
Esimerkit toiminnasta:
Aasi on 96 vuotta vanha ja rahaa on 0 mk.
Kylläisyys: 5
Onnellisuus: 5
Jaksaminen: 5
Valinnat: q, r, k, t
Anna seuraava valinta: q
Aasi on 96 vuotta vanha ja rahaa on 0 mk.
Kylläisyys: 5
Onnellisuus: 5
Jaksaminen: 5
Valinnat: q, r, k, t
Anna seuraava valinta: Z
Virheellinen syöte!
Anna seuraava valinta: ???
Virheellinen syöte!
Anna seuraava valinta: t
Aasi on 97 vuotta vanha ja rahaa on 1 mk.
Kylläisyys: 5
Onnellisuus: 5
Jaksaminen: 4
Valinnat: q, r, k, t
Anna seuraava valinta: 
Aasi on 100 vuotta vanha ja rahaa on 12 mk.
Kylläisyys: 6
Onnellisuus: 9
Jaksaminen: 2
Aasi on jäänyt eläkkeelle.
Valinnat: q, a
Anna seuraava valinta: X
Virheellinen syöte!
Anna seuraava valinta: r
Virheellinen syöte!
Anna seuraava valinta: k
Virheellinen syöte!
Anna seuraava valinta: a
Aasi on 0 vuotta vanha ja rahaa on 0 mk.
Kylläisyys: 5
Onnellisuus: 5
Jaksaminen: 5
Valinnat: q, r, k, t
Anna seuraava valinta:
Resurssit
Lataa nämä kooditiedostot omalle koneellesi alta.
aasilogiikka.py
"""
Määrittelee aasigotchin varsinaisen taustalla toimivan logiikan.
"""
import aasimaaritelmat as am

def alusta():
    """
    Alustaa aasidatan, eli luo uuden aasin sekä asettaa sen alkutilanteeseen.
    """
    aasidata = {
        "KYLLÄISYYS": am.ALKU,
        "ONNELLISUUS": am.ALKU,
        "JAKSAMINEN": am.ALKU,
        "IKÄ": 0,
        "RAHA": 0,
        "ELÄKE": False,
    }
    return aasidata

def _vanhene(aasidata):
    """
    Vanhentaa aasia ja jättää sen tarvittaessa eläkkeelle. Tarkoitettu vain
    moduulin sisäiseen käyttöön.
    """
    aasidata["IKÄ"] += 1
    
    if aasidata["IKÄ"] == am.ELAKEIKA:
        aasidata["ELÄKE"] = True

def _tarkista_tilat(aasidata):
    """
    Muuttaa aasin tiloja ajan kuluessa ja jättää aasin tarvittaessa
    sairaseläkkeelle. Tarkoitettu vain moduulin sisäiseen käyttöön.
    """
    if aasidata["IKÄ"] % 2 == 0:
        if aasidata["KYLLÄISYYS"] > 6 and aasidata["JAKSAMINEN"] < am.MAKSIMI_TILA:
            aasidata["JAKSAMINEN"] += 1
        aasidata["KYLLÄISYYS"] -= 1
    if aasidata["IKÄ"] % 3 == 0:
        aasidata["ONNELLISUUS"] -= 1
    
    if aasidata["KYLLÄISYYS"] <= 0 or aasidata["ONNELLISUUS"] <= 0 or aasidata["JAKSAMINEN"] <= 0:
        aasidata["ELÄKE"] = True

def ruoki(aasidata):
    """
    Ruokkii aasia, eli kasvattaa aasin kylläisyyttä, ellei se ole jo maksimissa.
    """
    _vanhene(aasidata)
    _tarkista_tilat(aasidata)
    if aasidata["KYLLÄISYYS"] < am.MAKSIMI_TILA:
        aasidata["KYLLÄISYYS"] += 1
    
def kutita(aasidata):
    """
    Kutittaa aasia, eli kasvattaa aasin onnellisuutta, ellei se ole jo maksimissa.
    """
    _vanhene(aasidata)
    _tarkista_tilat(aasidata)
    if aasidata["ONNELLISUUS"] < am.MAKSIMI_TILA:
        aasidata["ONNELLISUUS"] += 1

def tyoskentele(aasidata):
    """
    Teettää aasilla töitä, eli vähentää aasin jaksamista rahapalkkaa vastaan.
    """
    _vanhene(aasidata)
    aasidata["JAKSAMINEN"] -= 1
    aasidata["RAHA"] += 1
    _tarkista_tilat(aasidata)

aasimaaritelmat.py
"""
Määrittelee aasigotchin koodissa käytetyt vakiot.
"""

# Syötevalinnat
LOPETA = "q"
RUOKI = "r"
KUTITA = "k"
TYOSKENTELE = "t"
VALINNAT = [LOPETA, RUOKI, KUTITA, TYOSKENTELE]

ALUSTA = "a"
ELAKEVALINNAT = [LOPETA, ALUSTA]

# Aasin tilat
ALKU = 5
ELAKEIKA = 100
MAKSIMI_TILA = 10

main.py
import ???
import ???
import ???

def main():
    aasidata = aasilogiikka.???
    
    while True:
        aasikaytto.nayta_tila(aasidata)
        syote = aasikaytto.pyyda_syote(aasidata)
        
        if syote == aasimaaritelmat.LOPETA:
            break
        elif syote == aasimaaritelmat.RUOKI:
            ???
        elif syote == aasimaaritelmat.KUTITA:
            ???
        elif syote == aasimaaritelmat.TYOSKENTELE:
            ???
        elif syote == aasimaaritelmat.ALUSTA:
            ???

if __name__ == "__main__":
    ???

Tarkistin päivitetty 25.3.2020
Palauta aasikaytto.py ja main.py. Voit valita kaksi tiedostoa kerralla pitämällä Ctrl-näppäintä pohjassa.
Varoitus: Et ole kirjautunut sisään. Et voi vastata.

Lopputyötehtävät 1

Näistä sopii valita yksi. Huomaa, että tehtäviä on tässä valinnassa vain kaksi: miinantallaajat valitsevat ensimmäisen, muut toisen. Tämä johtuu siitä, että spektri- ja piiri-lopputyöt käyttävät samaa apukirjastoa käyttöliittymäikkunan tekemiseen.

Hiiri tarttuu haravaan

Kuka nyt 2000-luvulla pelaisi miinaharavaa merkkigrafiikalla terminaalissa? Tässä ja seuraavissa tehtävissä hankimme perustan, jonka päälle Miinantallaaja-polun valinneet voivat rakentaa kauniin graafisen miinaharavan, jota pelataan hiirellä. Olemme tehneet tätä varten oman pienen kirjaston, ja tässä tehtävässä aloitamme siihen tutustumisen. Aiheina ovat sovellusikkunat ja käsittelijäfunktiot.
Opittavat asiat: Sovellusikkunan luominen. Hiiren käsittely haravasto-kirjaston avulla. Käsittelijäfunktioiden toteuttaminen ja käyttö.
Tavoite: Toteuttaa ohjelma, jossa hiiren käsittelijäfunktio kertoo missä kohdassa ruutua hiiren nappia painettiin.
Ennen kuin aloitat:
Tehtävässä käytetään Miinantallaaja-lopputyötä varten tehtyä haravasto-moduulia, joka avustaa huomattavasti lopputyön graafisen käyttöliittymän tekemisessä. Lataa kirjasto alta ja tutustu siihen huolellisesti - kirjastossa on kattavat dokumentaatiomerkkijonot sekä lopussa pieni esimerkkiohjelma.
haravasto.py
Myös Miinantallaaja-lopputyön sivulla on hieman pohjustusta haravaston käyttöön, joten se kannattaa käydä lukaisemassa. Asenna myös Pyglet, jos et vielä tehnyt sitä harjoitusesimerkkiä kokeillaksesi.
Huomaa, että näissä harjoitustehtävissä sinun ei tarvitse tuoda Pygletiä omaan koodiisi - kaikki tapahtuu haravaston kautta. Tarkistinpalvelimelle ei ole edes asennettu Pygletiä, joten sen suora käyttöönotto aiheuttaa ModuleNotFoundError-poikkeuksen. Lopputyössä voit toimia tietenkin parhaaksi katsomallasi tavalla.
1. toteutettava funktio: kasittele_hiiri
  • Dokumenttimerkkijono
    :
"""
Tätä funktiota kutsutaan kun käyttäjä klikkaa sovellusikkunaa hiirellä.
Tulostaa hiiren sijainnin sekä painetun napin terminaaliin.
"""
  • Parametrit
    :
    • hiiren x-sijainti (kokonaisluku)
    • hiiren y-sijainti (kokonaisluku)
    • hiiren painike (kokonaisluku)
    • painetut muokkausnäppäimet (kokonaisluku - ei käytetä tehtävässä, mutta tulee määritellä jotta funktiota voidaan kutsua)
Funktio tulostaa saamansa parametrit terminaaliin (suoritusesimerkeistä näet tulostuksen muotoilun). Hiiren painike on kokonaisluku, jossa eri arvot vastaavat eri nappeja. Näitä arvoja ei tarvitse muistaa, sillä voit käyttää haravaston vakioita HIIRI_VASEN, HIIRI_KESKI ja HIIRI_OIKEA selvittääksesi mitä nappia painettiin. Voit vaikka harjoitella
sanakirjojen
käyttöä tekemällä sanakirjan, jossa nämä vakioarvot ovat
avaimia
ja merkkijonot "vasen", "keski" ja "oikea" arvoja.
2. toteutettava funktio: main
  • Dokumenttimerkkijono:
"""
Luo sovellusikkunan ja asettaa käsittelijäfunktion hiiren klikkauksille.
Käynnistää sovelluksen.
"""
Pääohjelmafunktion tulee luoda ikkuna käyttämällä haravaston luo_ikkuna-funktiota sekä asettaa käsittelijäfunktion hiirelle haravaston aseta_hiiri_kasittelija-funktiolla. Tutustu siis näiden funktioiden toimintaan. Ikkunan koko ja taustaväri on vapaasti valittavissa ja taustavärillä ei ole merkitystä, koska ikkunaa ei piirretä kertaakaan luomisen jälkeen. Lopuksi sovellus pitää vielä käynnistää aloita-funktiolla.
Toteutettava pääohjelma:
if __name__ == "__main__":
    main()
Esimerkit toiminnasta:
Esimerkeissä näkyy vain mitä tulostuu terminaaliin.
Hiiren nappia vasen painettiin kohdassa 123, 53
Hiiren nappia oikea painettiin kohdassa 20, 10
Hiiren nappia keski painettiin kohdassa 250, 39
Palauta vain tekemäsi tiedosto!
Varoitus: Et ole kirjautunut sisään. Et voi vastata.

Ihan tavallinen ikkuna

Jotta spektriä voidaan pukata ja piiriä pyörittää graafisesti, täytyy opetella graafisten käyttöliittymien perusteet. Tämä on opiskelusarjan ensimmäinen tehtävä, jossa opit luomaan käyttöliittymäikkunan parilla kompomentilla. Apuna toimii pieni kurssia varten tehty kirjasto, jonka avulla homma hoituu yksinkertaisten funktiokutsujen kautta.
Opittavat asiat: Käyttöliittymäikkunan luomisen perusteet. Kurssin ikkunasto-moduulin käytön perusteet.
Tavoite: Ohjelma, joka luo käyttöliittymäikkunan.
Asennettava moduuli: matplotlib
Tekemämme ikkunasto-moduuli vaatii toimiakseen matplotlib-kirjaston. Asennuksen voi tehdä pip-ohjelmalla komennolla pip install matplotlib. Normaalisti pip tulee Pythonin mukana. Kurkkaa esitehtävistä jos et muista miten sitä ajetaan. Joissain Linuxeissa sekä Mac OS X:ssä komento saattaa olla pip3 - pelkkä pip asentaa moduuleja Pythonin kakkosversioon.
Ennen kuin aloitat:
Tehtävässä käytetään ikkunasto-kirjastoa, jota käytetään sekä Spektriä pukkaa että Piiri pieni pyörii lopputyöaiheissa. Kirjastosta löytyy funktiot, joiden avulla pystyt luomaan yksinkertaisia käyttöliittymiä. Lataa kirjasto alla olevasta linkistä ja tutustu siihen huolellisesti - kirjastossa on kattavat dokumentaatiomerkkijonot sekä lopussa pieni esimerkkiohjelma.
ikkunasto.py
Kirjasto kannattaa heti alkuun testata. Mikäli saat viestin puuttuvasta DLL:stä, kyseessä on todennäköisesti tämä, joka tulee siis asentaa.
Myös lopputyöaihesivuilla on kerrottu lyhyesti graafisten käyttöliittymäkirjastojen perusteet, joihin on siis syytä käydä tässä vaiheessa tutustumassa.
Huomaa, että näissä harjoitustehtävissä sinun ei tarvitse tuoda Tkinteriä tai Matplotlibiä omaan koodiisi - kaikki tapahtuu ikkunaston kautta. Tarkistinpalvelimelle ei ole edes asennettu näitä, joten niiden suora käyttöönotto aiheuttaa ModuleNotFoundError-poikkeuksen. Lopputyössä voit toimia tietenkin parhaaksi katsomallasi tavalla.
Luo myös ohjelman alussa sanakirja, johon voidaan tallentaa viittaukset tärkeisiin käyttöliittymäelementteihin.
elementit = {
    "tekstilaatikko": None
}
Koska ohjelma toimii pääasiassa käsittelijäfunktioilla, et pysty itse määrittelemään mm. sitä mitä parametreja kullekin funktiolle annetaan. Niinpä ohjelman tila ja viittaukset käyttöliittymäelementteihin täytyy pitää
globaalisti saatavilla
. Kaikkein selkein tapa on kasata ne yhteen sanakirjaan, jota voidaan käsitellä kaikissa ohjelman funktioissa.
1. toteutettava funktio: tulosta_testirivi
  • Dokumenttimerkkijono
    :
"""
Tulostaa testirivin käyttöliittymän tekstilaatikkoon.
"""
Kun funktiota kutsutaan, se kirjoittaa elementit-sanakirjasta löytyvään tekstilaatikkoon vaikka merkkijonon "aasisvengaa", tai voit myös keksiä oman viestisi. Käytä ikkunaston kirjoita_tekstilaatikkoon-funktiota. Viestillä ei tässä vaiheessa ole muuta tarkoitusta kuin osoittaa, että käyttöliittymän elementit on onnistuneesti kytketty toisiinsa tämän käsittelijäfunktion avulla.
2. toteutettava funktio: main
  • Dokumenttimerkkijono:
"""
Luo käyttöliittymäikkunan, jossa on vasemmalla kaksi nappia ja oikealla
tekstilaatikko, johon nappia painamalla voidaan tulostaa tekstiä.
"""
Pääohjelmafunktion tehtävä on luoda käyttöliittymän elementit, kytkeä nappeihin käsittelijäfunktiot ja lopulta käynnistää ohjelma. Haluamme käyttöliittymän, jossa on kaksi puoliskoa: vasemmalla on kaksi nappia ja oikealla tekstilaatikko. Napeista ensimmäiseen tulee kytkeä juuri tehty tulosta_testirivi-funktio käsittelijäksi. Toisen napin käsittelijä on ikkunaston lopeta-funktio. Nappien tekstit voit valita itse.
Kun luot tekstilaatikon, talleta viittaus siihen aiemmin määriteltyyn sanakirjaan.
Tarvitset tämän kokonaisuuden tekemiseen ikkunaston luo_ikkuna, luo_kehys, luo_nappi ja luo_tekstilaatikko -funktioita. Tutustu siis niiden toimintaan. Suoritusesimerkit-otsikon alla on annettu kuvaruutukaappaus valmiista käyttöliittymästä. Mittasuhteet saattavat omassasi olla eri, koska ne riippuvat funktioiden argumenteista, mutta asettelun tulee olla sama.
Toteutettava pääohjelma:
if __name__ == "__main__":
    main()
Esimerkit toiminnasta:
Käyttöliittymän asettelun tulisi näyttää tältä. Mittasuhteet voivat erota.
Varoitus: Et ole kirjautunut sisään. Et voi vastata.

Lopputyötehtävät 2

Näistäkin sopii valita yksi.

Miinoitustuokio

Satunnaisuus on peleissä tärkeä tekijä, ja sitä varten on tietenkin olemassa omat ohjelmointityökalunsa. Tästä tehtävästä saat apua Miinantallaaja-harjoitustyön automaattiseen kentänluontiin, jossa siis satunnaisuutta tarvitaan miinojen sijoittamiseen kentälle. Lisäksi tutustumme siihen, miten pelikirjastoissa tyypillisesti piirretään grafiikkaa ruudulle.
Opittavat asiat: random-moduulin sisältöön tutustuminen ja sopivan satunnaistamiskeinon kehittäminen miinojen asettamiseen. Peligrafiikan piirtämisen perusteet. Piirtokäsittelijäfunktion toteuttaminen käyttämällä haravasto-moduulia.
Tavoite: Ohjelma, joka asettaa kentälle annetun määrän miinoja satunnaisiin kohtiin, ja piirtää lopputuloksen peli-ikkunaan.
Ennen kuin aloitat:
Tehtävässä käytetään samaa haravasto-moduulia kuin edellisessäkin. Lisäksi tarvitset miinaharavaa varten suunnitellun grafiikkapaketin, jonka sisällön voit sijoittaa valitsemaasi kansioon.
Koska piirtokäsittelijällä ei ole lainkaan parametrejä, piirrettävää kenttää ei voida antaa sille argumenttina. Tästä syystä ohjelmassa on jollain tavalla tehtävä kenttä tavoitettavaksi kaikkien funktioiden sisältä. Tässä tehtävässä käytämme pelin tilaa ylläpitävää sanakirjaa, joka on alkeiskurssin keinoista suositeltavin tapa. Laita siis koodisi alkuun tämä koodipätkä heti importien jälkeen:
tila = {
    "kentta": []
}
Luonnollisesti ohjelman suorituksen aikana tyhjä lista korvataan kenttää kuvaavaalla kaksiulotteisella listalla. Huomaa, että tarkistin vaatii tämän näköisen sanakirjan löytyvän koodista.
1. toteutettava funktio: miinoita
  • Dokumenttimerkkijono
    :
"""
Asettaa kentälle N kpl miinoja satunnaisiin paikkoihin.
"""
  • Parametrit
    :
    • miinoitettava kenttä (2-ulotteinen
      lista
      )
    • lista vapaista ruuduista (lista joka sisältää koordinaattipari-
      monikkoja
      )
    • asetettavien miinojen lukumäärä (kokonaisluku)
Funktio valitsee vapaiden ruutujen joukosta - eli vapaita ruutuja esittävästä listasta - yhteensä N ruutua, ja asettaa kunkin ruudun koordinaattien osoittamaan kohtaan kentälle miinan (miina merkitään "x"). Tämän voi tehdä usealla tavalla - pidä kuitenkin huoli siitä, että samaa koordinaattiparia ei voida valita kahdesti! Jo miinoitetut koordinaattiparit kannattaa siis poistaa koordinaattiparilistasta.
2. toteutettava funktio: piirra_kentta
  • Dokumenttimerkkijono:
"""
Käsittelijäfunktio, joka piirtää kaksiulotteisena listana kuvatun miinakentän
ruudut näkyviin peli-ikkunaan. Funktiota kutsutaan aina kun pelimoottori pyytää
ruudun näkymän päivitystä.
"""
Avaa haravasto.py ja lue aseta_piirto_kasittelija-funktion dokumenttimerkkijonosta ohjeet miten
piirtofunktio
tulee toteuttaa. Piirrettävä kenttä tulee lukea tila-sanakirjasta "kentta" avaimella. Ruutuja piirrettäessä niiden ruutukoordinaatit tulee laskea kertomalla ruudun listaindeksit ruudun koolla (jonka voit katsoa grafiikkatiedostojen ominaisuuksista). Kentän läpi silmukointi muistuttaa varsin vahvasti aiempaa harjoitusta.
3. toteutettava funktio: main
def main():
    """
    Lataa pelin grafiikat, luo peli-ikkunan ja asettaa siihen piirtokäsittelijän.
    """

    haravasto.lataa_kuvat(#tähän tulee polku kansioon johon tallensit kuvat)
    haravasto.luo_ikkuna(600, 400)
    haravasto.aseta_piirto_kasittelija(piirra_kentta)
    haravasto.aloita()
Toteutettava pääohjelma:
Pääohjelma tulee sijoittaa if __name__ == "__main__":-
ehtolauseen
alle. Pääohjelman tarkoitus on testata funktioiden toimintaa. Tämä tapahtuu määrittelemällä 15x10 kenttä, johon sijoitetaan 35 miinaa. Miinat sijoitetaan
kutsumalla
miinoita-funktiota. Kentän voit luoda oheisella koodinpätkällä:
kentta = []
for rivi in range(10):
    kentta.append([])
    for sarake in range(15):
        kentta[-1].append(" ")

tila["kentta"] = kentta
Lisäksi tarvitset listan vapaista ruuduista. Tämä lista tuotetaan seuraavalla koodinpätkällä. Kiinnitä huomiota siihen miten dimensiot yhdistyvät koodissa rivien, sarakkeiden ja koordinaattien käsitteisiin.
jaljella = []
for x in range(15):
    for y in range(10):
        jaljella.append((x, y))
Kutsu tämän jälkeen ensin miinoitus-funktiota ja sitten main-funktiota.
Esimerkit toiminnasta:
Lopputuloksen tulisi näyttää suurinpiirtein tältä.
Varoitus: Et ole kirjautunut sisään. Et voi vastata.

Osoittelu on rumaa...

...mutta ah niin kätevää - ainakin hiirellä ruudulta osoittelu. Tässä tehtävässä opitaan parikin spektri-lopputyössä tarpeellista taitoa: kuvaajan piirtäminen käyttöliittymäikkunan sisälle sekä hiiren klikkausten lukeminen.
Opittavat asiat: Kuvaajan piirtäminen ohjelmaikkunan sisälle matplotlib- ja ikkunasto-kirjastojen yhteistyöllä. Kuvaajaan kytketyn hiiren käsittelijäfunktion toteuttaminen. Tapahtumien varastointi ohjelman muistiin.
Tavoite: Ohjelma, jossa kuvaajaa klikkaamalla saadaan tulostettua tekstilaatikkoon klikatun kohdan x- ja y- data-arvot.
Ennen kuin aloitat:
Käyttöliittymäikkunaan upotettu kuvaaja muodostuu kahdesta osasta: itse kuvaajasta, ja piirtoalueesta. Tekemämme ikkunasto-moduulin luo_kuvaaja-funktio palauttaa nämä molemmat, mutta sinun tehtäväsi on piirtää niihin. Ensin mainittu on matplolibin Figure-tyypin objekti, jonka dokumentaation löydät täältä. Ikkunoinnin vuoksi kuvaajaan tulee lisätä subplot (axes-tyyppinen objekti) - siihen ei voi piirtää suoraan.. Kuvaaja tulee kuitenkin varmuudella näkyviin vasta, kun piirtoalueobjektin draw-metodia kutsutaan - tämä tulee tehdä koodissa vaikka näkisit kuvaajan ilmankin.
Hiiren
käsittelijäfunktiolla
on sama toimintaperiaate kuin edellisen tehtävän napin käsittelijällä, mutta sillä on yksi parametri: hiiritapahtuma (dokumentaatio). Tapahtuma on
objekti
, jolla on muutamia tarpeellisia
attribuutteja
. Näistä tärkeimmät ovat:
  • x ja y, jotka kertovat missä kohtaa piirtoaluetta hiirtä klikattiin
  • button, joka kertoo mitä hiiren nappia klikattiin (1 = vasen, 2 = keski, 3 = oikea)
  • xdata ja ydata, jotka kertovat akselien arvot klikatussa pisteessä
Tehtävässä tarvitaan myös vastaava
sanakirja
kuin edellisessä, mutta johtuen sen laajemmasta luonteesta, vaihdettakoon sen nimeksi tila
, koska se kertoo yleisesti ohjelman tilasta. Sanakirjaan lisätään uusi arvain-arvo-pari, johon tallennetaan suorituksen aikana valitut datapisteet kahden alkion
monikkoina
.
tila = {
    "tekstilaatikko": None,
    "pisteet": []
}
1. toteutettava funktio: valitse_datapiste
  • Dokumenttimerkkijono
    :
"""
Ottaa vastaan hiiren klikkaustapahtuman ja lukee siitä datapisteen x- ja
y-arvot. Arvot tulosteetaan tekstilaatikkoon sekä talletetaan ohjelman
tilasanakirjassa olevaan pisteet-listaan.
"""
  • Parametrit
    :
    • hiiritapahtuma (matplotlibin MouseEvent-objekti)
Funktion tulee lukea saamastaan hiiritapahtumasta klikatun pisteen arvot akseleilla. Nämä löytyvät siis xdata- ja ydata-attribuuteista. Arvot tulostetaan käyttöliittymän tekstilaatikkoon kahden desimaalin tarkkuudella - katso viestin muoto suoritusesimerkeistä. Toiseksi tämä sama datapiste tulee lisätä tilasanakirjan pisteet-listaan monikkona. Tämä vaihe on tärkeä, koska lopputyössä on tarpeen pystyä jälkikäteen selvittämään mikä oli viimeisin valittu piste. Kun pisteet talletetaan tilasanakirjan sisällä, ne löytyvät sieltä kätevästi.
2. toteutettava funktio: main
  • Dokumenttimerkkijono:
"""
Luo käyttöliittymän, jossa on klikattava kuvaaja sekä tekstilaatikko. Kuvaajaan
piirretään käyrä parametreina saatujen data-arvojen perusteella.
"""
  • Parametrit:
    • x data (lista, sisältää liukulukuja)
    • y data (lista, sisältää liukulukuja)
Funktiolla on sama tarkoitus kuin edellisessä tehtävässä. Tällä kertaa käyttöliittymä tosin jaetaan kahteen kehykseen pystysuunnassạ. Ylempään kehykseen tulee kuvaaja, jonka lisäämistä voit ihmetellä luo_kuvaaja-funktion dokumenttimerkkijonosta. Käsittelijäfunktioksi asetetaan juuri tehty valitse_datapiste. Alempaan tulee tuttu tekstilaatikko. Lisäksi funktion tulee piirtää parametreina annettu data kuvaajaan.
Esimerkki lopputuloksesta löytyy suoritusesimerkeistä.
Toteutettava pääohjelma:
if __name__ == "__main__":
    datax = [0.0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0, 1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 1.7, 1.8, 1.9, 2.0]
    datay = [0.0, 0.19, 0.36, 0.51, 0.64, 0.75, 0.84, 0.91, 0.96, 0.99, 1.0, 0.99, 0.96, 0.91, 0.84, 0.75, 0.64, 0.51, 0.36, 0.19, 0.0]
    main(datax, datay)
Esimerkit toiminnasta:
Käyttöliittymän tulisi näyttää suurinpiirtein tältä. Mittasuhteet voivat erota
Varoitus: Et ole kirjautunut sisään. Et voi vastata.

Koodarin kompleksi

Jo aiemmin opittiin, että Python käsittelee kompleksilukuja oikein mielellään. Viimeksi niitä käsiteltiin komentorivillä, mutta mitenkä sujuukaan lukujen kysely graafisessa käyttöliittymässä? Piiri pieni pyörii -tehtävässä tätä saatetaan tarvita, joten asia on syytä opetella. Opetellaan samalla virheilmoitusten antamista.
Opittavat asiat: Käyttäjän syötteiden pyytäminen ja käsittely graafisessa käyttöliittymässä.
Tavoite: Ohjelma, joka laskee kompleksiluvun osoitinmuodon.
Ennen kuin aloitat:
Voit käyttää pohjana edellisen tehtävän käyttöliittymää. Tekstilaatikon lisäksi ohjelmassa on nyt toinen dynaaminen komponentti: tekstikenttä, johon käyttäjä voi syöttää kompleksiluvun. Toimitaan samoin kuin aiemminkin, eli tallennetaan viittaus tähän tekstikenttään sanakirjaan, jotta siihen päästään käsittelijäfunktioissa käsiksi kätevästi. Määritellään siis ohjelman alkuun seuraavanlainen sanakirja:
elementit = {
    "tekstilaatikko": None,
    "tekstikentta": None
}
1. toteutettava funktio: muuta_osoitinmuotoon
  • Dokumenttimerkkijono
    :
"""
Lukee kompleksiluvun syötekentästä ja muuttaa sen osoitinmuotoon, jossa
osoittimen kulma on esitetty asteina. Kompleksiluku sekä sen osoitinmuoto
tulostetaan käyttöliittymässä olevaan tekstilaatikkoon.
"""
Tämä on käsittelijäfunktio, joten sillä ei ole parametreja eikä se palauta mitään. Syöte luetaan tekstikentästä, johon päästään käsiksi elementit-sanakirjan kautta (ikkunasto-moduulissa on lukemiseen oma funktionsa). Mikäli käyttäjän antama syöte ei ole kelvollinen kompleksiluku, avataan viesti-ikkuna, joka kertoo käyttäjälle virheestä. Tähänkin löytyy funktio ikkunastosta.
Muunnoksessa tarvittava
funktio
on jo tuttu. Kulma täytyy jälleen kerran muuntaa asteiksi. Lopputulos kirjoitetaan käyttöliittymän tekstilaatikkoon esimerkkien mukaisessa muodossa. Kaikki liukuluvut esitetään kolmen desimaalin tarkkuudella.
Riippumatta siitä onnistuiko muunnos vai ei, käsittelijäfunktion tulisi lopuksi tyhjätä syötekentän sisältö.
2. toteutettava funktio: main
  • Dokumenttimerkkijono
"""
Luo käyttöliittymäikkunan, jossa on vasemmalla tekstikenttä otsikoineen, kaksi nappia (muunnosnappi ja quit) ja oikealla tekstilaatikko.
"""
Pääohjelmafunktio pohjautuu edelliseen. Uusina lisäyksinä lisäämme vasempaan kehykseen tekstikentän syötteitä varten sekä sen yläpuolelle ohjeistavan tekstirivin (jossa lukee esim. "Kompleksiluku:"). Muista sijoittaa tekstikentän luontifunktion palauttama arvo elementit-sanakirjaan, jotta tekstikentän sisältö voidaan lukea muissa ohjelman osissa. Testinappi korvataan muunnosnapilla, jonka käsittelijäksi asetetaan juuri tehty muunnosfunktio.
Toteutettava pääohjelma:
if __name__ == "__main__":
    main()
Esimerkit toiminnasta:
Esimerkki toiminnasta, kun käyttäjä syöttää kompleksiluvun.
Esimerkki toiminnasta, kun käyttäjä syöttää jotain muuta.
Varoitus: Et ole kirjautunut sisään. Et voi vastata.

Lopputyötehtävät 3

Näistäkin voi yhden valita.

Tulvatutkimus

Tulvatäyttö on perusalgoritmi, jolla on kaikenlaista käyttöä ohjelmoinnissa. Sillä voidaan mm. selvittää rajattujen, mielivaltaisen muotoisten alueiden pinta-ala. Myös piirto-ohjelmien täyttötoiminto perustuu siihen. Lisäksi tulvatäytöllä voi vaikka navigoida labyrintteja tai laskea kuinka pitkälle pelihahmo voi liikkua vuorossa vaihtelevassa maastossa. Sattumoisin sillä on käyttöä myös Miinojen tallaamisessa, jossa pitäisi avata tyhjiä ruutuja räjähdysmäisesti joka suuntaan, mutta paljastamatta miinoja. Algoritmi ei ole ihan sieltä helpoimmasta päästä keksiä itse ilman ohjelmointikokemusta, joten olemme poikkeuksellisesti kuvanneet tehtävänantoon varsin tarkasti miten tulvatäyttö etenee.
Tässä tehtävässä luotainrobotti tutkii planeetan pintaa ja merkitsee tuntemattomia alueita turvallisiksi, välttäen aiemman skannauksen tutkimat vaaralliset ruudut.
Opittavat asiat: Tulvatäyttöalgoritmin toiminta ja yleisesti hieman monimutkaisempien algoritmien toteuttaminen Pythonilla. Poistojen tekeminen listasta siten, että ohjelma ei muutu jäätävän hitaaksi.
Tavoite: Ohjelma, joka tutkii toisiinsa yhteydessä olevat tuntemattomat ruudut kartalta.
Ennen kuin aloitat:
Tehtävässä voit piirtää kentän näkyviin samalla tavalla kuin miinoitus-tehtävässä - ota siis siellä tehty piirra_kentta-funktio käyttöön. Myös main-funktio toimii suurin piirtein sellaisenaan (ks. alla).
1. toteutettava funktio: tulvataytto
  • Dokumenttimerkkijono
    :
"""
Merkitsee planeetalla olevat tuntemattomat alueet turvalliseksi siten, että
täyttö aloitetaan annetusta x, y -pisteestä.
"""
  • Parametrit
    :
    • täytössä käytettävä planeetta (2-ulotteinen
      lista
      )
    • täytön aloituspisteen x-koordinaatti (kokonaisluku)
    • täytön aloituspisteen y-koordinaatti (kokonaisluku)
Planeetan kartta sisältää kahdenlaisia merkkejä: tuntemattomia (" ") ja vaarallisia ("x"). Turvallista kuvataan "0"-merkillä. Tehtävänä on korvata aloituspisteesta alkaen kaikki toisiinsa kosketuksissa olevat tuntemattomat alueet turvallisella. Jos tutkimusta yritetään aloittaa vaarallisen ruudun kohdalta kohdalta, ei tehdä mitään. Funktion toteutuksessa tulee seurata allakuvattua algoritmia hyvin tarkasti. Äläkä ainakaan käytä
rekursiota
(tiedät käyttäväsi rekursiota, jos kutsut tulvataytto-funktiota sen itsensä sisältä).
Tulvatäyttö aloitetaan luomalla uusi lista, jossa on alkiona yksi
monikko
, joka sisältää täytön aloituspisteen
. Tämän jälkeen mennään
silmukkaan
, jossa pyöritään niin kauan, että kaikki täytettävät alueet on täytetty. Yksi silmukan
kierros
etenee seuraavasti:
  1. Otetaan listasta ulos yksi koordinaattipari käsiteltäväksi (huom. se poistetaan listasta) - tähän on olemassa oma listametodinsa.
  2. Merkitään se turvalliseksi, eli merkitään planeettaan siihen kohtaan "0"
  3. Käydään vuorotellen läpi kaikki viereiset ruudut (8 kpl) (huomioiden planeetan reunat!) (ks. viime kerran ninja-tehtävä)
  4. Jos viereinen ruutu on tuntematon, lisätään se koordinaattiparilistaan
Näin siis koordinaattipareja sisältävä lista kasvaa sitä mukaa kun sitä käydään läpi, ja tyhjenee aivan tyhjäksi asti vasta kun kaikki toisiaan koskettavat tuntemattomat alueet on tutkittu. Turvalliseksi merkitseminen tapahtuu siis silmukan kierroksen alussa; koska koordinaattipari on aiemmalla kierroksella lisätty merkittävien listaan, tiedetään varmuudella, että sen osoittamasta ruudusta löytyy tuntematon ruutu (kohdan 4 tarkistuksen vuoksi).
Funktio ei palauta mitään.
2. toteutettava funktio: main
  • Dokumenttimerkkijono:
"""
Lataa pelin grafiikat, luo peli-ikkunan ja asettaa siihen piirtokäsittelijän.
"""
  • Parametrit:
    • planeetta (kenttää kuvaava lista, ks. alempana)
Funktio pohjautuu miinoitustehtävän main-funktioon. Huomaamme kuitenkin, että alla esitetty planeetta ei mahdu nätisti 600x400 ikkunaan. Muuta siis ikkunan kokoa sopivaksi - kaikkein parhaiten tämä onnistuu, kun mittaat len-funktiolla kentän dimensiot ja kerrot ne yhden spriten dimensioilla.
Toteutettava pääohjelma:
Testausta varten kannattaa tehdä
pääohjelma
, jossa kutsutaan luotuja funktioita. Pääohjelmassa voit määritellä seuraavan planeetan:
planeetta = [
    [" ", " ", " ", "x", " ", " ", " ", " ", " ", " ", " ", "x", " "], 
    [" ", " ", "x", "x", " ", " ", " ", "x", " ", " ", " ", "x", " "], 
    [" ", "x", "x", " ", " ", " ", " ", "x", " ", " ", "x", "x", " "], 
    ["x", "x", "x", "x", "x", " ", " ", "x", " ", "x", " ", " ", " "], 
    ["x", "x", "x", "x", " ", " ", " ", " ", "x", " ", "x", " ", " "], 
    [" ", " ", "x", " ", " ", " ", " ", " ", " ", "x", " ", " ", " "]
]
Kutsu sitten tulvataytto-funktiota sopivalla aloituspisteellä. Kutsu lopulta myös main-funktiota, jotta näet miten tulvatäyttö toimii.
Nopeusvaatimukset:
Poiketen kaikista muista tehtävistä kurssilla, tässä tehtävässä liian hidas koodi hylätään. Tiedät näin käyneen, jos tarkistuksessa lukee jotain tyyliin "Stopped responding and timed out after 10,01 seconds." suoritettavan komennon alla ja itse tarkistustulos jää tyhjäksi. Hitauden syynä on yleensä poistojen tekeminen listasta. Jos listasta poistetaan alusta tai välistä alkioita, tämä aiheuttaa massiivisen siirto-operaation jossa kaikkia listan alkioita poistokohdasta eteenpäin joudutaan siirtämään yhdellä alkua kohti. Pienillä kentillä eroa ei huomaa, mutta tarkistimen kokeilemalla 100x100 kentällä kyllä. Poistot pitää siis tehdä listan lopusta.
Lisäksi remove ei ole hyvä metodi, koska se poistaa sille annetun alkion ensimmäisen esiintymän listasta. Algoritmissa kuitenkin samoista koordinaattipareista päätyy useita kopioita listaan, joten vaikka poistaisit removella viimeisen alkion, todennäköisimmin sen alkion jokin kopio poistetaan aiemmasta kohtaa listaa. Tutki siis listojen metodeja ja etsi paremmin tähän tehtävään soveltuva metodi.
Toinen vaihtoehto liian pitkälle suoritusajalle on se, että teet
ikuisen silmukan
esim. siten, että algoritmi käy läpi uudestaan ruutuja jotka se on jo kerran käynyt läpi ja jää siten pyörimään kehää.
Varoitus: Et ole kirjautunut sisään. Et voi vastata.

Datakaivuri kaatopaikalla

Tässä tehtävässä harjoitellaan kaikkeen datan käsittelyyn liittyvää tärkeää perustaitoa, eli datatiedostojen lukemista. Olet saanut tehtävänannon koodaustaidottomalta tutkijalta. Lisäksi tutkija, joka koodia on sinulta pyytänyt, on aivan uskomattoman organisointikyvytön, joten datakansioissa voi olla vaikka mitä roskaa kuten kuvia. Lisäksi osa datatiedostoistakin on rikki. Yleisesti ottaen olisi hyvä, että dataa lukevat ohjelmat pystyvät löytämään oikean datan hieman epämääräisemminkin järjestetyistä kansioista, koska ohjelman rajoituksia on vaikea pitää mielessä kun kiintolevylle tallentelee juttuja tavisten tapaan miten sattuu.
Opittavat asiat: Datan lukeminen useasta
tiedostosta
ohjelman sisälle
tietorakenteisiin
. Virheellisten datatiedostojen selvittäminen ja oikeaoppinen tapa käsitellä niitä. Datarivien lukeminen.
Tavoite: Ohjelma, joka lukee dataa useasta tiedostosta muistiin.
Ennen kuin aloitat:
Jotta tehtävän tekeminen olisi mielekästä, alla on annettu ohjelma, joka luo hakemiston, jossa on satunnaisia datatiedostoja. Kaikki ohjelman tekevät datatiedostot ovat ehjiä, joten sinun tulee käydä itse rikkomassa osa niistä. Samalla voit kopioida kansioon vaikka lomakuvasi koodin ihmeteltäväksi. Aja tämä ohjelma siis terminaalissa ja anna sille
komentoriviargumentiksi
kansio johon haluat puskea datatiedostot.
generoi_data.py
import os
import sys
import random

NIMET = ["Muumipappa", "Hemuli", "Haisuli", "Nipsu", "Pikachu", "Bulbasaur", "Nalle Puh", "Ihaa", "Eunji", "Tomomi", "Haruna", "Seungyeon", "Ihsahn", "Abbath", "Fenriz"]

MERKIT = "abcdefghjiklmnopqrstuvwxyz"

def luo_data(kansio):
    os.makedirs(kansio, exist_ok=True)
    for i in range(10):
        with open(os.path.join(kansio, "".join([random.choice(MERKIT) for x in range(random.randint(4, 10))]) + ".mydat"), "w") as kohde:
            for i in range(random.randint(4, 20)):
                kohde.write("{},{:.4f},{:.4f}\n".format(
                    random.choice(NIMET),
                    random.random() * 1000,
                    random.random() * 100
                ))                
    
if __name__ == "__main__":
    try:
        luo_data(sys.argv[1])
    except IndexError:
        print("Ohjelman käyttö:")
        print("python generoi_data.py kansio")    

Kopioi myös Ihan tavallinen ikkuna -tehtävästä main-funktio.
1. toteutettava funktio: lue_data
  • Dokumenttimerkkijono
    :
"""
Lukee kaikki datatiedostot annetusta kansiosta. Ohittaa tiedostot, jotka eivät
ole päätteeltään .mydat sekä tiedostot, joiden sisältämässä datassa on
virheitä. Rikkinäisten tiedostojen nimet ilmoitetaan käyttäjälle.
"""
  • Parametrit
    :
    • luettavan kansion polku (
      merkkijono
      )
  • Palauttaa
    :
    • Datatiedostojen sisällön
      tietorakenteena
      (lista, joka sisältää 3 alkion monikkoja)
    • Virheellisten .mydat-tiedostojen nimet (lista merkkijonoja)
Funktion tulee käydä läpi annetun kansion sisältämä hakemistopuu ja etsiä sieltä kaikki .mydat-tiedostot ja lukea niiden sisältö (muut tiedostot ohitetaan!) Data luetaan ohjelman käyttämään tietorakenteeseen vasta kun saavutaan kunkin tiedoston loppuun. Mikäli ennen loppua kohdataan virheellinen rivi, kaikki tiedostossa ollut data hylätään ja tiedoston nimi lisätään virheellisten listaan. Oikeanlaiset datarivit näyttävät tältä:
Hammie,154.3578,12.9402
Eli rivillä on kolme pilkulla erotettua arvoa, joista ensimmäinen on aina merkkijono. Kukin datarivi luetaan
monikoksi
, joka sisältää merkkijonon ja kaksi
liukulukua
, esim:
("Hammie", 154.3578, 12.9402)
Nämä monikot kannattaa tallentaa ensin tilapäiseen listaan, ja lisätä vasta tiedoston lopussa varsinaiseen datalistaan. Tämä datalista palautetaan, kun kaikki tiedostot on luettu. Huomaa myös, että tiedostoissa saattaa olla lopussa tyhjä rivi tai sitten ei. Ratkaisutavasta riippuen tämä saattaa vaatia ylimääräistä käsittelyä.
2. toteutettava funktio: avaa_kansio
  • Dokumenttimerkkijono:
"""
Napinkäsittelijä, joka pyytää käyttäjää valitsemaan kansion avaamalla
kansioselaimen. Lataa datan valitusta kansiosta ja ilmoittaa käyttöliittymän
tekstilaatikkoon montako riviä luettiin sekä virheellisten tiedostojen nimet.
"""
Funktion tulee avata hakemistoselain (ikkunasto-moduulin funktiolla), ja käyttää sen palauttamaa arvoa lue_data-funktion argumenttina. Kun data on luettu, tekstilaatikkoon kirjoitetaan kaikkien viallisten tiedostojen nimet (esim. "Viallinen tiedosto: x") sekä lopulta luettujen datarivien määrä (ts. palautetun datalistan pituus).
Muutettava funktio: main
Vaihda testinapin tekstiksi "lataa" tai jotain muuta kuvaavaa, ja käsittelijäksi juuri tehty avaa_kansio.
Toteutettava pääohjelma:
if __name__ == "__main__":
    main()
Esimerkit toiminnasta:
Esimerkkikuva
Varoitus: Et ole kirjautunut sisään. Et voi vastata.

Piirillinen vastuksia

Tässä tehtävässä tutustutaan yksinkertaisten piirikaavioiden piirtämiseen käyttöliittymäikkunaan. Vähemmän yllättäen tätä taikuutta tarvitaan piirilopputyössä. Tehtävässä käyttäjä syöttää piiriin vastuksia, ja piirikaavioita päivitetään sitä mukaa kun siihen lisätään jotain. Käytössä on tälläkin kertaa apukirjasto, joka yksinkertaistaa prosessin alkeiskurssille sopivalle tasolle.
Opittavat asiat: Kurssin piiristo-moduulin käyttö piirikaavioiden piirtämiseen. Piirin komponenttien kysely ja tallentaminen graafisessa käyttöliittymässä.
Tavoite: Ohjelma, jolla syötetään sarjaan kytkettyjä vastuksia, ja joka piirtää niistä piirikaavion jännitelähteen kera.
Asennettava moduuli: SchemDraw
Piirien piirtelyssä taustalla toimii SchemDraw-moduuli. Asennus menee samalla tavalla kuin matplotlibin kohdalla, eli pip install SchemDraw. Kirjastoon voit tutustua sen dokumentaatiossa, mutta tehtävän tekemisen kannalta tämä ei ole tarpeen, koska käytämme omaa apukirjastoa.
Ennen kuin aloitat:
Tarvitset kaksi kurssia varten tehtyä moduulia: piiristo-moduulin, joka tarjoaa funktiot piirien piirtelyyn, sekä SchemCanvas-palikan, jonka avulla SchemDraw saadaan piirtämään käyttöliittymäikkunan sisälle. Tutustu piiristo-moduulin toimintaan lukemalla sieltä löytyvät dokumentaatiomerkkijonot. SchemCanvas-moduuliin ei ole tarpeen tutustua - sen sisältö menee alkeiden ulkopuolelle.
piiristo.py
SchemCanvas.py
Ohjelman alkuun on jälleen tarpeen määrittää sanakirja, johon talletetaan arvoja sekä viittauksia suorituksen aikana.
tila = {
    "syote": None,
    "laatikko": None,
    "piiri": None,
    "komponentit": [],
    "jannite": 0,
    "taajuus": 0,
}
1. toteutettava funktio: aseta_jannite
  • Dokumenttimerkkijono
    :
"""
Lukee liukulukuarvon syötekentästä ja asettaa sen piirin jännitelähteen
jännitteeksi.
"""
Käsittelijäfunktio, joka yrittää lukea liukulukuarvon syötekentästä ja tallentaa arvon tilasanakirjaan. Jos syötekentässä ei ole liukulukuarvoa, annetaan virheilmoitus edellisestä tehtävästä tutulla viesti-ikkunalla. Syötekenttä on ystävällistä myös tyhjätä kun arvo on luettu. Lisäksi kirjoitetaan tekstilaatikkoon, että jännitelähteen jännite on asetettu annettuun arvoon.
2. toteutettava funktio: aseta_taajuus
  • Dokumenttimerkkijono:
"""
Lukee liukulukuarvon syötekentästä ja asettaa sen piirin jännitelähteen
taajuudeksi.
"""
Sama kuin edellinen, mutta taajuudelle.
3. toteutettava funktio: lisaa_vastus
  • Dokumenttimerkkijono:
"""
Lukee liukulukuarvon syötekentästä, ja lisää vastuksen, jonka resistanssi on
luettu arvo, piirissä olevaan ainoaan haaraan. Päivittää piirikaaviokuvan.
"""
Sama kuin aiemmat, mutta arvon tallentamisen sijaan komponentit-listaan lisätään uusi alkio: kahden arvon monikko, jossa ensimmäinen arvo on "r" ja jälkimmäinen luettu liukulukuarvo. Vastuksen lisäämisen jälkeen piirikaaviokuva tulee päivittää käyttämällä piiristo-moduulin funktioita piirra_jannitelahde, piirra_haara ja piirra_piiri.
SchemDraw on suunniteltu alunperin valmiiden piirien piirtämiseen, joten joka kerta kun kuvaa halutaan "päivittää", se vedetään tyhjäksi ja piirretään uudestaan. Koska tässä tehtävässä sekä lopputyössä piiri alkaa aina jänniteläheestä, tämä nollaus tapahtuu kun piirra_jannitelahde-funktiota kutsutaan. Haarat piirretään yksi kerrallaan. Tekemämme piiristo-moduuli huolehtii pääasiassa komponenttien asettelusta, mutta jonkin verran voit joutua säätelemään myös itse (tosin vasta lopputyössä - tämän tehtävän piirtelyt ovat aika suoraviivaisia). Nämä funktiot vasta valmistelevat piirin - ruudulle piirto tapahtuu vasta kun kutsut piirra_piiri-funktiota.
Tutustu mainittujen funktioiden dokumentaatioon, jotta ymmärrät toiminnan yksityiskohdat.
Virheellisestä syötteestä annetaan edelleen virheilmoitus viesti-ikkunan kautta.
4. toteutettava funktio: main
  • Dokumenttimerkkijono:
"""
Luo käyttöliittymäikkunan, jossa on vasemmalla puolella syötekenttä
numeroarvoille, neljä nappia ja tekstilaatikko. Oikealla puolella on
piirikaaviokuva.
"""
Käyttöliittymä luodaan samalla tavalla kuin aiemmissa tehtävissä. Napit kytketään juuri tehtyihin funktioihin. Viittaukset syötekenttään, tekstilaatikkoon sekä piirikaavioon tallennetaan tilasanakirjaan. Tekstilaatikon ja piirikaavion mittasuhteet on hyvä asettaa itse.
Toteutettava pääohjelma:
if __name__ == "__main__":
    main()
Esimerkit toiminnasta:
Käyttöliittymän tulisi näyttää suurinpiirtein tältä.
Varoitus: Et ole kirjautunut sisään. Et voi vastata.
?
  1. Kuvaus
  2. Esimerkit
Absoluuttinen polku (absolute path) on käyttöjärjestelmäkäsite, joka kertoo hakemiston "koko osoitteen". Absoluuttinen polku ilmaistaan levyaseman juuresta lähtien joten se ei ole riippuvainen siitä mikä on aktiivinen hakemisto. Absoluuttisia polkuja pyritään yleensä välttämään koodissa, erityisesti jos tarkoitus on tehdä koodia jota joku muukin saattaa käyttää. Toinen käyttäjä ei välttämättä sijoita tiedostoja juuri täsmälleen samanlaiseen hakemistorakenteeseen kuin olet omalla koneellasi tehnyt. Erityisesti jos tiedostosi yleensä asuvat kotihakemistossa, pelkästään absoluuttisessa polussa oleva eri käyttäjänimi sotkee kaiken jonkun muun koneella.
Ajonaikaisesta (engl. run time) puhuttaessa määreenä on se aikaväli, kun ohjelma on käynnissä. Esimerkiksi Pythonissa virheet (syntaksivirheitä lukuun ottamatta) tarkastetaan ajonaikaisesti. Ohjelma saattaa siis olla käynnissä ja toimia tiettyyn pisteeseen saakka, kunnes törmätään käsittelemättömään poikkeukseen – ajonaikaiseen virheeseen (engl. run time error).
  1. Kuvaus
  2. Esimerkit
Alkio (engl. item, element) on listan tai muun tietorakenteen sisältämä yksittäinen arvo. Useimmiten alkioista puhutaan juuri listojen yhteydessä. Tällöin alkiolla on arvon lisäksi paikka eli indeksi, joka kertoo sen sijainnin listassa etäisyytenä listan alusta. Niinpä siis listan ensimmäisen alkion indeksi on 0.
  1. Kuvaus
  2. Esimerkit
Alustamisella (engl. initialize) tarkoitetaan yleisesti jonkin arvon asettamista muuttujalle muuttujan luonnin yhteydessä. Pythonissa ei ole mahdollista luoda muuttujaa, jolla ei ole myös jotain arvoa. Niinpä tyypillisesti käytetäänkin sanamuotoa ”muuttuja alustetaan arvolla x”, millä tarkoitetaan sitä, että muuttuja, joka luodaan, saa luomisen yhteydessä (eikä vasta joskus myöhemmin) arvon x.
  1. Kuvaus
  2. Esimerkit
Argumentti (engl. argument) on funktiokutsussa käytettävä arvo, joka välitetään kutsuttavalle funktiolle. Funktiokutsun alkaessa argumentit sijoitetaan parametreiksi kutsuttuihin muuttujiin, joiden kautta arvoihin pääsee funktion sisällä käsiksi.
Arvo (engl. value) on konkreettista, tietokoneen muistissa sijaitsevaa tietoa, jota käytetään ohjelman suorituksen aikana. Arvoilla on tyyppi ja sisältö; esimerkiksi numero 5 on tyypiltään kokonaisluku, jonka sisältö on 5. Useimmiten arvot liitetään muuttujiin, mutta myös operaatioiden ja funktiokutsujen paluuarvot sekä koodissa sellaisenaan esiintyvät arvot ovat arvoja. Käytännössä siis kaikkea konkreettista mitä ohjelma käsittelee voidaan kutsua arvoiksi.
  1. Kuvaus
  2. Esimerkit
Avain (engl. key) on ikään kuin sanakirjan ”indeksi”, eli sillä valitaan yksittäinen arvo tietorakenteen sisältä. Kutakin avainta vastaa yksi arvo. Avaimina käytetään yleensä merkkijonoja, mutta ne voivat olla mitä tahansa muuntumattomia tietotyyppejä, kuten lukuja tai monikkoja.
  1. Kuvaus
  2. Kurssin avainsanat
Avainsanat (engl. keyword) ovat ohjelmointikielessä kielen käyttöön varattuja sanoja, joilla on erityinen merkitys. Hyvät tekstieditorit tyypillisesti merkitsevät avainsanat muista nimistä eroavalla tavalla (esimerkiksi lihavoinnilla tai tietyllä värillä). Avainsanat ovat yleensä suojattuja, eli samannimisiä muuttujia ei voi luoda. Yleisiä avainsanoja Pythonissa ovat esimerkiksi funktioihin liittyvät def ja return. Avainsanat ovat siis osa ohjelmointikielen kielioppia.
  1. Kuvaus
  2. Esimerkit
Avainsana-argumentti-termiä (engl. keyword argument, lyh. kwarg) käytetään, kun funktio- tai metodikutsussa argumentteja annetaan sijoittamalla niitä parametrien nimiin. Tätä käytetään erityisesti format-metodin yhteydessä: "Hei {nimi}".format(nimi="hemuli"). Toinen yleinen käyttötapaus on silloin, kun kutsutulla funktiolla on paljon valinnaisia argumentteja ja näistä vain osa halutaan määrittää. Avainsana-argumentin käyttö voi myös selkeyttää koodia, erityisesti sellaisten argumenttien kohdalla joille annetaan arvoksi True tai False.
  1. Kuvaus
  2. Esimerkit
Avausmoodilla kerrotaan Pythonille (ja käyttöjärjestelmälle) millä tavalla tiedosto avataan. Tiedosto voidaan avata lukemista tai kirjoittamista varten. Oletuksena, eli jos avausmoodia ei erikseen määritellä, tiedosto avataan lukumoodissa ("r"). Kirjoitusmoodeja on kaksi:
  • "w", eli write, joka kirjoittaa tiedoston sisällön puhtaalta pöydältä hävittäen mahdollisesti aiemmin olemassa olleen saman nimisen tiedoston.
  • "a", eli append puolestaan kirjoittaa olemassaolevan tiedoston loppuun.
Molemmat kirjoitusmoodit luovat tiedoston, jos sitä ei vielä ole olemassa.
Siinä missä UNIX-pohjaiset järjestelmät tuottavat \n-merkkejä rivinvaihdoiksi, Windows tuottaa \r\n-rivinvaihtoja, joissa r on carriage return -merkki. Se on kirjoituskoneiden peruja ja tarkoittaa toimenpidettä, jossa kirjoituspää siirretään takaisin rivin alkuun. Yleisesti ottaen tämä on lähinnä asia, joka on hyvä tietää – Python käsittelee molempia rivinvaihtoja kiltisti.
Data (engl. data) on ohjelmoinnin asiayhteydessä mitä vaan tietoa, joka ei kuitenkaan yleisesti kata itse ohjelmakoodia. Yleensä datasta puhuttaessa tarkoitetaan yksittäisiä literaaliarvoja, muuttujien sisältämää tietoa tai jostain tietolähteestä (kuten tiedostosta tai verkko-osoitteesta) luettua tai sinne kirjoitettua tietoa. Nyrkkisääntönä voi kuitenkin pitää sitä, että koodi ja data ovat eri asioita, ja koodi käsittelee dataa. (Joissain yhteyksissä koodikin lasketaan dataksi, mutta näihin ei tällä kurssilla syvennytä.)
Debuggaus (engl. debugging) tarkoittaa ohjelmointivirheiden – bugien – jäljittämistä ja korjaamista. Bugien jäljille pääsemiseen on monia eri tapoja, joista ehkä hyödyllisimpänä Python tarjoaa ohjelman kaatumisen yhteydessä näytettävät virheviestit. Myös debug-printit ovat tavanomainen keino virheiden paikantamiseen; kyseessä on print-komentojen ripottelu koodiin väliaikaisesti esimerkiksi sen selvittämiseen, mihin asti koodin suoritus pääsee, tai muuttujien arvojen tutkimiseen ajonaikaisesti. Debuggaus on niin oleellinen osa ohjelmointia, että sitä varten on kehitetty myös erikseen työkaluja, joita kutsutaan debuggereiksi. Debuggereihin emme kuitenkaan tällä kurssilla koske.
Pythonissa dokumenttimerkkijono (engl. docstring) on kommentin kaltainen merkintä, mutta sillä on oma erityistarkoituksensa. Dokumenttimerkkijono merkitään yleensä kolmella lainausmerkillä (eli '''dokumentti''' tai """dokumentti""". Jos dokumenttimerkkijono on sijoitettu funktion def-rivin alapuolelle (sisennettynä), siitä tulee funktion dokumentaatio, jonka saa esiin help-funktiolla tulkissa. Samoin kooditiedoston alkuun sijoitettu dokumenttimerkkijono muuttuu moduuliin dokumentaatioksi. Dokumenttimerkkijonossa on hyvä kertoa funktion toimintaperiaate sekä selittää mitä sen parametrit ja paluuarvot ovat.
Dokumenttimerkkijonoja ei tule käyttää kommenttien sijasta! Muualla kuin edellä mainituissa paikoissa kommentointiin tulee käyttää kommentteja (eli #-merkillä alkavia rivejä)
  1. Kuvaus
  2. Esimerkit
Ehto-nimitystä (engl. condition) käytetään tällä kurssilla ehtolauseiden ja while-silmukoiden siitä osasta, joka määrittelee milloin lause on tosi ja milloin epätosi. Ehtoa on siis kaikki joka on ehtolauseen aloittavan avainsanan (if tai elif) ja sen päättävän kaksoispisteen välissä.
  1. Kuvaus
  2. Esimerkit
Ehtolause (engl. conditional statement) on yksittäisen ehdon määrittelevä rivi koodissa, jota seuraa sisennetty koodilohko, joka määrittää miten ehdon toteutuessa tulee toimia. Varsinaisia ehtolauseita ovat if- ja elif-lauseet, joista jälkimmäinen ei voi esiintyä ilman ensimmäistä. Toisiinsa liitetyt ehtolauseet muodostavat ehtorakenteita. Ehtolause päättyy aina kaksoispisteeseen, ja tämän kaksoispisteen jälkeen on seurattava vähintään yksi sisennetty koodirivi.
  1. Kuvaus
  2. Esimerkit
Ehtorakenne (engl. conditional structure) on yhdestä tai useammasta toisiinsa liitetystä ehtolauseesta muodostuva rakenne, joka haarauttaa ohjelman suoritusta. Useimmissa ehtorakenteissa on vähintään kaksi haaraa: if ja else. Näiden välissä voi olla myös mielivaltainen määrä elif-lauseilla aloitettuja haaroja. On myös mahdollista, että ehtorakenteessa on pelkkä if-lause. Ehtorakenteessa kussakin haarassa on suoritettavaa koodia, joka kuvaa miten ohjelman tulee ehdon määrittelemässä tilanteessa toimia.
Kokonaisuudessaan ehtorakenne käydään läpi siten, että ensin tarkistetaan järjestyksessä ensimmäisen, eli if-lauseen, ehdon paikkansapitävyys. Jos ehto evaluoitui totuusarvoon True, ohjelman suoritus jatkuu kyseisen if-lauseen lohkosta, jonka suorituksen jälkeen siirrytään koko lopun ehtorakenteen ohi. Jos ehto taas evaluoitui Falseksi, käydään järjestyksessä ehtolauseita läpi toistaen samaa kuin ensimmäisen if-lauseen kohdalla, ja jos mikään ehto ei ollut paikkansapitävä, suoritetaan else-lauseen lohko.
Epätosi (engl. false) on toinen kahdesta mahdollisesta totuusarvosta ja toisen, eli toden, vastakohta. Sitä voidaan pitää lopputuloksena loogisissa ja vertailuoperaatorioissa, jotka eivät pidä paikkansa. Esimerkiksi vertailuoperaatio 5 < 4 ei pidä paikkansa, joten kyseinen operaatio evaluoituu epätodeksi. Pythonissa epätotta merkitään avainsanalla False.
  1. Kuvaus
  2. Esimerkit
Erotin (engl. separator) on merkkijonoihin ja tekstitiedostoihin liittyvä termi. Sillä tarkoitetaan tiettyä merkkiä, joiden kohdilta merkkijono on tarkoitus katkaista, kun se luetaan koodiin. Esimerkiksi, jos merkkijono sisältää tietoja, jotka on tarkoitus lukea listaan, erotin erottelee merkkijonon osat alkioiksi. Koodissa käytetään usein merkkijonojen split-metodia näissä tilanteissa – metodilla voidaan siis pätkiä erottimien kohdilta merkkijono listaksi.
Evaluointi (engl. evaluation) tarkoittaa lausekkeen tai muuttujan arvon lopputuloksen määrittämistä. Suoritettaessa lauseet evaluoituvat joksikin tietyksi arvoksi.
Exception on yleisimpien poikkeusten pääluokka. Kutsumme sitä Pokémon-poikkeukseksi, koska jos sitä käyttää try-except-rakenteessa, except ottaa kiinni kaikki poikkeukset. Tämä ei ole hyvä asia, koska se tekee vikatilanteiden tulkitsemisen vaikeammaksi sekä ohjelman käyttäjälle, että koodarille itselleen – se ottaa nimittäin kiinni myös ohjelmointivirheet, jolloin et saa mitään hyödyllistä tietoa ohjelman kaatuessa.
  1. Kuvaus
  2. Esimerkit
Merkkijonojen format-metodi on Pythonissa tehokas tapa sisällyttää muuttujien arvoja tulostettavaan tai tallennettavaan tekstiin. Merkkijonoon määritetään paikanpitimiä (esim: {:.2f}) joihin sijoitetaan format-metodin argumentit. Esimerkki: "Aasin korvien väli on {:.2f} tuumaa".format(mittaus).
  1. Kuvaus
  2. Esimerkit
Funktio (engl. function) on ohjelmassa oleva itsenäinen kokonaisuus, joka muodostuu määrittelyrivistä (def-lauseella) sekä funktion suoritettavista koodiriveistä. Funktioita käytetään selkeyttämään ohjelman rakennetta sekä koodin toiston välttämiseen. Funktiot kommunikoivat keskenään ja pääohjelman kanssa funktion parametrien sekä paluuarvojen välityksellä. Funktion sisällä määritetyt muuttujat (ml. parametrit) ja muut nimet ovat olemassa ainoastaan funktion sisällä. Vastaavasti funktioiden ei pitäisi lukea arvoja itsensä ulkopuolelta.
  1. Kuvaus
  2. Esimerkit
Funktiokutsu (engl. function call) on menetelmä, jonka seurauksena ohjelman suoritus ”hyppää” toiseen kohtaan koodia – sen funktion alkuun, jota kutsutaan. Funktiota kutsuttaessa sillä annetaan sulkeissa argumentit, joihin funktiolohkon koodista käsin pääsee käsiksi funktiomäärittelyn vastaavista kohdista löytyvien parametrien kautta. Funktion suoritus päättyy, kun törmätään funktion loppuun tai return-lauseeseen. Tällöin ohjelmakoodin suoritus palaa takaisin edelliseen kohtaan, eli sinne, mistä funktiota kutsuttiin, ja funktiokutsu korvautuu funktion paluuarvolla.
Toisin sanoen kutsumalla saadaan yksi ohjelman osa käyttämään toista – esimerkiksi pääohjelma funktiota tai funktio toista funktiota.
  1. Kuvaus
  2. Esimerkit
Funktioiden määrittely tapahtuu def-lauseella, jonka yhteydessä annetaan nimi funktiolle sekä sen parametreille. Kaikkien näiden valinta on oleellinen osa hyvän ja yleiskäyttöisin funktion kirjoittamista. Nimi tulisi valita siten, että se kuvaa mahdollisimman hyvin mitä funktio tekee - vastaavasti parametrien nimien tulisi olla sellaisia, että niistä voi helposti päätellä millaiset argumentit funktiolle pitää antaa. Funktion varsinainen koodi määritetään sisennettynä def-rivin alle. Funktion koodi voi ja usein sisältääkin useita rivejä - se voi myös sisältää muita sisennyksiä (esim. ohjausrakenteita).
  1. Kuvaus
  2. Esimerkit
Generaattori (engl. generator) on erityinen objektityyppi, joka toimii esimerkiksi for-silmukassa listan tavoin. Generaattori ei kuitenkaan ole muistissa oleva kokoelma arvoja, vaan erityinen funktio, joka tuottaa arvoja laiskasti, eli sitä mukaa kuin sitä käydään läpi. Tästä johtuen generaattorin ”sisältöä” ei ole mahdollista tulostaa, eikä siitä voida valita alkioita indeksiosoituksella. Generaattorit eivät kuulu alkeiskurssin aihepiiriin.
  1. Kuvaus
  2. Esimerkit
  3. Tilasanakirjat
Globaali muuttuja (engl. global variable) on pääohjelman tasolla esitelty muuttuja, jota muokataan suoraan funktiossa tuomatta sitä funktion nimiavaruuteen parametrin kautta. Globaalien muuttujien käyttö on huonoa ohjelmointityyliä, ja niiden sijaan tietoa kuuluisikin kuljettaa funktioille argumentteina ja ottaa funktiolta vastaan paluuarvoina muutettuja arvoja. Näin tekemällä välttää niin kutsutun globaalin tilan, joka huonontaa koodin ymmärrettävyyttä.
Globaali näkyvyys koskee kaikkia nimiä (muuttujat, funktiot jne.) jotka on määritelty pääohjelman tasolla. Kaikki nimet jotka kuuluvat globaalin näkyvyyden piiriin ovat luettavissa mistä tahansa ohjelmakoodissa. Niihin ei voi kuitenkaan sijoittaa uusia arvoja muualla kuin pääohjelmatasolla. Yleisesti ottaen globaalilta näkyvyysalueelta tulisi käyttää funktioiden sisällä vain vakioita ja muita funktioita. Varsinaiset pääohjelman muuttujat pitäisi aina siirtää funktioihin parametrien kautta.
Haara (engl. branch) on yksi keskenään vaihtoisista reiteistä, joita pitkin ohjelman suoritus voi tietystä pisteestä lähtien edetä. Esimerkiksi ehtorakenteissa jokainen if-, elif- ja else-lohko haarauttaa ohjelman suorituksen.
  1. Kuvaus
  2. Esimerkit
Hypystä (engl. jump) puhuttaessa tarkoitetaan ohjausrakenteen aiheuttamaa siirtymistä, jonka jälkeen ohjelman suoritus jatkuukin jostain muualta kuin seuraavalta koodiriviltä.
  1. Kuvaus
  2. Esimerkki
Ikuinen silmukka tai ikisilmukka (engl. infinite loop) on silmukka, joka ei pääty ikinä – silmukan alaisuuteen kuuluvaa koodia siis toistetaan ”ikuisesti”. Ikisilmukoilla on ohjelmoinnissa käyttötarkoituksensa, mutta silloin tällöin tahattomasti syntynyt ikisilmukka voi myös olla ohjelman jumiutumisen aiheuttava bugi. Pythonissa ikuiset silmukat onnistuvat pääasiassa while-silmukoilla.
  1. Kuvaus
  2. Esimerkit
Indeksi (engl. index) on kokonaislukuarvo, joka osoittaa alkion sijainnin järjestetyssä tietorakenteessa (lista, monikko, mutta myös merkkijono!). Indeksit alkavat nollasta, joten viimeinen indeksi on (rakenteen pituus - 1). Tätä voi ajatella etäisyytenä rakenteen alusta. Python tuntee myös negatiiviset indeksit, jolloin indeksi -1 viittaa aina viimeiseen alkioon, -2 toiseksi viimeiseen jne. Kun rakenteesta otetaan alkio indeksin perusteella, puhutaan usein osoittamisesta.
  1. Kuvaus
  2. Esimerkit
Kun käytetään tietorakenteen, esimerkiksi listan, indeksiä, puhutaan (indeksi)osoittamisesta. Tämä osoittaminen merkitään hakasuluilla, esim. arvosanat[0]. Indeksiosoitus palauttaa alkion. Osoitus listan ulkopuolelle aiheuttaa IndexError-poikkeuksen, ja on hyvä pitää mielessä että listan viimeinen indeksi on sen pituus - 1 (koska indeksointi alkaa nollasta). Indeksi voi olla myös negatiivinen, jolloin laskenta alkaa listan lopusta (eli -1 on listan viimeinen alkio).
Katso myö: leikkaus.
Jäsenarvo (engl. attribute) on objektille kuuluva arvo, eli ominaisuus eli attribuutti. Se on siis nimi, joka kuuluu objektin sisäiseen nimiavaruuteen, ja siihen päästään käsiksi objektin kautta: aika.tm_hour joka antaisi aika-objektista tunnit.
Kierros (engl. iteration) on toistorakenteiden eli silmukoiden yhteydessä käytetty sana. Kierroksella viitataan siihen, kun silmukan alla sijaitseva koodi suoritetaan kertaalleen alusta loppuun – tämä on siis yksi kierros.
Kirjasto (engl. library) tai moduuli (engl. module) (kuten niitä Pythonissa virallisesti kutsutaan) on valmiiksi kirjoitettua koodia, jolla on oma rajattu tarkoituksensa. Tyypillisesti kirjasto sisältää ainakin nipun aihepiiriinsä kuuluvia funktioita, mutta voi sisältää muutakin (esim. luokkia tai vakioita). Esimerkiksi Turtle on kirjasto, jonka tarkoitus on tarjota helposti käytettäviä piirtofunktioita.
  1. Kuvaus
  2. Materiaaliesimerkki
  3. Peruskäyttö
Komentoriviargumentti (engl. command line argument) tai -parametri on nimitys lisätiedolle, joka annetaan komennon yhteydessä kun ohjemaa käynnistetään komentoriviltä. Komentoriviargumentit erotetaan toisistaan tyypillisesti välilyönnillä. Esimerkiksi komennossa python koodi.py koodi.py on itse asiassa komentoriviargumentti. Komentoriviargumentteja voi käsitellä Python-koodissa sys-moduulin argv-muuttujan kautta.
  1. Kuvaus
  2. Esimerkit
Kommentti (engl. comment) on kooditiedostossa olevaa tekstiä, joka ohitetaan kun koodia suoritetaan. Kussakin kielessä on oma tapansa sille miten rivi merkitään kommentiksi. Pythonissa se on #- eli risuaitamerkki (engl. hash character), jonka jälkeen riviltä löytyvän tekstin Python-tulkki ohittaa kokonaan. Kommenteilla voi selventää koodin lukijalle (tai itselleen) mitä koodissa tapahtuu. Yleensä kommentit on hyvä laittaa omille riveilleen kommentoitavan koodin yläpuolelle.
Ohjelman ja sen funktioiden toiminta kuvataan yleensä mieluiten dokumenttimerkkijonossa. Kommentteja käytetään enemmänkin välihuomioiden tekemiseen.
Toinen tapa käyttää kommentteja on tilapäisesti kommentoida rivejä pois esimerkiksi vaihtoehtoisen koodin testaamiseksi. Tällöin aiempaa koodia ei tarvitse poistaa – kätevää, jos myöhemmin osoittautuu, että sitä tarvitaan sittenkin.
Kooditiedosto (engl. code file) on tekstimuotoinen tiedosto, joka sisältää suoritettavaa koodia. Python-kooditiedosto suoritetaan komentokehotteesta kirjoittamalla python koodi.py, jossa koodi.py on tiedoston nimi. Kooditiedostoa suorittaessa yksittäisten rivien paluuarvot eivät tule näkyviin – ainoastaan print-funktiolla tulostettavat tiedot näkyvät käyttäjälle.
Ohjelman käyttämät arvot ovat kovakoodattuja (engl. hard coded) silloin, kun ne esiintyvät literaaliarvoina – eli semmoisenaan – ohjelman lähdekoodissa sen sijaan, että ne selvitettäisiin ajonaikaisesti esimerkiksi kysymällä käyttäjältä tai lukemalla tiedostosta.
Kutsupyyntö (eng. callback) on erityisesti nykyaikaisessa ohjelmoinnissa yleinen mekanismi, jossa toiselle - usein jonkun muun tekemälle - ohjelman osalle annetaan funktio, jota sen tulee kutsua toimintansa aikana. Jos tavallinen funktiokutsu vastaa puhelinsoittoa, kutsupyyntö on loogisesti soittopyyntö. Jos ohjelman osa käyttää kutsupyyntöä, sen dokumentaatio tyypillisesti kertoo, millaisen funktion sille voi antaa - erityisesti mitä parametreja funktiolla voi olla ja millainen arvo sen tulee palauttaa.
Käsittelijä(funktio) (engl. handler) on funktio, joka on kiinnitetty tapahtumaan siten, että sitä kutsutaan kun tarkkailtu tapahtuma havaitaan. Tämä johtaa siihen, että yleensä käsittelijää ei kutsuta samassa koodissa missä se on määritelty, vaan se toimii takaisinkutsuna. Käsittelijät liittyvät yleensä käyttöliittymä- ja pelikirjastoihin, joissa ohjelman pääsilmukka pyörii kirjaston sisällä ja tarkkailee tapahtumia. Käsittelijät ovat varsinaisen sovelluksen tapa toteuttaa omat toimintonsa tapahtumien kautta. Koska sovelluksen kirjoittaja ei voi vaikuttaa siihen miten käsittelijäfunktiota kutsutaan, sen parametrien ja paluuarvojen tulee vastata kirjaston antamia määrityksiä.
Käyttöliittymä (engl. User Interface, lyh. UI) on rajapinta ohjelman ja ohjelman käyttäjän – tyypillisesti ihmisen – välillä. Yksinkertaisessa tekstipohjaisessa käyttöliittymässä käyttäjältä voidaan pyytää ohjelman suoritusta varten tietoa input-funktiokutsujen avulla. print-funktiolla voidaan puolestaan esittää käyttäjälle tietoa ja lopputuloksia.
Monet loppukäyttäjälle interaktiiviseen käyttöön tarkoitetut ohjelmat toimivat jonkinlaisen graafisen käyttöliittymän (engl. Graphical User Interface, lyh. GUI) kautta. Näihin sisältyy yleensä ikoneita, painikkeita, avattavia valikoita ynnä muita hiirellä tai kosketusnäytöllä tökittäväksi tarkoitettuja käyttöliittymäelementtejä. Tällä kurssilla tutustumme lopputyön yhteydessä pintaa raapaisemalla graafisten käyttöliittymien sielunelämään.
Käyttöliittymäelementti (engl. UI element, widget) on jokin (yleensä graafiselle) käyttöliittymälle ominainen komponentti, jonka kautta käyttäjän vuorovaikutus ohjelman kanssa on mahdollista. Tällaisia ovat esimerkiksi napit, valikot, liukusäätimet ynnä muut.
Lause (engl. statement) on ohjelmointikielessä nimitys yksittäiselle suoritettavalle asialle, joka on yleensä yksi koodirivi.
Lauseke (engl. expression) tarkoittaa ohjelmoinnissa evaluoitavaa yksikköä. Esimerkiksi 5 + 5 ja "aasi" != "apina" ovat lausekkeita, jotka evaluoituvat arvoiksi 10 ja True. Lauseke yksin ei muuta ohjelman tilaa mitenkään, ellei sillä ole sivuvaikutuksia. Sen sijaan lauseke vaikuttaa osana lausetta.
  1. Kuvaus
  2. Esimerkit
Leikkaamisella (engl. slice) tarkoitetaan sitä, kun sekvenssistä (yleensä listasta, mutta myös merkkijonoista) otetaan osasekvenssi. Lopputuloksena on samaa tyyppiä oleva arvo, joka on kopio valitusta alueesta. Valinnassa merkitään aloitus- ja lopetusindeksit. Molemmat ovat tosin valinnaisia. Leikkaus merkitään sivu = kokoelma[5:10] joka ottaisi siis alkiot indekseistä 5…9. Kaksoispisteen jälkeinen luku on ensimmäinen indeksi jota ei oteta mukaan!
Leikkaaminen ei koskaan aiheuta IndexErroria!
  1. Kuvaus
  2. Esimerkit
Lista (engl. list) on järjestetty kokoelma arvoja, joka on Python-ohjelmoinnissa todellinen monitoimikone. Lista voi sisältää mitä tahansa arvoja, eikä sen kokoa tarvitse tuntea ennalta.
Listassa olevia arvoja kutsutaan alkioiksi. Jokaisella alkiolla on listassa paikka, jota kutsutaan indeksiksi. Indeksit alkavat nollasta! Kaiken tämän lisäksi lista on luonteeltaan muuntuva tietotyyppi. Kaikesta tästä on kerrottu hyvin paljon kolmosmateriaalissa.
Lista voi myös sisältää muita listoja. Tällä tavalla muodostettua tietorakennetta kutsutaan kaksiulotteiseksi listaksi (engl. two-dimensional list). Tietenkin sisäkkäisiä listoja (engl. nested list) voi olla kahtakin tasoa syvemmälle, jolloin ulottuvuuksien lukumäärä kasvaa vastaavasti. Tällöin puhutaan moniulotteisista listoista (engl. multidimensional list).
Literaaliarvo (engl. literal) on yleisnimitys arvoille jotka esiintyvät koodissa sellaisenaan. Arvo ei siis ole muuttujassa, vaan se on kirjoitettu koodiin. Esimerkiksi lauseissa x = 5 ja print("aasi"), 5 ja "aasi" ovat literaaliarvoja. Termiä käytetään pääasiassa yksinkertaisten muuttujatyyppien eli lukujen, totuusarvojen ja merkkijonojen kanssa.
  1. Kuvaus
  2. Muunnokset
Liukuluku (engl. floating point number, lyh. float) on tietokoneiden käyttämä desimaaliluvun approksimaatio. Tietokoneet eivät arkkitehtuurinsa vuoksi pysty käsittelemään oikeita desimaalilukuja, joten niiden tilalla käytetään liukulukuja. Liukuluvut saattavat aiheuttaa pyöristysvirheitä - tämä on hyvä pitää mielessä niitä käyttäessä. Pythonissa on olemassa decimal-moduuli, joka pystyy käsittelemään desimaalilukuja tarkasti.
Lohko (engl. block) on nimitys joukolle koodirivejä jotka kuuluvat yhteen. Lohkoa yhdistää se, että rivit ovat samalla sisennystasolla (tosin lohko voi sisältää myös muita lohkoja). Tyypillisiä lohkoja ovat esim. ehtorakenteiden suoritettavat osat, eli ne sisennyt koodirivit jotka seuraavat ehtoa / elseä. Lohko tulkitaan päättyneeksi kun vastaan tulee rivi, jonka sisennystaso on pienempi kuin lohkoon kuuluvien rivien.
  1. Kuvaus
  2. Lisätietoa
Looginen operaattori (engl. boolean operator) viittaa Boolen algebran operaatiohin, joissa käsitellään totuusarvoja. Tyypillisiä loogisia operaatioita ovat ehtolauseista tutut and, not ja or. Näistä and on tosi jos ja vain jos molemmat operandit ovat tosia; or on tosi jos ainakin toinen operandeista on tosi; ja not on tosi, jos sen ainoa operandi on epätosi.
Lähdekoodi – lyhemmin koodi – (engl. source code, code; alan slangi sorsa) tarkoittaa tekstiä, joka on kirjoitettu ohjelmointikielellä.
Merkillä (engl. character) tarkoitetaan ohjelmoinnissa yksittäistä datana esiintyvää kirjainta, numeroa, välimerkkiä tai muuta vastaavaa symbolia. Pythonissa merkki edustaa pienintä merkkijonon yksittäistä palasta.
  1. Kuvaus
  2. Esimerkit
Merkkijono (engl. string) on tietotyyppi, joka sisältää tekstiä. Sitä käytetään erityisesti käyttäjän kanssa viestimiseen. Merkkijonojen sisältöä voidaan myös tallentaa tiedostoihin. Pythonissa merkkijono merkitään lainaus- tai heittomerkillä (esimerkiksi "aasi" tai 'aasi'). Suosimme ensimmäistä. Merkkijono voidaan merkitä myös kolmella merkillä jolloin se voi olla monirivinen – tätä käytetään erityisesti dokumenttimerkkijonojen (docstring) kanssa. Merkkijono on muuntumaton tietotyyppi – kaikki, mikä näennäisesti muokkaa merkkijonoa, tosiasiassa luo (ja palauttaa) siitä muutetun kopion.
  1. Kuvaus
  2. Esimerkit
Metodi (engl. method) on funktio, joka on osa objektia eli objektin ominaisuus, jolla objekti usein muuttaa omaa tilaansa. Metodia kutsuttaessa käsiteltävä objekti tulee kutsun eteen: valinta.lower(). Metodeita kutsutaan myös joskus jäsenfunktioiksi (engl. member function).
Metodikutsu (engl. method call) vastaa toiminnaltaan funktiokutsua. Merkittävänä erona kuitenkin käsiteltävä objekti on metodikutsun edessä siinä missä funktiokutsussa se annettaisiin argumenttina. Metodikutsussa siis objekti tyypillisesti käsittelee itseään. Esimerkiksi sana.upper() on metodikutsu, jossa käsitellään sana-muuttujan viittaamaa objektia.
Moduuli (engl. module) on periaatteessa mikä tahansa Python-kooditiedosto. Yleisemmin kuitenkin moduulista puhutaan kirjaston synonyymina. Tyypillinen moduuli sisältää yhteen asiaan keskittyviä funktioita ja mahdollisesti muutakin (esimerkiksi vakioita ja luokkia). Laajat ohjelmat on usein myös jaettu useisiin moduuleihin siten että kukin moduuli keskittyy ohjelman toiminnan tiettyyn osa-alueeseen.
  1. Kuvaus
  2. Esimerkit
Monikko (engl. tuple) on ns. jäädytetty lista. Se on siis järjestetty kokoelma arvoja kuten listakin, mutta se on muuntumaton objekti - sen sisältöä ei siis voi muuttaa muuten kuin luomalla uuden kopion. Monikkoja voidaan siis ainoastaan luoda uusia ja lukea. Monikko merkitään yleensä kaarisulkeilla: (1, 2, 3), mutta myös pelkkä 1, 2, 3 on monikko.
Toisin kuin lista, monikko voi toimia sanakirjan avaimena.
  1. Kuvaus
  2. Esimerkit
Pythonissa objektit erotellaan muuntuviin ja muuntumattomiin. Muuntumaton (engl. immutable) arvo on sellainen, jonka sisältö ei voi muuttua - kaikki operaatiot jotka näennäisesti muuttavat arvoa tosiasiassa luovat siitä uuden kopion, joka yleensä sijaitsee uudessa muistipaikassa. Esimerkiksi merkkijonot ovat tyypillinen muuntumaton tyyppi Pythonissa. Siksi merkkijonojen kanssa näkee yleensä jotain tällaista: valinta = valinta.lower()
  1. Kuvaus
  2. Esimerkit
Pythonin objekteissa on kahta tyyppiä: muuntuvia ja muuntumattomia. Muuntuvat (engl. mutable) objektit ovat sellaisia, joiden arvo voi muuttua suorituksen aikana esim. metodikutsun seurauksena. Yleisin esimerkki muuntuvista objekteista on lista: muumilaakso.append("Hemuli") muuttaa muumilaakso-nimistä listaa pysyvästi lisäämällä siihen uuden arvon. Kaikki listaan viittaavat lauseet ohjelmassa käsittelevät tästä eteenpäin listaa, johon "Hemuli" on lisätty.
Yksinkertaistettu tapa käsittää muuttuja (engl. variable) on ajatella sitä tietovarastona – muuttuja sisältää jotain. Tätä ilmaisua käytetään usein puheessa, mutta se ei ole täysin tarkka. Tarkempi kuvaus on, että Python-muuttuja on viittaus arvoon. Se on siis yhteys muuttujan nimen ja tietokoneen muistissa olevan arvon välillä. Muuttuja ei siis varsinaisesti sisällä arvoa – se ainoastaan sisältää tiedon siitä mistä arvo löytyy.
Ohjelmointikielissä on oleellista ymmärtää määrittelyn (engl. definition) ero suorittamiseen. Määrittelemällä luodaan kuvauksia funktioista, muuttujista ja erilaisista tietorakenteista – tavallaan siis kerrotaan ohjelmointikieltä käyttäen, minkälainen jokin edellä mainituista asioista on, tai mitä sen kuuluisi tehdä. Pythonissa määrittelyn ja suorittamisen ero on helpoin ymmärtää funktioiden avulla. Funktiomäärittelyssä funktio vasta luodaan – ikään kuin tehtaalla koottu laite. Funktiota varsinaisesti käytetään – eli sen toiminnallisuus hyödynnetään funktiota varten määriteltyä koodia ajamalla – vasta funktiokutsun yhteydessä. Samaa vertausta käyttäen funktiokutsu vastaa siis sitä hetkeä, kun tehtaalta saapunut laite käynnistetään.
  1. Kuvaus
  2. Esimerkit
Nimeämätön vakio tai taikaluku (engl. magic number) on koodissa esiintyvä literaaliarvo, jota ei selitetä millään tavalla. Hyvään ohjelmointityyliin kuuluu taikalukujen välttäminen. Oikea – itsedokumentoiva – tapa on nimetä koodissa esiintyvät vakiot muuttujiin, jolloin niiden muuttaminen onnistuu tarpeen tullen yhdestä paikasta yhdellä muutoksella, ja koodin lukijan on helpompi ymmärtää koodia.
  1. Kuvaus
  2. Nimeämiskäytännöt
Muuttujilla, funktioilla, vakioilla, moduuleilla ja muilla vastaavilla on kullakin nimi (engl. identifier) – se osa lähdekoodia, joka tarkoittaa kyseistä asiaa. Esimerkiksi, jos ohjelmoija määrittelee koodin alussa muuttujan leveys arvolla 15, kyseisellä leveys-nimellä voidaan myöhemmin käyttää kyseistä muuttujaa. Nimen voidaan siis ajatella olevan ohjelmoijan ja koodia lukevan tulkin yhteinen ymmärrys siitä, mihin asioihin lähdekoodissa esiintyvät sanat viittaavat. Nimet kuuluvat aina johonkin nimiavaruuteen.
Nimiavaruus (engl. namespace) on joukko nimiä (muuttujia, vakioita, funktioita jne.) jotka kuuluvat samaan kontekstiin. Esimerkiksi funktion sisällä, eli funktiomääritelmän lohkossa on oma nimiavaruus: funktion sisällä määritetyt nimet ovat käytössä ainoastaan sen sisällä. Ohjelmalla on myös aina päänimiavaruus (engl. global namespace), jossa kaikki pääohjelmassa määritetyt nimet sijaitsevat. Tavallista import-lausetta käytettäessä saadaan niin ikään erillinen nimiavaruus, johon päästään käsiksi moduulin nimen kautta – moduulin sisäiset nimet ovat siis tällöin erillisessä avaruudessa. Katso myös näkyvyysalue.
Nimikonflikti syntyy, jos useammalle kuin yhdelle arvolle koitetaan antaa sama nimi. Tällöin tapahtuu niin, että tuoreempi sijoitus jåä voimaan. Tästä seuraa yleensä ohjelman kaatavia virheitä, koska usein arvot ovat eri tyyppiä. Voi jopa käydä niin, että epämääräisesti nimetyn funktion päälle tallennetaan vahingossa saman niminen muuttuja.
  1. Kuvaus
  2. Esimerkit
Näkyvyysalue (engl. scope) määrittää sen, onko jokin tietty nimi (muuttuja, funktio tms.) käytettävissä tietyssä kohdassa ohjelmaa. Esimerkiksi funktiomääritelmän lohkossa voidaan viitata funktiossa määriteltyihin muuttujiin, koska ne ovat funktion näkyvyysalueella. Sen sijaan muut funktiot eivät voi viitata näihin muuttujiin, koska ne kuuluvat eri näkyvyysalueelle. Globaalin (ts. pääohjelman) näkyvyysalueen nimet ovat luettavissa kaikkialla koodissa.
  1. Kuvaus
  2. Syventävää nippelitietoa
Näppäimistökeskeytyksellä (engl. keyboard interruption) voi pakottaa jumiin jääneen ohjelman sammumaan. Sen saa aikaan painamalla Ctrl+C sen terminaalin ollessa auki, jossa ohjelma pyörii. Pythonissa näppäimistökeskeytyksen saa käsiteltyä kaappaamalla KeyboardInterrupt-poikkeuksen try-except-rakenteella.
Objekti (engl. object), joskus myös olio, on Pythonissa yleistä terminologiaa. Kutsumme objekteja pääasiassa arvoiksi alkeiskurssilla, mutta Pythonissa kaikkea voi käsitellä objekteina. Tämä tarkoittaa, että mihin tahansa voidaan viitata muuttujilla (esimerkiksi funktion voi sijoittaa muuttujaan). Tämän kurssin puitteissa objekti-termiä käytetään sellaisista arvoista joilla on metodeja.
Objektit nousevat merkittävämpään rooliin alkeista eteenpäin, erityisesti koodissa jossa käytetään luokkia.
Ohjausrakenne (engl. control structure) on yleisnimitys ohjelmointikielen sallimista keinoista, jotka hallitsevat jollain tavalla ohjelman suorituksen kulkua. Näihin rakenteisiin lukeutuvat kurssin puitteissa ehtorakenteet, toistorakenteet sekä poikkeusten käsittely.
Ohjelmointiongelma on ohjelmointityön kohde. Se on siis jokin todettu tarve, jota varten ohjelmaa koodataan. Tarve voi olla jonkin tietokoneella tehtävän asian automatisointi, verkkosivun pystyttäminen tai ihan vain hauskan pelin tekeminen.
Ohjelmointityyli (engl. programming style) on joukko ohjeita tai tapoja, joita ohjelmoija noudattaa koodia kirjoittaessaan. Näihin tapoihin lasketaan muun muassa sisennyksen syvyys, muuttujien ja funktioiden nimeämiskäytännöt, välilyöntien käyttö lauseissa sekä monet muut tyyliseikat. Ohjelmointityylejä on useita erilaisia, ja tällä kurssilla opetetaan noudattamaan tiettyjä tyyliin liittyviä sääntöjä.
Ohjelmointivirhe eli bugi (engl. bug) on virhe ohjelman lähdekoodissa. Bugien seurauksena ohjelma ei välttämättä käynnisty ollenkaan, kaatuu, voi joissain tilanteissa toimia väärin ja joskus aiheuttaa jopa erittäin vakavia tietoturvaongelmia. Huolellinen ohjelmointi ja testaaminen – myös harvinaisilla nurkkatapauksilla – vähentää bugien todennäköisyyttä. Ohjelman havaitun virheellisen toiminnan aiheuttavan koodin etsimistä ja korjaamista kutsutaan debuggaukseksi.
Oletusarvo (engl. default value) on arvo, joka annetaan funktion valinnaisella parametrille mikäli sitä vastaavaa argumenttia ei annettu funktiota kutsuttaessa. Esimerkiksi def kysy_pituus(kysymys, maksimi=10): -määrittelyrivillä maksimi on valinnainen parametri, jonka oletusarvo on 10.
Ominaisuus (attribute) liittyy objekteihin siten, että objekteilla voidaan sanoa olevan ominaisuuksia. Tällä kurssilla useimmat näistä ominaisuuksista ovat metodeja, mutta ne voivat olla myös arvoja. Objektin ominaisuutta käsitellään notaatiolla, jossa objektin nimen ja ominaisuuden nimen väliin tulee piste, esim: valinta.lower()-metodikutsussa valinta on objekti ja lower on ominaisuus.
  1. Kuvaus
  2. Esimerkit
Operaatio-nimitystä (engl. operation) käytetään esimerkiksi matemaattisille operaatioille. Yleisesti ottaen puhutaan operaatiosta, kun koodirivillä esiintyy operaattori ja operandeja. Esimerkiksi 5 + 5 on operaatio.
Operaattori (engl. operator) on matematiikassa ja ohjelmoinnissa nimitys symboleille, jotka kuvaavat jotain operaatiota. Operaattorilla on aina vähintään yksi operandi, mutta useimmilla kaksi. Esimerkiksi +-merkki on yhteenlaskuoperaattori.
Operandi (engl. operand) on hieno matematiikassa ja ohjelmoinnissa käytössä oleva nimitys arvoille joita käytetään operaatiossa. Esimerkiksi 5 + 8 on yhteenlaskuoperaatio, jonka operandit ovat 5 ja 8. Operandien voidaan siis sanoa olevan operaatioiden kohteita.
Paikallinen muuttuja (eng. local variable) on muuttuja, joka on määritelty vain yhdessä kontekstissa, tyypillisesti - ja erityisesti tällä kurssilla - funktion sisällä (ml. funktion parametrit). Paikalliseen muuttujaan ei voi koskea ulkopuolelta, minkä lisäksi se lakkaa olemasta kun ohjelman suoritus poistuu sen kontekstista - eli yleensä kun funktion suoritus päättyy.
  1. Kuvaus
  2. Parametrien valinta
  3. Lisämuotoilu
Paikanpidin (engl. placeholder) on yleisesti tilapäinen merkintä, joka on tarkoitus korvata toisella. Tällä kurssilla sitä käytetään lähinnä merkkijonojen muotoilun yhteydessä. Paikanpidin merkkijonon sisällä merkitään aaltosulkeilla ("Hei {}".format(nimi)). Merkkijonojen paikanpitimissä voi olla lisämäärityksiä kuten näytettävien desimaalien lukumäärä ("Aaseilla on keskimäärin {:.2f} jalkaa".format(keskiarvo)). Paikanpitimien tilalle sijoitetaan format-metodikutsun argumentit, normaalisti esiintymisjärjestyksessä. Ne voidaan kuitenkin myös numeroida tai käyttää avainsanoja.
Pakeneminen (engl. escape) tarkoittaa ohjelmoinnissa sitä, että jokin merkki tulkitaan eri tavalla kuin normaalisti. Esimerkiksi "n" on vain n-kirjain, mutta "\n" on rivinvaihto – tässä siis \-merkki (kenoviiva, engl. backslash) aiheuttaa sen, että n-merkin normaali merkitys paetaan ja korvataan toisella merkityksellä; kenoviiva toimii siis koodinvaihtomerkkinä (engl. escape character). Yksi tyypillinen käyttö on sisällyttää "-merkki merkkijonoon, joka on rajattu "-merkeillä: "aasin korvien väli on 14\""
  1. Kuvaus
  2. Esimerkit
Palauttaminen (engl. return) tapahtuu aina kun funktion suoritus päättyy. Tyypillisesti funktion palauttama(t) arvo(t) määritellään funktion sisällä return-lauseella. Funktiota kutsuvassa koodissa paluuarvo näkyy funktiokutsun paikalla, jolloin se voidaan esimerkiksi tallentaa muuttujaan tai laittaa eteenpäin toiselle funktiolle.
Paluuarvo (engl. return value) on nimitys arvolle tai arvoille, jotka funktio palauttaa, kun sen suoritus päättyy - eli siis funktion tulos. Pythonissa funktiolla voi olla useita paluuarvoja. Koodia lukiessa paluuarvoa voi käsitellä päässään siten, että funktiokutsun paikalle sijoitetaan funktion paluuarvo sen jälkeen kun funktio on suoritettu. Paluuarvo löytyy funktion sisältä return-lauseen yhteydestä. return True -rivillä on yksi paluuarvo – totuusarvo True.
Parametri (engl. parameter) on funktion määrittelyssä nimetty muuttuja. Parametreihin sijoitetaan funktion saamien argumenttien arvot silloin, kun funktiota kutsutaan. Parametri on siis nimitys jota käytetään, kun puhutaan arvojen siirtymisestä funktion näkökulmasta. def kysy_syote(kysymys, virheviesti): -rivillä siis kysymys ja virheviesti ovat parametreja. Parametrille voidaan määrittää oletusarvo jonka se saa, jos sitä vastaavaa argumenttia ei anneta kutsuttaeassa – tämä tekee kyseisestä argumentista valinnaisen.
Parametrisaatio tarkoittaa jonkin prosessin käyttötarkoitusten laajentamista siten, että osa sen kiinteistä arvoista muutetaan muuttujiksi jolloin sama prosessi voidaan suorittaa eri arvoilla ja saada eri tulos. Esim. matemaattiset yhtälöt ovat eräänlaista parametrisaatiota: kaikki yhtälön kuvaavat pisteet tuotetaan samalla kaavalla vaihtamalla muuttujan (esim. x) arvoa. Ohjelmoinnissa parametrisaatio on hyvin konkreettista: tyypillisesti prosessi irrotetaan omaan funktioonsa jonka parametrit määrittävät mitkä arvot eivät ole kiinnitettyjä jolloin funktio toimii eri tavalla eri parametreilla, antaen esim. eri tuloksen.
  1. Kuvaus
  2. Esimerkit
Poikkeus (engl. exception) on ohjelmointikielessä määritelty virhetilanne. Poikkeuksella on tyyppi (esimerkiksi TypeError), jota voi käyttää poikkeuksen käsittelyssä ohjelman sisällä sekä myös apuna virhetilanteen ratkaisussa. Tyypillisesti poikkeukseen liitetään myös viesti, joka kertoo mistä ongelmassa on kyse. Pythonissa poikkeuksia käsitellään try-except-rakenteilla.
  1. Kuvaus
  2. try-except-else-finally
Poikkeusten käsittely (engl. exception handling) on ohjelmointikieleen sisäänrakennettu keino ohjelmoijalle reagoida poikkeuksiin. Pythonissa poikkeusten käsittely onnistuu try-except-rakenteella, jossa sekä try: että except: aloittavat omat lohkonsa; try-lohkon alle kirjoitetaan se koodi, joka mahdollisesti aiheuttaa jonkun tietyn poikkeuksen ja except-lohkon alle taas se koodi, joka suoritetaan siinä tapauksessa, että kyseinen poikkeus tapahtuu. Joissain muissa ohjelmointikielissä except-avainsanan sijaan käytetään avainsanaa catch, minkä takia yleisesti puhutaan poikkeusten kiinni ottamisesta.
  1. Kuvaus
  2. Esimerkit
Polku (engl. path) on tiedoston tai kansion sijainti kiintolevyllä. Polku voi olla absoluuttinen tai relatiivinen. Absoluuttinen polku sisältää kaikki kansiot aina juureen asti (esim. Windowsissa asemakirjain kuten C:), kun taas relatiivinen sisältää kansiot aktiiviseen kansioon asti (ts. siihen kansioon mistä ohjelma käynnistettiin). Polku esitetään ohjelmointikielissä yleensä merkkijonona, ja polun osat erotetaan kauttaviivalla /. Useimmiten polkuja muodostaessa kannattaa käyttää os.path-moduulin join-funktiota.
  1. Kuvaus
  2. Esimerkit
Interaktiivinen Python-tulkki (engl. interactive Python interpreter) tai Python-konsoli (engl. Python console) on ohjelma, johon voi kirjoittaa Python-koodirivejä. Nimitys ”interaktiivinen” tulee siitä, että koodirivi suoritetaan välittömästi sen syöttämisen jälkeen, ja ohjelma näyttää käyttäjälle koodirivin tuottaman paluuarvon (esimerkiksi matemaattisen operaation tuloksen). Kurssilla suositellaan IPython-tulkkia, joka käynnistetään asennuksen jälkeen komennolla ipython.
Python-tulkki (engl. Python interpreter) on ohjelma, joka muuttaa Python-koodin tietokoneelle annettaviksi ohjeiksi. Se vastaa niin kooditiedostojen kuin myös interaktiiviseen Python-tulkkiin kirjoitettujen komentojen suorittamisesta. Tällä kurssilla sanalla tulkki viitataan kuitenkin useimmiten nimenomaan interaktiiviseen Python-tulkkiin.
Pythonissa pääohjelma (engl. main program) on se osa koodia, joka suoritetaan, kun ohjelma käynnistetään. Nyrkkisääntönä pääohjelma sisältää kaikki lauseet sekä ohjausrakenteet jotka ovat kiinni koodin vasemmassa laidassa. Pääohjelma sijaitsee tyypillisesti koodin lopussa, ja useimmiten if __name__ == "__main__":-lauseen alla. Älä kuitenkaan käytä tätä lausetta alkupään harjoitustehtävissä, koska tarkistin ei pysty tällöin suorittamaan koodisi pääohjelmaa.
  1. Kuvaus
  2. Esimerkit
Rajapinta (engl. interface) viittaa yleisesti kahden eri asian välimaastoon, ja ohjelmoinnissa sillä tarkoitetaan erityisesti tapaa, jolla ohjelman eri osat voivat liittyä toisiinsa. Esimerkiksi funktion rajapinnasta puhuttaessa tarkoitetaan sitä muotoa, jossa funktio vastaanottaa tietoa ja suoriutumisen jälkeen antaa käsiteltyä tietoa tai jonkun lopputuloksen ulos. Kirjastoilla on yleensä olemassa jonkinlainen niin kutsuttu API, eli Application Programming Interface, joka kertoo sen, kuinka kirjaston toiminnallisuuksia käytetään. Ihmiset taas ovat ohjelmiin kytköksissä käyttöliittymän (engl. User Interface, lyh. UI) kautta, joka sekin on tietynlainen rajapinta.
Ratkaisumalli on ohjelmoijan muodostama abstrakti ajatus siitä miten ohjelmointiongelman ratkaisu etenee. Ratkaisumalli ei ole vielä koodia, mutta sen tulisi olla yksiselitteinen sekä selkeisiin välivaiheisiin jakaantuva, jotta sen pohjalta voidaan kirjoittaa ohjelma. Ratkaisumallia voi hahmotella päänsisäisesti, käyttämällä avuksi paperia sekä kokeilemalla asioita Python-tulkissa.
  1. Kuvaus
  2. Esimerkit
Rekursio (engl. recursion) on yleinen ohjelmointitermi, joka viittaa siihen, kun funktio kutsuu itseään. Rekursio on siis funktiopohjainen tapa luoda toistorakenne, jossa funktio välittää itselleen uusia argumentteja ja käsittelee omia paluuarvojaan. Rekursio on kätevä esimerkiksi puumaisia rakenteita käsitellessä – käsitellään yksi ”oksa” jollain tavalla, ja sitten rekursion avulla käsitellään tästä oksasta lähtevät oksat ja niin edelleen. Pythonissa rekursiota käytetään aika vähän. Osasyynä on sisäänrakennettu rekursiorajoitus, joka asettaa katon sille, kuinka monta kertaa funktio saa kutsua itseään.
Relatiivinen polku (relative path) on käyttöjärjestelmäkäsite, joka kertoo hakemiston tai tiedoston osoitteen suhteessa aktiiviseen hakemistoon (eli siihen missä komento suoritetaan). Relatiivinen polku ei välitä siitä millainen hakemistoviidakko on levyaseman juuren ja aktiivisen hakemiston välissä. Tästä johtuen relatiivista polkua käytetään yleensä ohjelman omiin alikansioihin viittaamiseen. Tällöin ohjelma alikansioineen voidaan siirtää toiseen paikkaan ilman, että polkuja tarvii muuttaa.
Rivinvaihtomerkki (engl. newline, line break, end of line; lyh. EOL) eli "\n" on merkki, joka tulostettaessa tai tiedostoon kirjoitettaessa saa aikaan rivinvaihdon. Jos merkkijonoa tarkastellaan ilman printtausta esim. konsolissa, rivinvaihdot näkyvät "\n"-merkkeinä.
  1. Kuvaus
  2. Määrittely
  3. Arvojen haku
  4. Sanakirjan muuttaminen
Sanakirja (engl. dictionary) on tietorakenne, jossa arvoille annetaan avaimet (yleensä merkkijono). Sanakirjan merkittävin etu on se, että selkeästi nimetyt avaimet tekevät tietorakennetta käsittelevästä koodista huomattavasti selkeämpää luettavaa. Python 3.7:sta lähtien sanakirjan avaimet ja arvot ovat siinä järjestyksessä missä ne on lisätty.
Sapluuna (engl. template) on muotti esimerkiksi tekstille, joka käyttäjälle halutaan näyttää, mutta joka ei semmoisenaan ole vielä valmis. Sapluunasta siis puuttuu tietoa, joka on tarkoitus saada sapluunan paikanpitimien tilalle.
Kurssilla yleisin sapluuna on merkkijono, jossa on paikanpitimiä format-metodia varten.
Sekvenssi (engl. sequence) on mikä tahansa arvo Pythonissa, jossa on tavaraa peräkkäin – esimerkiksi merkkijono, lista ja monikko kuuluvat näihin.
Matematiikasta tuttu sidontajärjestys (engl. precedence) määrittää sen, missä järjestyksessä lausekkeen operaatiot suoritetaan.
lopputulos = 10 + 2 * (2 + 3)
Yllä olevan koodin lopputulos on 20, sillä ensin lasketaan yhteen luvut 2 ja 3, joiden summa kerrotaan kahdella, ja johon lopuksi lasketaan vielä yhteen luku 10. Esimerkissä korkein presedenssi on siis sulkeilla, toisiksi korkein kertolaskulla ja matalin yhteenlaskulla.
Sijoittaminen (engl. assignment) liittyy muuttujiin ja arvoihin. Tyypillinen ilmaisu on ”muuttujaan sijoittaminen”, joka yksinkertaistettuna tarkoittaa sitä, että tietty arvo annetaan muuttujalle (x = 5). Tarkennettuna muuttujaan sijoittaminen kuitenkin tarkoittaa Pythonissa sitä, että muuttujan ja arvon välille luodaan viittaus – muuttuja tietää mistä arvo löytyy.
Samaa tarkoittavia ilmaisuja ovat mm. muuttujaan tallentaminen, arvon ottaminen ylös muuttujaan, arvoon viittaminen muuttujalla, arvon tunkeminen muuttujaan... jne.
Sijoitusoperaattoria (engl. assignment operator) eli =-merkkiä käytetään muuttujaan sijoituksessa. Operaattoria käytettäessä kohteena olevan muuttujan tulee aina olla sen vasemmalla puolen ja sijoitettavan arvon (tai lausekkeen, joka tuottaa sijoitettavan arvon) sen oikealla puolen.
Silmukkamuuttuja (engl. loop variable) on for-silmukan määrittelrivillä esitelty muuttuja, joka saa yksitellen kaikki läpikäytävän sekvenssin (esim. lista) arvot. Sen arvo siis vaihtuu jokaisella silmukan kierroksella. Yksinkertainen esimerkki materiaalista: for elain in elukoita:, jossa siis elain on silmukkamuuttuja. Mikäli läpikäytävä sekvenssi sisältää monikoita (tai listoja), silmukkamuuttujia voi olla myös useita: for opiskelija, arvosana in arvostelu:. Silmukkamuuttujat eivät ole erillisessä nimiavaruudessa, joten niiden tulee erota muista funktion/pääohjelman muuttujista.
Sisennetyn (engl. indented) koodirivin edessä on tyhjää eli välilyöntejä tai sarkainmerkkejä. Sisennyksen tehtävä on parantaa koodin luettavuutta yleisesti. Pythonissa sisennys myös erottaa koodilohkot toisistaan - kaikki samalla sisennystasolla olevat rivit ovat samaa lohkoa. Tällä kurssilla käytetään välilyöntejä, ja yksi sisennys on 4 välilyöntiä. Kaikki järkevät tekstieditorit saa syöttämään sarkainmerkin sijaan halutun määrän välejä.
Sisäänrakennetut funktiot (engl. builtin functions) ovat funktioita, jotka tulevat Pythonin mukana, ja niitä käyttääkseen ei tarvitse erikseen ottaa käyttöön mitään moduulia/kirjastoa.
Suorittaminen (engl. execution) tai ajaminen (engl. running) tarkoittaa ohjelman tai koodinpätkän koneistettua läpi käymistä, jolloin ohjelmassa tai koodissa määritellyt asiat tapahtuvat. Python-tulkki suorittaa sille annettua koodia lause kerrallaan – tällöin ohjelman sanotaan olevan käynnissä. Kun enempää suoritettavaa koodia ei ole, törmätään käsittelemättömään virheeseen tai koodissa erikseen niin määrätään, ohjelman suorittaminen päättyy.
Suoritusjärjestys (eng. presedence) määrittää missä järjestyksessä koodirivillä olevat lauseet suoritetaan. Eri tyyppisillä operaatioilla on eri prioriteetti suoritusjärjestyksesä. Ne löytyvät alla olevasta linkistä. Samantasoiset operaatiot suoritetaan vasemmalta oikealle. Kuten matematiikassa, suoritusjärjestykseen voi vaikuttaa suluilla.
Syntaksi (engl. syntax) on koodin kielioppi. Esimerkiksi Pythonin syntaksi määrittää, millainen teksti on tulkittavissa Python-koodiksi. Jos teksti ei noudata koodin syntaksia, sitä ei voida suorittaa. Syntaksi antaa myös koodaajalle tietoa siitä, missä muodossa halutunlainen ohje tulee antaa.
Syntaksivirhe (engl. syntax error) on poikkeus, joka syntyy, kun Python-tulkki tutkii kooditiedostoa ennen sen suorittamista ja havaitsee siellä rikkinäistä – eli jollain tapaa väärin kirjoitettua – koodia. Syntaksivirhe estää koodin suorittamisen.
Yksi hyvin yleinen syntaksivirhe on sulkujen auki jääminen. Tällöin syntaksivirheilmoitus näyttää poikkeuksen tapahtuneen vasta virheellistä riviä seuraavalla rivillä! Muista siis mystisen syntaksivirheviestin äärellä katsoa myös edeltäviä rivejä.
  1. Kuvaus
  2. Esimerkit
Syöte (engl. input) on tämän kurssin puitteissa käyttäjältä pyydetty tekstimuotoinen komento tai vastaus kysymykseen. Syöte kysytään input-funktiolla, ja se on aina merkkijono. Aina, kun ohjelma kysyy syötettä, sen suoritus pysähtyy, kunnes käyttäjä on antanut syötteen.
Takaisinkutsu (engl. callback) on yleinen ohjelmoinnissa käytetty menetelmä, jossa funktio ottaa parametrin kautta vastaan funktion kutsuttavakseen heti (synkroniset takaisinkutsut) tai joskus tulevaisuudessa (asynkroniset takaisinkutsut). Nimensä menetelmä on saanut soittopyynnöstä: kutsuttavaa funktiota, jolle jokin funktio välitetään argumenttina, ”pyydetään” kutsumaan tätä annettua funktiota. Pythonissa listojen sort()-metodin key-parametri on esimerkki callback-funktioiden käytöstä. Usein käyttöliittymiä toteutettaessa käyttöliittymäelementteihin kytketään callback-funktioita.
Tallennusformaatti on tiedoston "syntaksi", joka siis kertoo miten data on tiedostoon tallennettu. Tallennusformaatti asettaa rajat sille millaista dataa tiedostossa voidaan esittää. Sen perusajatus on se, että koodissa olevat tietorakenteet voidaan tallentaa tiedostoon jossain muodossa, ja myöhemmin ladata sieltä uudelleen. Tallennusformaatti voi seurata jotain alan standardia (esim. JSON), mutta lopullisesti on ohjelman tekijän vastuulla päättää mitkä tiedot ovat ohjelman kannalta relevantteja ja miten ne on paras esittää.
Tapahtuma (engl. event) on ohjelmointikäsite, jota käytetään yleisesti interaktiivisten sovellusten, jotka pyörivät reaaliajassa, yhteydessä. Näissä sovelluksissa on yleensä pääsilmukka, joka tarkkailee tapahtumia, joita voivat olla esimerkiksi: käyttäjä klikkaa hiirellä, käyttäjä painaa näppäimistön nappia, tietty aika on kulunut jne. Tapahtumiin voidaan kiinnittää käsittelijäfunktioita, jolloin funktiota kutsutaan aina kun tapahtuma havaitaan. Tällä tavalla helpotetaan merkittävästi interaktiivisten sovellusten ohjelmointia, koska itse sovellusta kirjoittaessa ei tarvitse huolehtia siitä miten ruudun tapahtumat tunnistetaan.
Periaatteessa tekstitiedosto (engl. text file) on mikä tahansa tiedosto, jonka sisältö voidaan lukea nätisti tekstieditorilla. Tämän kurssin kontekstissa kuitenkin tekstitiedosto on erityisesti sellainen tiedosto, jonka sisältöä käsitellään tekstinä Pythonissa. Eli siinä missä kooditiedostoja suoritetaan, tekstitiedostoja käytetään datan varastoimiseen ohjelman ajojen välillä.
Terminaali (engl. terminal), komentokehote (engl. prompt) ja komentorivi (engl. command line) ovat eri nimiä käyttöjärjestelmän tekstipohjaiselle käyttöikkunalle. Komentorivillä annetaan tekstikomentoja käyttöjärjestelmälle. Tällä kurssilla pääasiassa siirrytään cd- eli change directory -komennolla hakemistosta toiseen ja käytetään ipython-komentoa kooditiedostojen suorittamiseen sekä interaktiivisen tulkin avaamiseen.
  • Windowsissa komentoriville pääsee kirjoittamalla käynnistä-valikon hakuun cmd
  • Mac OS X -käyttöjärjestelmässä komentorivin saa auki kirjoittamalla Finderiin pääte (suomen kielisissä versioissa) tai terminal (englannin kielisissä versioissa)
  • Linux-työpöytäympäristöistä voit painaa Ctrl + Alt + T työpöydällä tai kirjoittaa hakuun {{terminal}}}
Testaamalla eli kokeilemalla (engl. test) selvitetään, toimivatko hartaasti näppäillyt koodirivit halutulla tavalla. Testejä suorittamalla siis etsitään koodista mahdollisia ohjelmointivirheitä. Ohjelmien testaaminen on jopa niin olennaista, että joidenkin alan työntekijöiden tehtävänä on ainoastaan automatisoitujen testien ohjelmointi. Lovelace-järjestelmän tarkistimet testaavat järjestelmään lähetetyt koodit.
Tiedostokahva (engl. file handle) on erityinen objekti, jota Pythonissa käytetään avattuun tiedostoon viittaamiseen. Huomattavaa on, että kahva ei ole sama asia kuin tiedoston sisältö, mutta sen kautta voidaan lukea tiedoston sisältö tai kirjoittaa tiedostoon. Tiedostokahva saadaan käyttöön open-funktiolla, jolle määritetään avattavan tiedoston sijainti sekä avausmoodi, jossa se avataan, esim: with open("aasi.txt", "r") as tiedosto: avaa aasi.txt-tiedoston with-lauseessa (jossa tiedostot tulee yleensä avata) siten, että muuttujasta nimeltä tiedosto löytyy tiedostokahva.
Tiedostonimi (engl. filename) on tiedoston koko nimi, joka sisältää varsinaisen tiedostolle annetun nimen sekä tiedostopäätteen. Esimerkiksi aasisvengaa.py on kokonainen tiedoston nimi, jossa varsinainen annettu nimi on aasisvengaa ja pääte on .py.
Koodin sisällä tiedostojen nimet esitetään merkkijonoina.
Tiedostopääte (engl. filename extension) on se osa tiedoston nimestä, joka on viimeisen pisteen oikealle puolen. Tiedostopäätteet ovat yleisesti käytetty tapa tiedostojen sisällön tunnistamiseen, eli ne ovat keino ilmaista tiedoston tyyppiä. Esimerkiksi kuvatiedostoilla voi olla vaikkapa .png- tai .jpg-pääte, kun taas Python-kooditiedoston pääte on yleensä .py, kuten nimessä aasisvengaa.py.
Tietorakenne (engl. data structure) on yleisnimitys kokoelmille, jotka sisältävät useita arvoja. Tietorakenteen tarkoitus on siis säilöä useammasta kuin yhdestä arvosta koostuvaa tietoa jollain lukuisista eri tavoista, joille kullekin yleensä on olemassa tietorakenteen helpon hyödyntämisen mahdollistavat ohjelmointikeinot, kuten arvojen lisääminen, poistaminen ja muokkaaminen tietorakenteesta. Tietorakenne on siis ohjelman sisäinen tapa käsitellä dataa siten, että varsinaiset yksityiskohdat on piilotettu ohjelmoijalta, joka käyttää tietorakenteita koodissaan.
Omissa ohjelmissa käytettävät tietorakenteet tulisikin valita siten, että niitä on helppo käsitellä koodissa, ja että ne palvelevat hyvin ohjelman tarkoitusta. Pythonissa yleisimmät tietorakenteet ovat lista, monikko ja sanakirja. Myös set – eli joukko-opillinen joukko, joka ei sisällä duplikaattiarvoja – on käytännöllinen tietorakenne. Sisäänrakennettujen lisäksi lukuisia käytänöllisiä tietorakenteita löytyy collections-moduulista.
Myöhemmillä kursseilla tutuksi tulevat myös muun muassa tärkeät tietorakenteet puu (engl. tree) ja graafi (engl. graph).
Tila (engl. state) viittaa sananmukaisesti ohjelman tilanteeseen. Käytännössä ohjelman tila kattaa kaikki sen tila-avaruuteen (engl. state space) kuuluvat asiat, kuten muuttujien arvot, tiedostoissa olevan datan ja sen, mitä kohtaa koodista sillä hetkellä ollaan suorittamassa. Taattu keino saada aikaiseksi korjauskelvotonta spagettikoodia on käyttää niin kutsuttua globaalia tilaa (engl. global state) – rikos, johon syyllistyvät epäpuhtaat globaaleja muuttujia hyödyntävät funktiot.
Myöhemmillä, ohjelmoinnin käsitteitä formaalimmin tutkivilla kursseilla tutuksi tulevat muun muassa tilakoneet (engl. state machine) sekä tilattomat (engl. stateless) että tilalliset (engl. stateful) ohjelmat.
Toistorakenne tai silmukka (engl. loop) on ohjausrakenne, jonka alaisuuteen kirjoitettua koodia toistetaan joko tietty lukumäärä toistoja tai kunnes jokin ehto lakkaa toteutumasta. Toistorakenteiden avulla ohjelmat pystyvät jouhevasti palaamaan aiempaan kohtaan suoritusta ja niillä voidaan myös helposti käsitellä suuria määriä arvoja. Toistorakenteita ovat Pythonissa for- ja while-silmukat.
Tosi (engl. true) on toinen kahdesta mahdollisesta totuusarvosta ja toisen, eli epätoden, vastakohta. Sitä voidaan pitää lopputuloksena loogisissa ja vertailuoperaatorioissa, jotka pitävät paikkansa. Esimerkiksi vertailuoperaatio 5 > 4 pitää paikkansa, joten kyseinen operaatio evaluoituu todeksi. Pythonissa totta merkitään avainsanalla True.
Totuusarvo (engl. boolean) on yleensä ohjelmointikielien yksinkertaisin tietotyyppi, jolla on vain kaksi arvoa: tosi (Pythonissa True) ja epätosi (Pythonissa False). Vertailuoperaattorit tuottavat totuusarvoja, ja niitä käytetään yleisimmin ehtolauseiden ja while-silmukoiden yhteydessä. Pythonissa kaikki arvot vastaavat jompaa kumpaa totuusarvoa. Yleisesti ns. tyhjät arvot (0, "", None jne.) ovat sama kuin False, ja loput sama kuin True.
  1. Kuvaus
  2. Esimerkit
Traceback – taaksepäin jäljittäminen – viittaa yleiseen tapaan tutkia virhetilanteen syntymistä sen juurilta alkaen. Python-tulkki tulostaa virhetilanteessa virheviestin, johon olennaisesti kuuluu traceback. Traceback esitetään purkamalla ohjelman funktiokutsuista syntynyt pino, jonka viimeisimmässä osassa varsinainen virhe tapahtui. Tästä syystä tracebackeja kutsutaan myös nimellä stacktrace, eli pinon jäljittäminen. Jos esimerkiksi pääohjelmassa kutsutaan funktiota f, josta käsin kutsutaan funktiota g, jossa virhe tapahtuu, funktiokutsujen pino on muotoa pääohjelmafg.
  1. Kuvaus
  2. Esimerkit
Tulostaminen (engl. print) onkin ohjelmoinnissa jotain muuta – joskaan ei lopulta periaatteiltaan kovin erilaista – kuin paperin ja musteen yhdistämistä halutunlaisiksi sivuiksi. Tietokoneohjelmien yhteydessä tulostamisella tarkoitetaan tekstin tuottamista esiin näytölle, erityisesti terminaaliin. Pythonissa tätä varten on oma funktio, print(...), joka tulostaa sille annetun argumentin terminaaliin.
  1. Kuvaus
  2. Esimerkit
Tynkäfunktio (engl. stub function) on funktio, jolle on kirjoitettu oikeanlainen määrittelyrivi parametreineen, mutta ei oikeaa sisältöä. Niitä yleensä kirjoitetaan koodiin ohjelman rakennetta suunniteltaessa sekä mahdollistamaan funktioiden kutsuminen muualle ohjelmassa siten, että sitä voidaan testata ennen kuin funktioiden toteutus on valmis. Tynkäfunktion sisältönä on usein pelkkä pass, joku informatiivinen tulostus tai jonkin oletusarvon palautus. Isommissa Python-ohjelmissa tynkäfunktioissa on tapana aiheuttaa NotImplementedError-poikkeus, jolloin reitti toteuttamattoman funktion kutsuun on helppo löytää tracebackistä.
Tyylisäännöt ovat kokoelma suosituksia, joiden mukaan koodia tulisi kirjoittaa. Kullakin kielellä on yleensä omansa. Tyylisääntöjen rikkominen ei varsinaisesti riko ohjelmaa, mutta tyylisääntöjen mukainen koodi on miellyttävämpää lukea ja usein tästä johtuen myös helpompi korjata. Tällä kurssilla seurataan Pythonin virallista tyylistandardia erityisesti tekstikenttätehtävissä. Myös tiedostotehtävissä on koodin laadun tarkistus, jossa käytetään PyLint-ohjelmaa.
  1. Kuvaus
  2. Esimerkit
Tyyppi (engl. type) on arvon ominaisuus – jokainen arvo edustaa aina jotain tiettyä tyyppiä. Tyypin tarkoitus on siis kertoa, minkälaisesta arvosta on kyse. Käytännössä tästä seuraa myös se, mitä operaatioita arvoilla voi tehdä, ja mitä metodeja niiltä löytyy. Funktiot on myös miltei aina toteutettu siten, että niille syötettävien argumenttien täytyy olla tietyntyyppisiä, jotta funktio voisi toimia. Tyypit ovat yksi ohjelmoinnin keskeisimmistä käsitteistä.
Pythonissa arvojen sopiminen koodista löytyviin operaatioihin tarkistetaan tilannekohtaisesti näiden arvon ominaisuuksien perusteella – ei siis suoraan itse tyyppiä tarkastamalla. Esimerkiksi useimmissa tapauksissa kokonaisluku ja liukuluku kelpaavat molemmat, mutta on myös tapauksia, joissa näin ei ole (esimerkiksi merkkijonoa ei voi kertoa liukuluvulla).
Tällä kurssilla tyypillisiä tyyppejä ovat kokonaisluku (int), liukuluku (float), merkkijono (str), lista (list), totuusarvo (bool) ja monikko (tuple). Myös funktioilla on oma tyyppinsä!
  1. Kuvaus
  2. Esimerkit
Tyyppimuunnos (engl. type casting, type conversion, type coercion) tarkoittaa sananmukaisesti jonkin koodissa esiintyvän muuttujan tai literaaliarvon tyypin muuntamista toiseksi. Pythonissa tähän törmää usein, kun käyttäjältä on saatu merkkijonona luku, jota halutaan käsitellä esimerkiksi kokonais- tai liukulukuna. Käytännössä tämä onnistuu esimerkiksi lauseilla int("123") tai float("3.14"). Joissain tilanteissa Python-tulkki suorittaa tyyppimuunnoksen automaattisesti, kuten laskettaessa yhteen kokonais- ja liukulukuja.
  1. Kuvaus
  2. Esimerkit
Vakio (engl. constant) on nimetty literaaliarvo. Niitä käytetään erityisesti silloin kun sama literaaliarvo esiintyy koodissa useasti. Yleisesti ottaen nimetty vakio on käytännöllisempi kuin koodissa oleva literaaliarvo, koska sen nimestä voi päätellä mitä se tekee. Samaten jos arvoa tarvitsee muuttaa, vakioita käyttäessä tarvitsee muuttaa vain kohtaa jossa se määritellään. Pythonissa ei ole erillistä tapaa luoda vakioita vaan ne ovat periaatteessa ihan vain muuttujia. Vakioiden nimet kirjoitetaan isolla. Esimerkiksi VASTAUS = 42.
Funktiota kutsuttaessa argumentti on valinnainen (engl. optional argument), jos funktiossa sitä vastaavalle parametrille on määritetty oletusarvo. Tällöin kyseistä argumenttia ei ole pakollista antaa funktiokutsussa. Jos valinnaisia argumentteja on useita, ne annetaan tyypillisesti avainsana-argumentteina.
Vertailuarvoa käytetään esim. listojen järjestämisessä. Vertailuarvo on listan alkiosta johdettu arvo, jota käytetään järjestämisperusteena. Esimerkiksi jos lista sisältää listoja, vertailuarvo voi olla jostain tietystä indeksistä otettu alkio. Se voi olla myös monimutkaisempi johdannainen, kuten listan alkioiden summa tai keskiarvo.
Vertailuoperaattoreita (engl. comparison operators) käytetään, kun verrataan arvoja toisiinsa. Ne ovat matematiikasta tuttuja ja niillä voidaan verrata suuruksia. Vertailuoperaattorit palauttavat totuusarvon True tai False riippuen vertailun lopputuloksesta. Vertailuoperaattoreita ovat <, <=, >, >=, == ja !=.
Ohjelmoinnin asiayhteydessä viittaaminen (engl. reference) tarkoittaa tapaa, jolla muuttuja liittyy arvoonsa. Viittauksen kohde on tietokoneen muisti, ja muuttuja itsessään – konepellin alla – sisältää osoitteen, mistä kohdasta tietokoneen muistia siihen liitetty arvo löytyy.
  1. Kuvaus
  2. Esimerkit
Virheviesti (engl. error message) on Python-tulkin tapa ilmoittaa koodissa tapahtuneesta poikkeuksesta. Virheviestiin kuuluu tieto siitä missä kohdassa koodin suoritusta se tapahtui, mikä rivi kooditiedostossa aiheutti poikkeuksen, poikkeuksen tyyppi (esimerkiksi SyntaxError) sekä lyhyt sanallinen kuvaus. Virheviestit ovat ohjelmoijan paras ystävä, ja niiden lukeminen on erittäin oleellinen ohjelmointitaito. Niitä ei siis ole syytä säikähtää, sillä ne auttavat selvittämään, mikä ohjelman koodissa on pielessä!
  1. Kuvaus
  2. Esimerkit
Avainsana break on erityinen komento, jota käytetään toistorakenteissa. Se päättää silmukan suorituksen välittömästi, ja koodin suoritus jatkuu ensimmäiseltä silmukan jälkeiseltä riviltä. Jos silmukassa oli else-osa, siihen ei mennä.
  1. Kuvaus
  2. Esimerkit
continue on toinen toistorakenteisiin liittyvä avainsana (toisen ollessa break). Toisin kuin break, joka lopettaa koko silmukan suorituksen, continue keskeyttää ainoastaan meneillään olevan kierroksen suorituksen – suoritus jatkuu siis seuraavasta kierroksesta. Huomaa, että tätä avainsanaa tarvitaan vain tilanteissa, joissa halutaan jättää osa kierroksesta suorittamatta, eli silmukan kierroksen loppuun ei ole tarpeen laittaa continue-avainsanaa.
  1. Kuvaus
  2. Esimerkit
enumerate on Pythonissa sisäänrakennettu funktion kaltainen erityisobjekti, joka tuottaa generaattoriobjektin. Sitä käytetään pääasiassa for-silmukoissa silloin, kun on tarpeen saada läpi käytävän listan alkioiden indeksit käyttöön silmukan sisällä. enumerate-objekti tuottaa monikkoja, joissa ensimmäisenä on alkion indeksi ja toisena itse alkio. Käyttöesimerkki: for i, hahmo in enumerate(muumilaakso):.
  1. Kuvaus
  2. Esimerkit
Pythonissa for on toinen silmukkatyyppi. Sen käyttötarkoitus on tietorakenteiden läpikäyminen – iterointi. Sitä käytetään erityisesti listojen kanssa. Yleisesti ottaen for-silmukkaa käytetään silloin, kun pystytään ennalta määrittämään montako kierrosta silmukkaa tulee pyörittää. Tietorakenteiden läpikäynnin lisäksi näihin lukeutuu tietyn toistomäärän tekeminen (esimerkiksi kymmenen toistoa). Silmukan määrittelyrivi on muotoa: for alkio in lista:, jossa alkion paikalle tulee silmukkamuuttujan nimi ja listan paikalla ilmoitetaan läpikäytävä tietorakenne.
  1. Kuvaus
  2. Esimerkit
Pythonissa moduuleja otetaan käyttöön import-lauseella. Normaalikäytössä (esim. import math) lause tuo ohjelmaan uuden nimiavaruuden, joka on sama kuin moduulin nimi. Tämän nimen kautta päästään käsiksi moduulin funktioihin. Nimistä voi myös tuoda ainoastaan osan from-import-lauseella: from math import ceil. Moduulille voidaan myös antaa eri nimi as-avainsanalla: import math as m.
  1. Kuvaus
  2. Esimerkit
Silmukoista while pohjautuu toistoon ehdon tarkastelun kautta - silmukan sisällä olevaa koodilohkoa suoritetaan niin kauan kuin silmukalle annettu ehto on tosi. Ehto määritetään samalla tavalla kuin ehtolauseissa, esim: while summa < 21. While-silmukat soveltuvat parhaiten sellaisiin tilanteisiin, joissa ei voida etukäteen selvittää montako toistoa tarvitaan - erityisesti syötteiden kysyminen käyttäjältä on tällainen tilanne.
  1. Kuvaus
  2. Esimerkit
Pythonissa with on hieman muista poikkeava avainsana, sillä se ei ole varsinaisesti ohjausrakenne tai uuden asian määrittely. Tällä kurssilla sitä käytetään pääasiassa tiedostojen avaamisessa, tyyliin with open("aasi.txt") as tiedosto:. Tiedoston luku- tai kirjoitusoperaatiot suoritetaan with-lauseen alla. Kun with-lohko päättyy, Python huolehtii automaattisesti with-lauseessa avattujen tiedostojen yms. sulkemisesta.