Eine Datei in PyCharm auf Inalte prüfen.

Hier werden alle anderen GUI-Toolkits sowie Spezial-Toolkits wie Spiele-Engines behandelt.
Antworten
YoDreck
User
Beiträge: 5
Registriert: Donnerstag 12. Dezember 2019, 17:19

Hallo,

Vorweg : Ich bin neu im Thema Python und habe das in der Berufsschule. Entschuldige möchte ich mich ebenfalls sollte das ganze hier im falschen Thread sein :/

Ich habe eine Frage zum Thema auslesen einer ganzen Datei die ich in meinem Code mit einbeziehe. Das ist eine ehr erweitere Schulaufgabe, wo eig. nur angegeben werden sollte (Mit einer Vorgabe von 5 Elementen die die Alkalimetalle sind), ob es sich um ein Alkalimetall handelt oder eben nicht. Vom Grundkonzept her funktioniert mein Code auch und liest mir die Infos aus der TXT raus und gibt mir demnach auch alles wieder was ich möchte. Aber mein Problem besteht darin, dass ich es nicht schaffe dass wenn ich einen falschen Namen eingebe, dass er zurück zum Anfang geht und mich darauf hinweist, dass meine Eingabe falsch war.

Probiert habe ich:

Code: Alles auswählen

if W not in Elemente:
     print("Element nicht vorhanden!")
     print("Bitte gib einen gueltigen Namen an!")
     abfrage()
else:
     """Code ab "if Daten[0]…""""
Er macht das dann auch, zumindest teilweise... Ich bekomme meine print("")'s angezeigt aber die zeigt er mir auch wenn das Element in Elemente vorhanden ist (Also auch wenn meine Eingabe ' W ' korrekt ist).
Hat jemand eine Lösung wie ich es schaffe, dass er mir die ***ganze*** Datei nach dem ersten String jeder Zeile durchsucht, mir dann entweder den Code unten ausführt oder mir dann eben sagt was ich oben versuchte.

Ich bedanke mich schonmal im voraus :)



###### Code ######

Code: Alles auswählen

Elemente = open('Periodensystem.txt', 'r')


def abfrage():
    print("Ueber welches Element möchtest du etwas wissen?")
    W = str(input("Element: "))

    for line in Elemente:
        Daten = line.rstrip().split(",")
        if Daten[0].__contains__(W):
            print("")
            print("Name: " + Daten[0])
            print("Kuerzel: " + Daten[1])
            print("Ordnungszahl: " + Daten[2])
            print("Gruppe: " + Daten[3])
            print("")
            abfrage()
    Elemente.close()


abfrage()


###### TXT######
Wasserstoff,H,1,Gase
Helium,HE,2,Gase
Lithium,LI,3,Alkalimetalle
Beryllium,BE,4,Erdalkalimetalle
Sirius3
User
Beiträge: 17750
Registriert: Sonntag 21. Oktober 2012, 17:20

Wenn man eine Datei einmal gelesen hat, ist der Dateizeiger am Ende, nochmaliges Lesen liefert dann nichts mehr. `input` liefert schon einen String, das nochmal in einen String zu wandeln, ist unsinnig. Warum benutzt Du hier `__contains__` wo Du doch oben `in` benutzt, was richtiger wäre.
Du prüfst jetzt, ob die Eingabe im Element vormkommt, also "lium" in "Helium" oder in "Beryllium". Ist das so gewollt?
Rekursion ist selten sinnvoll, und dort, wo Du es eingefügt hast würdest Du ja von vorne beginnen, wenn ein Eintrag gefunden wurde, und nicht, wie Du geschrieben hast, wenn es nicht gefunden wird.
Also was willst Du nun?

Element.close wird an einer ganz anderen Stelle aufgerufen, als das `open`. Damit so etwas gar nicht erst passieren kann, benutzt man das with-Konstrukt.

Zur Namenskonvention: Variablen werden in Python klein_mit_unterstrich geschrieben.

Code: Alles auswählen

def abfrage():
    print("Ueber welches Element möchtest du etwas wissen?")
    element = input("Element: ")
    with open('Periodensystem.txt') as elemente:
        for line in elemente:
            name, kuerzel, ordnungszahl, gruppe = line.rstrip().split(",")
            if element in name:
                print("")
                print(f"Name: {name}")
                print(f"Kuerzel: {kuerzel}")
                print(f"Ordnungszahl: {ordnungszahl}")
                print(f"Gruppe: {gruppe}")
                print("")

abfrage()
Wenn man etwas wiederholen will, benutzt man eine Schleife. Zum Beispiel:

Code: Alles auswählen

while True:
    abfrage()
    if input("Nochmal (j/n)") == "n":
        break
YoDreck
User
Beiträge: 5
Registriert: Donnerstag 12. Dezember 2019, 17:19

Danke für deine Antwort.

Ich möchte, einen genauen wert aus der TXT ziehen die mir dann das ausgibt was er mir printen soll. Da ich mal davon ausgehe, dass man den ganzen Namen sucht muss ich das erstmal so lassen. Die TXT hat noch mehr als diese 4 Zeilen :D...

Aber das klappte ja soweit bei mir.

Ich möchte, dass er mir bei einer falschen Eingabe die abfrage erneut startet.
Sirius3
User
Beiträge: 17750
Registriert: Sonntag 21. Oktober 2012, 17:20

Wenn Du das machen willst, mußt Du Dein Problem in kleinere Teile teilen, von denen Du die Lösung umsetzen kannst. Also Einlesen und Suchen kannst Du schon. Dann mußt Du Dir nur noch merken, ob es einen Treffer gab und das als Bedingung zum Abbruch der Schleife, die ich Dir gezeigt habe, nehmen.
YoDreck
User
Beiträge: 5
Registriert: Donnerstag 12. Dezember 2019, 17:19

Okay, vielen Dank :)
YoDreck
User
Beiträge: 5
Registriert: Donnerstag 12. Dezember 2019, 17:19

Guten Morgen,

das ganze funktioniert jetzt soweit. aber das Problem ist wenn ich die abfrage mache (egal wie ich das versuche einzubauen!) ob der Wert vorhanden ist, printet er mir für alle 118 zeilen in der TXT "Element nicht gefunden" und springt dann zurück zur abfrage. Wie kann man das lösen, dass er das nur einmal anzeigt. Ich weiß ich muss mich da auch ausprobieren aber ich komme damit einfach nicht weiter!
Jankie
User
Beiträge: 592
Registriert: Mittwoch 26. September 2018, 14:06

Du kannst z.B. ein Flag einbauen, das immer False ist und wenn er eins findet wird es auf True gesetzt, wenn das Flag am Ende immer noch False ist kannst du dann ausgeben, dass er das Element nicht gefunden hat.


kurzes Beispiel:

Code: Alles auswählen

SOURCE = """A
B
C
D
E
F
G"""

zu_suchen = input("Nach was soll gesucht werden?: ")

flag = False
for line in SOURCE:
    if line.strip() == zu_suchen:
        flag = True

print(('Gefunden', 'nicht gefunden')[flag == False])
Benutzeravatar
__blackjack__
User
Beiträge: 13107
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@Jankie: Das ist ineffizient denn wenn es gefunden wurde braucht man ja nicht weitersuchen. Wenn das in einer Funktion steckt gibt man dann einfach `True` zurück. Und nach der Schleife dann ein ``return False``, denn wenn der Code nicht in der Schleife durch das ``return True`` dort abgebrochen wurde, dann weiss man ja, das es nicht gefunden wurde:

Code: Alles auswählen

def search(lines, what):
    for line in lines:
        if line.strip() == what:
            return True
    return False
Wobei man das mit `any()` und einem Generatorausdruck auch kompakter ausdrücken kann:

Code: Alles auswählen

def search(lines, what):
    return any(line.strip() == what for line in lines)
Mit literalen Wahrheitswerten vergleicht man nicht. ``flag == False`` würde man als ``not flag`` schreiben, oder nur ``flag`` und die Reihenfolge der Werte im Tupel ändern. Wobei das auch eher nach einem Hack aussieht aus einer Zeit als es noch keinen bedingten Ausdruck gab:

Code: Alles auswählen

print("gefunden" if search(SOURCE, zu_suchen) else "nicht gefunden")
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
YoDreck
User
Beiträge: 5
Registriert: Donnerstag 12. Dezember 2019, 17:19

Danke für die Hilfe, jetzt funktioniert es genau so wie ich mir das vorgestellt habe :D...
Antworten