Class-Methode

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
rejes
User
Beiträge: 4
Registriert: Samstag 10. November 2018, 14:02

[

Code: Alles auswählen

import datetime


class ResearchGroup:
    # constructor
    name = ""
    head = ""
    cost = 0
    # ist eine konstante variable
    total_presentation = 40
    # assozation * also mehrere Mitglieder
    members = []

    def __init__(self, name, head):
        self.head = head
        self.name = name

    # get methoden sind statisch
    @staticmethod
    def get_member():
        return Member(ResearchGroup.id, ResearchGroup.name)

    @staticmethod
    def get_head():
        return ResearchGroup.head

    def set_head(self, head):
        pass

    # fügt professor oder wimi mitglied hinzu
    def add_member(member):
        memberType = input('Professor or WiMi member?: Type p for professor or w for Wimi and press Enter ')
        if memberType == "p" or memberType == "P":
            actualMember = Professor(member)
            cost = int(input('Professor : Type cost for professor '))
            ResearchGroup.members.append(actualMember)
        elif memberType == "w" or memberType == "W":
            actualMember = WiMi(member)
            ResearchGroup.members.append(actualMember)


# abstrakte Klasse
class Member:

    def __init__(self, id, name):
        self.id = id
        self.name = name

    def show(self):
        raise NotImplementedError("Subclass must implement abstract method")


# veerbte Klasse
class Professor(Member):
    _cost_center_no = ResearchGroup.cost

    def show(self):
        print("Show Professor member:", self.name, " Cost: ",_cost_center_no )


# veerbte Klasse
class WiMi(Member):
    def show(self):
        print("Show WiMi member:", self.name)


class Presentation:

    def __init__(self, title, date):
        self.title = title
        self.date = date

    # gibt das heutige datum und uhrzeit zurück
    def change_date(self):
        return self.datetime.datetime.now()
Hallo,
Ich habe so ein Code erstellt für meine heutige Abgabe. nun wird leider der Code nicht ausgeführt.. deswegen wollte ich fragen ob ich da ein Fehler habe ? Oder was ich da noch eintippen soll damit es in der Konsole ausgegeben wird ? (Wir mussten eine Klassendiagramm in Python Programm umsetzen)

Ps: Könnt es auch gerne bewerten ob es gut oder schlecht ist.. :)

Danke im voraus
Rejes
Benutzeravatar
__blackjack__
User
Beiträge: 13069
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@rejes: Der Code wird ausgeführt. Nur steht da halt nur Code der Klassen definiert. Nachdem der Code auf Modulebene ausgeführt wurde, sind die Klassen definiert und das war's dann und das Programm endet. Was hättest Du denn erwartet und warum?

Der Code ist übrigens nicht so gut. Kritik folgt im nächsten Beitrag. :-)
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
rejes
User
Beiträge: 4
Registriert: Samstag 10. November 2018, 14:02

__blackjack__ hat geschrieben: Samstag 19. Januar 2019, 13:04 @rejes: Der Code wird ausgeführt. Nur steht da halt nur Code der Klassen definiert. Nachdem der Code auf Modulebene ausgeführt wurde, sind die Klassen definiert und das war's dann und das Programm endet. Was hättest Du denn erwartet und warum?

Der Code ist übrigens nicht so gut. Kritik folgt im nächsten Beitrag. :-)
Dankeschön :) ich mache zum Erstenmal so etwas und deswegen war ich mir dabei sehr unsicher. Nachdem ich es erstellt habe kam in der Konsole nichts raus.. muss da nicht in der Konsole rauskommen ?
Wieso findest du den Code nicht so gut ? :) Das würde ich gerne wissen :)
Sirius3
User
Beiträge: 17737
Registriert: Sonntag 21. Oktober 2012, 17:20

@rejes: `ResearchGroup` ist keine Klasse, sondern ein Namensraum mit lauter globalen Variablen. Das ist ein total kaputtes Design. Mach eine richtige Klasse daraus. Alle Klassenattribute weg, richtige Methoden, keine static_methods. get_member ist sowieso komisch, da der Member den Namen der ResearchGroup bekommt? Sollte dann aber auch create_member heißen. Getter und Setter benutzt man in Python nicht, get_head und set_head löschen. In add_member ist actualMember falsches Englisch. `cost` wird nicht verwendet, Falscheingaben werden nicht behandelt. Professor und WiMa haben zu wenig Parameter.

Bei Professor hast Du wieder so eine komische Klassenvariable, die immer 0 ist. Auch wenn sich mal cost in ReserchGroup ändern würde. Was soll `_cost_center_no` heißen` kosten_mitte_nein?

Statt einer show-Methode wäre eine __str__-Methode flexibler benutzbar.

Wenn `change_date` immer die aktuelle Zeit zurück gibt, dann ist was falsch.

Was willst Du überhaupt machen? So ganz wird das aus dem Code nicht klar.
Benutzeravatar
__blackjack__
User
Beiträge: 13069
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@rejes: Das `datetime`-Modul wird importiert aber nicht verwendet. Dafür wird in `Presentation.change_date` versucht auf ein nicht vorhandenes `datetime`-Attribut zuzugreifen. An der Stelle müsste man dann schon mal Anmerken, das man Programme entwickelt, und nicht einmal alles komplett runterschreibt und *dann* erst das erste mal überhaupt etwas von dem Code ausführt. Immer eine Funktionionalität nach der anderen und jedes mal *testen* ob das was man da gerade geschrieben hat überhaupt funktioniert. Falls nicht macht es keinen Sinn mit der nächsten Funktionionalität weiter zu machen, die vielleicht sogar auf dem nicht-funktionierenden Code aufbaut. Denn dann wird die ja zwangsläufig auch nicht funktionieren. Erst ganz zum Schluss alle Fehler zu suchen kann zu einer sehr frustrierenden Erfahrung werden. Besonders ärgerlich ist es in solchen Fällen dann wenn sich herausstellt das die bereits geschriebene Lösung so nicht funktionieren kann, und man grössere Teile umschreiben muss.

Der Kommentar ``# constructor`` im Klassenkörper von `ResearchGroup` ist falsch. Und auch den zur `__init__()`-Methode zu verschieben wäre falsch, denn auch die ist kein Konstruktor sondern initialisiert ein zu dem Zeitpunkt bereits vorhandenes Objekt. Der Konstruktor heisst in Python `__new__()` und da gibt es nur *ganz* selten Gründe den selbst zu implementieren, also den von `object` zu überschreiben. Das macht man nur wenn man ewtas aussergewöhnliches, ”magisches” tun möchte.

Der Kommentar zur ”konstante[n] Variable” ist widersinnig. Entweder Konstante, oder Variable. Konstanten kennzeichnet man in Python auch nicht mit Kommentaren, die man ja nur an der Stelle sieht wo die Konstante definiert wird, sondern dadurch das der Name KOMPLETT_GROSS geschrieben wird. Dann sieht man auch an den Stellen wo die Konstante *verwendet* wird, das es keine Variable ist, sondern ein konstanter Wert. Dann kann auch der Kommentar entfallen.

Variablen haben auf Klassen nichts zu suchen. Es gibt nur ganz wenige Fälle in denen die Sinn machen, hier sehe ich keinen. Im Gegenteil die sind soweit ich das sehe falsch. `head` und `name` sind Attribute des Exemplars und da gehört auch `members` hin.

`cost` scheint eine Konstante zu sein‽ Macht aber bei dem gezeigten Code überhaupt keinen Sinn. Das wäre eher ein Property in dem die Kosten zum Beispiel aus einem fixen Anteil und den Kosten pro Mitglied berechnet werden.

Das die beiden `get_*`-Methoden statisch sind, macht keinen Sinn. Insgesamt machen diese simplen Getter und Setter in Python keinen Sinn. Weg damit.

Der Kommentar bei `add_member()` wäre besser der Inhalt des Docstrings. Der Methode fehlt das `self`-Argument und die sollte auf dem Objekt arbeiten und nicht auf der Klasse, weil da wie gesagt keine Variablen drauf gehören.

Namen für alles ausser Konstanten (hatten wir ja schon) und Klassen (MixedCase) wird in Python klein_mit_unterstrichen geschrieben. Also `member_type` statt `memberType`.

Beim vergleichen mit einem Buchstaben ist der Code etwas einfacher und weniger fehleranfällig wenn Du die Eingabe in kleinbuchstaben umwandelst, dann brauchst Du nur noch mit einem kleinen literalen Buchstaben vergleichen.

Was soll denn das `member`-Argument von `ResearchGroup.add_member()` sein? Du verwendest das beim erstellen von `Professor` und `WiMi`, aber die erben von `Member` und das erwartet *zwei* Argumente: die `id` und den `namen`‽ Und die Werte könnte man auch vom Benutzer abfragen, wenn man da sowieso schon Benutzerinteraktion in der Methode hat. Wobei die Benutzerinteraktion da nicht hingehört.

Du möchtest in einem Wörterbuch die Bedeutung von „actual“ und „current“ nachschlagen und künftig „actual“ nicht mehr falsch verwenden. :-)

Für einen Professor wird bei der Eingabe `cost` erfragt und dann nicht verwendet. Warum wird das dann da überhaupt abgefragt? Kann es sein das meine Vermutung zu `cost` auf der `ResearchGroup` richtig ist und `cost` auch ein Attribut von `Member`-Objekten ist und das *da* eigentlich der Defaultwert 0 als Konstante sein soll? Wobei WiMis in der Realität ja auch nicht für lau arbeiten. Das ist sehr komisch. Ich würde also sagen `cost` ist ein ganz normales Attribut bei `Member`-Objekten.

Wenn man denn unbedingt abstrakte Klassen haben möchte bei denen Benutzer die nicht implementieten Methoden auch tatsächlich in abgeleiteten Klassen implementieren muss damit sich Exemplare davon erstellen lassen, dann gibt es dafür Dekoratoren im `abc`-Modul.

Der Kommentar „vererbte Klasse“ macht keinen Sinn. Das sieht man doch direkt in der Zeile danach am Code. Faustregel: Kommentare beschreiben nicht *was* der Code macht, denn das beschreibt der Code bereits, sondern *warum* er es so macht, sofern das nicht offensichtlich ist.

Der Sinn von `Professor._cost_center_no` erschliesst sich mir so gar nicht. Ich hätte nicht einmal den Hauch einer Idee was das mal werden sollte…

`Presentation.change_date()` macht 0 Sinn. Also erst einmal würde man bei dem Namen erwarten, dass das Datum vom `Presentation`-Exemplar tatsächlich geändert wird. Und dann fehlt da ein Argument *auf was* es geändert wird. Dann wäre es aber ein Setter, die man in Python so nicht schreibt. Also soll das Datum vielleicht auf das aktuelle geändert werden. Dann ist `update_date()` ein besserer Name für die Methode.

Als Zwischenergebnis und nur sehr oberflächlich getestet:

Code: Alles auswählen

#!/usr/bin/env python3
import abc
import datetime


class ResearchGroup:
    
    COST = 0
    TOTAL_PRESENTATION = 40

    def __init__(self, name, head):
        self.name = name
        self.head = head
        self.members = list()

    @property
    def cost(self):
        return sum(member.cost for member in self.members) + self.head.cost

    def add_member(self):
        """Füge Professor oder Wimi als Mitglied hinzu."""
        # 
        # TODO User interaction doesn't belong here!
        # 
        member_type2create_func = {'p': Professor, 'w': WiMi}
        member_type = input(
            'Professor or WiMi member?: Type p for professor or w for Wimi'
            'and press Enter '
        ).lower()
        create_member = member_type2create_func[member_type]
        id_ = int(input('Please enter id: '))
        name = input('Please enter the name: ')
        cost = int(input('Please enter the cost: '))
        self.members.append(create_member(id_, name, cost))
    
    def show(self):
        print('Research group', repr(self.name), 'lead by:')
        self.head.show()
        print('Members:')
        for member in self.members:
            member.show()
        print('Total cost:', self.cost)


class Member(abc.ABC):

    def __init__(self, id_, name, cost):
        self.id = id_
        self.name = name
        self.cost = cost

    @abc.abstractmethod
    def show(self):
        pass


class Professor(Member):
    
    def show(self):
        print('Show Professor member:', self.name, ' Cost: ', self.cost)


class WiMi(Member):

    def show(self):
        print('Show WiMi member:', self.name, ' Cost:', self.cost)


class Presentation:

    def __init__(self, title, date):
        self.title = title
        self.date = date

    def update_date(self):
        self.date = datetime.datetime.now()


def main():
    research_group = ResearchGroup(
        'Würgeschlangen', Professor(42, 'Evil', 23000)
    )
    research_group.add_member()
    research_group.show()


if __name__ == '__main__':
    main()
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
Antworten