andie39‘s Fragen Thread

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.
Benutzeravatar
andie39
User
Beiträge: 152
Registriert: Dienstag 7. Dezember 2021, 16:32

Darum frage ich.
Jetzt sollen die ja nur verfügbar oder verliehen kennen.
Was ist denn die beste Lösung nach den Profis hier?
Benutzeravatar
andie39
User
Beiträge: 152
Registriert: Dienstag 7. Dezember 2021, 16:32

sparrow hat geschrieben: Mittwoch 19. Januar 2022, 06:17 Eigentlich ist das eine Eigenschaft, die ich beim Film erwarten würde. Verliehen oder nicht. Oder ein Status der nicht nur 2 Werte haben kann: Verliehen/Verloren/Aussortiert.
Du meinst Eigenschaft aus der Objektorientietung?
rogerb
User
Beiträge: 878
Registriert: Dienstag 26. November 2019, 23:24

@andie39,

verfügbar / verliehen ist *ein* Attribut, so wie an / aus. Man hat ja auch keine Anschalter und separate Ausschalter für's Licht. Ein Schalter kann beide Zustände darstellen. So ist das auch bei dem Attribut "verfügbar" / "verliehen" das ist ein boolscher Wahrheitswert.

verfügbar == True -> kann ausgeliehen werden
verfügbar == False -> kann nicht ausgeliehen werden.

Attribut, Eigenschaft, Property ist hier im weiteren Sinne das gleiche und hat erstmal nichts mit Objektorientierung zu tun.
Erst wenn es an die technische Umsetzung geht, kann es sein, dass das Attribut "verfügbar" auch ein Attribut in einer Klasse ist. Es kann aber auch einer Spalte in einer csv-Tabelle oder einem Schlüssel in einem Dictionary entsprechen.

Aktuell hast du ja nur das Attribut "Name" und das Attribut "verliehen" .
Das kann dann also eine csv-Datei sein, in der jeder Film ein Zeile mit seinen Attributen belegt.
In der Spalte "Name" steht halt "Rambo" oder "Escaperoom" und in der Spalte "verliehen" steht entweder True oder False.
Benutzeravatar
andie39
User
Beiträge: 152
Registriert: Dienstag 7. Dezember 2021, 16:32

Das war meine Frage, weil ich gerade das neue Thema Klassen begonnen habe.

Ob das gemeint war oder eine einfachere Lösung
Benutzeravatar
andie39
User
Beiträge: 152
Registriert: Dienstag 7. Dezember 2021, 16:32

NEUE FRAGE

Aktuell bin ich dabei list comprehensions zu verstehen, grundsätzlich tue ich das.
Aber doch stolpere ich etwas wenn es komplexer wird auch im Hinblick der Schleifen, sprich genauer wenn zwei Schleifen zum Einsatz kommen.
Bei einer einzelnen ist das nicht das Problem.

Beispiel:

numbers_times_2 = [x*2 for x in numbers]

Code: Alles auswählen

numbers = [1,2,3,4,5,6]
numbers_times_2 = [x*2 for x in numbers]
Das das gleiche wie:

Code: Alles auswählen

numbers_times_2 = []
    for x in numbers:
        numbers_times_2.append(x*2)
Das verstehe ich auch.

Aber bei einem größeren Beispiel:

Siehe hier:
https://einfachpython.de/python-list-co ... erstellen/

Code: Alles auswählen


weekday_temperatures = [
{'day': 'Monday',    'date': '2019-07-15', 'temperature': 31},
{'day': 'Tuesday',   'date': '2019-07-16', 'temperature': 33},
{'day': 'Wednesday', 'date': '2019-07-17', 'temperature': 27},
{'day': 'Thursday',  'date': '2019-07-18', 'temperature': 25},
{'day': 'Friday',    'date': '2019-07-19', 'temperature': 30},
{'day': 'Saturday',  'date': '2019-07-20', 'temperature': 31},
{'day': 'Sunday',    'date': '2019-07-21', 'temperature': 29},
{'day': 'Monday',    'date': '2019-07-22', 'temperature': 25},
{'day': 'Tuesday',   'date': '2019-07-23', 'temperature': 31},
{'day': 'Wednesday', 'date': '2019-07-24', 'temperature': 26},
{'day': 'Thursday',  'date': '2019-07-25', 'temperature': 23},
{'day': 'Friday',    'date': '2019-07-26', 'temperature': 22},
{'day': 'Saturday',  'date': '2019-07-27', 'temperature': 23},
{'day': 'Sunday',    'date': '2019-07-28', 'temperature': 32}
]
hot_work_days = [(hot_day['date'], hot_day['temperature']) for hot_day in[workday for workday in weekday_temperatures if workday['day'] not in ['Saturday', 'Sunday']] if hot_day['temperature'] >= 30]


Ich verstehe hier folgendes:

hot_work_days = [(hot_day['date'], hot_day['temperature']) for hot_day in[workday for workday in weekday_temperatures if workday['day'] not in ['Saturday', 'Sunday']] if hot_day['temperature'] >= 30]
Es ist in eine ecke Klammer gesetzt weil die Variabel ja eine Liste sein soll.
(hot_day['date'], hot_day['temperature']) ist am Anfang und ja wenn man so will das, was in der Liste ausgegeben werden soll.
Es soll der Wert von date und temperatur ausgegeben werden Zeile für Zeile also für jede Zeile hot_day und später dann eben unter der Bedningung das die Temperatur größer oder gleich 30 ist:
if hot_day['temperature'] >= 30]
Auch wird nach dem Tag durchsucht und auch hier gibt es eine Bedingung.

Was mir hier nicht ganz klar ist, hot_day iterierung läuft ja auch über die Liste: weekday_temperatures.
Das wird aber nicht direkt so benannt sonder:
for hot_day in und dann kommt in einer eigenen Klammer/Liste die Suche nach dem Tag, diese Suche/Schleife verweißt ja erst explizit auf die weekday_temperatures.
Ist für mich sehr schwierig zu verstehen.
Und die alternative Form ist mir auch nicht klar wie die ausgeschrieben werden würde.

Wie kann man diese verschachtelten Listen genau verstehen?
Sirius3
User
Beiträge: 17749
Registriert: Sonntag 21. Oktober 2012, 17:20

Solch ein Konstrukt kann man gar nicht verstehen. Es sagt nur "schaut wie cool ich bin, dass ich so viel in eine Zeile stopfen kann.
Also als erstes das sinnvoll umgebrochen:

Code: Alles auswählen

hot_work_days = [
    (hot_day['date'], hot_day['temperature'])
    for hot_day in [
        workday for workday in weekday_temperatures
        if workday['day'] not in ['Saturday', 'Sunday']
    ]
    if hot_day['temperature'] >= 30
]
Dann muß man die innere Liste herausnehmen, und den Variablen sinnvolle Namen geben.
Ein Datensatz mit day, date und temperature ist kein `workday`. Und auch kein `hot_day`. Da mir gerade kein wirklich sinnvoller Name für diese Kombination an Daten einfällt, nenne ich es einfach `entry`.

Code: Alles auswählen

workday_temperatures = [
    entry for entry in weekday_temperatures
    if entry['day'] not in ['Saturday', 'Sunday']
]

hot_work_day_temperatures = [
    (entry['date'], entry['temperature'])
    for entry in workday_temperatures
    if entry['temperature'] >= 30
]
Damit wird klar, dass wir die Inputdaten `weekday_temperatures` in zwei Schritten filtern.
Könnte man auch in einem Schritt machen:

Code: Alles auswählen

hot_work_day_temperatures = [
    (entry['date'], entry['temperature'])
    for entry in weekday_temperatures
    if entry['day'] not in ['Saturday', 'Sunday'] and entry['temperature'] >= 30
]
Zuletzt geändert von Sirius3 am Donnerstag 20. Januar 2022, 19:16, insgesamt 1-mal geändert.
Benutzeravatar
andie39
User
Beiträge: 152
Registriert: Dienstag 7. Dezember 2021, 16:32

Dein zweiter Code der ist für mich nachvollziehbar.
Heißt das, du nutzt keine list_comprehension?
rogerb
User
Beiträge: 878
Registriert: Dienstag 26. November 2019, 23:24

@andie39,

(in der zwischenzeit hatte Sirius3 etwas ähnliches geschrieben, ich poste meine Antwort trotzdem mal)

ich denke nicht, dass ich eine bessere Erklärung finde als in der verlinkten Erklärung.
Der Hinweis die Listcomprehension umzuformatieren, so dass sie über mehrere Zeilen geht, ist schonmal sehr gut.

Code: Alles auswählen

hot_work_days1 = [
    (hot_day["date"], hot_day["temperature"])
    for hot_day in [workday for workday in weekday_temperatures if workday["day"] not in ["Saturday", "Sunday"]]
    if hot_day["temperature"] >= 30
]
In diesem Fall erkennt man aber, dass es eine innere Listcomprehension gibt, die erstmal eine Wochentage-Liste erstellt. Diese ist umschlossen von einer äußeren, die dann wieder über diese iteriert und alle ausgibt für die die Temperatur größer 30 ist.

Also etwas auseinandergezogen würde das so aussehen:

Code: Alles auswählen

workdays = [workday for workday in weekday_temperatures if workday["day"] not in ["Saturday", "Sunday"]
hot_work_days = [(hot_day["date"], hot_day["temperature"]) for hot_day in workdays]
Es ist aber eigentlich ein etwas spezieller Fall, da über eine einfache Liste aus Dictionaries iteriert wird. Eine verschachtelte Listcomprehension wäre nicht nötig um auf die Ergebnisse zu kommen.
Man kann einfach über die Ergebnisse iterieren und alle Tage mit ihren Temperaturwerten ausgeben für die gilt: Kein Samstag oder Sonntag *UND* Temperatur über 30

Code: Alles auswählen

hot_work_days2 = [
    (hot_day["date"], hot_day["temperature"])
    for hot_day in weekday_temperatures
    if hot_day["day"] not in ["Saturday", "Sunday"] and hot_day["temperature"] >= 30
]
Das ist ein kaum erkennbarer Unterschied zu oben.

Fazit: Selbst wenn man selbst versteht, was diese verschachtelte Listcomprehension tut, fällt es anderen sicher schwerer, da sie den Code nicht geschrieben haben.
Man sollte so etwas nicht tun und statt dessen eine einfache for-Schleife verwenden:

Code: Alles auswählen

hot_work_days = []
for day in weekday_temperatures:
    if day["day"] not in ["Saturday", "Sunday"] and day["temperature"] >= 30:
            hot_work_days.append((day["date"], day["temperature"]))
Wenn ich mich nicht vertan habe, machen alle Beispiele das gleiche, aber lesbarer ist meiner Meinung nach das letzte.
Benutzeravatar
andie39
User
Beiträge: 152
Registriert: Dienstag 7. Dezember 2021, 16:32

Danke. Also wird hier von euch eine listcomprehe sion selten genutzt?
Zumindest bei derart verschachtelten Liste /Dictonaries?

Ach ja.
Das hier ist ja ein Tulpel weches aus einen Dictionary generiert ist:

(entry["date"], entry["temperature"])
In den eckigen Klammern wird ja definiert was in die Tupel geschrieben wird. Es wird dort der Wert zum dem Schlüssel aus dem Dictionary eingefügt richtig?

Wenn man nun aber den Schlüssel selbst dort haben wollen würde.
Das macht hier keinen Sinn ich weiß, es geht mir nur um das Prinzip:
Was müsste man schreiben damit der Schlüssel ausgegeben wird?
rogerb
User
Beiträge: 878
Registriert: Dienstag 26. November 2019, 23:24

andie39 hat geschrieben: Donnerstag 20. Januar 2022, 20:49 Wenn man nun aber den Schlüssel selbst dort haben wollen würde.
Eigentlich braucht man das nur wenn man über ein Dictionary iterieren will. Dazu gibt es verschiedene Möglichkeiten.
Betrachten wir mal nur das Dictionary für den ersten Tag:

Code: Alles auswählen

first_day = weekday_temperatures[0]

# iterieren über die keys
for key in first_day:
    print(key)

"""
day
date
temperature
"""

# iterieren über die values
for value in first_day.values():
    print(value)

"""
Monday
2019-07-15
31
"""

# iterieren über beides
for key, value in first_day.items():
    print(f"{key:15}: {value}")

"""
day            : Monday
date           : 2019-07-15
temperature    : 31
"""
Benutzeravatar
andie39
User
Beiträge: 152
Registriert: Dienstag 7. Dezember 2021, 16:32

Ahh ok.

Also ich muss sagen;
Das ist alles nicht ohne.

Da wird dann ein Dictionary zu einer Liste mit Tupeln…..

Nebenbei in der Eingangsfrage mit dem Link zur Aufgabe dort steht:

Angenommen wir haben einen Datensatz mit Temperaturen an verschiedenen Wochentagen. Die Liste besteht aus Tupeln (Wochentag, Datum, Temperarur). Wir möchten jetzt alle Arbeitstage finden, an denen über 30°C erreicht wurden, Wochenenden interessieren uns nicht.

weekday_temperatures = [
{'day': 'Monday', 'date': '2019-07-15', 'temperature': 31},
{'day': 'Tuesday', 'date': '2019-07-16', 'temperature': 33},

Aber das ist doch eine Liste von Dictionarys oder irre ich mich?
Tupel sind ()
Dictionary {}
rogerb
User
Beiträge: 878
Registriert: Dienstag 26. November 2019, 23:24

Ja, gute gesehen. Da hat vielleicht jemand erst den Text geschrieben und sich dann später beim Programmieren gedacht, dass ein Dictionary besser wäre, dann aber vergessen den Text zu ändern.
Sowas kommt manchmal vor, wenn Kommentare im Code stehen, die keiner liest. Da wird dann aus irgendeinem Grund der Code geändert und die Kommentare ergeben Jahre später keinen Sinn mehr.
Benutzeravatar
andie39
User
Beiträge: 152
Registriert: Dienstag 7. Dezember 2021, 16:32

Ein Glück. Ich dachte schon ich wäre jetzt komplett daneben.

Also ich muss sagen:
Respekt vor jedem der so programmieren kann.
Das ist echt herausfordernd und viel.

Ich merke das ich immer wieder das entscheidende nicht sehe.

Gerade habe ich das Thema Klassen und Methoden durchgenommen.
Da war ich schon gespannt da mir immer wieder bei echten Code Beispielen das Class und self untergekommen ist.
Also etwad das wichtig ist, ich aber nicht kannte.

Jedenfalls gab es am Ende eine kleine Aufgabe nichts besonderes eigentlich aber ich kam nicht auf die Lösung.

Als ich dann die Lösung abgespielt hatte habe ich das schon verstanden. Aber zuvor…..wie ein Brett vor dem Kopf…..
Benutzeravatar
__blackjack__
User
Beiträge: 13103
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@andie39: Also ich benutze „comprehensions“ (gibt ja mehr als nur die für Listen) und Generatorausdrücke recht häufig. Auch mal verschachtelt. Eher nicht mehr als zwei Ebenen tief. Es muss einfach genug bleiben, dass man es noch verstehen kann, wo auch, wie man IMHO am Beispiel sehen kann, die Formatierung eine grosse Rolle spielt. Also Beispielsweise wenn man ein 2D-Feld mit True/False-Werten als Zeichenkette haben möchte mit "#" für True und "." für False, dann ist das hier IMHO vertretbar:

Code: Alles auswählen

    def __str__(self):
        return "\n".join(
            "".join("#" if cell else "." for cell in row) for row in self.rows
        )
Eine Möglichkeit solche Ausdrücke einfacher zu halten ist eventuell auch Teilausdrücke in sinnvoll benannte Funktionen heraus zu ziehen. Und/oder im konkreten Beispiel aus den Wörterbüchern Werte mit einem `collections.namedtupel`-Typ oder einer eigenen Klasse zu machen. Kommt halt auch so ein bisschen darauf an wo die Daten her kommen und wo sie hin sollen. Und in diesem Fall auch wie sehr man denen vertraut. Ist jetzt ein ganz anderes Thema, aber in den Wörterbüchern sind redundante Informationen drin. Da habe ich gleich mal den Reflex testen zu wollen ob "day" und "date" denn tatsächlich überall zusammen passen.

Code: Alles auswählen

#!/usr/bin/env python3
from datetime import datetime as DateTime
from pprint import pprint

from attr import attrib, attrs

DAYNAMES = [
    "Monday",
    "Tuesday",
    "Wednesday",
    "Thursday",
    "Friday",
    "Saturday",
    "Sunday",
]


@attrs(frozen=True)
class DayTemperature:
    date = attrib()
    temperature = attrib()

    @property
    def day_name(self):
        return DAYNAMES[self.date.isoweekday() - 1]

    def is_work_day(self):
        return self.date.isoweekday() < 6

    @classmethod
    def from_mapping(cls, mapping):
        result = cls(
            DateTime.strptime(mapping["date"], "%Y-%m-%d").date(),
            mapping["temperature"],
        )
        if result.day_name != mapping["day"]:
            raise ValueError(
                f"date is a {result.day_name},"
                f" mapping says it is a {mapping['day']}"
            )
        return result


def main():
    days = list(
        map(
            DayTemperature.from_mapping,
            [
                {"day": "Monday", "date": "2019-07-15", "temperature": 31},
                {"day": "Tuesday", "date": "2019-07-16", "temperature": 33},
                {"day": "Wednesday", "date": "2019-07-17", "temperature": 27},
                {"day": "Thursday", "date": "2019-07-18", "temperature": 25},
                {"day": "Friday", "date": "2019-07-19", "temperature": 30},
                {"day": "Saturday", "date": "2019-07-20", "temperature": 31},
                {"day": "Sunday", "date": "2019-07-21", "temperature": 29},
                {"day": "Monday", "date": "2019-07-22", "temperature": 25},
                {"day": "Tuesday", "date": "2019-07-23", "temperature": 31},
                {"day": "Wednesday", "date": "2019-07-24", "temperature": 26},
                {"day": "Thursday", "date": "2019-07-25", "temperature": 23},
                {"day": "Friday", "date": "2019-07-26", "temperature": 22},
                {"day": "Saturday", "date": "2019-07-27", "temperature": 23},
                {"day": "Sunday", "date": "2019-07-28", "temperature": 32},
            ],
        )
    )

    hot_work_days = [
        day for day in days if day.is_work_day() and day.temperature >= 30
    ]

    pprint(hot_work_days)


if __name__ == "__main__":
    main()
Subtile Falle: Tupel sind nicht ``()``, beziehungsweise sind die leeren Klammern tatsächlich das einzige Tupel das so entstehen muss (wenn man es literal schreibt). Man hat oft Klammern um es deutlicher zu machen oder weil es syntaktisch notwendig ist um Mehrdeutigkeiten zu vermeiden/aufzulösen, aber Tupel mit Werten entstehen durch Komma(s).
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
Benutzeravatar
andie39
User
Beiträge: 152
Registriert: Dienstag 7. Dezember 2021, 16:32

Ich sag ja wirklich komplex und herausfordernd.
Ich habe mir auch nun gedacht das ich den Kurs erst einmal durchgehe und damit alles mal gesehen habe.

Feinheiten und Details lassen sich dann später ja auch wieder nachschlagen.

Ich hoffe mal das ist eine gute Idee.
Benutzeravatar
andie39
User
Beiträge: 152
Registriert: Dienstag 7. Dezember 2021, 16:32

Neue Frage: Komposition

Aktuell bin ich beim Thema Objektorierntierung

Klassen, Methoden

Und hier bei der Komposition.
Ich brauche das nicht erklären, wisst ihr besser.

Hier habe ich nun eine kleine Frage. Ich habe zwei Code Beispiele für Komposition.
Code 1 aus dem Internet
Code 2 aus einem Buch, das ich neben meinem Udemy Kurs lese.

Code 1

Code: Alles auswählen


class Employee: 
  
    
    def __init__(self, name, age): 
        self.name = name 
        self.age = age 
  
    
    def emp_data(self): 
        print('Name of Employee : ', self.name) 
        print('Age of Employee : ', self.age) 
  
  
class Data: 
    def __init__(self, address, salary, emp_obj): 
        self.address = address 
        self.salary = salary 
  
        
        self.emp_obj = emp_obj 
  
    
    def display(self): 
  
        
        
        self.emp_obj.emp_data() 
        print('Address of Employee : ', self.address) 
        print('Salary of Employee : ', self.salary) 
  

emp = Employee('Ronil', 20) 
  
data = Data('Indore', 25000, emp) 
  
data.display()

Hier ist es klar:
self.emp_obj.emp_data() emp_obj von data ist emp_obj und das ist emp
Also ist der code = emp.emp_data()
emp_data ist eine Klasse davor und definitert und wird durch emp = Employee('Ronil', 20)
Im Konstruktor gebildet.

Soweit alles klar hier auch wie Data konstruiert wird.

Nun Code 2:

Code: Alles auswählen


class WindowsMyDocuments:
    def save(self,document):
        destination = Path.home() / "Documents" / "scan.txt"
        print("Saving to: ", destination)
        destination.write_text(document)
        
        
class LinuxHomeDir:
    def save(self,document):
        destination = Path.home() / "scan.txt"
        print("Saving to: ", destination)
        destination.write_text(document)
        

class Fileprinter:
    def __init__(self, windows, linux):
        self._windows = windows
        self._linux = linux
    
    def print(self, document):
        destination =(
            self._linux
            if platform.system() = "linux"
            else self._windows
        )
        destination.save(document)
        
        
print_to_file = Fileprinter(
    windows = WindowsMyDocumemts(), 
    linux = LinuxHomeDir()
)

print_to_file.print(file1)

Auch hier eigentlich klar was mich hier irritiert ist:

print_to_file = Fileprinter(
windows = WindowsMyDocumemts(),
linux = LinuxHomeDir()
)

Das windows=WindowsMy…… ist doch nicht nötig oder?
Es geht doch auch wie in Code1:

print_to_file = Fileprinter(
WindowsMyDocumemts(),
LinuxHomeDir()
)



Oder irre ich mich?
Benutzeravatar
sparrow
User
Beiträge: 4193
Registriert: Freitag 17. April 2009, 10:28

Man kann Argumente per Position oder per Keyword übergeben. Da der Name eines Arguments meist schon viel über desse Funktion aussagt, ist es manchmal gar nicht verkehrt, die auch zu benennen, obwohl es eigentlich nicht nötig ist.
Grundsätzlich hat man dann natürlich auch die Eigenschaft, dass die Reihenfolge der Argumente ergal ist und gezielt nur bestimmte Argumente gesetzt werden können, während andere den Standardwert behalten.
Benutzeravatar
andie39
User
Beiträge: 152
Registriert: Dienstag 7. Dezember 2021, 16:32

sparrow hat geschrieben: Sonntag 23. Januar 2022, 00:21 Man kann Argumente per Position oder per Keyword übergeben. Da der Name eines Arguments meist schon viel über desse Funktion aussagt, ist es manchmal gar nicht verkehrt, die auch zu benennen, obwohl es eigentlich nicht nötig ist.
Grundsätzlich hat man dann natürlich auch die Eigenschaft, dass die Reihenfolge der Argumente ergal ist und gezielt nur bestimmte Argumente gesetzt werden können, während andere den Standardwert behalten.
Heißt das ich mich nicht irre und das windows =windowsMy… unnötig ist?
Und man nur windowsMy… hätte schreiben können?
Benutzeravatar
__blackjack__
User
Beiträge: 13103
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@andie39: Also das erste Beispiel finde ich nicht klar und ich würde auch sagen das ist falsch. Erst einmal modelliert die Klasse `Employee` keinen Angestellten, denn dazu fehlen Eigenschaften die einen Angestellten ausmachen. Beispielsweise das Gehalt. Das was in `Employee` zusammengefasst wird, kann man vielleicht als `Person` bezeichnen.

Dann haben wir da Abkürzung (`emp_*`) in einem Namen und bei `Employee` ist dass dann auch noch die Abkürzung für die Klasse — was keinen Sinn macht, denn diese Information steht ja bereits im Klassennamen, die braucht man nicht noch mal wiederholen. Und bei Vererbung wird es dann komisch, weil die Methoden Abkürzungen enthalten die dann vielleicht gar nicht mehr zum Namen der abgeleiteten Klasse gehören.

Bleibt `data()`, was so gar kein guter Name für eine Methode ist, mal abgesehen davon, dass der Name supergenerisch ist. Und die Methode erfüllt die gleiche Aufgabe wie `Data.display()`, was sinnvoller benannt ist, und dann sollte das bei `Employee` bzw. `Person` vielleicht auch so heissen.

Bei `Data` ist der Name auch zu generisch. Wenn die erste Klasse `Person` heisst, würde man `Data` aber *nicht* `Employee` nennen wollen, denn ein `Employee` *ist* ja eine Person, das wäre also eine Vererbung und keine Komposition. Also bräuchte man einen Namen wo die *Bestandteile* Adresse, Gehalt, und Person tatsächlich sinnvoll sind. Vielleicht ein Arbeitsvertrag, also `EmploymentContract`.

In der zweiten Klasse ist dann `emp` wieder eine blöde Abkürzung. Insbesondere weil in Kontexten wo der Arbeitnehmer vorkommen kann, ja auch der Arbeitgeber eventuell irgend wo mal modelliert werden könnte. Und dann hat man lauter Code wo `emp`-Abkürzungen sind und darf dann jedes mal überlegen oder nachforschen ob da nun jeweils `employee` oder `employer` gemeint ist. Abk. s. i.d.R. doof. 🤡

Der Suffix `*_obj` macht in 99,99% der Fälle keinen Sinn, weil in Python *alles* was man an einen Namen binden kann, ein Objekt ist. Objekt und Wert sind in Python synonym.

Und ja ich weiss, dass das aus dem Internet ist und nicht von Dir, Du kannst da nichts für!

Code: Alles auswählen

class Person:
    def __init__(self, name, age):
        self.name = name
        self.age = age

    def display(self):
        print("Name of Person:", self.name)
        print("Age of Person:", self.age)


class EmploymentContract:
    def __init__(self, employee, address, salary):
        self.employee = employee
        self.address = address
        self.salary = salary

    def display(self):
        self.employee.display()
        print("Address of Employee:", self.address)
        print("Salary of Employee:", self.salary)


person = Person("Ronil", 20)
contract = EmploymentContract("Indore", 25_000, person)
contract.display()
Was man da inhaltlich noch anmerken könnte, wäre das `age` ungünstig ist. Da müsste man dann einmal im Jahr alle Daten durchgehen und das Alter um eins rauf setzen. Geburtsdatum macht da mehr Sinn. `age` kann man dann als `property()` anbieten, weil man das ja ausrechnen kann.

Beim zweiten Beispiel kann man die Namen der Argumente beim Aufruf auch weg lassen. Was mich bei dem Beispiel irritiert ist die leicht sinnlose Komplexität, denn die Plattform ändert sich nicht während der Laufzeit, und diese Entscheidung dann jedes mal beim Aufruf von `print()` zu treffen, macht überhaupt keinen Sinn.

Alle drei Klassen sind keine wirklichen Klassen. Die beiden ersten haben nicht einmal einen Zustand und bei ``print_to_file.print(…)`` sieht man an den Namen schon, dass da irgendwas faul ist. `print_to_file()` wäre schon ein sinnvoller Name für die Tätigkeit die da ausgeführt wird.

Aber erst einmal zu den ersten beiden ”Klassen” die gar keine Methoden enthalten sondern jeweils nur eine Funktion. Die kann man auch einfach als das schreiben, als Funktion:

Code: Alles auswählen

def _windows_save(document):
    destination = Path.home() / "Documents" / "scan.txt"
    print("Saving to: ", destination)
    destination.write_text(document, encoding="utf-8")


def _linux_save(document):
    destination = Path.home() / "scan.txt"
    print("Saving to: ", destination)
    destination.write_text(document, encoding="utf-8")
Dann kann man einfach aufgrund von `platform.system()` auswählen welche davon aufgerufen werden soll. Und das muss man auch nicht mit einer Klasse verkomplizieren, sondern kann da einfach *einmal* entscheiden welche der beiden Funktionen unter einem sinnvollen Namen verwendet wird:

Code: Alles auswählen

def _windows_save(document):
    destination = Path.home() / "Documents" / "scan.txt"
    print("Saving to: ", destination)
    destination.write_text(document, encoding="utf-8")


def _linux_save(document):
    destination = Path.home() / "scan.txt"
    print("Saving to: ", destination)
    destination.write_text(document, encoding="utf-8")


save = _linux_save if platform.system() == "linux" else _windows_save

save("Example text.")
Wobei man das noch weiter vereinfachen könnte, da die beiden Funktionen fast das gleiche machen und sich nur durch einen Teilpfad unterscheiden.
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
Benutzeravatar
andie39
User
Beiträge: 152
Registriert: Dienstag 7. Dezember 2021, 16:32

Hallo.

Ja aber die Namen sind hier nicht wichtig.
Also zumindest im
Hinblick der Frage wobei ich verstehe was du meinst.
Das sind Beispiele von anderen aus einem Buch und dem Internet. Ob die Variabelnamen etc passend sind ist, zumindest für mich gerade uninteressant.
Mir geht es explizit um meine Frage ob ich das richtig sehe oder das windows = WindowsMy…. doch entscheidend ist.
Antworten