andie39‘s Fragen Thread
Ja es macht immer Sinn etwas neues zu lernen.
Bitte poste doch den ganzen Code mit zugehöriger, vollständiger Fehlermeldung. Der Code hört doch nicht mit einem Doppelpunkt auf.
Bitte poste doch den ganzen Code mit zugehöriger, vollständiger Fehlermeldung. Der Code hört doch nicht mit einem Doppelpunkt auf.
"When I got the music, I got a place to go" [Rancid, 1993]
Wie ich schon schrieb:
Ich habe soviel probiert ich könnte alle Versuche gar nicht mehr posten.
Naja es ist im Endeffekt wieder eine Schleifen-Geschichte. Ich war sicher jetzt weiß ich es aber Pustekuchen.
Ich sehe ehrlich gesagt keinen Fortschritt bei mir. Im Gegenteil es sind eher lauter Rückschritte.
- __blackjack__
- User
- Beiträge: 13003
- Registriert: Samstag 2. Juni 2018, 10:21
- Wohnort: 127.0.0.1
- Kontaktdaten:
@andie39: Bei dem jetzt gezeigten fehlt ja etwas. Da muss auf jeden Fall die Liste geschrieben werden, weil Dateimodus "w" den Inhalt der Datei löscht.
Im Grunde versuchst Du da schon zu viel in einer Funktion zu lösen. Ich würde dringend raten das schreiben der Filme und das lesen der Filme in jeweils eine eigene Funktion auszulagern. Denn das sind eigenständige Operationen die in beide Richtungen etwas machen müssen, was sonst an anderen Stellen im Programm nichts zu suchen hat: Mit Zeilenendezeichen umgehen. Denn die gehören ja nicht zu den Filmtiteln. Die sind ausschliesslich für das speichern in einer Datei notwendig, damit man die Titel dort sinnvoll auseinanderhalten und wieder einlesen kann.
Darauf aufbauen kann man dann eine Funktion, die einen Filmtitel hinzufügt. Da würde ich Benutzerinteraktion komplett raus lassen. Genau wie beim schreiben und lesen der Daten. Kein `print()` und kein `input()`. Das gehört nicht zu den grundlegenden Operationen, die von diesen Funktionen durchgeführt werden. Lesen, Schreiben, und hinzufügen eines Titels sind ja beispielsweise unabhängig davon ob man über eine Textkonsole, eine GUI, oder eine Weboberfläche mit dem Benutzer kommuniziert, oder ob diese Operationen automatisiert von anderem Code verwendet werden, beispielsweise weil man eine Liste mit Filmtiteln von einer Webseite mit Neuerscheinungen, oder einem RSS-Feed bekommen hat, und die der Datei hinzufügen möchte.
Also als API beispielsweise:
Wobei `load_movies()` eine Liste mit den Filmtiteln liefert, also wirklich nur die Titel ohne Zeilenendezeichen. Und `add_movie()` einen Wahrheitswert liefert, je nach dem ob das hinzufügen erfolgreich war, oder ob es den Filmtitel schon gab.
Wenn man das implementiert, könnte eine interaktive Verwendung so aussehen:
Im Grunde versuchst Du da schon zu viel in einer Funktion zu lösen. Ich würde dringend raten das schreiben der Filme und das lesen der Filme in jeweils eine eigene Funktion auszulagern. Denn das sind eigenständige Operationen die in beide Richtungen etwas machen müssen, was sonst an anderen Stellen im Programm nichts zu suchen hat: Mit Zeilenendezeichen umgehen. Denn die gehören ja nicht zu den Filmtiteln. Die sind ausschliesslich für das speichern in einer Datei notwendig, damit man die Titel dort sinnvoll auseinanderhalten und wieder einlesen kann.
Darauf aufbauen kann man dann eine Funktion, die einen Filmtitel hinzufügt. Da würde ich Benutzerinteraktion komplett raus lassen. Genau wie beim schreiben und lesen der Daten. Kein `print()` und kein `input()`. Das gehört nicht zu den grundlegenden Operationen, die von diesen Funktionen durchgeführt werden. Lesen, Schreiben, und hinzufügen eines Titels sind ja beispielsweise unabhängig davon ob man über eine Textkonsole, eine GUI, oder eine Weboberfläche mit dem Benutzer kommuniziert, oder ob diese Operationen automatisiert von anderem Code verwendet werden, beispielsweise weil man eine Liste mit Filmtiteln von einer Webseite mit Neuerscheinungen, oder einem RSS-Feed bekommen hat, und die der Datei hinzufügen möchte.
Also als API beispielsweise:
Code: Alles auswählen
def load_movies(filename):
...
def save_movies(filename, movies):
...
def add_movie(filename, movie):
...
Wenn man das implementiert, könnte eine interaktive Verwendung so aussehen:
Code: Alles auswählen
In [143]: !cat movies.csv
Love actually
Die Hard
The Grinch
In [144]: load_movies("movies.csv")
Out[144]: ['Love actually', 'Die Hard', 'The Grinch']
In [145]: add_movie("movies.csv", "Spiderman - Homecoming") # Das sollte funktionieren.
Out[145]: True
In [146]: !cat movies.csv
Love actually
Die Hard
The Grinch
Spiderman - Homecoming
In [147]: add_movie("movies.csv", "Die Hard") # Den Film gibt es bereits.
Out[147]: False
In [148]: !cat movies.csv
Love actually
Die Hard
The Grinch
Spiderman - Homecoming
“Most people find the concept of programming obvious, but the doing impossible.” — Alan J. Perlis
Du warst ja schon nah dran
In der Schleife über alle Zeilen, prüft man jetzt jede Zeile ob sie der Eingabe entspricht. Wird ein Treffer gefunden, gibt es die entsprechende Meldung und die Schleife wird abgebrochen.
Der for - else Zweig wird nur ausgeführt, wenn es kein "break" in der Schleife ausgelöst wurde, also der Titel noch nicht vorhanden ist.
Dann - und nur dann öffnest du die Datei zum (a)nhängen.
In der Schleife über alle Zeilen, prüft man jetzt jede Zeile ob sie der Eingabe entspricht. Wird ein Treffer gefunden, gibt es die entsprechende Meldung und die Schleife wird abgebrochen.
Der for - else Zweig wird nur ausgeführt, wenn es kein "break" in der Schleife ausgelöst wurde, also der Titel noch nicht vorhanden ist.
Dann - und nur dann öffnest du die Datei zum (a)nhängen.
Code: Alles auswählen
def add_movie():
with open ("movies.csv", "r") as file:
lines = file.readlines()
eingabe = input("Geben Sie einen Filmtitel ein:")
for element in lines:
if eingabe == element:
print(f"Der Titel {eingabe} ist bereits in der Datenbank")
break
else:
print(f"Der Titel {eingabe} wird neu in die Datenbank eingefügt")
with open("movies.csv", "a") as file:
file.write(eingabe + "\n")
Mit break habe ich auch versucht solche Gedanken hatte ich konnte die aber nicht umsetzen.rogerb hat geschrieben: ↑Sonntag 16. Januar 2022, 00:37 Du warst ja schon nah dran
In der Schleife über alle Zeilen, prüft man jetzt jede Zeile ob sie der Eingabe entspricht. Wird ein Treffer gefunden, gibt es die entsprechende Meldung und die Schleife wird abgebrochen.
Der for - else Zweig wird nur ausgeführt, wenn es kein "break" in der Schleife ausgelöst wurde, also der Titel noch nicht vorhanden ist.
Dann - und nur dann öffnest du die Datei zum (a)nhängen.
Code: Alles auswählen
def add_movie(): with open ("movies.csv", "r") as file: lines = file.readlines() eingabe = input("Geben Sie einen Filmtitel ein:") for element in lines: if eingabe == element: print(f"Der Titel {eingabe} ist bereits in der Datenbank") break else: print(f"Der Titel {eingabe} wird neu in die Datenbank eingefügt") with open("movies.csv", "a") as file: file.write(eingabe + "\n")
Eben w. Write überschreibt ja eine Datei.
Das hier sieht schlüssig aus. Ich verstehe nicht warum ich auf den Weg nicht gekommen bin bzw warum ich andere Wege für schlüssig und logisch gehalten habe, es aber nicht sind.
Ich hatte soger eine Idee das erst in die Liste „lines“ die Eingabe als append Anhang hinzugefügt wird aber auch das hat nicht geklappt.
Es gibt immer wieder Dinge die nicht klar sind auch in der remove Funktion die funktioniert und einen Film hinzugefügt. Hier stolpere ich über die Stelle an der in die Datei geschrieben wird.
Hintergrund: Ich dachte es gibt gff einen Befehl zum entfernen den ich nicht kenne also habe ich Google bemüht. Dabei stellte ich fest, dass es das wohl nicht gibt und man es überschreibt.
Ich GLAUBE das meiste zu verstehen bis eben zum
write:
Dieser Code ist es ja:
Nehmen wir an die folgenden Filme sind schon drin:
Alien, Predator, Terminator
Jeder hat dann ja eine Indexposition 1,2,3 und die Liste kann iteriert werden.
Ich lese die Funktion so:
Datei wird geöffnet und der Inhalt der Zeilen als Liste in lines gepackt.
Jetzt wird die Datei zum schreiben geöffnet,
eine Abfrage nach einem Film der hinzugefügt werden soll gemacht, dieser als Variabel eingabe gespeichert.
Nun für jeden Wert in lines geprüft ob der eingegebene Wert ungleich ist und wenn das true ist wird der Wert in die Datei geschrieben.
Beispiel: Eingabe ist: Rambo:
Es wird geprüft: Ist Rambo ungleich Alien?
Wenn true: Schreibe Alien in die Datei
Dann: Ist Predator ungleich Rambo
Wenn true: Schreibe Predator in die Datei
Wäre Rambo schon drin, wäre die Frage: Ist Rambo
ungleich Rambo false und es würde nicht in die Datei geschrieben.
Was mich stutzig macht ist:
w für write überschreibt eine Datei. a statt w fügt etwas hinzu.
Ich hätte eigentlich also erwartet, dass hier mit w folgendes geschehen wäre:
Alien wird reingeschrieben da true, dann wird Predator geprüft ist auch ungleich der Eingabe und würde nun Alien überschreiben.
Am Ende wäre nur Terminator in der Liste.
Aber alle drei Filme sind noch drin.
Warum überschreibt w. nicht die vorherigen Werte?
Hintergrund: Ich dachte es gibt gff einen Befehl zum entfernen den ich nicht kenne also habe ich Google bemüht. Dabei stellte ich fest, dass es das wohl nicht gibt und man es überschreibt.
Ich GLAUBE das meiste zu verstehen bis eben zum
write:
Dieser Code ist es ja:
Code: Alles auswählen
def remove_movie():
with open("movies.csv", "r") as file:
lines = file.readlines()
with open("movies.csv", "w") as file:
eingabe = input("Welchen Film möchten Sie enternen?")
for element in lines:
if element != eingabe + ("\n"):
file.write(element)
Alien, Predator, Terminator
Jeder hat dann ja eine Indexposition 1,2,3 und die Liste kann iteriert werden.
Ich lese die Funktion so:
Datei wird geöffnet und der Inhalt der Zeilen als Liste in lines gepackt.
Jetzt wird die Datei zum schreiben geöffnet,
eine Abfrage nach einem Film der hinzugefügt werden soll gemacht, dieser als Variabel eingabe gespeichert.
Nun für jeden Wert in lines geprüft ob der eingegebene Wert ungleich ist und wenn das true ist wird der Wert in die Datei geschrieben.
Beispiel: Eingabe ist: Rambo:
Es wird geprüft: Ist Rambo ungleich Alien?
Wenn true: Schreibe Alien in die Datei
Dann: Ist Predator ungleich Rambo
Wenn true: Schreibe Predator in die Datei
Wäre Rambo schon drin, wäre die Frage: Ist Rambo
ungleich Rambo false und es würde nicht in die Datei geschrieben.
Was mich stutzig macht ist:
w für write überschreibt eine Datei. a statt w fügt etwas hinzu.
Ich hätte eigentlich also erwartet, dass hier mit w folgendes geschehen wäre:
Alien wird reingeschrieben da true, dann wird Predator geprüft ist auch ungleich der Eingabe und würde nun Alien überschreiben.
Am Ende wäre nur Terminator in der Liste.
Aber alle drei Filme sind noch drin.
Warum überschreibt w. nicht die vorherigen Werte?
- __blackjack__
- User
- Beiträge: 13003
- Registriert: Samstag 2. Juni 2018, 10:21
- Wohnort: 127.0.0.1
- Kontaktdaten:
@andie39: Ich glaube ein Problem was das ganze an der Stelle verkompliziert ist das Dateiobjekt und dass das einen Zustand hat und da Tests mit ``in``, das darüber iterieren, und das lesen mit `read()` alle den Zustand ändern und das deshalb Einfluss auf folgende Tests/Operationen hat. Diese Operationen laufen aber ”geräuschlos” ab, liefern aber nicht mehr unbedingt das Ergebnis das man erwartet, wenn man sich über diesen inneren Zustand nicht im klaren ist.
Also zum Beispiel das nach einem `read()` sozusagen nichts mehr in dem Dateiobjekt ist, weil die aktuelle Leseposition, die in dem Dateiobjekt verwaltet wird, dann am Ende der Datei steht:
Hätte man in [156] nach etwas gesucht was *nicht* in der Datei enthalten gewesen wäre, hätte das letzte `read()` eine leere Zeichenkette geliefert.
Hier mal eine mögliche Implementierung von der API die ich vorgeschlagen hatte:
Also zum Beispiel das nach einem `read()` sozusagen nichts mehr in dem Dateiobjekt ist, weil die aktuelle Leseposition, die in dem Dateiobjekt verwaltet wird, dann am Ende der Datei steht:
Code: Alles auswählen
In [151]: file = open("movies.csv")
In [152]: file.read()
Out[152]: 'Love actually\nDie Hard\nThe Grinch\nSpiderman - Homecoming\n'
In [153]: file.read() # Wir sind am Ende, total am Ende:
Out[153]: ''
In [154]: "Die Hard\n" in file # ist in der Datei enthalten, aber:
Out[154]: False
In [155]: file = open("movies.csv") # Funktioniert bei einer neu geöffneten Datei:
In [156]: "Die Hard\n" in file
Out[156]: True
In [157]: file.read() # liefert nicht mehr den gesamten Dateiinhalt:
Out[157]: 'The Grinch\nSpiderman - Homecoming\n'
Hier mal eine mögliche Implementierung von der API die ich vorgeschlagen hatte:
Code: Alles auswählen
def validate_movie(movie):
if "\n" in movie:
raise ValueError(f"illegal newline in {movie!r}")
return movie
def load_movies(filename):
with open(filename, "r", encoding="utf-8") as file:
return [line.rstrip() for line in file]
def save_movies(filename, movies):
with open(filename, "w", encoding="utf-8") as file:
file.writelines(f"{validate_movie(movie)}\n" for movie in movies)
def add_movie(filename, movie):
validate_movie(movie)
movies = load_movies(filename)
if movie in movies:
return False
movies.append(movie)
save_movies(filename, movies)
return True
“Most people find the concept of programming obvious, but the doing impossible.” — Alan J. Perlis
- __blackjack__
- User
- Beiträge: 13003
- Registriert: Samstag 2. Juni 2018, 10:21
- Wohnort: 127.0.0.1
- Kontaktdaten:
@andie39: Der Dateimodus "w" wirkt beim *öffnen* der Datei. Die Datei wird geöffnet und geleert und die aktuelle Position ist am Anfang der Datei. Das wars. Ab da arbeitet man dann ganz normal mit der geöffneten leeren Datei.
Bei "a" wird die Datei geöffnet und die aktuelle Position ganz ans Ende gesetzt. So das der erste Schreibvorgang nicht am Anfang der Datei erfolgt, sondern am Ende, also die Datei um weitere Bytes erweitert, ohne dass sich an den Daten die schon da waren, etwas ändert.
Das `write()` macht in beiden Fällen genau das gleiche. Das schreibt die Daten an die aktuelle Position und bewegt diese um die Anzahl der geschriebenen Bytes weiter, so das der nächste Schreibvorgang hinter die Daten vom letzten Schreibvorgang schreibt.
Bei "a" wird die Datei geöffnet und die aktuelle Position ganz ans Ende gesetzt. So das der erste Schreibvorgang nicht am Anfang der Datei erfolgt, sondern am Ende, also die Datei um weitere Bytes erweitert, ohne dass sich an den Daten die schon da waren, etwas ändert.
Das `write()` macht in beiden Fällen genau das gleiche. Das schreibt die Daten an die aktuelle Position und bewegt diese um die Anzahl der geschriebenen Bytes weiter, so das der nächste Schreibvorgang hinter die Daten vom letzten Schreibvorgang schreibt.
“Most people find the concept of programming obvious, but the doing impossible.” — Alan J. Perlis
Ach so.
Ich dachte erst wenn man reinschreibt wird ûberschrieben. Das erklärt das natürlich.
Die Suche per IN, in der gesamten Datei war ja eh nicht zielführend. Wie Sirius ja als Beispiel ES und EScape Room genannt hat.
Zum read() Befehl:
Ach so, wenn man ein weiteres Mal direkt hinter dem read ein erneutes macht ist die Position am Ende. Und kann nicht mehr durchlaufen?
Man muss dann die Datei erst erneut öffnen?
Ich dachte erst wenn man reinschreibt wird ûberschrieben. Das erklärt das natürlich.
Die Suche per IN, in der gesamten Datei war ja eh nicht zielführend. Wie Sirius ja als Beispiel ES und EScape Room genannt hat.
Zum read() Befehl:
Ach so, wenn man ein weiteres Mal direkt hinter dem read ein erneutes macht ist die Position am Ende. Und kann nicht mehr durchlaufen?
Man muss dann die Datei erst erneut öffnen?
Hallo,rogerb hat geschrieben: ↑Sonntag 16. Januar 2022, 00:37 Du warst ja schon nah dran
In der Schleife über alle Zeilen, prüft man jetzt jede Zeile ob sie der Eingabe entspricht. Wird ein Treffer gefunden, gibt es die entsprechende Meldung und die Schleife wird abgebrochen.
Der for - else Zweig wird nur ausgeführt, wenn es kein "break" in der Schleife ausgelöst wurde, also der Titel noch nicht vorhanden ist.
Dann - und nur dann öffnest du die Datei zum (a)nhängen.
Code: Alles auswählen
def add_movie(): with open ("movies.csv", "r") as file: lines = file.readlines() eingabe = input("Geben Sie einen Filmtitel ein:") for element in lines: if eingabe == element: print(f"Der Titel {eingabe} ist bereits in der Datenbank") break else: print(f"Der Titel {eingabe} wird neu in die Datenbank eingefügt") with open("movies.csv", "a") as file: file.write(eingabe + "\n")
habe mal getestet, deni Code funktioniert auch nicht.
er fügt zwar neue Filme hinzu, aber wenn es den Film schon gibt, dann fügt er den Film trotzden nochmal hnizu.
Ich dachte erstm es liegt daran,dass dein els: nicht auf der gleichen Höhe eingerückt ist, wie das if, aber wenn ich das ändere, wird es nehrfach hinzugefügt.
Ich dachte auch immer das if und else immer in der gleichen Höhe der Einrückung seni müssen?!
Das Problem hatten wir ja jetzt schon sehr oft: gelesene Zeilen haben immer das Zeileende-Zeichen als letztes Zeichen, `eingabe` hat das aber nicht, so dass der Vergleich `eingabe == element` immer fehlschlägt.
Nicht nur auf `if` kann ein `else` folgen, sondern auch auf `for`, `while` oder `try/except`.
Aber es ist wirklich wichtig, Funktionen zu schreiben, die nur eine Sache machen, und die Richtig. Dann hast Du deutlich weniger Probleme, den Ablauf einer Funktion zu verstehen.
Nicht nur auf `if` kann ein `else` folgen, sondern auch auf `for`, `while` oder `try/except`.
Aber es ist wirklich wichtig, Funktionen zu schreiben, die nur eine Sache machen, und die Richtig. Dann hast Du deutlich weniger Probleme, den Ablauf einer Funktion zu verstehen.
Ich habe es gelöst, element so nuss es sein;
if eingabe == element.strip("\n"):
\n muss entfernt werden beim Vergleich
Nachtrag: Hatte ich vor dem Post von Sirius gepostet
Ach dann macht das mit dem else Sinn.
wenn es direkt im Block nit if gleich ist, dann wird er ja immer wenn eingabe und element ungleich sind den Film hinzufügen.
Hier prüft die for Schleife jetzt nur ob der Film vorhanden ist, erst wenn die for Schleife komplett false ist wird else durchgeführt und der Film hnizugefügt.
if eingabe == element.strip("\n"):
\n muss entfernt werden beim Vergleich
Nachtrag: Hatte ich vor dem Post von Sirius gepostet
Ach dann macht das mit dem else Sinn.
wenn es direkt im Block nit if gleich ist, dann wird er ja immer wenn eingabe und element ungleich sind den Film hinzufügen.
Hier prüft die for Schleife jetzt nur ob der Film vorhanden ist, erst wenn die for Schleife komplett false ist wird else durchgeführt und der Film hnizugefügt.
Genau, das hatte ich gestern so spät nicht mehr getestet. Du hast die Lösung ja gefunden.
Ich würde auch eigentlich das csv-Modul oder das json-Modul dafür verwenden. Dann ist die Gefahr geringer, in solche Fehler zu laufen.
Danke für eure Geduld ich GLAUBE jetzt hab ich es begriffen.
Man muss schon genau schauen was wo eingerückt ist und was passiert.
Ja das mit dem Modul wurde schon erwähnt mir geht es hier nur um eine Übung passend zu meinem Onlinekurs.
Erst wenn ich merke ich kann es, was dauern kann, wie man ja hier sieht mache ich weiter.
Dieses Programm ist nur dafür da. Hauptsächlich auch weil hier noch das dictionary kommt, wenn es darum geht einzufügen, ob ein Film verliehen ist oder nicht
Man muss schon genau schauen was wo eingerückt ist und was passiert.
Ja das mit dem Modul wurde schon erwähnt mir geht es hier nur um eine Übung passend zu meinem Onlinekurs.
Erst wenn ich merke ich kann es, was dauern kann, wie man ja hier sieht mache ich weiter.
Dieses Programm ist nur dafür da. Hauptsächlich auch weil hier noch das dictionary kommt, wenn es darum geht einzufügen, ob ein Film verliehen ist oder nicht
So, ich habe nun die Funktion zum suchen eines Films in der Datenbank geschrieben und die halbwegs die Funktion einen Film als Verliehen oder Verfügbar zu markieren:
Hier die Funktion zur Suche:
Und hier einen Film als verliehen und verfügbar zu markieren:
Aber das ist erzeugt nur ein Dictionary welches den eingegebenen Film als verliehen und die anderen als verfügbar kennzeichnet.
Er müsste dann noch in die movies.csv schreiben und dort diese Informationen setzen und natürlich auch die, die noch als verliehen dort sind, dürfen nicht einfach überschrieben werden.
Je mehr ich mir das so ansehe und dazu google stelle ich fest:
So aufwendig sollte das in der Realität niemals sein.
das CSV Modul von Anfang an würde vieles erleichtern, wie auch hier ja schon geschrieben wurde.
Und auch _blackjack_ hat Recht:
Die Funktionen sollten einfacher gehalten werden.
Allerdings ging es mir ja auch darum, gelerntes zu probieren.
Nachdem Filme hinzufügen, Filme entfernen und Filme suchen im nachhinein nicht so ein Problem sind, da diese ja nur eine einfache Liste sind, wird es mit der Zusatz ob die verliehen oder verfügbar sind etwas schwieriger.
Abgesehen vom CSV Modul etc.
Wenn man es so programmieren würde wie ich es gerade versuche, ohne Module etc:
Wie würdet ihr es machen?
Die Funktion die,die Filme kennzeichnet so schreiben, dass diese ein dictionary erzeugt,
wie oben, aber erst noch prüft ob hier einige bereits den Wert "verliehen" haben und diese dann entsprechend überspringen?
Dieses dictonary dann in eine neue Datei schreiben die man aufrufen und prüfen kann?
Das wäre so mein Gedanke, wie seht ihr das?
Hier die Funktion zur Suche:
Code: Alles auswählen
def find_movie():
with open ("movies.csv", "r") as file:
lines = file.readlines()
eingabe = input("Welchen Film suchen Sie?")
for element in lines:
if eingabe == element.strip("\n"):
print(f"{eingabe}, ist in der Datenbank vorhanden.")
break
else:
print(f"{eingabe} ist in der Datenbank NICHT vorhanden.")
Code: Alles auswählen
def mark_lend():
with open ("movies.csv", "r") as file:
lines = file.readlines()
movies_marked = {}
eingabe = input("Welcher Film soll als verliehen markiert werden?")
for element in lines:
if eingabe == element.strip("\n"):
movies_marked[element] = "Verliehen"
else:
movies_marked[element] = "Verfügbar"
Er müsste dann noch in die movies.csv schreiben und dort diese Informationen setzen und natürlich auch die, die noch als verliehen dort sind, dürfen nicht einfach überschrieben werden.
Je mehr ich mir das so ansehe und dazu google stelle ich fest:
So aufwendig sollte das in der Realität niemals sein.
das CSV Modul von Anfang an würde vieles erleichtern, wie auch hier ja schon geschrieben wurde.
Und auch _blackjack_ hat Recht:
Die Funktionen sollten einfacher gehalten werden.
Allerdings ging es mir ja auch darum, gelerntes zu probieren.
Nachdem Filme hinzufügen, Filme entfernen und Filme suchen im nachhinein nicht so ein Problem sind, da diese ja nur eine einfache Liste sind, wird es mit der Zusatz ob die verliehen oder verfügbar sind etwas schwieriger.
Abgesehen vom CSV Modul etc.
Wenn man es so programmieren würde wie ich es gerade versuche, ohne Module etc:
Wie würdet ihr es machen?
Die Funktion die,die Filme kennzeichnet so schreiben, dass diese ein dictionary erzeugt,
wie oben, aber erst noch prüft ob hier einige bereits den Wert "verliehen" haben und diese dann entsprechend überspringen?
Dieses dictonary dann in eine neue Datei schreiben die man aufrufen und prüfen kann?
Das wäre so mein Gedanke, wie seht ihr das?
- __blackjack__
- User
- Beiträge: 13003
- Registriert: Samstag 2. Juni 2018, 10:21
- Wohnort: 127.0.0.1
- Kontaktdaten:
@andie39: Du könntest eine extra Datei erstellen wo die verliehenen Filme entweder extra gespeichert werden, oder das Programm so schreiben, dass die verliehenen Filme sozusagen verschoben werden, also wenn Film X verliehen wird, dann aus der movies-Datei entfernen und zur lent-movies-Datei hinzufügen und wenn der Film zurück kommt, das ganze wieder umgekehrt.
Oder Du speicherst die Information zu jedem Film dazu, beispielsweise das Filme die da sind, als erstes Zeichen vor dem Titel ein "+" haben und alle die verliehen sind ein "-".
In beiden Fällen würde ich dann wieder dafür plädieren, dass es eine Lese- und eine Schreibfunktion gibt und diese beiden Funktionen die *einzigen* sind, die etwas von "+", "-", und "\n" wissen. Liefern und als Argument erwarten würden diese beiden Funktionen dann Listen aus Tupeln (Filmtitel, Wahrheitswert), wobei der Wahrheitswert, also `True` oder `False` aussagt ob der Film verfügbar oder verliehen ist. Wobei es auch gerne ein `collection.namedtuple()`-Typ sein darf, der diese beiden Informationen zusammenfasst.
Oder Du speicherst die Information zu jedem Film dazu, beispielsweise das Filme die da sind, als erstes Zeichen vor dem Titel ein "+" haben und alle die verliehen sind ein "-".
In beiden Fällen würde ich dann wieder dafür plädieren, dass es eine Lese- und eine Schreibfunktion gibt und diese beiden Funktionen die *einzigen* sind, die etwas von "+", "-", und "\n" wissen. Liefern und als Argument erwarten würden diese beiden Funktionen dann Listen aus Tupeln (Filmtitel, Wahrheitswert), wobei der Wahrheitswert, also `True` oder `False` aussagt ob der Film verfügbar oder verliehen ist. Wobei es auch gerne ein `collection.namedtuple()`-Typ sein darf, der diese beiden Informationen zusammenfasst.
“Most people find the concept of programming obvious, but the doing impossible.” — Alan J. Perlis
Hmm….
gute Frage wie ich das am besten machen sollte.
Ich habe mir aber mal deine Beispiele hier genauer angesehen:
Sieht sinnvoll aus, kleinere Funktionen werden in andere mit eingebaut so das man die auch nicht immer neu schreiben muss.
Sehr clever.
Aber ich habe ich eine Frage zu einer Funktion :
Load und safe öffnen und schreiben ja nur.
Load erstellt eine Liste die wird als movies später definiert und dort ein Film in die Liste hinzugefügt um dann die neue Liste Zeile für Zeile damit save dort eben die einzelnen Filme wieder in die Datei reinschreibt das macht soweit Sinn aber hier, dieser Teil der add Funktion:
Ich weiss das man einen Rückgabewert entsprechend false oder true nach Bool definieren kann, aber was macht das genau?
Was bringt die Rückgabe false?
Lässt es das Programm dann hier stoppen, so dass die Funktion nicht weiter ausgeführt wird? Was hier ja das hinzufügen des Films und die Datei neu schreiben wäre?
Und wenn ja, wäre die Rückgabe true am Ende der Funktion dann nicht überflüssig da die Funkt dort sowieso endet?
gute Frage wie ich das am besten machen sollte.
Ich habe mir aber mal deine Beispiele hier genauer angesehen:
Code: Alles auswählen
def validate_movie(movie):
if "\n" in movie:
raise ValueError(f"illegal newline in {movie!r}")
return movie
def load_movies(filename):
with open(filename, "r", encoding="utf-8") as file:
return [line.rstrip() for line in file]
def save_movies(filename, movies):
with open(filename, "w", encoding="utf-8") as file:
file.writelines(f"{validate_movie(movie)}\n" for movie in movies)
def add_movie(filename, movie):
validate_movie(movie)
movies = load_movies(filename)
if movie in movies:
return False
movies.append(movie)
save_movies(filename, movies)
return True
Sehr clever.
Aber ich habe ich eine Frage zu einer Funktion :
Load und safe öffnen und schreiben ja nur.
Load erstellt eine Liste die wird als movies später definiert und dort ein Film in die Liste hinzugefügt um dann die neue Liste Zeile für Zeile damit save dort eben die einzelnen Filme wieder in die Datei reinschreibt das macht soweit Sinn aber hier, dieser Teil der add Funktion:
Code: Alles auswählen
movies = load_movies(filename)
if movie in movies:
return False
movies.append(movie)
save_movies(filename, movies)
return True
Was bringt die Rückgabe false?
Lässt es das Programm dann hier stoppen, so dass die Funktion nicht weiter ausgeführt wird? Was hier ja das hinzufügen des Films und die Datei neu schreiben wäre?
Und wenn ja, wäre die Rückgabe true am Ende der Funktion dann nicht überflüssig da die Funkt dort sowieso endet?
- __blackjack__
- User
- Beiträge: 13003
- Registriert: Samstag 2. Juni 2018, 10:21
- Wohnort: 127.0.0.1
- Kontaktdaten:
@andie39: Die Funktion selbst macht mit dem Rückgabewert nichts, aber der Aufrufer kann daran feststellen ob der Aufruf geklappt hat, oder ob es den Film schon gab. In den Funktionen ist ja keine Benutzerinteraktion enthalten. Der Code der das aufruft, möchte dem Benutzer vielleicht gerne mitteilen ob das hinzufügen erfolgreich war oder nicht. Wenn einen das nicht interessiert, kann man das ignorieren.
“Most people find the concept of programming obvious, but the doing impossible.” — Alan J. Perlis
Ok, aber dann wäre doch ein print Befehl eher nötig, der mitteilt ob es den Film gibt oder nicht?__blackjack__ hat geschrieben: ↑Montag 17. Januar 2022, 01:12 @andie39: Die Funktion selbst macht mit dem Rückgabewert nichts, aber der Aufrufer kann daran feststellen ob der Aufruf geklappt hat, oder ob es den Film schon gab. In den Funktionen ist ja keine Benutzerinteraktion enthalten. Der Code der das aufruft, möchte dem Benutzer vielleicht gerne mitteilen ob das hinzufügen erfolgreich war oder nicht. Wenn einen das nicht interessiert, kann man das ignorieren.
Du benutzt es ja auch bei der load_movies, aber das würde doch auch ohne gehen oder nicht?
Also so:
Code: Alles auswählen
def load_movies(filename):
with open(filename, "r", encoding="utf-8") as file:
[line.rstrip() for line in file]
Desweiteren bei der add_movie dann:
Code: Alles auswählen
def add_movie(filename, movie):
validate_movie(movie)
movies = load_movies(filename)
if movie in movies:
return False
movies.append(movie)
save_movies(filename, movies)
Denn movies.append(movie) ist ja nicht im if block untergebracht sondern würde doch nach der if Anweisung so oder so ausgeführt werden, da nicht eingerückt oder nicht?