Aufgabe für Uni

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
the_s
User
Beiträge: 4
Registriert: Dienstag 19. Dezember 2017, 12:30

Hey Leute! Ich erlaube mir mal einfach hier vorbeizustauben und mein Problem hier zu posten! Ich hab für die Uni ne Hausaufgabe, an der ich jetzt schon lange hänge. Ich komm aber nicht auf die Lösung!
Es soll eine Textdatei eingelesen werden, welche Namen und Alter enthält und aus diesen Daten eine Liste pro Person macht (Vorname, Nachname, Alter). In der Textdatei sind jedoch die Daten teils durch ";" oder anderen Zeichen getrennt, welche zu IndexError führen würden.
Es kann auch sein, dass das Alter so gegeben ist, dass sich dies nicht zu einem Integer ändern lässt (ValueError).
Auch kann es sein, dass es die Datei einfach nicht gibt (IOError).

Der Code sieht wie folgt aus:

Code: Alles auswählen

def Read_Personen_check(filename):
        Personen = []
        try:
                infile = open(filename, 'r') 
                for line in infile:
                        liste = line.split(',')
                        Vorname = liste[0].strip()
                        Nachname = liste[1].strip()
                        Alter = int(liste[2]) 
                        Personen.append([Vorname, Nachname, Alter])
                infile.close()
                return Personen
        except IOError:
                print "Kein File gefunden!"
                return Personen
        except IndexError:
                return "Index out of Range!"
                return Personen
        except ValueError:
                return "Konversion zu int nicht möglich!"
                return Personen
        else:
                pass
               
filename1 = "does_not_exist.txt"
l = Read_Personen_check(filename1)
print l

filename2 = "Personen_fehlerhaft.txt"
l = Read_Personen_check(filename2)
print l

Mein Problem ist, dass ich den else Block nicht richtig codieren kann. Ich möchte, dass bei einem Fehler trotzdem weitergearbeitet wird und die Liste mit den möglichen Daten auffüllt.
Es sollte wie folgt aussehen:

Kein File gefunden!
[]
Index out of range!
Konversion zu int nicht moeglich!
Index out of range!
[['Simon', 'Juljanovic', 17], ['Julia', 'Gernot', 15], ['Sarah', 'Mueller', 13], ['Mark', 'Schmitt', 19]]

Bei mir kommt folgendes:
Kein File gefunden!
[]
Index out of range!


Kann mir BITTE jemand helfen?

LG
sebastian0202
User
Beiträge: 168
Registriert: Montag 9. Mai 2016, 09:14
Wohnort: Berlin

Du kannst ja die Variable 'Personen' einfach deinen Funktionen übergeben!
Die manipulierst du dann und gibst sie einfach zurück und übergibst sie dann erneut.
Könnte also so aussehen:

Code: Alles auswählen

TEST=[]
def befuellen(TEST, wert="0"):
    TEST.append(wert)
    return TEST

TEST = befuellen(TEST)
print TEST
TEST = befuellen(TEST,"TEXT")
print TEST
Auf deinen Code gehe ich nicht ein, dass können andere sehr viel besser!
the_s
User
Beiträge: 4
Registriert: Dienstag 19. Dezember 2017, 12:30

Danke für den Input.
Ich denke aber, dass der Fehler darin liegt, dass ich die Try Schleife nicht komplett durchlaufen kann. Zurzeit wird nach einem Fehler die Schleife abgebrochen. Es sollte aber so sein, dass der Fehler ausgegeben wird (z.B. "Index out of Range!") und danach wieder von vorne die Schleife begonnen wird, sodass jede Date in der Textdatei durchlaufen wird.
skirnir
User
Beiträge: 33
Registriert: Sonntag 25. Januar 2015, 10:59

Dann musst du die IndexError und ValueError Exceptions innerhalb der for-Schleife behandeln.
Sirius3
User
Beiträge: 17737
Registriert: Sonntag 21. Oktober 2012, 17:20

@the_s: vergiss was Dir sebastian0202 vorgeschlagen hat. Man sollte nie Listen, die als Parameter übergeben werden, ändern, außer es wird explizit klar, dass die Liste geändert wird, z.B. die Funktion `extend_with_persons` oder so heißt. Dann sollte die Funktion aber keinen Rückgabewert haben.

Bei einer Exception wird der try-Block und damit auch die for-Schleife verlassen und landet bei Dir auch noch bei einem `return`. Du willst aber nur, dass die aktuelle Zeile "ignoriert" wird, dann darf der try-Block auch nur die relevanten Zeilen umschließen.

Zum Code allgemein: Funktionen und Variablen werden generell komplett klein geschrieben. Große Anfangsbuchstaben gibt es nur bei Klassennamen. Eingerückt wird immer mit 4 Leerzeichen pro Ebene, nicht 8 oder gar Tabs. Fehler die nicht sinnvoll abgefangen werden können, z.B. fehlende Dateien, sollten gar nicht abgefangen werden, sondern nur weitergereicht. Die Verstümmelung von Fehlerinformation hilft auch nicht gerade bei der Fehlersuche. Eine Funktion sollte nur einen Typ als Rückgabewert haben und nicht mal Liste und mal String. Dateien öffnet man am besten mit dem with-Statement, sonst wird sie im Fehlerfall nämlich nicht mehr geschlossen. Ein `else`-Zeig, der nur `pass` enthält ist überflüssig und kann gelöscht werden.

Dann kommt sowas raus:

Code: Alles auswählen

def read_persons(filename):
    personen = []
    with open(filename) as lines:
        for line in lines:
            try:
                surname, name, age = line.split(',')
            except IndexError:
                print "Zeile hat falsche Anzahl an Spalten:", line
            else:
                try:
                    age = int(age)
                except ValueError:
                    print "Alter keine Zahl:", age
                else:
                    personen.append((surname.strip(), name.strip(), age))
    return personen
the_s
User
Beiträge: 4
Registriert: Dienstag 19. Dezember 2017, 12:30

Vielen vielen Dank Leute! Habe das Beispiel mit Hilfe eures Inputs gelöst.

Mein Fehler war wirklich, dass ich die Ausnahmebehandlung nicht in der for - Schleife durchgeführt habe.

@Sirius3: Danke, anscheinend lernen wir es bisserl anders. Ich habe die Datei trotzdem nicht mit while geöffnet, sondern mit .open() und am Ende mit .close() geschlossen. Funktioniert tadellos.

Insgesamt kommt das raus, was erwartet wird! Danke nochmals!
Sirius3
User
Beiträge: 17737
Registriert: Sonntag 21. Oktober 2012, 17:20

@the_s: seit es with-Statements gibt, gibt es eigentlich kein "anders Lernen" mehr, sondern nur ein "falsch Lernen".
the_s
User
Beiträge: 4
Registriert: Dienstag 19. Dezember 2017, 12:30

Gibt es with erst seit python 3?
__deets__
User
Beiträge: 14522
Registriert: Mittwoch 14. Oktober 2015, 14:29

Nö. Python 2.5 glaube ich, aber definitiv schon seit 10 Jahren.
Benutzeravatar
/me
User
Beiträge: 3555
Registriert: Donnerstag 25. Juni 2009, 14:40
Wohnort: Bonn

the_s hat geschrieben:Gibt es with erst seit python 3?
Das gibt es schon seit Python 2.5, also gut 11 Jahre.
Antworten