Listan alkiona olioita
Palataan luvun alun esimerkkiin, jossa haluttiin käsitellä
ohjelmointikurssin opiskelijatietoja. Opiskelijoita on sen verran monta,
että ei ole järkevää määritellä omaa muuttujaa jokaista luotavaa
Opiskelija
-oliota varten. Sen sijaan luodut Opiskelija
-oliot
(tai täsmällisesti ottaen viitteet luotuihin olioihin) voidaan tallentaa
listaan. Kun lista on luotu, sen loppuun voidaan lisätä uusi
Opiskelija
-olio esimerkiksi seuraavasti:
opiskelijalista.append(Opiskelija("Matti Virtanen", "11111F"))
Tässä on siis sekä luotu uusi olio että lisätty se heti listan loppuun. Toinen vaihtoehto on luoda ensin olio, panna jokin muuttuja viittaamaan siihen ja lisätä sitten olio listaan tämän muuttujan avulla:
uusi_opiskelija = Opiskelija("Matti Virtanen", "11111F")
opiskelijalista.append(uusi_opiskelija)
Listaa voidaan indeksoida samalla tavalla kuin lukuja sisältävää listaa.
Jos lista jo sisältää vähintään i + 1
alkiota, voidaan sen
indeksille i
sijoittaa viittaus juuri luotuun Opiskelija
-olioon
esimerkiksi seuraavasti (listassa indeksillä aikaisemmin ollut arvo
häviää):
uusi_opiskelija = Opiskelija("Matti Virtanen", "11111F")
opiskelijalista[i] = uusi_opiskelija
Listassa indeksillä i
olevalle Opiskelija
-oliolle voidaan kutsua
Opiskelija
-luokan metodeita seuraavasti:
print("Opiskelijan", opiskelijalista[i].kerro_nimi())
print("kurssiarvosana on", opiskelijalista[i].laske_kokonaisarvosana())
On myös mahdollista käydä for-käskyssä läpi kaikki listan oliot ja kutsua heille jokaiselle vuorotellen luokan metodeita seuraavaan tapaan:
for kurssilainen in opiskelijalista:
print("Opiskelijan", kurssilainen.kerro_nimi())
print("kurssiarvosana on", kurssilainen.laske_kokonaisarvosana())
Katsotaan sitten esimerkkiohjelmaa, joka ensin lukee käyttäjän antamat opiskelijoiden nimet ja opiskelijanumerot, pyytää sen jälkeen käyttäjältä samojen opiskelijoiden tentti- ja harjoitusarvosanat ja lopuksi tulostaa tuloslistan, jossa on myös opiskelijoiden kokonaisarvosanat.
Tämä ohjelma on jaettu useampaan funktioon, ja tieto
Opiskelija
-oliot sisältävästä listasta välitetään funktioiden
välillä funktioiden parametrien ja paluuarvojen avulla.
Funktio lue_kokonaisluku
on jälleen apufunktio, joka lukee
käyttäjältä yhden kokonaisluvun ja käsittelee mahdolliset virheelliset
syötteet.
Funktio lue_opiskelijatiedot
luo ensin tyhjän listan opiskelijoita
varten. Sitten se lukee opiskelijoiden nimet ja opiskelijanumerot
käyttäjältä niin, että yhden opiskelijan nimi ja opiskelijanumero on
annettu yhdellä rivillä. Tästä rivistä erotetaan split
-metodin
avulla erikseen nimi ja opiskelijanumero. Näiden perusteella luodaan
uusi Opiskelija
-olio ja lisätään se listan loppuun. Kun kaikkien
opiskelijoiden tiedot on luettu, funktio palauttaa arvonaan opiskelijat
sisältävän listan.
Funktio lisaa_arvosanatiedot
käy parametrina annetun
Opiskelija
-olioita sisältävän listan läpi olio kerrallaan. Se pyytää
käyttäjältä kunkin opiskelijan tentti- ja harjoitustehtäväarvosanan ja
antaa ne käsiteltävälle oliolle Opiskelija
-luokan metodien avulla.
Funktio tulosta_tulokset
käy jälleen parametrina annetun
Opiskelija
-olioita sisältävän listan läpi. Se tulostaa jokaisesta
opiskelijasta opiskelijanumeron, nimen sekä tentti-, harjoitus- ja
kokonaisarvosanan, jotka selvitetään Opiskelija
-luokan metodien
avulla. Listan läpi käyvä for-käsky on nyt kirjoitettu vähän eri muotoon
kuin edellisessä funktiossa. Tämä ei ole mitenkään välttämätöntä, vaan
for-käsky olisi voitu kirjoittaa myös samalla tavalla kuin funktiossa
lue_arvosanatiedot
. Esimerkissä on vain haluttu näyttää, miten
listaa voi käydä läpi myös indeksoinnin avulla.
Pääohjelma kutsuu määriteltyjä funktioita niin, että halutut toimenpiteet (opiskelijoiden henkilötietojen kysyminen, arvosanatietojen kysyminen ja tulosten tulostaminen) tehdään halutussa järjestyksessä. Tulostamisessa yksi tulosrivi on koottu useasta f-stringien avulla muotoilusta merkkijonosta.
import opiskelija
def lue_kokonaisluku():
luku_onnistui = False
while not luku_onnistui:
try:
luku = int(input())
luku_onnistui = True
except ValueError:
print("Virheellinen kokonaisluku!")
print("Anna uusi!")
return luku
# Funktio lukee kayttajien antamien opiskelijoiden nimet ja
# opiskelijanumerot. Se luo vastaavat Opiskelija-oliot ja
# lisaa ne listaan. Funktio palauttaa taman listan.
def lue_opiskelijatiedot():
opiskelijat = []
print("Anna opiskelijoiden nimet ja opiskelijanumerot")
print("samalla rivilla kauttaviivalla erotettuna.")
print("Lopeta tyhjalla rivilla.")
rivi = input()
while rivi != "":
tiedot = rivi.split("/")
if len(tiedot) != 2:
print("Virheellinen rivi!")
else:
uusi = opiskelija.Opiskelija(tiedot[0], tiedot[1])
opiskelijat.append(uusi)
rivi = input()
print("Opiskelijoiden tiedot luettu!")
return opiskelijat
# Funktio pyytaa kayttajalta parametrina saadussa listassa
# olevien opiskelijoiden tentti- ja harjoitusarvosanat ja
# lisaa ne listan Opiskelija-olioille.
def lisaa_arvosanatiedot(opiskelijalista):
for kurssilainen in opiskelijalista:
print(f"Anna opiskelijan {kurssilainen.kerro_nimi():s} tenttiarvosana:")
tentti_as = lue_kokonaisluku()
print("harjoitusarvosana:")
harjoitus_as = lue_kokonaisluku()
kurssilainen.muuta_tenttiarvosana(tentti_as)
kurssilainen.muuta_harjoitusarvosana(harjoitus_as)
print("Arvosanat lisatty!")
# Funktio tulostaa parametrina annetussa listassa
# olevien Opiskelija-olioiden kurssitulokset.
def tulosta_tulokset(opiskelijat):
print("numero nimi tentti harj kurssi")
for i in range(len(opiskelijat)):
print(f"{opiskelijat[i].kerro_opiskelijanumero():6s} " +
f"{opiskelijat[i].kerro_nimi():15s} " +
f"{opiskelijat[i].kerro_tenttiarvosana():<6d} " +
f"{opiskelijat[i].kerro_harjoitusarvosana():<6d} " +
f"{opiskelijat[i].laske_kokonaisarvosana():<6d}")
def main():
opiskelijatiedot = lue_opiskelijatiedot()
lisaa_arvosanatiedot(opiskelijatiedot)
tulosta_tulokset(opiskelijatiedot)
print("Ohjelma paattyy.")
main()
Alla on esimerkki ohjelman suorituksesta:
Anna opiskelijoiden nimet ja opiskelijanumerot
samalla rivilla kauttaviivalla erotettuna.
Lopeta tyhjalla rivilla.
Virta Nina/66445G
Heikkila Heikki/77553V
Lahti Mika/56789T
Lahti Maija/87642R
Opiskelijoiden tiedot luettu!
Anna opiskelijan Virta Nina tenttiarvosana:
4
harjoitusarvosana:
5
Anna opiskelijan Heikkila Heikki tenttiarvosana:
5
harjoitusarvosana:
5
Anna opiskelijan Lahti Mika tenttiarvosana:
1
harjoitusarvosana:
3
Anna opiskelijan Lahti Maija tenttiarvosana:
5
harjoitusarvosana:
0
Arvosanat lisatty!
numero nimi tentti harj kurssi
66445G Virta Nina 4 5 5
77553V Heikkila Heikki 5 5 5
56789T Lahti Mika 1 3 2
87642R Lahti Maija 5 0 0
Ohjelma paattyy.