Seite 1 von 2

Problem mit ABC.data

Verfasst: Sonntag 20. August 2006, 14:50
von Malle
Folgendes Problem:
Ich erstelle mir eine Datei (.data) über Python. Bei der ich beim Start das Programms über int(raw_input('Zahl: )) Eine Zahl eingeben muss. jetzt speichere ich sie noch ab und will sie später mit einer weiteren Zahl addieren. Doch dann sagt mir dér Editor das dass nicht geht.

Kurz: Ich will eine Zahl Speichern und diese später mit einer weiteren addieren (das Programm wird dabei nach dem Speichern erst einmal geschlossen).

Ich bin für jeden Tipp String Code usw. Dankbar

mfg malle

Verfasst: Sonntag 20. August 2006, 15:16
von BlackJack
Das sagt Dir der *Editor*!?

Wie wär's wenn Du mal zeigst was Du hast und wie die Fehlermeldung aussieht?

Verfasst: Sonntag 20. August 2006, 18:27
von Malle
Hier die meldung

Traceback (most recnt call last):
File "C:\Dokumente und Einstellungen\Tim\Desktop\Ersparniss\Test.py",
in?
c = f + 2
TypeError: unsupported operand type(s) for+: 'file' and 'int'

Hier das Test skript:

Code: Alles auswählen

#Test Data

import cPickle as p

print '1 = Aufrufen'
print '2 = Erstellen'
print '3 = Beenden'


a = raw_input('Zahl: ')
testdatei = 'test.data'
if a == '2':
    test = int(raw_input('Zahl'))
    f = file(testdatei, 'w')
    p.dump(test, f)
    f.close()
if a == '1':
    f = file(testdatei)
    gz = p.load(f)
    print 'Die Zahl ist', gz
if a == '3':
    print 'by'
if a == '4':
    c = f + 2
    print c
[/code]

Verfasst: Sonntag 20. August 2006, 18:48
von Python 47
1.Es gibt keine 4 zur Auswahl. Jedenfalls steht nichts von einer 4 da. Also würde theoretisch keiner eine 4 eingeben.

2. Ein paar Leerzeilen machen den Code übersichtlicher

3. Und was ist wenn ich 5 eingebe?

4. Benutze doch elif und else

5. Wenn du das Programm wirklich beenden willst dann benuzte nach dem print by ein sys.exit()

Um dir jetzt zu erklären warum das nicht geht wie du das willst hab ich keine Zeit mehr. Hab einen Termin. Wollt dir blos schnell sagen was mir zu deinem Code auffällt.

Verfasst: Sonntag 20. August 2006, 19:55
von jAN
wenn a=4 ist, ist f nicht definiert...

Verfasst: Sonntag 20. August 2006, 20:44
von bb1898
jAN hat geschrieben:wenn a=4 ist, ist f nicht definiert...
Das stimmt, passt allerdings schlecht zu der Fehlermeldung (s.o.):

Code: Alles auswählen

Traceback (most recnt call last):
File "C:\Dokumente und Einstellungen\Tim\Desktop\Ersparniss\Test.py",
in?
c = f + 2
TypeError: unsupported operand type(s) for+: 'file' and 'int' 
Ist f von einem früheren Test des Programms in der gleichen interaktiven Sitzung vielleicht noch definiert? Dann würde alles zusammenpassen.

Jedenfalls ist die Meldung klar und wenig überraschend: zu einer Datei kann man keine ganze Zahl addieren. Richtig wäre es z.B. so:

Code: Alles auswählen

if a == '4':
    f = file(testdatei)
    gz = p.load(f)
    c = gz + 2
    print c

Verfasst: Sonntag 20. August 2006, 20:52
von BlackJack
Pickle Dateien bitte immer im Binärmodus öffnen.

Hier würde ich die Zahl aber lieber in eine Textdatei speichern. Die kann man auch ausserhalb von Python lesen und bearbeiten.

Verfasst: Montag 21. August 2006, 15:53
von Malle
@ Python Master:
Das war nur ein Beispiel skript das ganze Programm ist dann natürlich Sauberer geschrieben.
@ Black Jack:
Was ist ein Binärmodus? Wie Öffne ich pickle im Binärmodus? Wie speichere ich eine Zahl in einer textdatei, sodass ich nur die Zahl später aufrufen kann?
@ bb1898:
wie kann f noch definiert sein? und Danke das hilft mir zwar weiter aber ein problem besteht noch, und zwar will ich eine Zahl einegen die das Programm abspeichert und diese Zahl dann mit einer weiteren Zahl addieren wenn ich das Programm neustarte
(Öffne Programm; werde gebeten zahl einzugen:z.B:1;schließe Programm;Öffne Programm; werde wieder gebeten Zahl einzugeben z.B.: 1;...usw.

Verfasst: Montag 21. August 2006, 17:03
von BlackJack
Malle hat geschrieben:Was ist ein Binärmodus? Wie Öffne ich pickle im Binärmodus?
Dateien kann man entweder im Textmodus oder im Binärmodus öffnen. Im Textmodus (Voreinstellung) gibt es Betriebssysteme die bestimte Bytes besonders behandeln. Zum Beispiel als "Dateiende" Kennzeichnung oder es werden Bytesequenzen durch andere Bytesequenzen ausgetauscht.

Du öffnest nicht `pickle` im Binärmodus, sondern Dateien. Dazu gibt's das zweite Argument bei `open()`.
Wie speichere ich eine Zahl in einer textdatei, sodass ich nur die Zahl später aufrufen kann?
Du wandelst sie in eine Zeichenkette und speicherst die in die Datei.

Re: Problem mit ABC.data

Verfasst: Montag 21. August 2006, 17:31
von gerold
Malle hat geschrieben:Ich will eine Zahl Speichern und diese später mit einer weiteren addieren
Hi Malle!

Lesestoff: http://www.python-forum.de/topic-6157.html

Mir war langweilig... :roll:

Code: Alles auswählen

#!/usr/bin/env python
# -*- coding: iso-8859-1 -*- 

import types

FILENAME = "save.txt"


def read_number(filename):
    """
    Liest die Zahl aus der Datei. Kann die Datei nicht geöffnet werden, oder
    ist in der ersten Zeile keine Zahl, dann wird 0 zurück gegeben.
    
    :param filename: Dateiname
    """
    
    try:
        f = file(filename, "r")
    except IOError:
        return 0
    
    try:
        try:
            num = int(f.readline())
        except ValueError:
            num = 0
    finally:
        f.close()
    
    return num


def write_number(filename, num):
    """
    Schreibt die Zahl in die Datei. Dabei wird eine evt. bereits existierende
    Datei überschrieben
    
    :param filename: Dateiname
    :param num: Ganzzahl, die in die Datei geschrieben wird.
    """
    
    assert(isinstance(num, (types.IntType, types.LongType)))
    
    f = file(filename, "w")
    try:
        f.write(str(num))
    finally:
        f.close()


def show_number(num):
    """
    Zeigt die Zahl an.
    
    :param num: Zahl, die angezeigt wird.
    """
    
    print 
    print "*" * 50
    print "Zaehlwerk"
    print "*" * 50
    print
    print "Aktuelle Zahl: %i" % num


def ask_for_number():
    """
    Fragt nach einer neuen Zahl. Wenn "exit" übergeben wird, oder wenn STRG+C 
    gedrückt wurde, dann gibt die Funktion None zurück.
    """
    
    while True:
        print
        print (
            "Welche Zahl soll addiert werden? Geben Sie eine Ganzzahl ein um diese "
            "zur aktuellen Zahl zu addieren. \n"
            "Geben Sie 'exit' ein um das Programm zu verlassen. "
        )
        
        try:
            s = raw_input("Ihre Eingabe: ")
        except KeyboardInterrupt:
            print
            print "Es wurde STRG+C gedrueckt!"
            print
            return None
            
        if s.lower() == "exit":
            return None
        else:
            try:
                num = int(s)
                return num
            except ValueError:
                print
                print "HINWEIS! Bitte geben Sie eine Ganzzahl ein."


def main():
    """
    Hauptprozedur
    """
    
    while True:
        old_number = read_number(FILENAME)
        show_number(old_number)
        new_number = ask_for_number()
        if new_number is None:
            break
        new_number = old_number + new_number
        write_number(FILENAME, new_number)
    
    print
    print "Servus :-)"
    print


if __name__ == "__main__":
    main()
Vielleicht bringt es dir ja was.

mfg
Gerold
:-)

Verfasst: Montag 21. August 2006, 21:44
von Malle
Hui Gerold ne menge Text von dem ich nur 80% verstehe, ich bin mir zwar sicher das dass mich weiter bringen wird aber heute hab ich erst mal genug von Python. Da ich momentan aus unerfindlichen gründen keinen klaren gedanken fassen kann. :? :( :? . Desshalb hab ich auch 2h und 24 min für das folgende skript gebraucht:

Code: Alles auswählen

# Rauchrechner V.0.1
# Made by Malle

import cPickle as p

print 'Wilkommen bei Malles Rauch Ersparniss Rechner.'
zigdatei = 'zig.data' # Datei in der die Zigaretten gezählt werden
tagdatei = 'tag.data' # Datei in der die Ausgaben gezählt werden
spedatei = 'spe.data' # speichert alle eingaben ab

def menu():
    print 'Druecken sie bitte eine der folgenden Zahlen und bestätigen mit Enter'
    print '1 um neue Daten Aufzunehmen und in das Ersparte einzusehen'
    print '2 um Alles zu löschen'
    print '3 um das Menue Erneut Anzuzeigen'
    print '4 um das Programm zu Beenden'

menu()
while True:
    print '_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ '
    zahl = raw_input('Geben Sie nun Bitte eine Zahl ein: ')

    if zahl == '1':
        zig = int(raw_input('Wieviel haben Sie geraucht?: '))
        a = file(zigdatei, 'w')
        p.dump(zig, a)
        a.close()

        tag = int(raw_input('vor wieviel Tagen haben sie zuletzt geraucht?: '))
        b = file(tagdatei, 'w')
        p.dump(tag, b)
        b.close()

        b = file(tagdatei)
        lt = p.load(b)  # lt steht kurz fuer lade tage
        gvf = lt * 4 / 3 # gvf steht fuer geld verbrauch frueher

        a = file(zigdatei)
        lz = p.load(a) # lz steht fuer lade zigaretten
        gvj = 0.2 * lz # gvj steht fuer geld verbrauch jetzt

        gg = gvf - gvj # gg steht fuer gespartes geld

        spe = gg
        c = file(spedatei, 'w')
        p.dump(spe, c)
        f.close()

        c = file(spedatei)
        ls = p.load(c) # ls steht fuer lade speicherdatei
        ge = ls + gg # ge steht fuer gesamtes Ersparniss
        print 'Sie haben bereits', ge, 'Euro gespart.'    
        
    elif zahl == '2':
        del zigdatei
        del gelddatei
    elif zahl == '3':
        menu()

    elif zahl == '4':
        print 'Danke bis zum nächsten mal'
        break

    else:
        print 'Ungültige Eingabe!?! Bitte erneut wählen'
Das momentane Problem liegt dabei das ich zu der gespeicherten Datei die zwei Zahlen eingeben und berechnen lassen will. und dann das so entstandene Ergebniss abspeichere und somit die davor gespeicherte Datei überschreibe. Ps ich weis das der Anweisungsblock elif zahl == 2 ... (del XXX) falsch ist.
Danke im Voraus mfg Malle

Verfasst: Dienstag 22. August 2006, 07:01
von BlackJack
Du solltest jede Datei die Du öffnest auch wieder schliessen. Ausserdem könntest Du gleich vernünftige Namen verwenden anstatt die Bedeutung von den kryptischen 1-3 Buchstaben Kürzeln in Kommentare zu schreiben.

Verfasst: Dienstag 22. August 2006, 07:13
von jens
import cPickle as p finde auch unschön, diese Abkürzung p ist einfach etwas übertrieben ;) Besser wäre das: import cPickle as pickle Noch besser aber so:

Code: Alles auswählen

try:
    import cPickle as pickle
except ImportError:
    import pickle

Was anderes: Du benutzt drei unterschiedliche Dateien zum abspeichern der Daten. Du speicherst aber eh mit pickle, also kommst du mit einer einzigen Datei auch aus!
Pack deine Daten in ein Dict und speicher den mit pickle ab ;)

Was du mit Dictionaries anstellen kannst, steht hier: [wiki]Tutorial/Dictionary[/wiki]

Zum dritten: Benutzte mehr Funktionen... Du hast ja schon menu(). Zerteil den Code in der Mega-while-Schleife und pack Stücke Sinnvoll in Funktionen, die du in der while-Schleife einfach benutzt.
So wird die lange, lange while-Schleife schön kurz und übersichtlich...

Verfasst: Dienstag 22. August 2006, 12:34
von Malle
Damnke für die Tips, ich werd sie auch gleich mal umsetzen aber meine eigendliche Frage beantwortet das glaube nicht?
Ps.: Wie bekomme ich so eine aufreihung von Zahlen im Editor?

Code: Alles auswählen

<- solche
<- Zahlen meine ich
<- die mir die lines anzeigen?

Verfasst: Dienstag 22. August 2006, 13:26
von Python 47
Welchen Editor benutzt du denn?

Verfasst: Dienstag 22. August 2006, 15:23
von Malle
Ich benutze Idle.

Verfasst: Mittwoch 23. August 2006, 23:14
von Malle
Immer noch ein Problem:

Code: Alles auswählen

import cPickle as p

bladatei = 'bla.data'
dic = {}
dic["text"] = int(raw_input('Zahl eigeben'))

bla = 0
a = file(bladatei, 'w')
p.dump(bla, a)
a.close()

a = file(bladatei)
bla3 = p.load(a)
aaa = dic["text"] + bla3
bla = aaa
a = file(bladatei, 'w')
p.dump(bla, a)
print aaa
a.close()
So vorerst einmal das ist wieder nur ein Test teil eines größeren Programms. Es sollte eigendlich eine Zahl abspeichern und dann später durch eine Erneute eingabe die beiden Zahlen addieren (zuersteigegebene + zweiteingabe) und das Ergebniss Abspeichern. Das Ergebniss wird dabei zur ersteingabe.
Ich wäre echt dankbar für nen nützlichen code oder einen sehr hilfreichen Tipp. mfg.

Verfasst: Mittwoch 23. August 2006, 23:29
von BlackJack
Okay, die Teddybär Methode. Schnapp Dir ein Kuscheltier, setz' es neben dem Monitor und erkläre ihm den Quelltext Zeile für Zeile. Das da oben ist ganz einfacher, linear abgearbeiteter Quelltext. Wenn das nicht hilft, dann weiss ich auch nicht weiter.

Verfasst: Donnerstag 24. August 2006, 06:58
von jens
Malle hat geschrieben:Ich benutze Idle.
Schau mal hier: [wiki]IDLE[/wiki] :)

Verfasst: Donnerstag 24. August 2006, 15:21
von Malle
@ jens danke für den link
@ BlackJack Nein hilft trotz euserst merkwürdiger Metapher nicht, is aber auch egal.
@ Gerold danke für deinen Code der hat letztendlich doch all meine Probleme gelöst. Auch wenn noch gewisse Teile des Programms fehlen (z.B. ein menu oder eine löschfunktion), und es für manche Pros noch ziemlich unprofessionell aussieht. Poste ich erstmal das Skript.

Code: Alles auswählen

# Ersparnissrechner 0.4, python
# made by Malle
# -*- coding: iso-8859-1 -*-

import types
print "*" * 70
print "Ersparnissrechner, zum Beenden Strg+C druecken oder exit Eingeben"
print "*" * 70
TAGE = "tage.txt"
ZIG = "zig.txt"


def read_number(filename):
    try:
        t = file(filename, "r")
    except IOError:
        return 0
    try:
        try:
            numtag = int(t.readline())
        except ValueError:
            numtag = 0
    finally:
        t.close()

    return numtag

def read_number2(zigaretten):
    try:
        z = file(zigaretten, "r")
    except IOError:
        return 0
    try:
        try:
            numzig = int(z.readline())
        except ValueError:
            numzig = 0
    finally:
        z.close()
    return numzig
    
def write_number(filename, numtag):
    assert(isinstance(numtag, (types.IntType, types.LongType)))
    t = file(filename, "w")
    try:
        t.write(str(numtag))
    finally:
        t.close()

def write_number2(zigaretten, numzig):
    assert(isinstance(numzig, (types.IntType, types.LongType)))
    z = file(zigaretten, "w")
    try:
        z.write(str(numzig))
    finally:
        z.close()

def show_number(numtag):
    print "Aktueller Tag: %i" % numtag

def show_number2(numzig):
    print "Anzahl Zigaretten: %i" % numzig
    
def ask_for_number():
    print
    print "Vor wieviel Tagen haben Sie zuletzt geraucht?"
    try:
        s = raw_input("Eingabe: ")
    except KeyboardInterrupt:
        print
        print "Es wurde STRG+C gedrückt!"
        print
        return None
    if s.lower() == "exit":
        return None
    else:
        try:
            numtag = int(s)
            return numtag
        except ValueError:
            print
            print "Bitte geben sie eine ganze Zahl ein."

def ask_for_number2():
    print
    print "Wieviele haben sie seither geraucht"
    try:
        s = raw_input("Eingabe: ")
    except KeyboardInterrupt:
        print
        print "Es wurde Strg+C gedrückt!"
        print
        return None
    if s.lower() == "exit":
        return None
    else:
        try:
            numzig = int(s)
            return numzig
        except ValueError:
            print
            print "Bitte geben sie eine Ganze Zahl ein."
    
def berechnung_frueher():
    old_number = read_number(TAGE)
    show_number(old_number)
    new_number = ask_for_number()
    
    new_number = old_number + new_number
    write_number(TAGE, new_number)
    global frueher
    frueher = new_number * 4 / 3
    

def berechnung_jetzt():
    old_number2 = read_number2(ZIG)
    show_number2(old_number2)
    new_number2 = ask_for_number2()
    
    new_number2 = old_number2 + new_number2
    write_number2(ZIG, new_number2)
    global jetzt
    jetzt = new_number2 * 0.2

def main():
    while True:
        berechnung_frueher()
        berechnung_jetzt()
        geldfrueher = frueher
        geldjetzt = jetzt
        Ersparniss = geldfrueher - geldjetzt
        print
        print "Sie haben bereits", Ersparniss, "Euro gespart."
        print
        

if __name__ == "__main__":
    main()