Seite 2 von 2

Re: Geschweifte Klammern Ausgabe bei __repr__

Verfasst: Dienstag 24. Oktober 2023, 17:04
von Sirius3
Jetzt solltest Du Dir nochmal ganz genau anschauen, welche Argumente welchem __init__-Aufruf übergeben werden. Du hast zwei Fehler, die sich gegenseitig aufheben.

Re: Geschweifte Klammern Ausgabe bei __repr__

Verfasst: Dienstag 24. Oktober 2023, 17:34
von martin2p
Meinst du hier?:

Code: Alles auswählen

school = School("Pleissa", "high", 100)
print(school)
print(school.name)
print(school.level)
school.number_of_Students = 200
print(school.number_of_Students)
Dass quasi die 200 nicht ausgegeben wird sondern 100 bleibt?

Re: Geschweifte Klammern Ausgabe bei __repr__

Verfasst: Dienstag 24. Oktober 2023, 18:53
von __blackjack__
@martin2p: Da bleibt nichts bei 100. Und bei `School` ist das auch noch richtig. Bei den beiden abgeleiteten Klassen ist es falsch.

Im Grunde würde ich es auch als falsch ansehen das man bei `PrimarySchool` immer ein "primary" und bei `HighSchool` immer ein "high" übergeben muss. Das ist ja offensichtlich redundant und sollte schon im Datentyp enthalten sein und nur bei der allgemeinen `School`-Klasse übergeben werden müssen, weil es dort eben noch nicht aus dem Datentyp klar ist um welche Art von Schule es sich handelt.

Re: Geschweifte Klammern Ausgabe bei __repr__

Verfasst: Dienstag 24. Oktober 2023, 19:22
von martin2p
Ihr meint also, dass man bei diesen beiden:

Code: Alles auswählen

school = PrimarySchool("Grundschule", "primary", 300, "Pickup Allowed")
print(school)

school = HighSchool("Gymnasium", "High", 500, ["Tennis", "Basketball"])
print(school)

quasi die Bezeichnung der Klasse in die jeweilige def __init__() übergeben soll?

Code: Alles auswählen

class PrimarySchool(School):
    def __init__(self, level, name, number_of_Students, pickup_policy):
        super().__init__(level, name, number_of_Students)
        self.pickup_policy = pickup_policy

class HighSchool(School):
    def __init__(self, level, name, number_of_Students, sports_teams):
        super().__init__(level, name, number_of_Students)
        self.sports_teams = sports_teams
Ich hab versucht im jeweiligen Konstruktor das level = high oder primary zu setzen, dann kommt er jedoch mit den default Argumenten wie name, etc. nicht mehr klar.

Re: Geschweifte Klammern Ausgabe bei __repr__

Verfasst: Dienstag 24. Oktober 2023, 20:26
von __blackjack__
@martin2p: Weder `PrimarySchool.__init__()` noch `HighSchool.__init__()` sollte man `level` übergeben müssen. Das macht keinen Sinn etwas übergeben zu müssen was bei jedem Aufruf den jeweils gleichen Wert haben muss. Denn ein ``school = PrimarySchool("high", "Van Rossum Elementary", 42, "pickup allowed")`` wäre *falsch* weil eine Grundschule keine Highschool ist. Und *das* das eine Grundschule ist, wird ja schon dadurch klar, dass man `PrimarySchool` verwendet. Wenn man eine Highschool haben wollte, würde man ja die `HighSchool`-Klasse verwenden. Also *muss* man bei `PrimarySchool` als `level` *immer* "primary" übergeben und bei `HighSchool` *immer* "high". Das macht keinen Sinn. Dieses Wissen sollte in der Klasse selbst stecken.

Re: Geschweifte Klammern Ausgabe bei __repr__

Verfasst: Mittwoch 25. Oktober 2023, 02:00
von snafu
Analog zu "primary" würde ich ja "secondary" nehmen. Diese Einteilung der Schulformen ist im englischsprachigen Raum geläufig. Und im Deutschen gibt es ja auch die Sekundärstufe.

Wenn du jetzt noch den mehrfach geäußerten Vorschlag der Vorposter umsetzt, dann hast du (hoffentlich) ein bisschen mehr von der Funktionsweise einer Basisklasse beim Vererben verstanden. Mach dir einfach mal klar, dass eine abgeleitete Klasse nicht zwingend jedes Argument der Basisklasse in ihrer Signatur enthalten muss. Manchmal werden Argumente auch nur intern verwendet, um die Basisklasse sinnvoll initialisieren zu können.

Re: Geschweifte Klammern Ausgabe bei __repr__

Verfasst: Mittwoch 25. Oktober 2023, 17:54
von martin2p
Ich verstehe worauf ihr hinaus wollt, aber ich habe keine Ahnung wie ich das in den Code einbauen soll. Dass quasi der Klassenname als Referenz für das Level einzusetzen ist :(

Die Subklassen PrimarySchool und Highschool greifen ja immer auf den __str__ Befehl der Elternklasse School zurück, also auf diesen Ausdruck:

Code: Alles auswählen

def __str__(self):
        return f"A {self.level} school named {self.name} with {self.number_of_Students} students. "
Könnt ihr mir bitte zeigen wie ich das schreiben muss? Ich bekomme es einfach nicht hin...

Code: Alles auswählen

class School:
    def __init__(self, level, name, number_of_Students):
        self.name = name
        self.level = level
        self.number_of_Students = number_of_Students

    def __str__(self):
        return f"A {self.level} school named {self.name} with {self.number_of_Students} students."



class PrimarySchool(School):
    def __init__(self, name, number_of_Students, pickup_policy):
        super().__init__(name, number_of_Students)
        self.pickup_policy = pickup_policy

    def __str__(self):
        return f"{super().__str__()} The pickup policy is {self.pickup_policy}."



class SecondarySchool(School):
    def __init__(self, name, number_of_Students, sports_teams):
        super().__init__(name, number_of_Students)
        self.sports_teams = sports_teams

    def __str__(self):
        return f"{super().__str__()} SportsTeams: {self.sports_teams}."


######################################

school = School("Pleissa", "Highschool", 100)
print(school)
print(school.name)
print(school.level)
school.number_of_Students = 200
print(school.number_of_Students)

school = PrimarySchool("Grundschule", 300, "Pickup Allowed")
print(school)

school = SecondarySchool("Gymnasium", 500, ["Tennis", "Basketball"])
print(school)

Re: Geschweifte Klammern Ausgabe bei __repr__

Verfasst: Mittwoch 25. Oktober 2023, 18:25
von narpfel
@martin2p: Die Elternklasse erwartet, dass ein `level` an `__init__` übergeben wird. Also musst du beim Aufruf von `super().__init__` in den Kindklassen ein `level` übergeben.

Re: Geschweifte Klammern Ausgabe bei __repr__

Verfasst: Mittwoch 25. Oktober 2023, 18:59
von martin2p
Über self.level oder level="Primary" ?

Ich habe verschiedene Varianten durchprobiert und erhalte nur Errors

Re: Geschweifte Klammern Ausgabe bei __repr__

Verfasst: Mittwoch 25. Oktober 2023, 19:03
von __deets__
Schau dir die Parameter von school an, und was du daran übergibst in deinen abgeleiteten Klassen. Im super()-Aufruf.

Re: Geschweifte Klammern Ausgabe bei __repr__

Verfasst: Mittwoch 25. Oktober 2023, 19:11
von narpfel
martin2p hat geschrieben: Mittwoch 25. Oktober 2023, 18:59 Ich habe verschiedene Varianten durchprobiert und erhalte nur Errors
Die Fehlermeldungen sind dazu da, dir zu helfen. Fehlermeldungen zu lesen und zu verstehen ist eins der wichtigsten Dinge, die man lernen muss, weil Fehlermeldungen der Weg sind, mit der dir Python sagt, was du wo falsch gemacht hast. Also musst du die Fehlermeldungen entweder selbst lesen, oder (zusammen mit dem passenden Code) hier zeigen, damit wir Hinweise geben können, die dir helfen, die Fehlermeldungen zu verstehen.

Und zu deiner Frage: Übergeben ist ein fester Begriff, der immer das gleiche bedeutet. Man übergibt Parameter an Funktionen. Eine Zuweisung ist keine Übergabe.

Re: Geschweifte Klammern Ausgabe bei __repr__

Verfasst: Mittwoch 25. Oktober 2023, 19:17
von martin2p
So ich habs nun endlich ... mit euch möchte ich nie Rätselraten spielen :lol:

Code: Alles auswählen

class School:
    def __init__(self, level, name, number_of_Students):
        self.name = name
        self.level = level
        self.number_of_Students = number_of_Students

    def __str__(self):
        return f"A {self.level} school named {self.name} with {self.number_of_Students} students."


class PrimarySchool(School):
    def __init__(self, name, number_of_Students, pickup_policy):
        super().__init__("Primary", name, number_of_Students)
        self.pickup_policy = pickup_policy

    def __str__(self):
        return f"{super().__str__()} The pickup policy is {self.pickup_policy}."


class SecondarySchool(School):
    def __init__(self, name, number_of_Students, sports_teams):
        super().__init__("Secondary", name, number_of_Students)
        self.sports_teams = sports_teams

    def __str__(self):
        return f"{super().__str__()} SportsTeams: {self.sports_teams}."


######################################

school = School("Highschool", "Pleissa", 100)
print(school)
print(school.name)
print(school.level)
school.number_of_Students = 200
print(school.number_of_Students)

school = PrimarySchool("Testschule", 300, "Pickup Allowed")
print(school)


school = SecondarySchool("Testschule2", 500, ["Tennis", "Basketball"])
print(school)

Code: Alles auswählen

A Highschool school named Pleissa with 100 students.
Pleissa
Highschool
200
A Primary school named Testschule with 300 students. The pickup policy is Pickup Allowed.
A Secondary school named Testschule2 with 500 students. SportsTeams: ['Tennis', 'Basketball'].
Ist das nun in Ordnung so????

Re: Geschweifte Klammern Ausgabe bei __repr__

Verfasst: Donnerstag 26. Oktober 2023, 16:59
von snafu
Ich kenne die Aufgabenstellung im Original nicht, aber der direkte Aufruf von School() sieht in diesem Zusammenhang irgendwie komisch aus, zumindest wenn da "Highschool school" rauskommt. Da fährt man besser, wenn man das Level optional macht, also mit None vorbelegt und beim Erzeugen des Textes dann eine Sonderbehandlung für None einbaut.

Und die Sport-Teams könnte man auch mit ", ".join() anzeigen lassen.

Re: Geschweifte Klammern Ausgabe bei __repr__

Verfasst: Freitag 27. Oktober 2023, 13:19
von __blackjack__
Wegen dem leichten Unglauben, dass man da so viel Code ”wiederholen” muss, hier mal das gleiche Programm in der Programmiersprache in der mein erster Kontakt mit Objektorientierung war: Turbo Pascal. Da muss man nicht nur Getter/Setter schreiben, weil es keine Properties gibt, sondern sich auch noch selber um die Speicherverwaltung kümmern, und die Klassen zum entsprechenden Untertyp casten weil man nicht einfach so alle Methoden aufrufen kann, sondern nur solche die zur Typdeklaration passen:

Code: Alles auswählen

program Schools;

type
  PSchool = ^TSchool;
  TSchool = object
    private
      name: String;
      level: String;
      numberOfStudents: Word;
    public
      constructor Init(n: String; lvl: String; nStudents: Word);
      function GetName: String;
      function GetLevel: String;
      function GetNumberOfStudents: Word;
      procedure SetNumberOfStudents(n: Word);
      function ToString: String; virtual;
  end;
  PPrimarySchool = ^TPrimarySchool;
  TPrimarySchool = object(TSchool)
    private
      pickupPolicy: String;
    public
      constructor Init(n: String; nStudents: Word; pPolicy: String);
      function GetPickupPolicy: String;
      function ToString: String; virtual;
  end;
  PHighschool = ^THighschool;
  THighschool = object(TSchool)
    private
      sportsTeams: String;
    public
      constructor Init(n: String; nStudents: Word; teams: String);
      function GetSportsTeams: String;
      function ToString: String; virtual;
  end;

var
  school: ^TSchool;

constructor TSchool.Init(n: String; lvl: String; nStudents: Word);
begin
  name := n;
  level := lvl;
  numberOfStudents := nStudents;
end;

function TSchool.GetName: String;
begin
  GetName := name;
end;

function TSchool.GetLevel: String;
begin
  GetLevel := level;
end;

function TSchool.GetNumberOfStudents: Word;
begin
  GetNumberOfStudents := numberOfStudents;
end;

procedure TSchool.SetNumberOfStudents(n: Word);
begin
  numberOfStudents := n;
end;

function TSchool.ToString: String;
var
  s: String;
begin
  Str(GetNumberOfStudents, s);
  ToString := 'A ' + GetLevel + ' school named ' + GetName + ' with ' + s
              + ' students.';
end;

constructor TPrimarySchool.Init(n: String; nStudents: Word; pPolicy: String);
begin
  inherited Init(n, 'primary', nStudents);
  pickupPolicy := pPolicy;
end;

function TPrimarySchool.GetPickupPolicy: String;
begin
  GetPickupPolicy := pickupPolicy;
end;

function TPrimarySchool.ToString: String;
begin
  ToString := inherited ToString + ' The pickup policy is ' + GetPickupPolicy
              + '.';
end;

constructor THighschool.Init(n: String; nStudents: Word; teams: String);
begin
  inherited Init(n, 'high', nStudents);
  sportsTeams := teams;
end;

function THighschool.GetSportsTeams: String;
begin
  GetSportsTeams := sportsTeams;
end;

function THighschool.ToString: String;
begin
  ToString := inherited ToString + ' Sports teams: ' + GetSportsTeams + '.';
end;

begin
  school := New(PSchool, Init('Pleissa', 'high', 100));
  WriteLn(school^.ToString);
  WriteLn(school^.GetName);
  WriteLn(school^.GetLevel);
  school^.SetNumberOfStudents(200);
  WriteLn(school^.GetNumberOfStudents);
  Dispose(school);

  school := New(PPrimarySchool, Init('Codecademy', 300, 'pickup allowed'));
  WriteLn(PPrimarySchool(school)^.GetPickupPolicy);
  WriteLn(school^.ToString);
  Dispose(school);

  school := New(PHighschool,
                Init('Rock''n''Roll High', 500, 'Tennis, Basketball'));
  WriteLn(PHighschool(school)^.GetSportsTeams);
  WriteLn(school^.ToString);
  Dispose(school);
end.
Die Sport-Teams habe ich hier mal als Zeichenkette umgesetzt, weil eine dynamische Datenstruktur das noch mal *deutlich* verlängert hätte, weil man die hätte selbst implementieren müssen, und die Klassen hätten dann noch einen Destruktor gebraucht um den Speicher *dafür* dann auch wieder freizugeben.