Kirjautuminen

Haku

Tehtävät

Oppaat: Python-ohjelmointi: Osa 7 - Omat funktiot

  1. Osa 1 - Ensimmäinen ohjelma
  2. Osa 2 - Tiedon käsittely
  3. Osa 3 - Ehtorakenteet
  4. Osa 4 - Toistorakenteet
  5. Osa 5 - Listojen käsittely
  6. Osa 6 - Merkkijonot
  7. Osa 7 - Omat funktiot
  8. Osa 8 - Tiedostot ja virheet
  9. Osa 9 - Standardikirjasto
  10. Osa 10 - Tietorakenteet
  11. Osa 11 - Alkeita edemmäs
  12. Osa 12 - Yhteenveto
  13. Liite 1 - Asennus ja käyttö

Kirjoittaja: Antti Laaksonen. Vuosi: 2015.

Opassarjan kuluessa on tutustuttu moneen hyödylliseen funktioon. Esimerkiksi funktio str muuttaa arvon merkkijonoksi, funktio range muodostaa lukuja sisältävän listan, funktio len laskee merkkijonon merkkien määrän ja funktio min etsii listan pienimmän luvun.

Tämän oppaan aiheena on omien funktioiden laatiminen. Funktiot selventävät koodin rakennetta, koska niiden avulla eri puolilla ohjelmaa tarvittava samanlainen koodi täytyy kirjoittaa vain kerran. Lisäksi hyvin suunniteltuja funktioita voi käyttää uudestaan tulevissa ohjelmissa.

Oppaan ensimmäinen funktio tulostaa tekstin laatikon sisään. Seuraavaksi nähdään, mitä hyötyä funktiosta on tässä tapauksessa.

Johdanto: Toistuva koodi

Seuraava ohjelma tulostaa tekstin laatikkoon:

print("*" * 15)
print("*", "Tervetuloa!", "*")
print("*" * 15)

Ohjelman tulostus on seuraava:

***************
* Tervetuloa! *
***************

Tässä "*" * 15 on lyhennysmerkintä, joka tarkoittaa 15 tähtimerkkiä. Vastaavasti "abc" * 4 olisi merkkijono "abcabcabcabc".

Samalla tavalla voi toteuttaa ohjelman, jossa kaikki tekstit ovat laatikoissa:

print("*" * 15)
print("*", "Tervetuloa!", "*")
print("*" * 15)
print("*" * 20)
print("*", "Anna tunnussana:", "*")
print("*" * 20)
sana = input()
if sana == "python":
    print("*" * 11)
    print("*", "Oikein!", "*")
    print("*" * 11)
else:
    print("*" * 11)
    print("*", "Väärin!", "*")
    print("*" * 11)

Ohjelman tulostus voi olla seuraava:

***************
* Tervetuloa! *
***************
********************
* Anna tunnussana: *
********************
python
***********
* Oikein! *
***********

Ohjelma toimii kyllä halutulla tavalla, mutta sen koodissa on turhaa toistoa, koska laatikon tulostavat komennot on kopioitu moneen kohtaan. Seuraavaksi nähdään, kuinka koodin rakennetta voi parantaa funktion avulla.

Funktio

Seuraavassa ohjelmassa on funktio laatikko, joka tulostaa halutun tekstin laatikkoon. Ohjelman toiminta vastaa edellistä ohjelmaa, mutta koodin rakenne on huomattavasti selkeämpi.

def laatikko(teksti):
    print("*" * (len(teksti) + 4))
    print("*", teksti, "*")
    print("*" * (len(teksti) + 4))

laatikko("Tervetuloa!")
laatikko("Anna tunnussana:")
sana = input()
if sana == "python":
    laatikko("Oikein!")
else:
    laatikko("Väärin!")

Funktion alussa on sana def, jonka jälkeen tulee funktion nimi laatikko. Sitten suluissa ovat funktion parametrit. Tässä funktiolla on yksi parametri teksti, joka tarkoittaa tekstiä, joka funktion täytyy tulostaa laatikkoon.

Funktio laatikko yleistää tekstin tulostuksen laatikkoon. Funktiolle voi antaa parametrina minkä tahansa tekstin ja funktio osaa tulostaa sen ympärille oikean määrän tähtimerkkejä. Merkintä "*" * (len(teksti) + 4) tarkoittaa, että tähtimerkkejä on neljä enemmän kuin tekstin pituus.

Seuraavassa ohjelmassa myös laatikon reunamerkki on funktion parametri:

def laatikko(teksti, reuna):
    print(reuna * (len(teksti) + 4))
    print(reuna, teksti, reuna)
    print(reuna * (len(teksti) + 4))

laatikko("Tervetuloa!", "*")
laatikko("Anna tunnussana:", "?")
sana = input()
if sana == "python":
    laatikko("Oikein!", "!")
else:
    laatikko("Väärin!", "!")

Ohjelman tulostus voi olla seuraava:

***************
* Tervetuloa! *
***************
????????????????????
? Anna tunnussana: ?
????????????????????
python
!!!!!!!!!!!
! Oikein! !
!!!!!!!!!!!

Nyt funktiolla on kaksi parametria: parametri teksti on tulostettava teksti ja parametri reuna on merkki, jolla teksti täytyy ympäröidä.

Palautusarvo

Funktio palauttaa usein arvon ohjelman kohtaan, jossa funktiota kutsutaan. Näin toimii esimerkiksi funktio len, joka palauttaa sille annetun merkkijonon pituuden. Funktiossa komento return poistuu funktiosta ja palauttaa arvon.

Seuraavassa ohjelmassa on funktio kaanna, joka kääntää merkkijonon toisinpäin. Ohjelma kysyy käyttäjältä sanoja ja kääntää niitä toisinpäin.

def kaanna(mjono):
    uusi = ""
    for merkki in mjono:
        uusi = merkki + uusi
    return uusi

while True:
    sana = input("Anna sana: ")
    if sana == "":
        break
    print("Toisinpäin: " + kaanna(sana))

Ohjelman tulostus voi olla seuraava:

Anna sana: kirja
Toisinpäin: ajrik
Anna sana: valinta
Toisinpäin: atnilav
Anna sana: puro
Toisinpäin: orup
Anna sana:

Ohjelma kutsuu silmukassa funktiota kaanna parametrina käännettävä sana. Funktio muodostaa käännetyn sanan ja palauttaa sen komennolla return. Sitten käännetty sana liittyy tulostettavan merkkijonon osaksi.

Funktion kaanna avulla voi myös tarkistaa, onko sana palindromi eli onko se sama alusta loppuun ja lopusta alkuun luettuna. Tehdään sitä varten uusi funktio palindromi:

def palindromi(sana):
    return sana == kaanna(sana)

Tämä funktio palauttaa totuusarvon (True tai False) sen mukaan, onko sille annettu sana palindromi vai ei. Funktio palindromi kutsuu funktiota kaanna, koska se haluaa verrata sanaa toisinpäin käännettyyn sanaan. Jos sana on palindromi, se on sama käännettynä.

Seuraava ohjelma kertoo, ovatko käyttäjän antamat sanat palindromeja:

def kaanna(teksti):
    uusi = ""
    for merkki in teksti:
        uusi = merkki + uusi
    return uusi

def palindromi(teksti):
    return teksti == kaanna(teksti)

while True:
    sana = input("Anna sana: ")
    if sana == "":
        break
    if palindromi(sana):
        print("Sana on palindromi!")
    else:
        print("Sana ei ole palindromi!")

Ohjelman tulostus voi olla seuraava:

Anna sana: enne
Sana on palindromi!
Anna sana: kaivo
Sana ei ole palindromi!
Anna sana: syksy
Sana ei ole palindromi!
Anna sana: autioitua
Sana on palindromi!
Anna sana:

Kun käyttäjä kirjoittaa sanan, tapahtuu seuraavaa:

  1. Pääohjelma kutsuu funktiota palindromi.
  2. Funktio palindromi kutsuu funktiota kaanna.
  3. Funktio kaanna palauttaa funktiolle palindromi käännetyn sanan.
  4. Funktio palindromi palauttaa pääohjelmalle arvon True, jos sana on palindromi, ja arvon False, jos sana ei ole palindromi.

Esimerkki: Alkuluvut

Alkuluku on positiivinen kokonaisluku, joka on jaollinen vain luvulla 1 ja itsellään. Lisäksi on sovittu, että luku 1 ei ole alkuluku. Seuraava ohjelma etsii kaikki alkulukut, jotka ovat pienempiä kuin 50.

def alkuluku(luku):
    if luku < 2:
        return False
    for jakaja in range(2, luku):
        if luku % jakaja == 0:
            return False
    return True

for luku in range(50):
    if alkuluku(luku):
        print(luku, end = ", ")
print()

Ohjelman tulostus on seuraava:

2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47,

Funktio alkuluku käsittelee luvun seuraavasti:

Tässä range(2, luku) kuvaa lukuväliä, jonka ensimmäinen luku on 2 ja viimeinen luku on yksi pienempi kuin luku. Esimerkiksi range(2, 7) sisältää luvut 2, 3, 4, 5 ja 6. Luku 7 ei ole jaollinen millään näistä luvuista, joten luku 7 on alkuluku.

Esimerkki: Tilasto

Seuraava ohjelma näyttää tilaston listan aineistosta:

def tilasto(luvut):
    if len(luvut) == 0:
        print("Tyhjä aineisto!")
        return
    for luku in luvut:
        print("*" * luku, luku)
    print("Keskiarvo:", round(sum(luvut) / len(luvut), 2))

tilasto([5, 3, 10, 8, 4, 4, 9, 3])

Ohjelman tulostus on seuraava:

***** 5
*** 3
********** 10
******** 8
**** 4
**** 4
********* 9
*** 3
Keskiarvo: 5.75

Funktion tilasto parametri on lista lukuja. Jos lista on tyhjä, funktio tulostaa virheviestin ja päättyy heti. Tässä funktio ei palauta arvoa, minkä vuoksi komennon return ainoa tarkoitus on poistua funktiosta.

Funktio käy läpi listan luvut ja tulostaa niitä vastaavat palkit. Lopuksi funktio laskee lukujen keskiarvon jakamalla lukujen summan niiden määrällä. Lukujen summa on muutettu liukuluvuksi, jotta jakolaskun lopputulos on liukuluku.

Yhteiset muuttujat

Funktion sisäiset muuttujat eivät vaikuta pääohjelman ja muiden funktioiden muuttujiin. Seuraavassa ohjelmassa sekä pääohjelmassa että funktiossa on muuttuja nimi, mutta muuttujat ovat erillisiä. Vaikka funktion muuttuja nimi saa arvon "Uolevi", pääohjelman muuttujan nimi arvo on edelleen "Henrikki".

def muutos():
    nimi = "Uolevi"

nimi = "Henrikki"
muutos()
print(nimi) # tulostaa "Henrikki"

Sanan global avulla pääohjelman ja funktion muuttujat voi yhdistää. Seuraavassa ohjelmassa muuttuja nimi on yhteinen, jolloin funktion suorituksen jälkeen myös pääohjelmassa muuttujan nimi arvo on "Uolevi".

def muutos():
    global nimi
    nimi = "Uolevi"

nimi = "Henrikki"
muutos()
print(nimi) # tulostaa "Uolevi"

Kirjoita kommentti

Huomio! Kommentoi tässä ainoastaan tämän oppaan hyviä ja huonoja puolia. Älä kirjoita muita kysymyksiä tähän. Jos koodisi ei toimi tai tarvitset muuten vain apua ohjelmoinnissa, lähetä viesti keskusteluun.

Muista lukea keskustelun ohjeet.
Tietoa sivustosta