Binärdatei lesen und schreiben

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
Pythonia
User
Beiträge: 5
Registriert: Freitag 14. Mai 2010, 21:38

hallo, ganz kurz, ich habe neu mit Programmieren angefangen,und kann zumindest vieles schnell lernen, mit python arbeite ich schon paar Monate(Python version 3-es ist das Einstiegsbuch von "galileoComputing von thoma theis),
ich hab da ein Spiel-programm (nach-)geschrieben, in dieser Spieleversion wird zunächst nach dem namen des Spielers gefragt. Anschließend bekommt der Spieler 5 Rechenaufgaben. Pro Aufgabe hat er nur einen Versuch.(...) Zuletzt wird die Gesamtzeit angegeben, die der Spieler für die Lösungsversuche benötigte...
Und wenn er alle 5 Aufgaben richtig löst, wird sein NAME und die ZEIT, die er dafür brauchte, in eine highscore-Datei aufgenommen, die in einer Datei abgespeichert ist (im Buch steht anfangs,die Highscore ist in ein TEXTDATEI gespeichert,
aber im Code sieht man eindeutig,dass es ein Binärdatei ist, in der die Highscore eingelesen und eingeschrieben wird !)

Mein PROBLEM liegt genau hier(!), die Binärdatei kann ich nicht schreiben,also sie bleibt immer leeeer, immer wenn ich die Highscore anschauen will, ist sie leer - auch wenn ich ein Spiel spiele und die Ergebnisse darin "speichere", die ist immer leer !
ich kann auch den CODE anzeigen,die ist recht simple - könnt ihr mir dann sagen wo das Problem liegt? DANKE
Pythonia
User
Beiträge: 5
Registriert: Freitag 14. Mai 2010, 21:38

Hier ist der Code, vorweg will ich euch noch diese Informationen geben, hoffe die helfen der Übersichtlichkeit usw..
(sie stehen als Kommentare am Anfang und zwichen den zeilen (...) ) !

#Aufbau des Programms
#Das Programm beinhaltet ein Hauptprogramm und 4 Funktionen.
#Im Hauptprogramm wird innerhalb einer Endlosschleife ein Hauptmenü aufgerufen.
#Der Spieler hat in diesem Hauptmenü die folgenden Möglichkeiten:
# -Anzeige der Highscore
# -Spielen
# -Programm beenden

# Die 4 Funktionen des Programms sind:
# -Funktion "hs_lesen()": Lesen der Highscores aus der Datei in eine Liste
# -Funktion "hs_anzeigen()": Anzeigen der Highscore-Liste auf dem Bildschirm
# -Funktion "hs_schreiben()": Schreiben der Highscore-Liste in die Datei
# -Funktion "spiel()": Stellen der Aufgaben,Lösen,Zeit ermitteln, usw.
# ----------------------------------------------------------------------

Code: Alles auswählen

import random, time, glob, pickle

#Funktion Highscore Lesen
def hs_lesen():
    #Liste wird hier erzeugt
    global hs_liste

    #Kein Highscore vorhanden, leere Liste wird erzeugt
    if not glob.glob("highscore.bin"):
        hs_liste = []
        return
    
    #Highscore vorhanden, laden
    x= open("highscore.bin","rb")
    hs_liste = pickle.load(x)
    x.close()
#------------------------------------
#Funktion Highscore Anzeigen
def hs_anzeigen():
    #Highscore nicht vorhanden
    if not hs_liste:
        print("Keine Highscores vorhanden")
        return

    #Ausgabe Highscore
    print("P. Name             Zeit")
    for i in range(len(hs_liste)):
        print("{0:2d}. {1:10} {2:5.2f} sec".format
              (i+1, hs_liste[i][0], hs_liste[i][1]))
        if i >= 9: #Es werden maximal 10 Highscores angezeigt
            break
#------------------------------------
#Funktion Highscore Schreiben
def hs_schreiben():
    #Zugriff
    x=open("highscore.bin","wb")
    pickle.dump(hs_liste,x) #gesamte Liste wird in Datei "x" eingeschrieben
    x.close()
#------------------------------------
#Funktion Spiel
def spiel():
    #Eingabe des Namens
    name=input("Bitte geben Sie ihren Namen ein (max.10 Zeichen): ")
    name=name[0:10]

    #Initialisierung Counter und Zeit
    richtig=0
    startzeit=time.time()

    # 5 Aufgaben
    for aufgabe in range(5):
        a=random.randint(10,30)
        b=random.randint(10,30)
        c = a + b

        #Eingabe
        try:
            zahl = int(input("Aufgabe "+str((aufgabe+1))
                             +" von 5: "+str(a)+" + "+str(b)+" : "))
            # Beachte: die Zahlenvariablen werden in Zeichenketten umgewandelt
            if zahl == c:
                print("***Richtig***")
                richtig += 1
            else:
                raise
        except:
            print("* Falsch *")

    #Auswertung
    endzeit=time.time()
    dif=endzeit-startzeit

    print("Ergebnis: {0:d} von 5 in {1:.2f} Sekunden".format
          (richtig, dif), end="")
    #Wenn nicht alle 5 Aufgaben richtig gelöst wurden,
    #kann kein Eintrag in die Highscore-Liste erfolgen
    if richtig == 5:
        print(", Highscore")
        print()
    else:
        print(", leider kein Highscore")
        print()
        return

    #Mitten in Liste schreiben
    gefunden = False
    for i in range(len(hs_liste)): #Highscore-Liste wird Element für Element durchsucht
        # Einsetzen in Liste
        if dif < hs_liste[i][1]:
            hs_liste.insert(i, [name,dif])
            gefunden= True
            break
        
   #Ans Ende der Liste schreiben
        if not gefunden:
            hs_liste.append([name,dif])

   #Highscore-Liste anzeigen
    hs_anzeigen()

        #Nun ist es dafür gesorgt, dass die Highscore-Liste immer aufsteigend
        #nach Ergebniszeit sortiert ist.
        #DIe Highscore-Liste wird unmittelbar nach jeder Änderung angezeigt
#------------------------------------
#Hauptprogramm mit Hauptmenü (im Menü stehen die 3 Möglichkeiten:)
        # -Anzeige der Highscore
        # -Spielen
        # -Programm beenden

#Initialisierung Zufallsgenerator
random.seed()

# Highscore aus Datei in Liste lesen
hs_lesen()

# Endlosschleife
while True:
    #Hauptmenü, Auswahl
    try:
        menu = int(input("Bitte eingeben "
            "(0: Ende, 1: Highscores, 2: Spielen): "))
    except:
        print("Falsche Eingabe")
        continue

    if menu == 0:
        break
    elif menu == 1:
        hs_anzeigen()
    elif menu == 2:
        spiel()
    else:
        print("Falsche Eingabe")

# Highscore aus Liste in Datei schreiben
hs_schreiben()
Benutzeravatar
gkuhl
User
Beiträge: 600
Registriert: Dienstag 25. November 2008, 18:03
Wohnort: Hong Kong

Hi,

dein Problem ist, dass in die Highscore nie der erste Wert eingetragen wird, weil die Stelle im Programm falsch eingerückt ist. pickle erzeugt eine Textdatei. Der Dateiname ist nur schlecht gewählt.

Grüße
Gerrit

PS: An dem Programm gibt es noch einiges zu verbessern. Dazu wird irgendjemand sicherlich noch was schreiben. Also hier bleiben, wenn du noch weitere Verbessungsvorschläge haben möchtest. :wink:
BlackJack

@gkuhl: `pickle` erzeugt keine Textdatei. Selbst das einfachste Format was nur Bytewerte aus dem ASCII-Bereich enthält, ist ein Binärformat, was unbedingt immer im Binärmodus gelesen und geschrieben werden muss, wenn man da nicht irgendwann Probleme mit bekommen möchte.
Benutzeravatar
gkuhl
User
Beiträge: 600
Registriert: Dienstag 25. November 2008, 18:03
Wohnort: Hong Kong

Gut zu wissen. Hatte mir irgendwie nur den ASCII-Teil gemerkt.
Benutzeravatar
mkesper
User
Beiträge: 919
Registriert: Montag 20. November 2006, 15:48
Wohnort: formerly known as mkallas
Kontaktdaten:

Vermeide seltsame Fehler, indem du keinen Code auf Modulebene ausführst, siehe Tutorial. Ach ja, schmeiß am besten direkt das Openbook weg und arbeite lieber das Tutorial durch. Gründe siehe Forensuche. :)
Pythonia
User
Beiträge: 5
Registriert: Freitag 14. Mai 2010, 21:38

ja ok, mit dem Buch bin ich sowieso bald fertig, werde mit dem Tutorial,die du mir empfohlen hast arbeiten;

aber kann mir einer trotzdem sagen wo genau das Problem hier im Programm ist ?
noch genauer: wie kann ich in die Highsore-Datei einschreiben...?
nur das klappt ja nicht...
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Pythonia hat geschrieben: aber kann mir einer trotzdem sagen wo genau das Problem hier im Programm ist ?
noch genauer: wie kann ich in die Highsore-Datei einschreiben...?
nur das klappt ja nicht...
Wie genau äußert sich das? "global" ist übrigens böse... darauf solltest Du verzichten. Wozu brauchst Du das für "hs_liste" eigentlich? Du kannst die doch genauso gut übergeben, sobald jemand die Liste sehen will...
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
Antworten