Toinen esimerkki

Tarkastellaan toisena esimerkkinä luokkaa Vesisailio, joka kuvaa yhden vesisäiliön toimintaa. Vesisäiliöön voi lisätä vettä ja siitä voi poistaa vettä. Vesisäiliöllä on kuitenkin koko, eikä säiliöön voi lisätä vettä enempää kuin siihen mahtuu. Säiliöstä ei voi myöskään poistaa vettä enempää kuin mitä siinä on. Esimerkin mielekkyys ei välttämättä tunnu heti ilmeiseltä, mutta esimerkkiluokkaa voi käyttää vähän muuttamalla sellaisissa sovelluksissa, joissa tarkastellaan jonkin tuotteen määrää varastossa. Lisäksi esimerkistä on helppo muokata luokka vaikka pankkitilin kuvaamiseen.

Luokan määrittely aloitetaan jälleen luokan otsikolla:

class Vesisailio:

Metodissa __init__ annetaan alkuarvot olion kentille __koko ja __maara. Näistä ensimmäinen kertoo käsiteltävän vesisälilön koon ja toinen veden määrän säiliössä. Luotavalle säiliölle annettava koko kerrotaan metodin parametrin avulla. Metodi tarkistaa, että annettu koko on vähintään 0. Se ei siis luo säiliöitä, joilla on negatiivinen koko. Uuden säiliön veden määräksi sijoitetaan 0.

def __init__(self, annettu_koko):
    if annettu_koko >= 0.0:
        self.__koko = annettu_koko
    else:
        self.__koko = 0.0
    self.__maara = 0.0

Luokkaan määritellään metodit kerro_koko ja kerro_maara, jotka palauttavat vastaavien kenttien arvot:

def kerro_koko(self):
    return self.__koko


def kerro_maara(self):
    return self.__maara

Metodin lisaa avulla voida lisätä veden määrää säiliössä. Metodi tutkii ensin, että sille annettu parametri on vähintään 0 (negatiivista määrää ei voi lisätä). Tämän jälkeen metodi tutkii, paljonko vesisäiliöön vielä mahtuu vettä. Jos parametrina annettu lisättävä määrä on korkeintaan yhtä suuri kuin säiliöön mahtuva määrä, koko haluttu määrä lisätään. Jos lisättävä määrä on suurempi kuin säiliöön mahtuva määrä, lisätään vain niin paljon kuin säiliöön mahtuu. Molemmissa tapauksissa säiliössä olevan veden määrää (kenttä __maara) kasvatetaan lisätyllä määrällä ja metodi palauttaa arvonaan oikeasti lisätyn määrän.

def lisaa(self, paljonko):
    if paljonko > 0.0:
        mahtuu = self.__koko - self.__maara
        if paljonko <= mahtuu:
            self.__maara += paljonko
            return paljonko
        else:
            self.__maara = self.__koko
            return mahtuu
    else:
        return 0.0

Metodin poista avulla voidaan poistaa vettä säiliöstä. Poistettava määrä annetaan metodille parametrina. Jälleen ensin tutkitaan, että poistettava määrä on vähintään 0 (negatiivista määrää ei voi poistaa). Sen jälkeen tutkitaan, onko parametrina annettu poistettava määrä suurempi kuin säiliössä tällä hetkellä oleva vesimäärä. Jos on, säiliöstä poistetaan vain niin paljon vettä kuin siellä on. Muussa tapauksessa säiliöstä poistetaan vettä haluttu määrä. Molemmissa tapauksissa metodi vähentää __maara-kentän arvoa ja palauttaa arvonaan säiliöstä oikeasti poistetun vesimäärän.

def poista(self, paljonko):
    if paljonko > 0.0:
        if paljonko > self.__maara:
            poistetaan = self.__maara
            self.__maara = 0.0
            return poistetaan
        else:
            self.__maara -= paljonko
            return paljonko
    else:
        return 0.0

Lisäksi määritellään metodi __str__, joka palauttaa merkkijonon, joka sisältää käsiteltävän Vesisailio-olion kenttien arvot.

def __str__(self):
    mjono = "Sailio: vetta " + str(self.__maara) + \
            " / " + str(self.__koko) + " l"
    return mjono

Luokan määrittely loppuu tähän.

Seuraavaksi on kirjoitettu pääohjelma, joka luo kaksi Vesisailio-oliota sekä lisää niihin vettä ja poistaa niistä vettä. Vesisäiliöiden koot sekä lisättävät ja poistettavat määrät kysytään käyttäjältä. Ohjelma myös tulostaa lisätyt ja poistetut määrät sekä vesisäiliöiden tiedot ohjelman lopussa. Ohjelma on kirjoitettu eri moduuliin kuin luokka Vesisailio. Alla olevassa koodissa on oletettu, että luokka on kirjoitettu moduuliin vesisailio (tiedoston nimi vesisailio.py). Käyttäjältä kysyttävien lukujen lukemiseen on kirjoitettu apufunktio, joka myös käsittelee mahdolliset virheelliset syötteet:

import vesisailio

def lue_desimaaliluku():
    luku_onnistui = False
    while not luku_onnistui:
        try:
            luku = float(input())
            luku_onnistui = True
        except ValueError:
            print("Virheellinen desimaaliluku!")
            print("Anna uusi!")
    return luku

def main():
    print("Anna ensimmaisen sailion koko.")
    koko1 = lue_desimaaliluku()
    sailio1 = vesisailio.Vesisailio(koko1)
    print("Anna toisen sailion koko.")
    koko2 = lue_desimaaliluku()
    sailio2 = vesisailio.Vesisailio(koko2)

    print("Lisataan vetta 1. sailioon.")
    print("Anna lisattava maara.")
    lisays = lue_desimaaliluku()
    lisattiin = sailio1.lisaa(lisays)
    print(f"Sailioon lisattiin {lisattiin:.2f} l.")
    print("Lisataan vetta 2. sailioon.")
    print("Anna lisattava maara.")
    lisays = lue_desimaaliluku()
    lisattiin = sailio2.lisaa(lisays)
    print(f"Sailioon lisattiin {lisattiin:.2f} l.")

    print("Poistetaan vetta 1. sailiosta.")
    print("Anna poistettava maara.")
    poisto = lue_desimaaliluku()
    poistettiin = sailio1.poista(poisto)
    print(f"Sailiosta poistettiin {poistettiin:.2f} l.")
    print("Poistetaan vetta 2. sailiosta.")
    print("Anna poistettava maara.")
    poisto = lue_desimaaliluku()
    poistettiin = sailio2.poista(poisto)
    print(f"Sailiosta poistettiin {poistettiin:.2f} l.")

    print("Ensimmaisen sailion tiedot:")
    print(sailio1)
    print("Toisen sailion tiedot:")
    print(sailio2)

main()

Seuraavaksi esimerkki ohjelman suorituksesta. Huomaa esimerkistä, kuinka säiliöihin ei todellakaan lisätä vettä enempää kuin mitä mahtuu eikä poisteta enempää kuin mitä säiliössä on. Todellisuudessa lisätyt ja poistetut määrät on pystytty tulostamaan käyttämällä hyväksi metodien paluuarvoja.

Anna ensimmaisen sailion koko.
50.0
Anna toisen sailion koko.
30.0
Lisataan vetta 1. sailioon.
Anna lisattava maara.
28.5
Sailioon lisattiin 28.50 l.
Lisataan vetta 2. sailioon.
Anna lisattava maara.
jotain
Virheellinen desimaaliluku!
Anna uusi!
41.0
Sailioon lisattiin 30.00 l.
Poistetaan vetta 1. sailiosta.
Anna poistettava maara.
29.5
Sailiosta poistettiin 28.50 l.
Poistetaan vetta 2. sailiosta.
Anna poistettava maara.
11.1
Sailiosta poistettiin 11.10 l.
Ensimmaisen sailion tiedot:
Sailio: vetta 0.0 / 50.0 l
Toisen sailion tiedot:
Sailio: vetta 18.9 / 30.0 l