Änderung der Liste abspeichern

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
saintblend
User
Beiträge: 2
Registriert: Montag 17. Mai 2021, 13:26

Hallo ich bin neu hier im Forum, sowie neu im Lernen der Python-Programmiersprache. Diese lerne ich derzeit im Rahmen meines Bauingenieurwesenstudiums.
Wir kriegen wöchentliche Aufgaben, die wir lösen müssen. Die haben bislang auch gut funktioniert und habe bislang auch alles bestanden, jedoch sitze ich derzeit mit einigen Kommilitonen an einem kleinen Problem. Und weil ich nicht weiss in welchem Forum ich mein Problem einordnen soll, habe ich jetzt einfach mal Allgemein ausgwählt.
Zur Aufgabe: Wir haben eine Liste in Form von Namen + Kontostand und müssen eine Kontoführung simulieren. Ich habe nun alle Funktionen schon programmiert und alles läuft einwandfrei, jedoch hadert es nun daran die Liste mit den Änderungen abzuspeichern. Die Aufgabenstellung lautet wie folgt:
Entwickeln Sie ein Programm, welches eine einfache Kontoführung simuliert. Lesen Sie dazu die Kundedaten (Kontonummer, Name, Guthaben) aus der .txt-Datei aus. In der Konsole sollen Sie eins der Konten auswählen und nun Ein- und Auszahlungen tätigen können, sowie die Möglichkeit haben Ihren Kontostand anzeigen zu lassen. Ihr Programm soll für beliebig viele Konten ausgelegt sein, sprich Anzahl der Kunden in der .txt-Datei und deren Kundeninformationen sind variable. Die beigelegte .txt-Datei dient lediglich als Testdatei für Sie.
Speichern Sie Änderungen am Kontostand in der gleichen .txt-Datei.
.
Bislang haben wir immer mit with open("dateiname2.txt","w") as datei: datei.write(f"......") gearbeitet. Hat einer eurerseits da eine Lösung und könnte weiterhelfen.
Mein Code sieht wie folgt aus (ich weiss, dass man das vieeel kürzer fassen könnte mit definierten Funktionen und anderen Methoden, wir aber noch nicht so weit im Studium):

Code: Alles auswählen

datei = open("Konto.txt", "r")
print("Willkomen zu Ihrem Banksystem!")
funktion = input("Was möchten Sie tun ?\n [1] Kontostand anzeigen\n [2] Einzahlen\n [3] Auszahlen\n [0] Ende\n Ihre Eingabe: ")

betragliste = []
vollenamen = []

def anzeigen(datei, zeile):
        for zeile in datei:
                print(zeile)

if int(funktion) > 3:
        print("Keine gültige Auswahl. Vielen Dank und auf Wiedersehen!")
elif int(funktion) < 0:
        print("Keine gültige Auswahl. Vielen Dank und auf Wiedersehen!")

elif funktion == "0":
        print("Das System wird beendet. Vielen Dank!")

elif funktion == "1":
        for zeile in datei:
                liste = zeile.strip().split()
                vornamen = liste[1]
                nachnamen = liste[2].replace(",", "")
                namen = vornamen + " " + nachnamen
                vollenamen.append(namen)
                betragliste.append(liste[3])
        print("Welches Kontostand möchten Sie anzeigen ?")
        for i in range(len(vollenamen)):
                print(f" [{i+1}] {vollenamen[i]} ")
        auswahl = int(input(" Ihre Eingabe: "))
        print(f"\n Ihr Kontostand beträgt: {betragliste[auswahl-1]} €")



elif funktion == "2":
        for zeile in datei:
                liste = zeile.strip().split()
                vornamen = liste[1]
                nachnamen = liste[2].replace(",", "")
                namen = vornamen + " " + nachnamen
                vollenamen.append(namen)
                betragliste.append(liste[3])
        print("Welches Konto möchten Sie verwenden ?")
        for i in range(len(vollenamen)):
                print(f" [{i+1}] {vollenamen[i]} ")
        auswahl = int(input(" Ihre Eingabe: "))
        wert = int(input("\n Wie viel möchten Sie einzahlen ?: "))
        betragliste[auswahl-1] = float(betragliste[auswahl-1]) + wert


elif funktion == "3":
        for zeile in datei:
                liste = zeile.strip().split()
                vornamen = liste[1]
                nachnamen = liste[2].replace(",", "")
                namen = vornamen + " " + nachnamen
                vollenamen.append(namen)
                betragliste.append(liste[3])
        print("Welches Konto möchten Sie verwenden ?")
        for i in range(len(vollenamen)):
                print(f" [{i+1}] {vollenamen[i]} ")
        auswahl = int(input(" Ihre Eingabe: "))
        wert = int(input("\n Wie viel möchten Sie auszahlen ?: "))
        betragliste[auswahl-1] = float(betragliste[auswahl-1]) - wert


with open("Konto.txt","w") as datei:
        datei.write(f".......")

print("Ihren Kontostand finden Sie unter Konto.txt. Vielen Dank und auf Wiedersehen!")
Vielen Dank im Voraus!
Benutzeravatar
noisefloor
User
Beiträge: 3853
Registriert: Mittwoch 17. Oktober 2007, 21:40
Wohnort: WW
Kontaktdaten:

Hallo,

warum liest du nicht _1x_ die Datei zu Beginn in _eine_ Liste (also eine Liste von Listen) und arbeitest dann damit? Das wäre einfacher. Die Datei, die du in der 1. Zeile liest, wrd auch nirgendwo geschlossen. Am besten direkt das `with` Statement verwenden - das kennst du ja anscheinend, weil es beim Schreiben benutzt wird.

Grundsätzlich solltest du immer aussagekräftige Datenamen benutzen - `datei`, funktion`etc. sind zu generisch. Eingerückt wird auch immer mit 4 Leerzeichen.
Über Listen kannst du direkt iterieren, mit `range` und Indexzugriff arbeiten ist i.d.R. ein Anti-Pattern. Wenn du eine Nummerierung beim Iterieren brauchst, dann gibt es die `enumerate` Funktion:

Code: Alles auswählen

...
for counter, item in enumerate(whatever_list):
   print(f'{counter}: {item}')
Dein Problem mit dem Schreiben verstehe ich nicht wirklich... Du musst halt über die Liste iterieren und dabei die Datei zeilenweise schreiben.

Gruß, noisefloor
Sirius3
User
Beiträge: 17737
Registriert: Sonntag 21. Oktober 2012, 17:20

Warum wandelst Du einmal die Eingabe `function` in ein int um, und mal nicht?
Am besten packt man die "Keine gültige Eingabe" in einen else-Block ganz unten.
Man öffnet nicht irgendwo im Code eine Datei und benutzt die dann an einer ganz anderen Stellen, sondern dort, wo sie gebraucht wird. Das gleiche gilt für `betragliste` und `vollenamen`.
Eingerückt wird immer mit 4 Leerzeichen pro Ebene, nicht 8, das ist zu viel, als dass es noch gut lesbar wäre.

Bei function 1: warum ersetzt Du im Nachnamen Komma durch ""? Was soll das?
`liste` ist ein schlechter Name für einen Datensatz. Viel zu allgemein.
Warum splittest Du erst Vor- und Nachname, wenn Du ihn später wieder zusammensetzt? Was passiert mit mehreren Vor- bzw. Nachnamen?
Man iteriert nicht über einen Index, sondern benutzt in diesem Fall enumerate.
Statt auf jeden Index +1 zu addieren, würde man dann auch von 1 starten.
Statt Namen und Beträge in zwei Listen zu speichern, benutzt man eine Liste mit Tupeln.
Das Umwandeln der Zahl macht man gleich beim Einlesen.
Da in Funktion1,2 und 3 jeweils der selbe Code steht, würde man das zu einem zusammenfassen.
Warum kannst Du nur eine Ganzzahl eingeben, aber der Betrag wird zum Float?
Das ganze sieht dann so aus:

Code: Alles auswählen

print("Willkomen zu Ihrem Banksystem!")
funktion = input("Was möchten Sie tun ?\n [1] Kontostand anzeigen\n [2] Einzahlen\n [3] Auszahlen\n [0] Ende\n Ihre Eingabe: ")
if funktion == "0":
    print("Das System wird beendet. Vielen Dank!")
elif funktion in ["1", "2", "3"]:
    with open("Konto.txt", encoding="utf8") as zeilen:
        daten = []
        for zeile in zeilen:
            name, betrag = zeile.strip().rsplit(None, 1)
            daten.append((name, float(betrag)))
    print("Welches Konto möchten Sie verwenden ?")
    for i, (name, betrag) in enumerate(daten, 1):
        print(f" [{i}] {name}")
    auswahl = int(input("Ihre Eingabe: "))
    if funktion == "1":
        print(f"\n Ihr Kontostand beträgt: {daten[auswahl-1][1]} €")
    else:
        name, betrag = daten[auswahl]
        if funktion == "2":
            wert = float(input("\n Wie viel möchten Sie einzahlen ?: "))
            betrag += wert
        else:
            wert = float(input("\n Wie viel möchten Sie auszahlen ?: "))
            betrag -= wert
        daten[auswahl] = (name, betrag)
        with open("Konto.txt","w", encoding="utf8") as datei:
            datei.write(f".......")
else:
    print("Keine gültige Auswahl. Vielen Dank und auf Wiedersehen!")

print("Ihren Kontostand finden Sie unter Konto.txt. Vielen Dank und auf Wiedersehen!")
Zum Speichern: das Ausgeben hast Du ja auch mit Schleife und Formatstrings gelöst, so funktioniert auch das Schreiben in eine Datei.
saintblend
User
Beiträge: 2
Registriert: Montag 17. Mai 2021, 13:26

Auf jeden Fall erstmal dankeschön für eure Antworten und eure Mühe mir da ein bisschen auszuhelfen.
Mag sein, dass meine Herangehensweise noch wirklich fragwürdig ist, aber bitte entschuldigt mich, da wir uns erst seit 2 Wochen mit Python beschäftigen.
Wieso ich das mit den Namen mache liegt an der Textdatei, die eingelesen wird - die sieht so aus:
1, Max Mustermann, 1000.0
2, Erika Mustermann, 1024.0
3, Felix Mustermann, 34.0


Ich bin noch nicht wirklich darauf gekommen wie ich nun die neuen Kontoständen in der selben Textdatei mithilfe von

Code: Alles auswählen

with open("Konto.txt","w") as datei:
ändere. Ich bin für jede weitere Hilfe sehr dankbar. LG.
Sirius3
User
Beiträge: 17737
Registriert: Sonntag 21. Oktober 2012, 17:20

Also hast Du gar keine Textdatei, mit irgendwelchen Leerzeichen als Trenner, sondern eine csv-Datei mit Komma als Trenner. Zum Lesen von csv-Datein benutzt man das csv-Modul.

Du mußt keine Datei ändern, sondern die kompletten Daten neu schreiben. Auch dafür benutzt man das csv-Modul.
Benutzeravatar
noisefloor
User
Beiträge: 3853
Registriert: Mittwoch 17. Oktober 2007, 21:40
Wohnort: WW
Kontaktdaten:

Hallo,
Ich bin noch nicht wirklich darauf gekommen wie ich nun die neuen Kontoständen in der selben Textdatei mithilfe von ...
Was hast du denn schon probiert? Was klappt nicht wie erwartet?

Das Vorgehen ist ähnlich dem Lesen:
* Datei im Öffnen, natürlich im Lesemodus
* Daten zeilenweise in die Datei schreiben.

Fertig. Im Prinzip so wie du schon im 1. Post geschrieben hast, nut halt um das `print` noch eine Schleife drum.

Gruß, noisefloor
Antworten