Hilfe gesucht ! Skript für Notendurchschnitt

Stellt hier eure Projekte vor.
Internetseiten, Skripte, und alles andere bzgl. Python.
Antworten
Newbie
User
Beiträge: 5
Registriert: Mittwoch 29. Juni 2011, 17:10

Heyho liebe Pythoner :'D !
Ich habe erst vor 3 Tagen mit der Erlernung von Python begonnen, und versuche Dinge umzusetzen, die mir hilfreich erscheinen um den Lernprozess voranzutreiben.
Deswegen habe ich versucht einen Notendurchschnittsberechner zu schreiben. Meinen Ansatz seht ihr da unten! Ich komme leider nicht weiter!
Der user gibt ein Fach und die dazugehörige Note ein, die Eingaben werden in eine Textdatei ausgelagert, so dass er sich das alles nochmal ansehen kann. Darin soll dann auch die Lösung der Rechnung erscheinen. Mein Problem ist nun die Noten aus der Textdatei auszulesen und in eine Rechnung einzubauen. Ich habe es erst mit einer Formatierung versucht und mit dem Befehl datei.seek()... wenig ergiebig. Würde mich über Vorschläge mit Erklärung freuen. Bin ja noch neu :)

Code: Alles auswählen

# -*- coding: cp1252 -*-
#
#

# Importe

# Hierein werden die Noten und die dazugehörigen Fächer verlagert
myFile = open('noten.txt', 'r')
myFile2 = open('noten.txt', 'w')


# Intro
print "Dieses Programm errechnet deinen Notendurchschnitt!"
print "Gib beliebig viele Noten an, schreibe 0 um die Noteneingabe zu beenden, und um die Berechnung zu starten!"

# Noteneingabe mit Fach

while True :
    fach = str(raw_input("Gib ein Fach ein : \t"))
    note = (raw_input("Gib die dazugehörige Note ein : \t"))
    myFile2.write(fach)
    myFile2.write ("..... = ")
    myFile2.write (note)
    myFile2.write ("\n")

    if fach == "0":
        myFile2.close()
        print "Deine Fächer und Noten befinden sich nun in der Noten.txt in dem Ordner!"
        break
        
        print myFile.seek(int)
    
    elif note > "6":
        print "Die Eingabe war ungültig"

    
deets

Statt die Datei zweimal zu oeffnen & mit seek zu hantieren, verlager mal den einlese-Teil nach die while-Schleife - die du ja mit break in dem if abbrichst.
Newbie
User
Beiträge: 5
Registriert: Mittwoch 29. Juni 2011, 17:10

deets hat geschrieben:Statt die Datei zweimal zu oeffnen & mit seek zu hantieren, verlager mal den einlese-Teil nach die while-Schleife - die du ja mit break in dem if abbrichst.
Entweder ich hab dich missverstanden oder es geht einfach nicht :< Kannst Du es vielleicht kurz in einem Codeblock aufschreiben, so wie du denkst, dass es geht ? Danke schon mal für die schnelle Antwort :)
deets

Noe. Wenn ich das mache, dann nehme ich dir doch den ganzen Lernspass!

Wenn du sagst "es geht einfach nicht", was hast du denn ausprobiert?

Wie gesagt: oeffne die Datei erstmal nur zum schreiben. Und *danach* zum lesen. Nach der while-schleife.
Newbie
User
Beiträge: 5
Registriert: Mittwoch 29. Juni 2011, 17:10

deets hat geschrieben:Noe. Wenn ich das mache, dann nehme ich dir doch den ganzen Lernspass!

Wenn du sagst "es geht einfach nicht", was hast du denn ausprobiert?

Wie gesagt: oeffne die Datei erstmal nur zum schreiben. Und *danach* zum lesen. Nach der while-schleife.
Ja, okay ! Da hast du recht (: Ich probier noch mal ein wenig rum und probiere deinen Vorschlag erfolgreich umzusetzen ! Ich poste dann noch mal :3
Newcomer
User
Beiträge: 131
Registriert: Sonntag 15. Mai 2011, 20:41

Hi,
du überschreibst alles, was in der Textdatei steht bei jedem datei.write(). Um dem vorzubeugen musst du: datei=open(noten.txt,"a") schreiben, damit er der notendatei nur anhängt und nicht gleich alles löscht. Um den modus lesen/schreiben zu ändern: datei.mode = "r"/"w", je nachdem, welchen modus du ändern möchtest. Und solange der User keine komischen Sachen eingibt, kannst du mit zb. einer forschleife die Eigaben durchlaufen lassen und testen ob sie sich in ints umwandeln lassen. Das wäre dann die Note:

Code: Alles auswählen

notenList=[] ## zum notenretten aus der forschleife (-:
for i in datei.read():
     try:
         i = int(i)
         notenList.append(i)
     except:
         pass
Das ist sicherlich nicht schön und nicht effizient, aber schließlich heiße ich ja auch noch Necomer und mir fällt im Moment keine andere ein (-: (Würde mir aber, da bin ich sicher).
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

Und auf gar keinen Fall, niemals und unter keinen Umständen sollte man ein `except` verwenden, welches alle Fehler verschluckt. Hier genügt es, einen `ValueError` abzufangen.
Das Leben ist wie ein Tennisball.
Newcomer
User
Beiträge: 131
Registriert: Sonntag 15. Mai 2011, 20:41

achso ja genau
Newbie
User
Beiträge: 5
Registriert: Mittwoch 29. Juni 2011, 17:10

Newcomer hat geschrieben:Hi,
du überschreibst alles, was in der Textdatei steht bei jedem datei.write(). Um dem vorzubeugen musst du: datei=open(noten.txt,"a") schreiben, damit er der notendatei nur anhängt und nicht gleich alles löscht. Um den modus lesen/schreiben zu ändern: datei.mode = "r"/"w", je nachdem, welchen modus du ändern möchtest. Und solange der User keine komischen Sachen eingibt, kannst du mit zb. einer forschleife die Eigaben durchlaufen lassen und testen ob sie sich in ints umwandeln lassen. Das wäre dann die Note:

Code: Alles auswählen

notenList=[] ## zum notenretten aus der forschleife (-:
for i in datei.read():
     try:
         i = int(i)
         notenList.append(i)
     except:
         pass
Das ist sicherlich nicht schön und nicht effizient, aber schließlich heiße ich ja auch noch Necomer und mir fällt im Moment keine andere ein (-: (Würde mir aber, da bin ich sicher).
Danke für deine Antwort :) ich hatte derweil schon die selbe Idee nur, dass ich die Noten sofort bei der Eingabe abfange und zu einer Liste hinzufüge. Also nicht aus der Datei noch mal heraus lese. Da ergibt sich aber das nächste Problem. Ich möchte ja dann, dass die einzelnen Nummern in der Liste addiert werden! Ich habe das dann wie folgt gelöst, aber ich erhalte immer die selbe Fehlermeldung :
IndexError: list index out of range
-> außerhalb der Reichweite / des Bereiches oO ?

Code: Alles auswählen

# -*- coding: cp1252 -*-
#
# NotenDurchschnittsBerechner
#
#

#-----------------------------

# Importe

import sys

#Liste

t = []
anzahl = 0
total = 0
count = 0

# Hierein werden die Noten und die dazugehörigen Fächer verlagert
myFile = open('noten.txt', 'r')
myFile2 = open('noten.txt', 'a')
 

# Intro
print "Dieses Programm errechnet deinen Notendurchschnitt!"
print """
_______________________________________
#              ~ SKRIPT ~      
#   
#   Version 2.0
#   
#-----------------------
# Die Eingabe "0" als Fach und Note führt
# zum Beenden der Eingabe und zum
# Rechenprozess!
#
#______________________________________
"""

# Noteneingabe mit Fach

fach = "tada"

while fach != "0" or note != "0":
    
    fach = str(raw_input("Gib ein Fach ein : \t"))
    anzahl += 1
    note = (raw_input("Gib die dazugehörige Note ein : \t"))
    t.append (int(note))
    count += 1
    myFile2.write(fach)
    myFile2.write (" ")
    myFile2.write (note)
    myFile2.write ("\n")

   
    if note > "6" or note < "0":
        print "Die Eingabe war ungültig !"

    

    elif fach == "0":
        
        print "Deine Fächer und Noten befinden sich nun in der Noten.txt in dem Ordner!"

        
        print anzahl
        print count

            if count == 10:
            ergebnis = (t[0]+t[1]+t[2]+t[3]+t[4]+t[5]+t[6]+t[7]+t[8]+t[9]+t[10]) / (anzahl - 1.0)
            print ergebnis
            print "Das Programm nun beenden? [J / N] \n"
            beenden = (raw_input())
            if beenden == "J":
                SystemExit()
                quit()

        elif count == 11:
            ergebnis = (t[0]+t[1]+t[2]+t[3]+t[4]+t[5]+t[6]+t[7]+t[8]+t[9]+t[10]+t[11]) / (anzahl - 1.0)
            print ergebnis
           
        
        elif count == 2:
            ergebnis = (t[0]+t[1]) / (anzahl - 1.0)
            print ergebnis
Kann mir irgendwer vielleicht nochmal auf die Sprünge helfen oder sagen, wie ich einzelne Listenpunkte einfacher miteinander addiere?
Danke schon mal im Vorraus :-)
deets

Uhhh. Ein paar Anmerkungen:

- du wechselt wild zwischen strings und ints durcheinander. Das kann nicht gutgehen, insbesondere weil Vergleiche von strings und ints niemals das richtige ergeben werden. Du solltest dir erstmal darueber klarwerden, welche Eingabe welchen Typen benoetigt.

- in diesem Sinne: note ist ein int, aber du vergleichst es mit *strings*. Das kann nicht das gewuenschte ergebnis liefern! Siehe:

Code: Alles auswählen

>>> 1 > "0"
False
- Du fuehrst mehrere Zaehlvariablen mit, die dasselbe zaehlen. Da reicht eine.

- lass mal das ganze file-geschreibsel weg. Das ist fuer den Anfang nur noch verwirrender. Loese die Aufgabe nur in-memory.

- die richtige Datenstruktur fuer deine Aufgabe ist ein dictionary, das den Namen eines Faches auf die Liste der Noten, die darin vergeben wurden, abbildet. Am einfachsten machst du dir das Leben, wenn du ein defaultdict verwendest:

Code: Alles auswählen

>>> from collections import defaultdict
>>> fach2noten = defaultdict(list)
>>> fach2noten["mathematik"].append(3)
>>> fach2noten
defaultdict(<type 'list'>, {'mathematik': [3]})
>>> fach2noten["deutsch"].append(1)
>>> fach2noten["deutsch"].append(4)
>>> fach2noten
defaultdict(<type 'list'>, {'mathematik': [3], 'deutsch': [1, 4]})
- wenn du Texteingaben wie "j" oder so einforderst, solltest du immer nur mit lowercase arbeiten, um unabhaengig davon zu sein, ob der Benutzen nun "j" oder "J" eingibt.

- last but not least: dein index-error ist ziemlich simpel: zaehl mal in Gedanken die Anzahl deiner Eingaben, und wieviele du dann versuchst zu verrechnen. Tipp: off-by-one-error... Python zaehlt ab 0, und eine Liste hat bei N Eintraegen den letzten Index bei N-1.
Newbie
User
Beiträge: 5
Registriert: Mittwoch 29. Juni 2011, 17:10

Wow ! Danke, super Antwort.Sehr hilfreich :) Ich werden den Skript mit deinen Tipps noch mal ganz neu aufsetzen. Dankeschön (:
Newcomer
User
Beiträge: 131
Registriert: Sonntag 15. Mai 2011, 20:41

Und warum zählst du die eingaben erst bei 10, 11 und 2 zusammen?
Antworten