Tämä ohjelma käyttää generaattorifunktiota, joka näyttää aina seuraavan tuloksen next()-funktiolla. Tässä esimerkissä käytetään pinta-alan ja piirin laskemista.
import math
#Muodostetaan kaksi funktiota ensimmäinen laskee pinta-alan ja toinen piirin.
def LaskePintaAla(sivu,valinta):
pintaAla = 0.0
if (valinta == 1):
pintaAla = math.pi*sivu**2
else:
pintaAla = sivu*sivu
if (valinta == 3):
pintaAla = 0.5*pintaAla
return pintaAla
def LaskePiiri(sivu, valinta):
piiri = 0.0
if (valinta == 1):
piiri = 2*math.pi*sivu
elif (valinta == 2):
piiri = 4*sivu
elif (valinta == 3):
piiri = 2*sivu
piiri += math.sqrt(2*sivu**2)
return piiri
valinta = 0
print("Valitse:")
print("1) Ympyrän pinta-ala/piiri")
print("2) Neliön pinta-ala/piiri")
print("3) Kolmion pinta-ala/piiri")
valinta = int(input())
print("Anna pinta-alojen ja piirien määrä")
maara = int(input())
#Muodostamme kaksi generaattoria ensimmäiseen tallennetaan pinta-alat ja toiseen piirit.
pinta_alat = (LaskePintaAla(i,valinta) for i in range(1,maara,1))
piirit = (LaskePiiri(i,valinta) for i in range(1,maara,1))
nayta = 1
while (nayta != 0):
#Näytetään seuraava pinta-ala tai piiri.
print("Valitse")
print("1) Seuraava pinta-ala")
print("2) Seuraava piiri")
print("0) Lopeta")
nayta = int(input())
if (nayta== 1):
print(next(pinta_alat))
elif (nayta == 2):
print(next(piirit))Olet ymmärtänyt jotain väärin. Generaattorifunktio olisi funktio, jossa yield-lauseella tuotetaan lisää arvoja. Sen sijaan for-rakenne on generaattorilauseke. Lisäksi vastoin koodisi kommenttia generaattorin idea on juuri se, että tiedot eivät ole siinä tallennettuina (kuten listassa olisi) vaan niitä lasketaan tarpeen mukaan lisää. Funktiolle ei myöskään tarvita ylärajaa, kuten lausekkeellasi on.
Eli generaattorifunktioilla koodissasi silmukka (yleensä while-silmukka) olisi generaattorifunktion sisällä, silmukassa yield palauttaisi aina lisää arvoja, ja piirit/pinta_alat alustettaisiin vain yhdellä funktiokutsulla:
piirit = LaskePiirit(valinta)
Koodin voisi siis oikealla generaattorifunktiolla tehdä näin:
import math
def sarja(alku, aste):
i = 1
while True:
yield alku * (i ** aste)
i += 1
tiedot = [
("Ympyrän", "säde", math.pi, 2 * math.pi),
("Neliön", "sivu", 1, 4),
("Suorakulmaisen, tasakylkisen kolmion", "kateetti", 0.5, 2 + (2**0.5)),
]
print("Valitse:")
for i in range(len(tiedot)):
print(f"{i+1}) {tiedot[i][0]} pinta-ala ja piiri")
valinta = int(input())
minkä, sivusana, ala1, piiri1 = tiedot[valinta - 1]
piiri = sarja(piiri1, 1)
ala = sarja(ala1, 2)
while True:
print(f"Piiri on {next(piiri)} ja pinta-ala {next(ala)}.")
print("0) Lopeta, 1) Jatka.")
if (input() == "0"):
breakToisaalta generaattorifunktio on aika turha, koska generaattorilausekkeella voisi tehdä näin:
piiri = (piiri1 * i for i in range(1, 1 << 100)) ala = (ala1 * (i * i) for i in range(1, 1 << 100))
(1 << 100 on iso luku, jolloin range on käytännön tarkoituksiin ääretön.)
Ylipäänsä koko generaattori on lähinnä vain häiriöksi, kun siinä häviää tieto, mitä oikeastaan edes lasketaan. (Alkuperäisessä koodissasi annat selata pinta-aloja ja piirejä eri tahtiin, mikä on lähinnä järjetöntä.) Ilman erillisiä generaattoreita voisi tehdä paljon järkevämmän silmukan:
for i in range(1, 1 << 100):
piiri = piiri1 * i
ala = ala1 * (i * i)
print(f"{minkä} {sivusana} on {i}, jolloin piiri on {piiri} ja pinta-ala {ala}.")
print("0) Lopeta, 1) Jatka.")
if (input() == "0"):
breakHuomaa myös, että tässä koodissa ei törttöillä valinta-lukuarvon kanssa muualla, vaan heti syötteen lukemisen jälkeen heitetään kyseinen merkityksetön lukuarvo pois ja käytetään niitä tietoja, jotka käyttäjä on kyseisellä luvulla valinnut.
Aihe on jo aika vanha, joten et voi enää vastata siihen.