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"): break
Toisaalta 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"): break
Huomaa 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.