Zeile aus File löschen

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
nfehren
User
Beiträge: 98
Registriert: Donnerstag 31. Oktober 2013, 15:11

Hallo mal wieder :)
Ich bin an einem Programm wo ich in der Arbeit meine Überstunden eintragen kann. Ich will folgende möglichkeiten Bereit stellen:
1. Zeit eintragen
2. Zeitlog anschauen
3. Zeit als "bezahlt" löschen
4. Gesamt unbezahlte Zeit anschauen
5. Programm beenden

Alles soll permanent in ein File geschrieben werden, dabei liegt aber nicht das Problem. Menupunkt 1 hab ich fertig, genauso wie Punkt 2. Aber Punkt 3 lässt mich grübeln.

Ich weis das man mit readline die Zeile irgendwie erfassen kann aber ich finde keine richtige Dokumentation darüber.

Ich will das man das Datum eingibt und dann der Eintrag gelöscht wird.
Soweit bin ich derzeit:

Code: Alles auswählen

#!/usr/bin/python3
# Importieren der Module zum schreiben und einlesen in eine Datei:
from helper_functions import read_files, write_hard_text_to_files, überprüfe_integer_auf_höhe
from time import *
# Begrüßung
print('{:-^50}'.format("Unbezahlte Überstunden"))
print('{:-^50}'.format("1. Zeit eintragen"))
print('{:-^50}'.format("2. Zeitlog anschauen"))
print('{:-^50}'.format("""3. Zeit als "bezahlt" löschen"""))
print('{:-^50}'.format("4. Gesamt unbezahlte Zeit anschauen"))
print('{:-^50}'.format("5. Programm beenden"))

while True:
    menu_auswahl = überprüfe_integer_auf_höhe("Auswahl: ",1,4)
    if menu_auswahl == 1:
        stunden = input("Geben sie ihre stundenzahl ein: ")
        lt = localtime()
        datum = strftime("%d.%m.%Y", lt)
        eintrag = ("Datum: {0}    ==>    {1} Stunden".format(datum,stunden))
        print(eintrag)
        write_hard_text_to_files("ueberstunden.txt",eintrag)
    if menu_auswahl == 2:
        read_files("ueberstunden.txt")
    if menu_auswahl == 3:
        print("... Menupunkt ist noch in Arbeit! ...")
    if menu_auswahl == 4:
        pass
    if menu_auswahl == 5:
        pass
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

Wenn du eine Zeile aus einer Datei löschen willst, dann muss du eine neue Datei schreiben. Natürlich ohne die neue Zeile ;-) Allerdings würde ich bei deinem Szenario zumindest über eine Datenbank nachdenken. SQLite wäre sicher ausreichend. Dann sparst du dir viel unnötige Arbeit.

Noch einige Hinweise zu deinem Code:

- Kommentare sollten einen Mehrwert liefern. Aussagen wie "Importieren der Module zum schreiben und einlesen in eine Datei:" sind daher überflüssig, denn der Import eines Moduls ist leicht am Code zu erkennen.

- Entscheide dich für eine Sprache, entweder Englisch oder Deutsch. Kein seltsamer Mix aus beidem.

- Verwende keine *-Importe, damit müllst du dir den gesamten Namensraum zu, überschreibst ungewollt Namen und kannst die Herkunft von Namen nur schwer nachvollziehen.

- Code gehört, abgesehen von Konstanten und Definitionen von Klassen und Funktionen, nicht auf modulebene. Sonst kannst du deinen Code nur schwer wiederverwenden. Strecke deinen Code in vernünftige Funktionen und starte das Programm über das folgende Idiom:

Code: Alles auswählen

if __name__ == "__main__":
    main()
Dein Programm sollte sich dabei in der main-Funktion befinden.

- Wenn du wieder und wieder den selben Code schreibst, dann abstrahiere. Verwende dazu Funktionen, Konstanten und Schleifen. Zeilen 6 bis 11 kannst du leicht zusammenfassen.

- Verwende elif, wenn sich Bedingungen ausschließen. In deinem Fall also

Code: Alles auswählen

if menu_auswahl == 1:
    ...
elif menu_auswahl == 2:
    ...
- Die Auswahl des Menüs kann man noch schöner machen:

Code: Alles auswählen

def stundenzahl_eintragen(...):
    ...

def ueberstunden_anzeigen(...):
    ...

...

MENU = [stundenzahl_eintragen, ueberstunden_anzeigen, ...]

menu_auswahl = überprüfe_integer_auf_höhe("Auswahl: ",1,4)
try:
    MENU[menu_auswahl+1](...)
except IndexError:
    print("Auswahl ungültig.")
Das Leben ist wie ein Tennisball.
BlackJack

Oder wenn schon keine relationale Datenbank, dann wenigstens nicht selber irgendwelche kruden Dateiformate erfinden, sondern vorhandenes verwenden. Zum Beispiel JSON oder CSV. Für beides gibt es Module in der Standardbibliothek.

Beim neu schreiben bietet es sich übrigens an die geänderten Daten erst in eine neue Datei zu schreiben und die am Ende zur alten umzubenennen. Dann gehen keine Daten verloren wenn mitten beim Schreiben das Programm abbricht, oder der Rechner abstürzt.
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

EyDu hat geschrieben: - Die Auswahl des Menüs kann man noch schöner machen:
In diesem Zusammenhang vielleicht ganz nützlich: Link
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

Danke Hyperion, an das Tutorial habe ich gar nicht gedacht. Nun ist er in den Bookmarks geparkt, wird sicher noch öfter gebraucht.
Das Leben ist wie ein Tennisball.
nfehren
User
Beiträge: 98
Registriert: Donnerstag 31. Oktober 2013, 15:11

Hyperion hat geschrieben:
EyDu hat geschrieben: - Die Auswahl des Menüs kann man noch schöner machen:
In diesem Zusammenhang vielleicht ganz nützlich: Link
Gucks mir grad an ist echt super gut das Tutorial vielen dank!

Super hilfreich! Sehr verständlich erklärt.

Das ist jetzt mein Code:

Code: Alles auswählen

def eintrag_hinzufügen():
    anz_stunden = input("Geben sie ihre Stundenzahl ein: ")
    lt = localtime()
    datum = strftime("%d.%m.%Y", lt)
    eintrag = ("Datum: {0}    ==>    {1} Stunden".format(datum,anz_stunden))
    write_hard_text_to_files("ueberstunden.txt",eintrag)

def einträge_angucken():
    read_files("ueberstunden.txt")

def eintrag_löschen():
    print("In Arbeit.")

def programm_beenden():
    print("In Arbeit.")

def menupunkt_ausführen(menu):
    while True:
        for index, item in enumerate(menu, 1):
            print("{0}  {1}".format(index, item[0]))
        auswahl = int(input("Auswahl: ")) -1
        menu[auswahl][1]()
        if 0 <= auswahl < len(menu):
            menu[auswahl][1]()
        else:
            print("Bitte nur Zahlen im Bereich 1 - {} eingeben".format(len(menu)))

menu = [
    ["Zeit eintragen", eintrag_hinzufügen],
    ["Zeitlog anschauen", einträge_angucken],
    ["""Zeit als "bezahlt" löschen""", eintrag_löschen],
    ["Programm beenden\n", programm_beenden]
    ]

menupunkt_ausführen(menu)
Jetzt habe ich eine sehr gut strukturierte Menuführung aber ich weis immernoch nicht wie ich eine Zeile aus einer Datei lösche.. Die Datenbank ist an sich gut die soll ich aber nicht benutzen weil dort kein wirklicher Lernbedarf besteht.
Benutzeravatar
/me
User
Beiträge: 3561
Registriert: Donnerstag 25. Juni 2009, 14:40
Wohnort: Bonn

nfehren hat geschrieben:Jetzt habe ich eine sehr gut strukturierte Menuführung aber ich weis immernoch nicht wie ich eine Zeile aus einer Datei lösche.
Man kann keine Zeilen aus einer Datei löschen. Du könntest aber eine neue Datei schreiben und die Zeile, die du nicht brauchst, weglassen.
Benutzeravatar
cofi
Python-Forum Veteran
Beiträge: 4432
Registriert: Sonntag 30. März 2008, 04:16
Wohnort: RGFybXN0YWR0

Und generell willst du in eine *neue* Datei schreiben und nur bei Erfolg die *alte* ueberschreiben.
Antworten