Arvon palauttavat funktiot
Tarkastellaan vähän toisenlaista versiota sijoituksen arvon kehittymisen laskevasta ohjelmasta: tällä kerralla käyttäjä haluaa vertailla useaa eri sijoitusmahdollisuutta, joilla on eri vuosituotto. Käyttäjällä on mielessään sijoitettava pääoma ja sijoitusaika ja hän haluaa vertailla pääoman arvoa sijoitusajan jälkeen eri sijoitustavoissa.
Ohjelmassa käyttäjä antaa oletetun vuosituoton käyttötilille, sijoitustilille, korkorahastosijoitukselle ja osakerahastosijoitukselle. Ohjelma laskee käyttäjän antaman pääoman arvon annetun sijoitusajan jälkeen ja tulostaa pääoman ennustetun arvon eri sijoitustavoille.
Tässä ohjelmassa pääoman arvo sijoitusajan jälkeen pitää laskea neljä eri kertaa. Jokaisella kerralla käytetään samaa kaavaa, mutta käytetty vuosituottoprosentti vaihtelee. On siis järkevää tehdä oma funktio, joka saa parametrina pääoman, sijoitusajan ja tuottoprosentin ja laskee pääoman arvon sijoitusajan jälkeen.
Tällä kerralla ei kuitenkaan haluta, että arvon laskeva funktio tulostaa käyttäjälle sijoituksen arvon, vaan tulostus halutaan tehdä pääohjelmassa. Näin funktiota voidaan käyttää monipuolisemmin, kun sen laskeman arvon tulostus on erotettu itse laskemisesta. Funktion laskema arvo voidaan tulostaa ohjelmassa vasta selvästi myöhemmin kuin itse laskeminen tapahtui tai laskettua arvoa voidaan käyttää ohjelmassa myöhemmin hyväksi.
Määritellään siis funktio laske_arvo
, joka laskee sijoituksen arvon
annetun sijoitusajan jälkeen. Alkuperäinen pääoma, sijoitusaika ja
vuosittainen tuottoprosentti annetaan tälle funktiolle parametreina. Nyt
tarvitaan kuitenkin jokin keino, jolla pääohjelma saa tietoonsa funktion
laskeman arvon, jotta tätä arvoa voitaisiin käyttää pääohjelmassa. Tähän
tarkoitukseen käytetään arvon palauttamista.
Funktio saadaan palauttamaan jokin arvo kirjoittamalla
return lauseke
missä lauseke
voi olla mikä tahansa lauseke, jonka arvo voidaan
laskea, myös pelkkä muuttujan nimi. Arvon palauttaminen tarkoittaa sitä,
että lasketaan lausekkeen arvo, päätetään funktion suoritus ja palataan
takaisin sinne kohtaan, missä funktiota kutsuttiin. Tässä kohdassa
funktion palauttama lausekkeen arvo on käytettävissä: se voidaan
esimerkiksi ottaa talteen johonkin muuttujaan sijoituskäskyn avulla tai
tulostaa suoraan print
-käskyssä. Tätä selvennetään alla olevassa
esimerkissä.
Funktio laske_arvo
voidaan kirjoittaa esimerkiksi seuraavasti:
def laske_arvo(paaoma, aika, vuosituotto):
loppuarvo = (1.0 + vuosituotto/100.0) ** aika * paaoma
return loppuarvo
loppuarvo
arvoksi.loppuarvo
arvo.Palautettu arvo saadaan käyttöön siellä, missä funktiota kutsutaan esimerkiksi sijoittamalla arvo johonkin muuttujaan seuraavasti:
sijoituksen_arvo = laske_arvo(10000, 5, 4.0)
Tässä on kutsuttu funktiota laske_arvo
suluissa annetuilla
parametrien arvoilla. Funktion suorittamisen jälkeen sen palauttama arvo
on sijoitettu muuttujaan sijoituksen_arvo
. Tämän jälkeen muuttujaa
sijoituksen_arvo
voi käyttää ohjelmassa samaan tapaan kuin mitä
tahansa muuta muuttujaa. Sijoituskäsky siis suoritetaan ihan samalla
tavalla kuin aikaisemmissa esimerkeissä esitetyt sijoituskäskyt: Ensin
lasketaan sijoituskäskyn oikealla puolella olevan lausekkeen arvo, mikä
funktiokutsun tapauksessa tarkoittaa kutsutun funktion suorittamista
suluissa annetuilla parametrien arvoilla. Tämän jälkeen lausekkeen arvo
eli funktion palauttama arvo annetaan arvoksi sijoituskäskyn vasemmalla
puolella olevalle muuttujalle. Voit tutkia funktion ja sen kutsun toimintaa
vielä alla olevan animaation avulla:
Funktion palauttamaa arvoa voidaan käyttää myös suoraan ilman että arvo tallennetaan minkään muuttujan arvoksi, esimerkiksi seuraavasti
print("Arvo lopuksi", laske_arvo(10000, 5, 4.0))
Tässä kutsutaan ensin funktiota laske_arvo
, suoritetaan funktio ja
sen jälkeen tulostetaan funktion palauttama arvo yhdessä muun
print
-käskyssä annetun tekstin kanssa. Tässä tapauksessa funktion
palauttamaa arvoa ei ole kuitenkaan tallennettu minkään muuttujan
arvoksi, joten arvoa ei voida käyttää ohjelmassa enää tämän jälkeen
muuten kuin kutsumalla funktiota uudestaan.
Myös funktio laske_arvo
voidaan kirjoittaa toisella tavalla kuin
edellä on esitetty. Kuten kerrottiin, return
-käskyssä voi
palautettavana arvona olla mikä tahansa lauseke, jonka arvo voidaan
laskea. Niinpä ei ole mikään pakko tallentaa funktion laskemaa arvoa
johonkin muuttujaan ennen return
-käskyn suorittamista, vaan
laskettava lauseke voidaan kirjoittaa suoraan return
-käskyyn
seuraavan esimerkin mukaisesti:
def laske_arvo2(paaoma, aika, vuosituotto):
return (1.0 + vuosituotto/100.0) ** aika * paaoma
Tässä lasketaan ensin return
-käskyssä olevan lausekkeen arvo ja
palautetaan se samalla kun lopetetaan funktion suoritus. Funktiota
voidaan kutsua ja sen palauttamaa arvoa käyttää ihan samalla tavalla
kuin edellisessä esimerkissä.
Seuraavaksi esimerkkiohjelma, joka pyytää käyttäjältä sijoitettavan pääoman, sijoitusajan vuosina sekä oletetut tuottoprosentit eri sijoitusmuodoille. Ohjelma tulostaa sijoitusten arvon sijoitusajan jälkeen.
def laske_arvo(paaoma, aika, vuosituotto):
loppuarvo = (1.0 + vuosituotto/100.0) ** aika * paaoma
return loppuarvo
def main():
rivi = input("Anna sijoitettava paaoma: ")
rahamaara = float(rivi)
rivi = input("Anna sijoitusaika vuosina: ")
vuodet = int(rivi)
rivi = input("Anna kayttotilin korko: ")
korko = float(rivi)
kayttotilisijoitus = laske_arvo(rahamaara, vuodet, korko)
rivi = input("Anna sijoitustilin korko: ")
korko = float(rivi)
sijoitustilisijoitus = laske_arvo(rahamaara, vuodet, korko)
rivi = input("Anna korkorahaston vuosituotto: ")
korko = float(rivi)
korkorahastosijoitus = laske_arvo(rahamaara, vuodet, korko)
rivi = input("Anna osakerahaston vuosituotto: ")
korko = float(rivi)
osakerahastosijoitus = laske_arvo(rahamaara, vuodet, korko)
print("Sijoitusten arvo", vuodet, "vuoden paasta:")
print("Kayttotili:", kayttotilisijoitus, "euroa")
print("Sijoitustili:", sijoitustilisijoitus, "euroa")
print("Korkorahasto:", korkorahastosijoitus, "euroa")
print("Osakerahasto", osakerahastosijoitus, "euroa")
main()
Python-ohjelmissa yksi funktio voi myös palauttaa kerralla useamman arvon, jotka voidaan ottaa talteen samanaikaisella sijoituksella. Tarkastellaan esimerkkinä seuraavaa ongelmaa: Internetissä ja urheilulehdissä on hyvin paljon erilaisia harjoitusohjelmia juoksuharrastuksen aloittamiseen ja kehittämiseen. Ongelma on kuitenkin se, että englanninkielisillä sivuilla ja lehdissä on yleensä annettu ohjeelliset juoksunopeudet juostavaa mailia kohti, kun taas suomalainen haluaisi tarkastella nopeutta kilometriä kohti. Kirjoitetaan ohjelma, jonka avulla käyttäjä voi helposti muuttaa esimerkiksi harjoitusohjelmassa annetun nopeusohjeen 8 min 5 s – 9 min 30 s / maili nopeudeksi kilometriä kohti.
Nopeusmuunnosta varten kirjoitetaan funktio muuta_km_vauhdiksi
, joka
saa parametrina mailinopeuden minuutit ja sekunnit ja muuttaa
mailinopeuden nopeudeksi kilometriä kohti. Funktion halutaan palauttavan
arvonaan sekä kilometrivauhdin minuutit että sekunnit. Tämä voidaan
tehdä kirjoittamalla return
-käskyyn molemmat palautettavat arvot
pilkulla erotettuna.
return km_minuutit, km_sekunnit
Funktion palauttamat arvot voidaan ottaa talteen esimerkiksi muuttujiin
ala_min
ja ala_s
seuraavalla sijoituskäskyllä:
ala_min, ala_s = muuta_km_vauhdiksi(maili_minuutit, maili_sekunnit)
Alla on funktion muuta_km_vauhdiksi
koodi:
def muuta_km_vauhdiksi(minuutit, sekunnit):
MAILIKERROIN = 1.609344
km_vauhti = int ((minuutit * 60 + sekunnit) / MAILIKERROIN)
km_minuutit = km_vauhti // 60
km_sekunnit = km_vauhti % 60
return km_minuutit, km_sekunnit
Alla on esimerkki pääohjelmasta, joka pyytää käyttäjältä kaksi eri mailinopeutta ja muuntaa ne annetun funktion avulla kilometrinopeuksiksi.
def main():
rivi = input("Anna nopeuden alarajan minuutit: ")
maili_min = int(rivi)
rivi = input("Anna nopeuden alarajan sekunnit: ")
maili_sek = int(rivi)
ala_min, ala_s = muuta_km_vauhdiksi(maili_min, maili_sek)
rivi = input("Anna nopeuden ylarajan minuutit: ")
maili_min = int(rivi)
rivi = input("Anna nopeuden ylarajan sekunnit: ")
maili_sek = int(rivi)
yla_min, yla_s = muuta_km_vauhdiksi(maili_min, maili_sek)
print("Suositeltu nopeus on", ala_min, "min", ala_s, "s / km -",
yla_min, "min", yla_s, "s / km")
main()
muuta_km_vauhdiksi
. Tallennetaan sen ensimmäinen
paluuarvo muuttujaan ala_min
ja toinen paluuarvo muuttujaan ala_s
.muuta_km_vauhdiksi
. Tallennetaan sen ensimmäinen
paluuarvo muuttujaan yla_min
ja toinen paluuarvo muuttujaan yla_s
.Esimerkki ohjelman suorituksesta:
Anna nopeuden alarajan minuutit: 8
Anna nopeuden alarajan sekunnit: 5
Anna nopeuden ylarajan minuutit: 9
Anna nopeuden ylarajan sekunnit: 30
Suositeltu nopeus on 5 min 1 s / km - 5 min 54 s / km
Sisäkkäiset funktiokutsut
Kuten aikaisemmin on todettu, funktiota kutsuttaessa parametrina voidaan antaa mikä tahansa lauseke, jonka arvo voidaan laskea. Myös toisen funktion kutsu on tällainen lauseke. Voidaan siis kirjoittaa funktion kutsu, jonka sisällä on parametrin arvona toisen (tai joissakin tapauksissa myös saman) funktion kutsu. Tällöin aina sisempi funktiokutsu suoritetaan ensin, ja sen paluuarvoa käytetään ulomman funktion parametrina.
Hyvin tyypillinen esimerkki sisäkkäisistä funktiokutsuista on tilanne,
jossa käyttäjältä luetaan arvo Pythonin valmiin input
-funktion
avulla ja tämä arvo pitää sitten muuttaa kokonais- tai desimaaliluvuksi
Pythonin valmiin int
- tai float
-funktion avulla. Tähän asti
olleissa esimerkeissä tämä on tehty kahdella eri ohjelmarivillä, joista
ensimmäisellä luetaan haluttu arvo ja toisella se muutetaan sopivan
tyyppiseksi luvuksi, esimerkiksi:
rivi = input("Anna nopeuden ylarajan sekunnit: ")
maili_sek = int(rivi)
Käskyt voidaan kuitenkin yhdistää yhdelle riville, jos
input
-funktion kutsu annetaan suoraan int
-funktion parametrina:
maili_sek = int(input("Anna nopeuden ylarajan sekunnit: "))
Nyt siis suoritetaan ensin sulkujen sisällä oleva input
-funktion
kutsu, joka pyytää ja lukee käyttäjältä sekuntien arvon. Funktio
palauttaa käyttäjältä saadun arvon merkkijonona. Tämä merkkijono tulee
ulomman int
-funktion kutsun parametrin arvoksi. Funktio int
taas
palauttaa sille parametrina annettua merkkijonoa vastaavan
kokonaisluvun. Rivin suoritus on vielä esitetty seuraavassa animaatiossa:
Pythonin valmiit kirjastot ja moduuli math
Pythoniin on määritelty valmiiksi suuri joukko funktioita erilaisten
toimintojen tekemiseen. Suuri osa näistä funktioista on ryhmitelty
kirjastoihin. Tyypillisesti yhteen kirjastoon on koottu joukko samaan
aiheeseen liittyviä valmiita funktioita ja mahdollisesti myös vakioita.
Näitä kirjastoja nimetetään Pythonissa moduuleiksi. Python-tulkin mukana
tulee esimerkiksi moduuli math
, joka sisältää erilaisia matemaattisia
funktioita (esimerkiksi neliöjuuren laskemiseeen) ja vakioita, sekä kirjasto
random
, jossa on taas satunnaislukujen generoimiseen tarkoitettuja
funktioita, joiden avulla voi jäljitellä lukujen arpomista.
Python-tulkin mukana tulevien kirjastojen lisäksi on julkisesti vapaasti
saatavilla suuri joukko muita Python-kirjastoja, esimerkiksi NumPy
tieteellistä laskentaa (esimerkiksi isojen matriisien tehokasta käsittelyä)
varten ja Pandas
datan käsittelyyn ja analysointiin.
Seuraavaksi käsitellään moduulia math
ja sen sisältämiä funktioita ja
vakioita. Kirjasto on asennettu valmiiksi Python-tulkin mukana, mutta
jotta sen funktioita voisi käyttää, pitää ohjelmatiedoston alussa ensin
kertoa, että ohjelmassa käytetään tätä kirjastoa. Se tehdään kirjoittamalla
import math
Tämän jälkeen ohjelmassa voidaan kutsua kirjaston sisältämiä funktioita
kirjoittamalla ensin math.
ja sen jälkeen funktion nimi, esimerkiksi
luvun 17 neliöjuuri voidaan laskea kirjoittamalla
math.sqrt(17)
Alla olevaan taulukkoon on koottu joitakin tärkeimpiä math
-moduulin
sisältämiä funktioita. Taulukko ei sisällä läheskään kaikkia funktioita.
Kattavan listan voi lukea Pythonin omasta dokumentaatiosta (linkki).
Funktio | Selitys |
ceil(x) |
pienin kokonaisluku, joka on \(\ge x\) |
floor(x) |
suurin kokonaisluku, joka on \(\le x\) |
trunc(x) |
x :n kokonaisosa ilman pyöristyksiä |
sqrt(x) |
neliöjuuri |
exp(x) |
e potenssiin x |
log(x) |
luonnollinen logaritmi |
log2(x) |
2-kantainen logaritmi |
log10(x) |
10-kantainen logaritmi |
cos(x) |
kosini |
sin(x) |
sini |
tan(x) |
tangentti |
Funktioiden lisäksi moduulissa on määritelty myös joitakin matemaattisia vakioita, esimerkiksi alla olevassa taulukossa esitetyt
Vakio | Selitys |
math.pi |
pii |
math.e |
luonnollisen logaritmin kantaluku |
math.inf |
suurin mahdollinen float-tyyppinen arvo |
Esimerkki
Oletetaan, että kesämökille on kaksi mahdollista reittiä: sinne voi kulkea kuvan mukaista tietä pitkin. Tie muodostaa suorakulmaisen kolmion kaksi sivua (kateetit). Toinen vaihtoehto on oikaista suoraan pellon ja metsän kautta. Suorempi reitti on selvästi lyhyempi (em. suorakulmaisen kolmion hypotenuusa), mutta hidaskulkuisempi.
Kirjoitetaan ohjelma, joka kysyy käyttäjältä tietä pitkin kulkevan reitin osien pituudet sekä käyttäjän nopeuden tiellä ja oikoreitillä. Ohjelma laskee ja tulostaa reitin pituuden kumpaakin kautta sekä kumpaakin vaihtoehtoon kuluneen ajan.
Oikoreitin pituuden laskemisessa käytetään pythagoraan lausetta: suorakulmaisen kolmion hypotenuusan pituuden voi laskea ottamalla neliöjuuren sen kateettien neliöiden summasta. Eli korotetaan kummankin kateetin pituus toiseen potenssiin, lasketaan näiden summa ja otetaan neliöjuuri tästä summasta. Näin on tehty alla olevassa esimerkkiohjelmassa.
import math
def main():
nopeus_tiella = float(input("Anna nopeus tieta pitkin (km/h)\n"))
nopeus_oikoreitilla = float(input("Anna nopeus oikoreittia pitkin (km/h)\n"))
sivu1 = float(input("Anna ensimmaisen tieosuuden pituus (km)\n"))
sivu2 = float(input("Anna toisen tieosuuden pituus (km)\n"))
oikoreitti = math.sqrt(sivu1 ** 2 + sivu2 ** 2)
aika_tie = (sivu1 + sivu2) / nopeus_tiella
aika_oikoreitti = oikoreitti / nopeus_oikoreitilla
print(f"Matka tieta pitkin on {sivu1 + sivu2:.2f} km,")
print(f"ja siihen menee aikaa {aika_tie:.1f} h.")
print(f"Matka oikoreittia pitkin on {oikoreitti:.2f} km,")
print(f"ja siihen menee aikaa {aika_oikoreitti:.1f} h.")
main()
Alla on esimerkki ohjelman suorituksesta.
Anna nopeus tieta pitkin (km/h)
7.0
Anna nopeus oikoreittia pitkin (km/h)
2.5
Anna ensimmaisen tieosuuden pituus (km)
7.0
Anna toisen tieosuuden pituus (km)
4.0
Matka tieta pitkin on 11.00 km,
ja siihen menee aikaa 1.6 h.
Matka oikoreittia pitkin on 8.06 km,
ja siihen menee aikaa 3.2 h.
Totuusarvon palauttavat funktiot ja niiden paluuarvon käyttö
Aikaisemmissa esimerkeissä funktion paluuarvo oli yksittäinen tai
useampi luku. Monesti ohjelmia kirjoitettaessa on kuitenkin kätevää
kirjoittaa erilaisiin tarkistuksiin funktioita, jotka tarkistavat, onko
jokin ehto tosi vai epätosi ja palauttavat sen mukaan joko arvon
True
tai False
. Tällaista paluuarvoa voidaan sitten käyttää
esimerkiksi if
- tai while
-käskyn ehdossa.
Tarkastellaan seuraavaa esimerkkiä: halutaan kirjoittaa ohjelma, joka laskee kahden tason suoran leikkauspisteen. Suoraa kuvaava yhtälö annetaan muodossa \(ax + by + c = 0\), missä \(a\), \(b\) ja \(c\) ovat kokonaislukuja. Leikkauspiste voidaan laskea muodostamalla suoria kuvaavista yhtälöistä yhtälöpari ja ratkaisemalla tämä yhtälöpari.
Leikkauspisteen laskemisessa tulee kuitenkin vastaan erilaisia erikoistapauksia:
- Suorat voivat olla yhtenevät eli niillä on sama kulmakerroin ja sama leikkauspiste y-akselin kanssa. Tällöin suorat leikkaavat toisensa koko ajan eikä niillä ole yhtä leikkauspistettä.
- Suorat voivat olla yhdensuuntaiset, mutta erilliset. Niillä on siis sama kulmakerroin, mutta ne leikkaavat y-akselin eri pisteissä. Tällöin suorilla ei ole lainkaan leikkauspisteitä.
- Molemmat suorat ovat y-akselin suuntaisia. Tällöin ne ovat joko yhtenevät tai sitten yhdensuuntaiset mutta erilliset sen mukaan, leikkaavatko ne x-akselin samassa vai eri kohdassa.
Näissä tapauksissa ei voida käyttää suoraan yhtälöryhmän ratkaisevaa kaavaa, vaan tapaukset on käsiteltävä erikseen.
Erikoistapausten käsittelemistä varten kannattaa kirjoittaa oma funktio, joka tarkistaa, onko kahdella suoralla sama kulmakerroin, ja toinen funktio, joka tarkistaa, onko kahden yhdensuuntaisen suoran leikkauspiste y-akselin kanssa sama. Jos molemmat suorat ovat yhdensuuntaisia y-akselin kanssa, jälkimmäinen funktio tarkistaa, onko niiden leikkauspiste x-akselin kanssa sama.
Tarkastellaan funktiota, joka tarkistaa, onko kahden suoran
kulmakertoimet samat. Funktio saa parametrinaan ensimmäisen suoran
\(x\):n ja \(y\):n kertoimet (xkerroin1
ja ykerroin1
)
sekä vastaavat toisen suoran kertoimet (xkerroin2
ja ykerroin2
).
Suorien yhtälössä esiintyvällä vakiolla ei ole merkitystä kulmakertoimia
laskettaessa. Ensimmäisen suoran kulmakerroin on nyt
xkerroin1 / ykerroin1
. Kulmakertointen yhtäsuuruuden tutkiminen
lausekkeella xkerroin1 / ykerroin1 == xkerroin2 / ykerroin2
ei
kuitenkaan ole järkevää, koska pyöristysvirheiden takia jakolaskujen
tuloksissa voi olla pieni ero, vaikka kulmakertoimet oikeasti
olisivatkin samoja.
Yksi vaihtoehto olisi sieventää kulmakertoimet murtolukuina, mutta
sievennykseltä säästytään, jos tutkitaan tuloja
xkerroin1 * ykerroin2
ja xkerroin2 * ykerroin1
. Jos ne ovat
yhtäsuuret, myös suorien kulmakertoimet ovat yhtäsuuret, vaikka
kulmakertoimia kuvaavat murtoluvut eivät olisikaan sievennetyssä
muodossa. Funktio siis tutkii näiden tulojen yhtäsuuruutta ja palauttaa
arvon True
, jos tulot ovat yhtäsuuria ja muuten arvon False
.
Kirjoitetaan funktio, joka saa parametrina kahden suoran yhtälöiden
\(x\):n ja \(y\):n kertoimet ja tarkistaa, onko suoriten
kulmakerroin sama. Funktio palauttaa arvon True
, jos kulmakerroin on
sama ja arvon False
, jos suorilla on eri kulmakerroin:
def sama_kulmakerroin(xkerroin1, ykerroin1, xkerroin2, ykerroin2):
if (xkerroin1 * ykerroin2 == xkerroin2 * ykerroin1):
return True
else:
return False
Katsotaan seuraavaksi, miten funktion paluuarvoa voi käyttää
pääohjelmassa. Funktion paluuarvo on siis True
tai False
ja sitä
voi käyttää if-käskyn ehdossa esimerkiksi seuraavasti:
if sama_kulmakerroin(eka_a, eka_b, toka_a, toka_b) == True:
Ehdossa oleva yhtäsuuruusvertailu arvoon True
on kuitenkin
tarpeeton, sillä funktion paluuarvo on jo itsessään tosi tai epätosi,
jolloin sitä voidaan käyttää suoraan if-käskyn ehtona seuraavasti:
if sama_kulmakerroin(eka_a, eka_b, toka_a, toka_b):
Tällöin if-käskyyn kuuluvat käskyt suoritetaan, jos funktion
sama_kulmakerroin
paluuarvo on True
, ja jätetään suorittamatta,
jos funktion paluuarvo on False
.
Jos taas halutaan tehdä if-käsky, johon kuuluvat käskyt suoritetaan
silloin kun funktio palauttaa arvon False
, voidaan tämä tehdä
not
-operaattorin avulla:
if not sama_kulmakerroin(eka_a, eka_b, toka_a, toka_b):
Tässä if
-käskyn ehto on tosi aina, kun funktion
sama_kulmakerroin
paluuarvo on False
.
Seuraavaksi koko suorien leikkauspisteen laskeva ohjelma. Aikaisemmin
kuvatun funktion sama_kulmakerroin
lisäksi ohjelmaan on määritelty
funktiot sama_akselileikkaus
, joka tutkii, leikkaavatko
yhdensuuntaiset suorat y-akselin (y-akselin suuntaiset suorat x-akselin)
samassa pisteessä, laske_leikkaus
, joka laskee suorien
leikkauspisteen, sekä pyyda_suora
, joka pyytää yhden suoran
kertoimet. Merkki \
pääohjelman kahden rivin lopussa kertoo
Python-tulkille, että rivi jatkuu seuraavalla rivillä.
Yksinkertaisuuden vuoksi ohjelma ei tarkista, että sille on todella annettu suoran yhtälö. Ohjelma ei siis toimi oikein silloin, jos sille annetaan “suoran” yhtälö, jossa sekä \(x\):n että \(y\):n kertoimet ovat nollia.
def sama_kulmakerroin(xkerroin1, ykerroin1, xkerroin2, ykerroin2):
if xkerroin1 * ykerroin2 == xkerroin2 * ykerroin1:
return True
else:
return False
def sama_akselileikkaus(a1, b1, c1, a2, b2, c2):
if b1 == 0 and b2 == 0: # suorat y-akselin suuntaiset
if a1 * c2 == a2 * c1:
return True
else:
return False
elif b1 * c2 == b2 * c1:
return True
else:
return False
def laske_leikkaus(a1, b1, c1, a2, b2, c2):
yleikkaus = (a1 * c2 - a2 * c1) / (b1 * a2 - b2 * a1)
if a1 == 0:
xleikkaus = (-b2 * yleikkaus - c2) / a2
else:
xleikkaus = (-b1 * yleikkaus - c1) / a1
return xleikkaus, yleikkaus
def pyyda_suora():
print("Anna suoran yhtalo")
a = int(input("Anna x:n kerroin: "))
b = int(input("Anna y:n kerroin: "))
c = int(input("Anna vakio: "))
return a, b, c
def main():
print("Etsitaan kahden suoran ax + by + c leikkauspiste")
eka_a, eka_b, eka_c = pyyda_suora()
toka_a, toka_b, toka_c = pyyda_suora()
if sama_kulmakerroin(eka_a, eka_b, toka_a, toka_b) and \
sama_akselileikkaus(eka_a, eka_b, eka_c, toka_a, toka_b, toka_c):
print("Suorat ovat yhtenevat koko pituudeltaan.")
elif sama_kulmakerroin(eka_a, eka_b, toka_a, toka_b):
print("Suorat ovat yhdensuuntaiset, ei leikkauspistetta.")
else:
x_koord, y_koord = laske_leikkaus(eka_a, eka_b, eka_c,\
toka_a, toka_b, toka_c)
print(f"Leikkauspiste on ({x_koord:.2f}, {y_koord:.2f})")
main()