erste Schritte mit Klassen und Objekten

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
akkdaa38
User
Beiträge: 2
Registriert: Samstag 27. November 2021, 19:06

Nabend liebe Community,

ich habe vor kurzem angefangen Python zu lernen und verzweifle echt an einer Aufgabe.
Ich soll eine Klasse Student erstellen, und dabei folgende 3 Studenten instanziieren:
- Anton, 19
- Quentin, 24
- Lena, 22

Und dabei soll ich diese Objekte in einem set mit dem Namen ergebnis hinzufügen.

Also bis jetzt sieht mein Code so aus:

Code: Alles auswählen

class Student:
    def __init__(self, name, alter):
        self.name = name
        self.alter= alter

    def info(self):
        return "'{}': {}".format(self.name, self.alter)

    def __str__(self):
        return self.info

Anton = Student(name="Anton", alter=19).info()
Quentin = Student(name="Quentin", alter=24).info()
Lena = Student(name="Lena", alter=22).info()


Die Ausgabe soll in etwa so aussehen: {"Anton": 19, "Quentin": 24, "Lena":22}

Nun ist das Problem an der Aufgabe, dass ich nicht so ganz verstehe wie ich diese Objekte in einem set mit dem Namen ergebnis hinzufügen kann.
Es wäre sehr lieb wenn ihr mit etwas helfen und Anreiz geben könntet.
Benutzeravatar
__blackjack__
User
Beiträge: 13077
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@akkdaa38: Ein `set` ist eine Datenstruktur von Python. Und wenn Du die `Student`-Objekte sonst zu nix brauchst, brauchst Du die nicht an Namen binden, sondern kannst gleich ein `set` aus den erstellten Objekten erstellen, denn `set` hat ähnlich wie Tupel, Listen, und Wörterbücher auch eine literale Schreibweise.

Die `info()`-Methode macht keinen Sinn und das Aufrufen schon gar nicht. Du sollst ja die *Objekte* am Ende in einem `set` haben und nicht das Ergebnis der `info()`-Aufrufe.

`__str__()` ist falsch weil das keine Zeichenkette zurück gibt. Da hättest Du `info()` wohl *aufrufen* wollen. Oder den Inhalt von `info()` eigentlich in die `__str__()` schreiben wollen.

Die Ausgabe soll auch sicher nicht so aussehen als wenn das `set` ein Wörterbuch (`dict`) wäre, denn das wäre extrem verwirrend.

Soll denn überhaupt etwas ausgegeben werden? Wenn man ein `set` in eine Zeichenkette umwandelt, selber oder indirekt weil man das Objekt beispielsweise `print()` übergibt, dann verwendet `set` die `repr()`-Darstellung der enthaltenen Elemente. Wie die anderen Container-Typen (`list`, `tuple`, `dict`, …) auch.

Für die `__repr__()` gibt es Konventionen an die man sich halten sollte, wenn man sie selbst implementiert: Entweder die Zeichenkette ist geeignet um sie als Python-Quelltext zu verwenden um so ein Objekt zu erstellen, oder es ist eine Information die sich an Programmierer richtet, zur Fehlersuche sinnvoll ist, und in ”spitze Klammern” eingefasst ist, also "<...>". Beispiel dafür wäre die Darstellung, welche man bekommt, wenn man die von `object` geerbte `__repr__()` verwendet, also so etwas wie "<__main__.Student at 0x7fbd13580f98>". Da steckt der Typ drin und eine ID, die dieses `Student`-Objekt eindeutig von anderen `Student`-Objekten unterscheidbar macht.
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
rogerb
User
Beiträge: 878
Registriert: Dienstag 26. November 2019, 23:24

@akkdaa38,

also wenn die Ausgabe so aussehen soll:
Die Ausgabe soll in etwa so aussehen: {"Anton": 19, "Quentin": 24, "Lena":22}
handelt es sich nicht um ein Set, sondern ein Dictionary. Also Schlüssel:Wert - Paare.
Ein Set besteht ja nur aus einzelnen Elementen. Zum Beispiel sähe das so aus: {"Anton", "Quentin", "Lena"}

Um die Ausgabe, die du vorgestellt hast zu erzeugen, könnte man so vorgehen:

Code: Alles auswählen

class Student:
    def __init__(self, name, alter):
        self.name = name
        self.alter = alter

# zunächst die Studenten-Objekte mit Name und Alter anlegen und in einer Liste speichern.
students = [
    Student(name="Anton", alter=19),
    Student(name="Quentin", alter=24),
    Student(name="Lena", alter=22),
]

# Dictionary-Comprehension zum Erzeugen eines Dictionaries. 
# Dabei sind die Elemente links und rechts vom Doppelpunkt jeweils
# Schlüssel und Wert des Dictionaries und werden über 
# den Zugriff auf die Attribute 'name' und 'alter' 
# schrittweise aus der 'students' Liste geholt und als kompletter Dictionary in 'ergebnis' gespeichert
ergebnis = {student.name: student.alter for student in students}
print(ergebnis)

"""
Ausgabe:
{'Anton': 19, 'Quentin': 24, 'Lena': 22}
"""
Falls die Ausgabe aber vielleicht so aussehen sollte (Achtung! Position der Anführungsstriche beachten):
{'Anton: 19', 'Quentin: 24', 'Lena: 22'}
Wäre es wirklich ein Set, wenn auch etwas verwirrend.
Und das ginge dann so:

Code: Alles auswählen

class Student:
    def __init__(self, name, alter):
        self.name = name
        self.alter = alter

    def __str__(self):
        return f"{self.name}: {self.alter}"


# Objekte erzeugen und gleich in einem Set anlegen.
# Durch die f'{}' Umschließung der Objekte werden sie mit der __str__ Methode in die
# gewünschten Zeichenketten umgewandelt  
ergebnis = {
    f'{Student(name="Anton", alter=19)}',
    f'{Student(name="Quentin", alter=24)}',
    f'{Student(name="Lena", alter=22)}'
}

print(ergebnis)
"""
Ausgabe:
{'Anton: 19', 'Quentin: 24', 'Lena: 22'}
"""
akkdaa38
User
Beiträge: 2
Registriert: Samstag 27. November 2021, 19:06

rogerb hat geschrieben: Samstag 27. November 2021, 20:37 @akkdaa38,

also wenn die Ausgabe so aussehen soll:
Die Ausgabe soll in etwa so aussehen: {"Anton": 19, "Quentin": 24, "Lena":22}
handelt es sich nicht um ein Set, sondern ein Dictionary. Also Schlüssel:Wert - Paare.
Ein Set besteht ja nur aus einzelnen Elementen. Zum Beispiel sähe das so aus: {"Anton", "Quentin", "Lena"}

Um die Ausgabe, die du vorgestellt hast zu erzeugen, könnte man so vorgehen:

Code: Alles auswählen

class Student:
    def __init__(self, name, alter):
        self.name = name
        self.alter = alter

# zunächst die Studenten-Objekte mit Name und Alter anlegen und in einer Liste speichern.
students = [
    Student(name="Anton", alter=19),
    Student(name="Quentin", alter=24),
    Student(name="Lena", alter=22),
]

# Dictionary-Comprehension zum Erzeugen eines Dictionaries. 
# Dabei sind die Elemente links und rechts vom Doppelpunkt jeweils
# Schlüssel und Wert des Dictionaries und werden über 
# den Zugriff auf die Attribute 'name' und 'alter' 
# schrittweise aus der 'students' Liste geholt und als kompletter Dictionary in 'ergebnis' gespeichert
ergebnis = {student.name: student.alter for student in students}
print(ergebnis)

"""
Ausgabe:
{'Anton': 19, 'Quentin': 24, 'Lena': 22}
"""
Falls die Ausgabe aber vielleicht so aussehen sollte (Achtung! Position der Anführungsstriche beachten):
{'Anton: 19', 'Quentin: 24', 'Lena: 22'}
Wäre es wirklich ein Set, wenn auch etwas verwirrend.
Und das ginge dann so:

Code: Alles auswählen

class Student:
    def __init__(self, name, alter):
        self.name = name
        self.alter = alter

    def __str__(self):
        return f"{self.name}: {self.alter}"


# Objekte erzeugen und gleich in einem Set anlegen.
# Durch die f'{}' Umschließung der Objekte werden sie mit der __str__ Methode in die
# gewünschten Zeichenketten umgewandelt  
ergebnis = {
    f'{Student(name="Anton", alter=19)}',
    f'{Student(name="Quentin", alter=24)}',
    f'{Student(name="Lena", alter=22)}'
}

print(ergebnis)
"""
Ausgabe:
{'Anton: 19', 'Quentin: 24', 'Lena: 22'}
"""
Hey, danke für diese ausführliche Antwort. Hat mir echt viel weiter geholfen. Jedoch kommt bei der Aufgabe immer wieder ein AttributeError:

Code: Alles auswählen

students = {"Anton"=19, "Quentin"=24, "Lena"=22}
for students_char in ergebnis:
	assert students_char.name in students
	assert students_char.alter == students[students_char.name]


Hier kommt der Fehler: 'str' object has no attribute 'name'

Inwiefern könnte dieser Fehler behoben werden?
Benutzeravatar
__blackjack__
User
Beiträge: 13077
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@akkdaa38: Das kann nicht sein, denn der Compiler kommt schon an der ersten Zeile nicht vorbei, weil das keine gültige Python-Syntax ist:

Code: Alles auswählen

In [58]: students = {"Anton"=19, "Quentin"=24, "Lena"=22}                       
  File "<ipython-input-58-9023e77716e0>", line 1
    students = {"Anton"=19, "Quentin"=24, "Lena"=22}
                       ^
SyntaxError: invalid syntax
Wenn Du Code und eine Fehlermeldung zeigst, dann wäre es gut wenn der Code lauffähig ist und zur Fehlermeldung gehört.

Warum hast Du denn bei dem Namen `students_char` den vorderen Teil in der Mehrzahl und warum überhaupt `char`? Was soll das bedeuten?
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
Antworten