andie39‘s Fragen Thread

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.
Benutzeravatar
andie39
User
Beiträge: 152
Registriert: Dienstag 7. Dezember 2021, 16:32

Else war für mich auch logisch aber else geht nicht da gab es einen Fehler.
Warum ist mir nicht klar.
Mir elif wird geprüft und wenn nicht vorhanden der Film hinzugefügt.
Benutzeravatar
sparrow
User
Beiträge: 4165
Registriert: Freitag 17. April 2009, 10:28

Das mit dem Fehler, der jetzt nicht mehr kommt, könnte daran liegen, dass der elif Zweig nie ausgeführt wird. Die Bedingung ist immer False.

Probier doch mal aus ob "irgendwas" in file jemals True sein kann.
Benutzeravatar
andie39
User
Beiträge: 152
Registriert: Dienstag 7. Dezember 2021, 16:32

Wieso wird der elif nicht ausgeführt ich verstehe es grad echt nicht. Er macht doch erst die erste Abfrage ob die true ist und danach die elif.
Wenn der Film schon drin ist meldet er das sonst fügt er den hinzu.
Ich stimme zu eigentlich sollte er if… und else machen sind ja nur true oder false.

Aber funktionieren tut es ja meine ich. Bin nicht am PC gerade aber gestern hat es meine ich korrekt funktioniert.
Benutzeravatar
andie39
User
Beiträge: 152
Registriert: Dienstag 7. Dezember 2021, 16:32

Ansonsten wäre mein Gedanke das man es so wie jetzt macht aber noch:

else:
assert false

einbaut
Sirius3
User
Beiträge: 17712
Registriert: Sonntag 21. Oktober 2012, 17:20

Zu Deinem Code

Code: Alles auswählen

def add_movie():
    with open ("movies.csv", "r+") as file:
        eingabe = input("Geben Sie einen Filmtitel ein:")
        if eingabe in file.read():       
            print("Titel schon vorhanden")
    
        elif eingabe not in file:  
            file.write(eingabe + "\n")
Wie ich schon schrieb, ist `eingabe` ohne Zeile-Ende-Zeichen niemals in den Zeilen einer Datei. Daher ist die Abfrage `eingabe not in file` immer wahr.
Zweiter Grund ist, dass Du mit `file.read()` bereits die gesamte Datei gelesen hast, also `file` sofort mit StopIteration abbricht, und deshalb `not in` immer wahr ist.
Daher kann man das elif durch ein viel einfacheres `else` ersetzen, was auch logisch viel sinnvoller ist, denn sonst müßte man sich Gedanken machen, was diese Abfrage eigentlich soll.

Als nächstes ist `eingabe in file.read()` falsch, denn wenn Du schon den Film "Escape Room" eingetragen hast, kannst Du nicht mehr "Es" eintragen, weil das schon als Teilstring im ersten Film enthalten ist.
Benutzeravatar
andie39
User
Beiträge: 152
Registriert: Dienstag 7. Dezember 2021, 16:32

Also wäre es besser so zu machen wie in der remove-funktion mit readlines eines liste erstellen und die zu iterieren richtig?
Sirius3
User
Beiträge: 17712
Registriert: Sonntag 21. Oktober 2012, 17:20

Oder so, wie ich es vorgeschlagen habe.
Benutzeravatar
andie39
User
Beiträge: 152
Registriert: Dienstag 7. Dezember 2021, 16:32

Da bin ich jetzt komplett durcheinander. Ich weiß du meintest lesen und schreiben unabhängig.

Ich bin mir ehrlich nicht ganz klar, dass die eingabe nit in file immer wahr ist. Dann würde er ja immer die Eingabe eintragen.
Ich meine das war gestern beim Test nicht der Fall.

Wobei ich aber meine das du es sicher besser weißt als ich vielleicht habe ich nicht richtig hingesehen. Ich werde später wenn ich Zeit habe das noch einmal testen am PC
Benutzeravatar
andie39
User
Beiträge: 152
Registriert: Dienstag 7. Dezember 2021, 16:32

Also ich habe es nochmal nachgeschaut und laufen lassen.
So wie ich es selber geschrieben habe:

Ist der Film unbekannt wird er eingetragen. Ist er bekannt kommt die Meldung das es den schon gibt und er wird nicht eingetragen.

Tausche ich elif durch else aus gibt es einen Syntaxfehler.

Ich weiß also wirklich nicht was falsch sein soll.
Sirius3
User
Beiträge: 17712
Registriert: Sonntag 21. Oktober 2012, 17:20

Und wie sieht dann Dein Code aus und wie lautet der Fehler exakt? Und hast Du es mit "Escape Room" und "Es" versucht?
Benutzeravatar
andie39
User
Beiträge: 152
Registriert: Dienstag 7. Dezember 2021, 16:32

Das hier ist der Code zum hnizufügen;

Code: Alles auswählen

def add_movie():
    with open ("movies.csv", "r+") as file:
        eingabe = input("Geben Sie einen Filmtitel ein:")
        if eingabe in file.read():       
            print("Titel schon vorhanden")
    
        elif eingabe not in file:  
            file.write(eingabe + "\n")
Funktioniert.
Escape Room kann ich hinzufügen, Es danach natürlich nicht, das ist klar, weil Es dann ja schon in EScape Room vorkommt.
Sirius3
User
Beiträge: 17712
Registriert: Sonntag 21. Oktober 2012, 17:20

Ja aber den Code kennen wir doch schon, wo ist der mit `else` und Syntaxfehler?
Benutzeravatar
sparrow
User
Beiträge: 4165
Registriert: Freitag 17. April 2009, 10:28

Um nochmal auf den Beitrag von __blackjack__ zurück zu kommen:
"Zurück in die Zukunft" ist traurig, weil es nicht in die Liste darf weil "Zurück in die Zukunft II" schon da ist.
Benutzeravatar
andie39
User
Beiträge: 152
Registriert: Dienstag 7. Dezember 2021, 16:32

Oh ja das der Syntaxfehler reiche ich nach.

Sorry

Ja stimmt das war mir sogar klar.

Ich hatte eigentlich gedacht ihr meint , dass ein Film trotzdem hinzugefügt wird auch wenn es den schon gibt.

Aber ja die in Suche in der gesamten Datei ist ein Problem.

Ich habe nachgedacht:

Ergo wäre es richtig, als .readlines zu lesen.
Dann kann ich alle Zeilen iterieren und mit einem Vergleichsoperator arbeiten.

Nur wenn einer der Elementa exakt gleich ist schreibt er den Film nicht rein.

Richtig?
Benutzeravatar
andie39
User
Beiträge: 152
Registriert: Dienstag 7. Dezember 2021, 16:32

So, ich habe nun seit über einer Stunde versucht die Funktion Film hinzufügen sauber zu schreiben, also nicht mit IN, was bei ähnlichen Filmen dann teilweise nicht klappen würde sondern auch mit einer
For-schleife welche die Objekte der Liste durchgeht siehe hier:

Code: Alles auswählen

def add_movie():
    with open ("movies.csv", "r") as file:
        lines =  file.readlines()
    with open("movies.csv", "w") as file:
        eingabe = input("Geben Sie einen Filmtitel ein:")
        for element in lines:     

Ich war sicher, jetzt weiß ich es und schreibe das eben schnell den Rest zusammen aber nein.
Am Ende wurde es ein Trial and Error,
Entweder gibt es Fehlermeldungen oder die Funktion funktioniert nicht und fügt nichts hinzu.
Ich habe soviel probiert ich könnte alle Versuche gar nicht mehr posten.


Gerade frage ich mich, ob es noch Sinn macht das Programmieren weiter zu verfolgen, wenn ich schon an so einer einfachen Funktion scheitere.
Benutzeravatar
Dennis89
User
Beiträge: 1125
Registriert: Freitag 11. Dezember 2020, 15:13

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.
"When I got the music, I got a place to go" [Rancid, 1993]
Benutzeravatar
andie39
User
Beiträge: 152
Registriert: Dienstag 7. Dezember 2021, 16:32

Dennis89 hat geschrieben: Samstag 15. Januar 2022, 23:36 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.
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.
Benutzeravatar
__blackjack__
User
Beiträge: 13006
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:

Code: Alles auswählen

def load_movies(filename):
    ...


def save_movies(filename, movies):
    ...


def add_movie(filename, movie):
    ...
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:

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
rogerb
User
Beiträge: 878
Registriert: Dienstag 26. November 2019, 23:24

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")
Benutzeravatar
andie39
User
Beiträge: 152
Registriert: Dienstag 7. Dezember 2021, 16:32

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")
Mit break habe ich auch versucht solche Gedanken hatte ich konnte die aber nicht umsetzen.

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.
Antworten