class Kurssi: def __init__(self, kurssiNimi): self.kurssinimi = kurssiNimi self.opiskelijat = [] def asetaOpiskelijakurssille(self, uusiOpiskelija): self.opiskelijat.append(Opiskelija(uusiOpiskelija)) #Luodaan uusi Opiskelija-luokan olio ja lisätään se opiskelijat listaan class Opiskelija: def __init__(self, opiskelijaNimi): self.oppilasnimi = opiskelijaNimi self.suoritus = 9 def palautaNimi(self, nimi): return self.oppilasnimi def asetaSuoritus(self, kurssiNimi): self.suoritus = (kurssiNimi) def tulosta(self): return self.oppilasnimi, self.suoritus #aliohjelmat def etsiOpiskelija(k): opiskelijaNimi = str(input("Anna OPISKELIJAN nimi: ")) for oppilas in k.opiskelijat: if oppilas.oppilasnimi == opiskelijaNimi: return (oppilas) print("Ei löydy opiskelijaa nimellä", opiskelijaNimi) print("Palataan valikkoon.") return(None) def etsiKurssi(kl): kurssiNimi = str(input("Anna KURSSIN nimi: ")) for kurssi in kl: if kurssi.kurssinimi == kurssiNimi: return (kurssi) print("Ei löydy kurssia nimeltä", kurssiNimi) print("Palataan valikkoon.") return(None) def lisaaKurssi(kl, tied): print ("---Kurssin lisäys---") uusiKurssi = str(input("Anna lisättävän KURSSIN nimi: ")) for kurssi in kl: if kurssi.nimi == uusiKurssi: print ("Kurssi nimeltä", uusiKurssi, "on jo lisätty. Et voi lisätä samannimistä kurssia kahdesti.") valikko (kl) uusiKurssi = Kurssi(uusiKurssi) kl.append(uusiKurssi) print ("Kurssi lisätty onnistuneesti!") toimintasilmukka(kl, tied) def lisaaOpiskelijakurssille(kl, tied): print ("---Opiskelijan lisäys kurssille---") kurssi = etsiKurssi(kl) if kurssi != None: uusiopiskelija = str(input("Anna lisättävän OPISKELIJAN nimi: ")) kurssi.asetaOpiskelijakurssille(uusiopiskelija) uusiopiskelija = Opiskelija(uusiopiskelija) #kl.append(uusiopiskelija) print ("Opiskelija lisätty kurssille onnistuneesti!") toimintasilmukka(kl, tied) def lisaaKurssisuoritus(kl, tied): print ("---Kurssisuorituksen lisäys opiskelijalle---") kurssi = etsiKurssi(kl) if kurssi != None: opiskelija = etsiOpiskelija(kurssi) if opiskelija != None: arvosana = int(input("Anna opiskelijan ARVOSANA (0-5): ")) opiskelija.asetaSuoritus(arvosana) print ("Kurssiarvosana lisätty onnistuneesti!") toimintasilmukka(kl, tied) def tulostaKurssisuoritus(kl, tied): print ("---Opiskelijan kurssisuoritusten tulostus---") oppilas = (input("Anna opiskelijan nimi: ")) for i in kl[0].opiskelijat: print ("ei toimi") #opiskelija.tulostakurssiSuoritus() def kirjoitaTiedostoon(kl, tied): print ("---Tietojen kirjoittaminen tekstitiedostoon---") tiedosto = open(tied, "a", encoding="UTF-8") for i in range(len(kl)): for j in range(3): tiedosto.write(kl[i][j]+"\n") tiedosto.close() print ("Tiedot kirjoitettu tekstitiedostoon kurssikirjanpito.txt") def valikko(kl, tied): print ("********") print ("1. Lisää kurssi") print ("2. Lisää opiskelija kurssille") print ("3. Lisää opiskelijan kurssisuoritus") print ("4. Tulosta opiskelijan kurssisuoritukset") print ("5. Tietojen kirjoittaminen tekstitiedostoon") print ("0. Lopeta") print ("********") def toimintasilmukka(kl, tied): valikko(kl, tied) while True: valinta = input("Anna valinta: ") if (valinta == "1"): lisaaKurssi(kl, tied) elif (valinta == "2"): lisaaOpiskelijakurssille(kl, tied) elif (valinta == "3"): lisaaKurssisuoritus(kl, tied) elif (valinta == "4"): tulostaKurssisuoritus(kl, tied) elif (valinta == "5"): kirjoitaTiedostoon(kl, tied) elif (valinta == "0"): print ("Kiitos ohjelman käytöstä!") break else: ("Annoit vääränlaisen valinnan. Anna valinta uudestaan.") toimintasilmukka(kl, tied) #pääohjelma tiedosto = "kurssikirjanpito.txt" kurssilista = [] toimintasilmukka(kurssilista, tiedosto)
Teen tällä hetkellä ohjelmaa perusopintojen harjoitustyötä varten, ja olen nyt tapellut (todennäköisesti) erittäin yksinkertaisen ongelman kanssa jo 2 viikkoa. Haluaisin saada tulostettua Kurssi-luokan opiskelijat listan olion ja hänen suorituksen. Aliohjelmassa tulostaKurssisuoritus kysytään ensin halutun opiskelijan nimeä, jonka jälkeen ohjelman tulisi tulostaa kaikki kurssit ja niiden arvosanat joissa opiskelija on mukana.
Olen kokeillut monia eri keinoja, mutta edistystä ei ole tapahtunut tippaakaan. Kysyin apua myös opettajalta, mutta ilman esimerkkejä en pysty ymmärtämään kuinka kyseinen toimenpide saadaan aikaan..
Niin ja tiedän että tiedostoon kirjoittaminenkin on vielä väärin, mutta siihen en ole vielä edes perehtynyt. Todennäköisesti se tulee olemaan toinen 2 viikon ongelmakohta.
Kiitokset avusta jo ennakkoon.
Tässä yksi esimerkki:
def tulostaKurssisuoritus(kl, tied): print("---Opiskelijan kurssisuoritusten tulostus---") oppilasnimi = input("Anna opiskelijan nimi: ") for kurssi in kl: for op in kurssi.opiskelijat: if op.oppilasnimi == oppilasnimi: print("Kurssi: %s - %d" % (kurssi.kurssinimi, op.suoritus))
Edit: muokkasin
No huhhuh. Sehän toimii kun junan vessa. Ei se kauhean kummoinen ongelma nähtävästi ollutkaan. Vaati tosiaan vaan sen esimerkin että oivaltaa miten se toimii.
Kiitokset avusta. Pääsee lopultakin eteenpäin tässä tehtävässä.
Pahoittelen että kysyn omassa topicissani uudestaan mutta en ollut varma onko järkevää laittaa miltei samanlaista koodinpätkää uudestaan uudella topicilla tällaisen (pikku)jutun takia.
Nyt tämä työ on edistynyt melko huimaa vauhtia, mutta eräs ongelma tähän vielä liittyy. Tällä hetkellä (ja jopa tuossa yllä olevassa koodissa) valinta 0 toimintasilmukassa ei lopeta ohjelmaa jos käyttäjä on tehnyt joitain muita toimintoja (eli valinnut valikosta 1,2,3,4 ta 5).
Ongelma johtuu vissiinkin siitä että muut aliohjelmat aina lopussa kutsuu toimintasilmukka aliohjelmaa, joka jollain tavalla sekoittaa tuon breakin. Tällä hetkellä break komento siis vain tulostaa tuon: Kiitos ohjelman käytöstä! lauseen ja kysyy uutta valintaa.
Onko tähän ongelmaan mitään järkevää ratkaisua? Eli sellaista ettei tarvitsisi poistaa noita toimintasilmukka-kutsuja muista aliohjelmista.
Teen työtä Notepad++:lla ja kaikki 4 pääosaa on omassa moduulissaan. Tämän vuoksi testasin ohjelmaa myös IDLE:llä, ja siellä oli sama tulos.
Älä kutsu toimintasilmukkaa esim. lisääKurssisuorituksen lopussa, vaan palaa silmukkaan return lauseella. Lisäksi kutsut turhaan toimintasilmukkaa elsessä.
Nyt kun syötät 0 se lopettaa kyllä silmukan, mutta palaat viimeisimpänä kutsuttuun toimintasilmukkaan, ja siut on syötettävä niille kaikille nolla ennen kuin ohjelma loppuu.
Esim:
nyt:
ts1 -> lks -> ts2 (0) ->lks ->ts1(0)
Kun sen pitäisi olla:
ts1 -> lks -> ts1 (0)
Kiitokset avusta. Tuo keino olisi muuten toiminut hyvin, mutta pelkän return-komennon avulla se ei tulosta käyttäjälle valikkoa. Tosin kiitos tuon sinun neuvon, oivalsin että nehän voisi yhdistää (valikko + toimintasilmukka) ja käyttää sitten tuota return-komentoa. Nyt siis toimii niinkuin pitääkin.
Kiitos avusta.
class Kurssi: def __init__(self, kurssiNimi): self.kurssinimi = kurssiNimi self.opiskelijat = [] def asetaOpiskelijakurssille(self, uusiOpiskelija): self.opiskelijat.append(Opiskelija(uusiOpiskelija)) class Opiskelija: def __init__(self, opiskelijaNimi): self.oppilasnimi = opiskelijaNimi self.suoritus = 99 def asetaSuoritus(self, arvoSana): self.suoritus = (arvoSana) #Aliohjelmat def etsiOpiskelija(k): opiskelijaNimi = str(input("Anna OPISKELIJAN nimi: ")) for oppilas in k.opiskelijat: if oppilas.oppilasnimi == opiskelijaNimi: return (oppilas) print("Ei löydy opiskelijaa nimellä", opiskelijaNimi) print("Palataan valikkoon.") return(None) def etsiKurssi(kl): kurssiNimi = str(input("Anna KURSSIN nimi: ")) for kurssi in kl: if kurssi.kurssinimi == kurssiNimi: return (kurssi) print("Ei löydy kurssia nimeltä", kurssiNimi) print("Palataan valikkoon.") return(None) def lisaaKurssi(kl): print ("---Kurssin lisäys---") uusiKurssi = str(input("Anna lisättävän KURSSIN nimi: ")) for kurssi in kl: if kurssi.kurssinimi == uusiKurssi: print ("Kurssi nimeltä", uusiKurssi, "on jo lisätty. Et voi lisätä samannimistä kurssia kahdesti.") return uusiKurssi = Kurssi(uusiKurssi) kl.append(uusiKurssi) print ("Kurssi lisätty onnistuneesti!") return def lisaaOpiskelijakurssille(kl): print ("---Opiskelijan lisäys kurssille---") kurssi = etsiKurssi(kl) if kurssi != None: uusiopiskelija = str(input("Anna lisättävän OPISKELIJAN nimi: ")) for oppilas in kurssi.opiskelijat: if oppilas.oppilasnimi == uusiopiskelija: print("Opiskelija löytyy jo kurssilta", kurssi.kurssinimi,"\npalataan valikkoon.") return kurssi.asetaOpiskelijakurssille(uusiopiskelija) uusiopiskelija = Opiskelija(uusiopiskelija) print ("Opiskelija lisätty kurssille onnistuneesti!") return return def lisaaKurssisuoritus(kl): print ("---Kurssisuorituksen lisäys opiskelijalle---") kurssi = etsiKurssi(kl) if kurssi != None: opiskelija = etsiOpiskelija(kurssi) if opiskelija != None: try: # Yritetään kysyä arvosanaa. Mikäli arvosana ei ole int-tyyppinen, siirrytään except kohtaan. arvosana = int(input("Anna opiskelijan ARVOSANA (0-5): ")) if (arvosana > 5) or (arvosana < 0): # Jos arvosana on pienempi kuin 0 tai suurempi kuin 5, arvosanaa ei lisätä. print ("Annoit vääränlaisen syötteen. Ainoastaan numerot 0-5 kelpaavat.") return else: opiskelija.asetaSuoritus(arvosana) print ("Kurssiarvosana lisätty onnistuneesti!") except (ValueError): # Suoritetaan tämä kohta vain jos annettu arvosana syöte ei ollut int-tyyppinen. print("Annoit vääränlaisen syötteen. Ainoastaan numeerinen arvosana kelpaa.") return def tulostaKurssisuoritus(kl, tied): print ("---Opiskelijan kurssisuoritusten tulostus---") oppilas = (input("Anna OPISKELIJAN nimi: ")) print("Opiskelijan", oppilas ,"kurssisuoritukset") for kurssi in kl: for op in kurssi.opiskelijat: if op.oppilasnimi == oppilas: print("Kurssi: %s -- Arvosana: %d" % (kurssi.kurssinimi, op.suoritus)) tiedosto = open(tied, "r", encoding="UTF-8") print("\nTekstitiedostoon tallennetut kurssisuoritukset:\n") while True: suoritus = tiedosto.readline() if len(suoritus) == 0: break print (suoritus) tiedosto.close() return def kirjoitaTiedostoon(kl, tied): print ("---Tietojen kirjoittaminen tekstitiedostoon---") now = datetime.datetime.now() tiedosto = open(tied, "a", encoding="UTF-8") tiedosto.write(now.strftime("Päivämäärä %Y-%m-%d %H:%M\n")) for kurssi in kl: for op in kurssi.opiskelijat: tiedosto.write("%s\t%s\t %d \n" % (op.oppilasnimi, kurssi.kurssinimi, op.suoritus)) tiedosto.close() print ("Tiedot kirjoitettu tekstitiedostoon kurssikirjanpito.txt") return def varmistus(varmistetaan): if varmistetaan: print("Et ole tallentanut tekemisiäsi toimintoja (Valinta 5).") vastaus = input("Haluatko palata takaisin valikkoon? (k/e): ") if vastaus == "k" or vastaus =="K": print("Palataan takaisin valikkoon.") return(True) return(False) def toimintasilmukka(kl): varmennus = False tiedosto = "kurssikirjanpito.txt" while True: print ("********") print ("1. Lisää kurssi") print ("2. Lisää opiskelija kurssille") print ("3. Lisää opiskelijalle kurssisuoritus") print ("4. Tulosta opiskelijan kurssisuoritukset") print ("5. Tietojen kirjoittaminen tekstitiedostoon") print ("0. Lopeta") print ("********") valinta = input("Anna valinta: ") if (valinta == "1"): lisaaKurssi(kl) varmennus = True elif (valinta == "2"): lisaaOpiskelijakurssille(kl) varmennus = True elif (valinta == "3"): lisaaKurssisuoritus(kl) varmennus = True elif (valinta == "4"): tulostaKurssisuoritus(kl, tiedosto) elif (valinta == "5"): kirjoitaTiedostoon(kl, tiedosto) varmennus = False elif (valinta == "0"): if varmistus(varmennus): continue print ("Kiitos ohjelman käytöstä!") break else: print ("Annoit vääränlaisen valinnan. Anna valinta uudestaan.") #Pääohjelma kurssilista = [] # Alustetaan kurssilista toimintasilmukka(kurssilista) # Kaikki toiminta toimintasilmukassa
Terve taas. Kuten kuvasta näkyy, ohjelmaan on tehty muutoksia. Tosin nyt olen yrittänyt saada ohjelman tulostaKurssisuoritus aliohjelman toimimaan niin, että se osaisi ottaa huomioon myös tekstitiedostoon tallennetut tiedot. Esimerkiksi jos Matille on eilen tallennettu kurssitieto: matikka 5, niin seuraavana päivänä jos käytän ohjelmaa ja tulostan Matin tiedot, niin ohjelma tulostaa myös tekstitiedostossa olevat tiedot ohjelman tämänhetkisten tietojen lisäksi.
Tällä hetkellä sain lisättyä vain toiminnon että ohjelma tulostaa koko tekstitiedoston sisällön tulostuksen yhteydessä, mutta tämä käy melko raskaaksi erityisesti jos tekstitiedostossa on paljon eri tietoja.
Onko ideoita kuinka saisi siis otettua tekstitiedostosta pelkästään halutun opiskelijan tiedot ja tulostettua ne näytölle?
kapi kirjoitti:
Onko ideoita kuinka saisi siis otettua tekstitiedostosta pelkästään halutun opiskelijan tiedot ja tulostettua ne näytölle?
Tuossa kun olet lukenut suoritusrivin, niin tarkistat että onko se valitun opiskelijan ja tulostat sen vain mikäli se koskee valittua opiskelijaa.
#... tiedosto = open(tied, "r", encoding="UTF-8") print("\nTekstitiedostoon tallennetut kurssisuoritukset:\n") while True: suoritus = tiedosto.readline() if len(suoritus) == 0: break #Lisää if lause että seuraava rivi suoritetaan vain, jos suoritus koskee valittua opiskelija print (suoritus) tiedosto.close() return #...
Käytännössä siis rivin pitäisi alkaa opiskelijan nimi + tabulaattorilla.
Kannattaisiko minun siis ottaa tuo päivämäärän lisäys toiminto kokonaan pois jotta helpottuu tämä tulostushomma?
Lisäys:
Ohoh..Sainpas tehtyä sen hiukan eri tavalla.
Jos nyt muut tappelee joskus saman ongelman kanssa, niin tässä ainakin yksi vaihtoehto jonka keksin, parempiakin keinoja voi kertoa. :)
#... tiedosto = open(tied, "r", encoding="UTF-8") print("\nTekstitiedostoon tallennetut kurssisuoritukset:\n") rivit = tiedosto.readlines() for rivi in rivit: if rivi.startswith (oppilas): print (rivi) tiedosto.close() return #...
Kiitokset Grezzille avusta. Pisti aivot enemmän miettimään niin helpotti ratkaisun keksimisessä.
Nykyinen koodisi luultavasti toimii väärin, jos tiedostossa esiintyvät esimerkiksi Jani ja Janipetteri: haku nimellä Jani tulostaa molempien tulokset. Sinun pitää startswith-kohdassa lisätä oppilaan nimen perään se erotinmerkki, joka tiedostossa merkitsee nimen päättymistä.
Juu, itse huomasin että ei se toimi ihan niinkuin pitäisi. Tarkoitatko erotinmerkillä tabia? Tiedostossa nimi loppuu aina tabiin, jonka jälkeen tulee kurssi ja arvosana.
Sitten tarkoitan tabia.
Noniin. Se oli nopea korjaus. Nyt näyttäisi toimivan niinkuin pitääkin. Kiitos Metabolix avusta. :)
Aihe on jo aika vanha, joten et voi enää vastata siihen.